-
Notifications
You must be signed in to change notification settings - Fork 3
Order of merged-stylesheets.css in <head> #24
Comments
A pretty common use case if you're using a third-party UI framework such as Bootstrap is loading it from a CDN, for example using Helmet to inject link tags. . The problem is that currently, Meteor's own stylesheet (merged-stylesheets.css) gets injected right at the top of the , meaning that Bootstrap's CSS will come afterwards and override your own user-defined styles. So I would suggest modifying the boilerplate-generator package so that Meteor's own stylesheet always comes last. Are there any downsides to doing this? |
Any update on this? |
@aliogalli, it appears the decision was made to not address it in the initial Boilerplate refactor (#8820 above) but instead to come back to it as a separate issue. @abernix, please don't forget to come back around to the CSS load issue. My code is littered with class="myapp" additions to Bootstrap classes just so I can override the default Bootstrap formatting. Clutters up and confuses the code. Re the previous discussions, I'm happy with whatever solution is decided upon, though I would lean toward adding a replacement field, suggested by hwilson, to allow me to put the merged code wherever I want (not for any particular use case, just seems the most flexible). |
I really like the proposed solution of using the The placement of the merged CSS has performance implications as well. Using SSR, bundle visualizer, Meteor 1.6 and dynamic imports I was able to drop the initial load time from 5 seconds to 1.4 seconds (thanks @benjamn!). The merged CSS is in the rendering critical path and it's delaying the app by the 0.5 seconds. It's also impacting the lighthouse performance results ( right now it's 52% but it could be 92% if I remove the non critical css and inline what's needed.) So @abernix I think this change is crucial for developing a highly performing Meteor apps in addition to having more control over the style sheets priority. |
Thanks for sharing your findings @aliogaili. Now that the boilerplate refactor has been completed, making the change outlined in meteor/meteor#8651 (comment) is quite straightforward (actually, I made the necessary code changes a while back to test things out; they could be easily brought into the main repo). I'll bring this up at this week's issue triage meeting. More details shortly - thanks! |
Thanks @hwillson Just to confirm, with the proposed solution, would it be possible to place the link outside of the head block? |
Since the boilerplate generator technically allows for multiple CSS resources, I would tweak @hwillson's <head>
<title>meteor-issue-8651</title>
<link
rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"
integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u"
crossorigin="anonymous"
/>
<meteor-bundled-css />
</head> The |
And while we're at it, we might as well support |
Perhaps we can think and name those placeholders as component (Meteor Component). The two components are Developers are already used to the concept of components and perhaps it's useful to name and present them that way. |
But as they aren't really components I personally don't think they should be "seen" as components which might confuse inexperienced developers. |
Fair point, I just thought I'd put it out there. |
But the concept of components has already been stretched out in the react ecosystem, think of react helmet, it's behaviour is not that different then the proposed Meteor tags. And inexperienced developers will probably not use those tags anyway, so perhaps it's debatable objection. |
@aliogaili, what about angular developers using meteor or vue or some other view layer? They might be used to components looking different. I think that this should be it's own thing which isn't something to relate to "components" because it's a part of Meteor's build system. But that's just my view of this. |
Got it @zimme I guess it's because I'm coming from react naming convention. So are you also objecting to what @benjamn proposed? because what he proposed in syntactically similar to a component (with vue naming convention) or are you just objecting on using react naming convention (which I agree that it might be confusing to some) ? |
What he suggested is ok with me because that's closer to html element naming convention. |
I agree with you, I think it's better to keep closer to the html naming convention. But I guess it's worth emphasizing, from conceptual perspective, that what's being proposed here is actually a custom html tags (a.k.a components) transpiled by Meteor build system and could potentially have additional props in future. |
what @benjamn proposed looks great to me. I can easily imagine using it in my apps. |
I just have a new comment: I love Meteor, but now that I think of it twice, I wish I was able to take full control of packages on the client-side. The problem is that Meteor client build provides an abstraction layer that was supposed to make things simpler (goold old Blaze-only times) but now is actually more complicated (because if you open front-end to multiple stacks, then you need more control over them) I totally believe we should be able to plug any front-end stack, and it should work with server-side rendering provided by the server-render package. To maintain backward compat, the current build system should be isolated in a package, and removing this package should let me play with the frontend stack at will (think of it like insecure package) I am totally PRO having some solution like meteor-client-bundler integrated in Meteor core and supported by MDG. I would then be able to control my client-side script and css order entirely, even maybe to switch my builder to webpack for the front, and still be able to connect to any meteor backend via HTTP or DDP and get this reactivity, if I opt-in for some packages that enable that to me. Well... Sorry if I am a dreamer |
@antoninadert I'm not sure where to begin convincing you of the value of Meteor's build system versus something like Webpack. What you're proposing no longer sounds like much of a framework at all, and I'm afraid I can't imagine that dream having more value than the current system for most Meteor developers. Let's keep this issue focused on the JS/CSS tag order problem? |
Sure ! |
I personally think that if loading order of CSS files matters, your CSS code is messed up. It is the purpose of the "cascading" part in CSS that you can override your styles as needed, your styles just have to be specific enough. The simplest solution to achieve this is to add a style class to your <html class="my-awesome-app"> You can now override any Bootstrap style easily by prepending it with .my-awesome-app .btn-primary {
background-color: magenta;
} A second approach is to use the SASS version of Bootstrap which allows you to customize Bootstrap via variables. In my own apps, I am using a combination of the two approaches and am very happy with this solution. Another benefit of the "class-on-html-tag" approach is that it can be applied to user use-cases, too. For instance, I am defining additional classes depending on the environment the app runs in. If the app runs on iOS, I add the |
In that case you won't mind if we change it to be the other way around ;) But seriously, I think relying on source order in CSS is pretty common, it helps avoid selector inflation. Making selectors more specific than needed is generally a bad idea anyway, and sometimes it's just not practical. For example, what if you're using a third-party bootstrap theme stylesheet and you need to ensure it always load after the main bootstrap CSS? You can't really just prepend every single class with |
To imply that CSS load order doesn't or shouldn't matter is simply incorrect. It's part of the CSS specification. See Section 6 of this W3C document entitled Order of Appearance. And, yes, you can overcome the load order by adding additional selector specificity, but that clutters up the CSS with extra selectors that could be avoided if the Meteor load order is changed. What I'm interested in most, is there a use case where changing the order of the CSS bundle from first to last will break existing code. If the developer has already worked around the issue by adding selectors, moving the bundle to the end shouldn't break anything. But is there a case where the existing order matters and would break code if the order is reversed? I'm looking for a reason to not simply implement case 1 (which involves moving 4 lines of code from the top to the bottom of the template). Otherwise, options 2 and 3 would suit your viewpoint since if you don't modify your code everything remains the same. |
I can't really think of a scenario where option 1 would break people's code, but with CSS who knows… It's worth pointing out that it's really easy to copy the package's code locally and change it manually if you need to. |
There might be cases where the simple change in load order breaks existing styles, since load order matters in CSS. Imagine a developer who had set styles for an html element like p and a third party library had overwritten this. This might be inadvertently, but changing the load order would change the styling immediately. Having said that, I think that putting the user-defined styles last is what developers would expect in the first place, since some just rely on the order of appearance and believe their own styles should always „win“. The only problem is that Meteor decided to do it the other way around, and I am a big fan of backwards compatibility unless it isn’t avoidable. I had so many cases in the past when a simple meteor update broke my apps that I became somewhat sensitive for this. |
@SachaG in principle, you’re right. That’s one of the reasons why I love Sass, since you can easily nest your styles then. However, this doesn’t always help. For instance, I had a third party library that made its own styles more specific in one of its minor releases which even broke the nested styles approach, and this would also break the styles if you had relied on loading order. In essence, there’s no good way to solve these kind of problems, since it is inherent in the way CSS works. |
Thanks for looking into this further @rcurrier666. Ideally we'd like to see @benjamn's approach mentioned in #24 (comment) and #24 (comment) implemented. With this approach a developer can control the location of Meteor's CSS bundle by putting the |
@hwillson, glad we agree on the approach! While simply moving the bundle to the end is a trivial change, it is bound to break someone's app. A couple of questions for you;
Look for a PR later in the week. And please bear with me, it's only my second PR, so I may need some guidance if I get it wrong. |
I'll answer
Yes, please! |
I agree with @skirunman on |
There is a major problem with inserting the CSS bundle in the body and with supporting moving around the JS bundle. If you've ever looked at the page source in the browser, you'll see there is NO HTML in the body, just Unless someone likes the special tag to move the CSS bundle into the body, or has another idea on how to handle it, I'm going to limit the bundled CSS to the head. And since I won't be looking at moving the bundled JS until after the CSS PR is complete, I'm going to open a new issue to discuss moving the bundled JS. That way the two features can be kept separate. |
Could someone provide me with details of how to run the tests in /meteor/packages/boilerplate-generator-tests. I want to make sure I haven't broken anything plus I need to add new tests (if I can figure out how to test my changes). TIA. |
@rcurrier666 You should be able to run those tests with the instructions in the Running specific tests section of So in your case you'd run:
|
@abernix, thanks. I tried that last night and it didn't work. I discovered that my Ubuntu image was missing some packages. After adding them, the tests work fine. Thanks for bearing with me, I've spent the last 7 years in a Windows + Perforce environment and so I'm dealing with a bit of a culture shock. |
This feature has been submitted as PR #9657 |
Just a note that the changes for both browser and mobile are now in the PR in case anyone wants to take a look at them or try them out. I'm waiting to hear back on where to document this feature and then hopefully one of the powers-that-be will merge the PR (maybe we can get it in 1.6.2?) |
All, I've opened a new issue to discuss implementing |
… CSS bundle. (#9657) Implements meteor/meteor-feature-requests#24.
I believe there should be a way to mark JS or CSS to be merged in specific package and then there would be 2 package position options: either in HTML < head> either in HTML end of < body> This is a standard way to position HTML < Script> and < Style> tags |
The new |
Since I did the original work, I'll take a look at it unless one of the
MDG folks wants to do so.
= Ron
…On 6/9/2018 6:27 PM, Sacha Greif wrote:
The new |meteor-bundled-css| thing isn't working for me. In
|template-web-browser.js|, |head| is blank and all my head content is
in |dynamicHead|, which doesn't get parsed for
|<meteor-bundled-css/>|. I'm not super clear what the differences are
between |head| and |dynamicHead|, I'm guessing it has something to do
with the SSR process?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#24 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/ADCTXGi6V1MmeKVXyKAzBulUquptwjRcks5t7HYPgaJpZM4NyHbO>.
|
I've reproduced the problem (using juliancwirko/scotty boilerplate) and have a browser fix coded and manually tested. I still need to fix the cordova template and write some unit-tests to cover the new cases. @SachaG, would you please open an issue for this so it can be tracked? I'll then do a PR for the fixes. |
Done: meteor/meteor#9982 |
Is this not closed as this implemented in meteor/meteor#9657 and released in Meteor 1.7. Understand there is still out outstanding bug. |
Migrated from: meteor/meteor#8651
The text was updated successfully, but these errors were encountered: