Google recommends inlining small CSS
developers.google.com
developers.google.com
Style is generally heavily interconnected with app state in modern web apps, so why not take advantage of a sophisticated state management system like Redux to declaratively manage your styles along with your state rather than adding/removing class names at runtime imperatively? With React's implementation of inline-styles, you can treat your styles as just another piece of JS data in your state tree, and have the entire power of the JS language at your fingertips to compose/extend/manage them, including powerful functional transformations, a flexible and statically analyzable module system, and prototypical inheritance, if you're into that kind of thing.
With this approach, you completely remove any need for preprocessors, get rid of a whole class of CSS limitations like the lack of a proper module system, and global scoping and the associated specificity issues, and your components become truly self-contained by default.
That said, I don't have a lot of actual experience with this approach in practice, so I definitely could be missing some nuances and practical limitations. I'd love to hear some opinions/experiences regarding using inline styles in React/Redux.
With CSS you can define a style that applies to all buttons on the page. to replicate this with inline styles you have to do
var styles = require("./styles/global");
// react stuff here
var thisButton = Object.assign(styles.button, { custom: stuff })
And that's the absolute most simple case. Replicating even slightly more complex CSS concepts like :nth-child or descendant selectors must result in a lot of code.Cascading in CSS is a bit of a love/hate relationship. Ultimately, it's like subclassing - neat idea, and great when it works, but often you hate life when a change at the top level cascades down and you didn't want it to.
At my previous workplace, we moved to be all about semantic markup, and our CSS matched that. Class names were to be minimized, because the structure should tell you what you need to know. (a few classes were required, but usually just to identify different top level items). Cascading saw heavy use, and it was generally cleaner than the specificity battles we had in legacy code where semantics weren't used, but it required a lot of discipline.
At my current workplace we're using React and BEM for CSS. Thus we avoid referencing element tags as much as possible and instead focus on very specific class names. BEM is, as far as I can tell, a means to avoid cascading as much as possible. Currently none of our CSS is inline. Not much discipline is required, but we have very little reuse (Sass provides some capability for reuse)
I tend to prefer my previous workplace's version, but the two are making very different kinds of products with different needs (my former place is basically building a CMS product and then marketing the output, whereas the current is a few single page web apps).
So in some scenarios cascading is an evil to be avoided, and in others it is a feature to exploit.
It's never safe to remove something so you have to fill your css with more and more complex rules and !important's to override the rest of the CSS on the page. At some point your CSS becomes impossible to manage and you are almost forced to start over again from scratch. After a couple of these times you start to curse the whole Global always on Cascading feature.
This is why ShadowDom and the WebComponents stuff is such a breath of fresh air.
I don't know if there is much room to optimize style sheet workflow when it is the lowest item on the totem poll in almost every situation.
<head>
<style>
.blue{color:blue;}
</style>
</head>
The critical styles needed to style the above-the-fold content are inlined and applied to the document immediately. The full small.css is loaded after initial painting of the page. Its styles are applied to the page once it finishes loading, without blocking the initial render of the critical content. https://developers.google.com/speed/docs/insights/OptimizeCS... import styles from './styles/global';
const thisButton = { ...styles.button, custom: stuff };
Also, nth-child and similar selectors aren't too bad, especially if you use a [1]helper library on top of React that lets you pass an array of styles to a component. All it then usually requires is adding a test against the iterator index when rendering a list of data. Something like: this.props.list.map((entry, index) => {
const style = [styles.row, index % 2 === 0 && styles.even];
return (<div style={style}>{entry}</div>);
});
A little bit of extra code but so much that I find it to be an issue.For the use case you mentioned, I personally would try to create a styled button component and take custom styles as a prop to extend the default style. However, I think you can also just apply these kinds of globally cascading styles using a regular CSS stylesheet and handle only the state-dependent styles inline if you prefer that approach.
As for features like nth-child, I don't see these being very difficult to implement, because you can easily map/reduce/filter your component tree with React since it's constructed from functional mappings of state data to begin with. nth-child would be as simple as applying/extending a style when (index + 1) % n === 0, for instance.
Descendant selectors, I'm honestly not too sure about.
> Further, inline CSS on HTML elements is blocked by default with Content Security Policy (CSP).
I'm probably not up to date on this stuff, since I am not a web dev, but does this mean it's actually not possible to use `style=""` in your HTML elements any more? I thought it was not recommended, but more for organizational reasons, not security reasons. What is the reason?
The same argument applies for CSS. If an attacker manages to output arbitrary HTML on your web page via some bug, they can add their own login form with <div style="position: fixed; ..."><form action="https://attacker/"> and harvest passwords this way. So CSP blocks that too. Again, this isn't because writing a form that way is a security vulnerability, but because if you've opted into CSP, you're stating that you're not writing forms this way so that you can enable these XSS and clickjacking protections.
The solution for network-level tampering and end-to-end authenticity is HTTPS. CSP just protects you against mistakes on the legitimate server.
Deleted comment
Some of CSP's protections are there to protect crap web developers from blowing their feet off. Unfortunately there are enough of these on the web platform that having inline CSS and inline JavaScript off by default is a good idea. The 'unsafe' in 'unsafe-inline' means 'I know what I am doing.'
Consider how this could work if Twitter made a mistake and gave you a way to inject improperly-sanitized HTML into a field which other people will see: you might be able to inject a follow or tweet button even if you didn't have enough access to completely rewrite the entire page or load arbitrary scripts. If you can style it to either look real or be positioned over a real button, the odds of someone clicking that go up dramatically.
That specific danger has largely gone away (except on all the corporate networks that are still on IE6 because custom apps), but there's still a desire to minimize attack surface. What if calc() or var() is found to have a bug in the future that allows arbitrary code execution?
(JS execution is mostly possible in obsolete browser versions though)
So we went from a blocking call and 5 lines of code to 17 lines and an async call. How is this in any way better than simply cramming the 4 lines of CSS internally? Maintenance will not be simpler because you will still probably have several rules to maintain over several files (and the inlining can be automated).
This seems like horrible over-engineered advice _especially_ for small CSS files.
So, the point of the example then is to optimize for the content that is delivered directly on the page. Note that the only style used in the page is '.blue' which is the only style left in the header (they additionally specify that you should do this for content above the fold). The javascript will fetch the rest of the style after the page has finished loading.
By loading only the immediately rendered styles, the entire page content finishes loading then the remaining styles are loaded. This is opposed to loading all of the styles, followed by the page content. Of course, when we're talking about a page that is around 1k in size either way it's not particular important.
Think of this like a "Hello World" for inlining CSS.
It's still drastic overkill for almost everyone except Google, but it does make sense for their use case.
var raf = requestAnimationFrame || mozRequestAnimationFrame ||
webkitRequestAnimationFrame || msRequestAnimationFrame;
if (raf) raf(cb);
else window.addEventListener('load', cb);
I've never thought to use requestAnimationFrame like that. When exactly does it fire? Is that the preferred callback these days for loading code after the page is "done" in some fashion? I've gotten used to using jQuery's `$(document).ready(..)` which as far as I know uses DOMContentLoaded or window.onload behind the scenes. When does the first animation frame happen in relation to those callbacks?[1] https://github.com/jquery/jquery/blob/dabd5ba96c05279b3ffb05...
[2] https://developer.mozilla.org/en-US/docs/Web/API/window/requ...
FYI `$(document).ready(foo)` is the same as `$(foo)`
$(function() {}) is a well known shortcut for jQuery. You might as well argue about whether or not to use the ternary operator or whether bootstrap's javascript is good or bad.
It's just your opinion. In these days King Canute could have used javascript styles instead of the sea.
So I see CSS optimisation as a multi-step process.
* Switch to a component-based rendering architecture (I favour React)
* Map CSS rules directly to components (I use CSS Modules)
* Have a JavaScript entry-point per route. The entry-point should only contain what's needed for that route, common bundles can be used too (I use webpack for this).
* Have equivalent CSS entry points per route (again, Webpack).
* On initial (ie server) render, render a style tag into the document that contains the content of the relevant entry CSS. By definition this is very close to being only the CSS required for that page (if your components have various different classes depending on config, there may be some bloat here, not sure if there's a workaround).
* On that same render, don't include an external reference to the actual stylesheets. (At this point we're mimicking Google's advice)
* On first client-side navigation (yeah, i'm assuming you're using client-side routing), load the required stylesheets for the destination URL, remove the style tag, then continue the navigation.
I'm actually excited, because in the React ecosystem, we're not too far removed from this entire process being relatively trivial to implement. I'm assuming other ecosystems are similar.
The other caveat is that the nature of generating common bundles automatically means that what's in those bundles will vary whenever the code is changed. This means that you'll lose the benefits of browser caching each time you release. If you have dependencies that you can guarantee will be in the common bundle (like it's safe to say React will always be in it, along with any other architectural libraries), then you're better off externalising them to somewhere that sticks around between releases (and therefore benefits more from browser caching). This will also make your common bundles much smaller.
For this reason, I think a better solution might be to inject critical styles into a STYLE tag in the HEAD, and then deliver one style file per component. The intuition behind this is that you can do your initial render with only the original payload (ideally in the first roundtrip), and that will buy you plenty of time for the cascade of web requests to get all the individual component files. With HTTP/2 multiplexing coming, there's no much penalty there. And then you get to cache your page at the granularity of a single component.
It's not a general rule, it's just suggesting that your 50 character block of CSS (that might be dynamic or conditional) would be better off as part of the main markup than a separate request and all the overhead associated with that.
If your static CSS exists in lots of small files, you would strongly benefit from rolling them together.
Both these recommendations may change with new delivery models (ie HTTP2).
<head>
<noscript>
<link rel="stylesheet" href="small.css">
</noscript>
</head>
..least whole point of this excercise is to make life a little bit more miserable for those pesky users who dare to disable js.https://w3c.github.io/webcomponents/spec/imports/#link-type-...
All is not lost, it seems.
It would be better to do the following:
1. Have only one or two external CSS files per page.
2. Serve CSS compressed when possible.
3. Ensure that CSS does not require any server-side processing or compression, that the server just spits out a .css or .css.gz file when the CSS is requested.
4. Ensure that the CSS files are relatively small.
5. Serve the CSS files with a very long cache time and with a version/hash string in the object name.
6. If feasible, make CSS changes relatively relatively rare.
If you do all of these things, adding the style into the web page will clutter your HTML and slow things down for frequent visitors. Yes, it might also increase perceived performance for some users who have not visited the site since the last change to the CSS.
If you're Google with a strong culture of web performance and have generally solved all the normal server issues with a globally-distributed network of edge servers, a 24x7 team of very talented engineers continuously monitoring and optimizing, etc. you might quite reasonably conclude that the biggest remaining area to improve page performance is chipping away at the long tail of users on high-latency connections, unreliable / flaky ISPs which might drop or delay requests for your render-blocking resources, etc.
The trick is realizing that relatively few people work at Google and most other places have not made the same investments to get to the point where this kind of micro-optimization is a net win versus the maintenance costs. Most sites tend to show easier problems - optimizing DNS, getting a CDN or using one better, reducing total transfer size, etc. – which are going to impact the user experience more than inlining some CSS.
This is particularly true as we rapidly head into an area where things like HTTP/2 are changing most of our optimization weights – e.g. packing things into CSS bundles is rapidly becoming an anti-pattern since it reduces the period where a cached resource is still valid.
The guidelines I outlined don't work well if retrieving the CSS requires a subsequent DNS lookup. One could argue that serving CSS from the host that serves the HTML is a good idea, but there are other tradeoffs involved.
The main thing I'd like to see in guides like this would be some general advice about how to measure this kind of thing (e.g. browser dev tools) and, more importantly, how to avoid some of the common confounds like local caches when measuring using a tool like WebPageTest.org.
(Disclaimer: this is what I work on.)
I'm also beginning to re-think CSS. I love CSS, but just like with OO, I'm thinking it may tempt us to think of structural considerations when we may just be wasting our time. I think the next app I write, I'm going to evolve my CSS, starting with inline styling, moving out to an inline style node in HEAD, then dynamically loading it from JS as in the Google example, and then finally using a class/series of classes.
In much the same way, in FP you can just make it work, then generalize, then group, then eventually create modules/classes full of generalized functions. This way of thinking seems to result in far quicker execution and far less complexity. Not sure if it translates to CSS, though. It'll be interesting to try it out.
I'm sure it will load spectacularly fast, but that sounds like a maintenance nightmare.
I spent a lot of effort on my "brochure" sites making sure that non-JS users will have a good experience (that includes being able to navigate the site, a privilege an increasingly large number of sites don't extend to non-JS users)[1]. Loading even part of my CSS through JS would ruin that experience.
1. I do make web apps that require JS, but only for actual applications that work in a similar manner to desktop apps, not for informational sites like blogs.
And I believe it -- up until a point. After that point, too much structure becomes its own kind of hindrance, where you're looking at a UI and wondering "What the hell cascades do I have going on here to make that two pixels too far to the right?" (Or something like that)
So I don't think we disagree. The only thing I'm adding is that to determine the right amount of structure, add it in only as needed. So I imagine by the time you got to a multi-page site you'd be using external stylesheets and common classes. You just wouldn't start there.
Sure do like me some Bootstrap, though. And a good reset sheet is a no-brainer. Need to think about this some more. I think the key question is: how much of this do you really need?
For instance, right now I'm writing a small personal app to take a movie script in native file format and display it as a web page. Where did I start? With the function to do the translation, of course. Now that it's working, I can always manually execute it if I need to. I may just stop here. I've done enough.
If I really, really want something I can upload scripts to online, I'll write a page. Or two. Then I'll throw my uploaded file at my pre-existing function, return the file name, and I'm done.
I may have spent 10 hours on this so far.
By contrast, the "old" way of doing it was to start with setting up a site using all sorts of frameworks. Maybe decide on a color scheme. On the back-end side, I'd be creating a class graph and working through my persistence strategy. Maybe I could use Mongo! Wouldn't Ruby be awesome?
I tend to easily get focused on tooling and technique instead of just doing the fucking work. (Apologies for the profanity, but this took me a long time to figure out). So I've discovered for my own work, I need to concentrate on making sure I grow only the needed complexity. Nothing more. Way too easy for me to screw up in this area.
In the case of my little app, sure, I could start adding frameworks. Or I could just emit some HTML. Who knows? Maybe plain HTML with a few classes and some style information in the HEAD might be fine. That's a win.
Anything over 1% of the total dev time would be a poor RoI and frankly I'd sooner spend that time making things more accessible to screen readers and such (something that many web applications already do very poorly frankly).
I iterate back and forth between including my stylesheet and not including it, while developing the HTML. I try to get the unstyled layout to make as much sense as possible, to be a complete presentation on it's own, albeit looking like it's from 1995.
I then add styling just to make it look good. Since the flow of the page already makes sense and is readable to a user, the CSS is usually much smaller and less intrusive.
I don't use CSS resets. The entire concept to me is the devil. You're design should not be trying to rewrite the world. You will probably get it wrong if you try.
Seriously, just inline rules like that. If it is only applied in one specific place across the entire site either because it cannot or does not need to be made more general, then inlining it is easier to maintain and understand.
com-google-api-explorer-client-history-EmbeddedHistoryItemView_HistoryItemUiBinderImpl_GenCss_style-showHideHeaders
It's generally really hard for me to take HTML advice from google seriously, their page sources at best look mediocre, and at worst they make my eyes bleed. How can code so complicated lead to such bland looking pages? I know I'm kind of being snarky, but I can't help it. Just look at the source of that page and the linked stylesheets, look at google.com, heck, if you can find me just one elegant page I'll be grateful, because to this day I haven't seen a single one.
That also perform utterly atrociously, compare modern Google Maps to classic Google Maps. The performance difference is night and day in the favour of the old school tiles version.
If web developers had to support every permutation of turning off cookies, fonts, images, JavaScript, stylesheets etc. you'd never get anything done.
You don't need to support every permutation of each technology; provide base functionality, and enhance it using each, if it's available.
CSS loading/parsing is render blocking. By loading CSS that isn't needed immediately asynchronously in a way that will use the browser cache if it's available, it makes the page visible much faster. It feels like overkill in the simple example, but it's a tried and true method. ( https://github.com/filamentgroup/loadCSS has > 2k stars if that kinda thing means anything)
From my experience on a large website (m.trulia.com), On a 3G connection with an 'average' (nexus 5) phone, this technique made almost a 2 second difference in perceived load time.
if the CSS isn't needed immediately, simply don't load it :)
Sometimes. Sometimes not. The problem is that browsers disagree on when it is and that some of them block way too much, which leads to the ugly workarounds.
There were some proposals for a <link rel="async stylesheet"> that didn't really seem to get much traction so far, but they're really the right way to solve this problem.
My understanding is that all of this will become an antipattern once we can support http/2. For today, however, it provides a very real performance boost.
Over-engineered absurdity
/* bold */
.bold {
font-weight: bold !important;
}
It has became my favourite real-world example of CSS misusage :)I don't see what's wrong here - they come in handy when you need a one-time style alteration.
The same could be said for a mobile device, where italic could be hard to read, so, say a different font is used. Again this would require changes to the HTML and breaks the separation of style from markup.
It doesn't particularly offend me, but I though it would be worth pointing out why some people disagree with this style of class naming.
I think of this stuff as the equivalent of walking into a job site and finding a dozen surge protectors daisy-chained and clustered together, with everyone there oblivious to the problem. "What? If it works, it works. Don't criticize."
For custom sections where you want to add styles you should consider what you are styling such as an "event", "highlight", "keyword", "first", "last" etc. Although the HTML5 tags are a lot more descriptive, numerous and extensible now, so css classes may not be the only option to add style descriptors to your content.
Now I'm not saying one should go out of their way to ensure every single accessibility technology can use their site, but when the more accessible way of emphasizing text is quite easy to use, I could see saying that using style for semantics is wrong.
The canonical .hide class I see many places, and use myself, has the exact same structure, and it is often better to do hiding this way than to toggle visibility or display, because it's a pain and error prone to toggle display directly on mixed display mode elements, e.g., inline-block, flexbox, etc., and visibility doesn't reflow.
So, don't be so sure this rule exemplifies mis-using css. It might, but without the context, it's pretty hard to draw that conclusion.
Vendor-installed SQL server database. In this DB is a table called tblYesNo with one column called YesNo. In the table are the following two rows:
YES
NO
INSERT INTO tblYesNo VALUES ('FileNotFound');
-- http://thedailywtf.com/articles/What_Is_Truth_0x3f_But I think the comment was overkill.
Not inlining the css as the style attribute of a tag.
The goal is not to have to fetch a second css page.
The goal is to have the CSS already present when the "above-the-fold" content renders, so that it's that much faster to render correctly, improving user experience.
That does not apply, of course, if your initial HTML page is a static asset, too.
The self-contained simplicity was appealing, the only hurdle was navigating a large file in my editor. But there's ways to manage that with bookmarks and neatly organised sections and so on.
I liked how the smallest component of the app, was the app itself. I see HTML, CSS and JS working together as one unit anyway in a single-pager, so I wanted them living and versioned together. On this particular app, I had lots of dynamic elements updating around and lots of exploring new concepts. Wanted to avoid dependency fragmentation headaches. And to be honest, switching between frontend files can be annoying (to me) when I'm doing lots of tinkering. I'd rather switch between locations in the same file.
<script>
var cb = function() {
var l = document.createElement('link'); l.rel = 'stylesheet';
l.href = 'small.css';
var h = document.getElementsByTagName('head')[0]; h.parentNode.insertBefore(l, h);
};
var raf = requestAnimationFrame || mozRequestAnimationFrame ||
webkitRequestAnimationFrame || msRequestAnimationFrame;
if (raf) raf(cb);
else window.addEventListener('load', cb);
</script>
Seems like it's time for a defer attribute on <link>.A bigger problem is that in some browsers (not Firefox, but iirc yes Chrome) that stylesheet load will then itself block rendering.
Publishing recommendations like this is a recognition that many small companies don't have the resources that Google does to rigorously experiment with different approaches and collect data.
That said, if you do have the resources, you should always measure & experiment with your own situation. Many of these recommendations go away with HTTP2, for example, and it's likely that the guidelines won't be updated until long after HTTP2 is widely adopted.
>Banning inline script is the biggest security win CSP provides, and banning inline style likewise hardens your application.[1]
So which is it? Should we be moving away from inline scripts and CSS, and tightening it up with CSP, or is performance/fewer requests more desirable? Also, with HTTP2, the performance issue seems moot.
[1]http://www.html5rocks.com/en/tutorials/security/content-secu...
Inline styles also prevent the user from overriding styles with a custom style sheet (think color blind people). This isn't necessarily against ADA/508 compliance, but it should be taken into consideration.
Just last night, I tested trying to separate out my fonts from my CSS. Google Pagespeed Insights still threw a fit over no async CSS, even though the CSS was 5 KB. FFS, Goog! I decided against that madness.
Don't inline CSS attributes
Inlining CSS attributes on HTML elements (e.g., <p style=...>) should be avoided where possible, as this often leads to unnecessary code duplication. Further, inline CSS on HTML elements is blocked by default with Content Security Policy (CSP).
How effective is this, really? If I can inline a CSS class, then I can inject any style on any HTML element even if I can't inline an attribute. Am I missing something here?
Also, in the case of a defined class, you only need to change the class definition to change all the instances, rather than chasing down each explicit style instance.
The reasoning is only valid if the defined style is used more than once. If the style is unique, the argument doesn't hold up.
The whole idea :
> Inline small CSS.
is too specific. I think when you work on a huge web-application you don't want to create such a bloat in your layouts and personally I don't think that this approach scales. On the other hand if you go with a simple web page, like a landing page with a couple of elements ... go for it.
> If the external CSS resources are small
What is "too small" anyway ? ( too general )
It may be better for delivery, but the second example is unreadable compared to the clean one. I can see why it's much better to add 15KB to your HTML file than having to request those 15KB from a separate file (one or two full round-trips of added latency :)).
Still, I won't use their method.
The Node module UnCSS (https://github.com/giakki/uncss) is working reliably for us, using PhantomJS to automatically extract the CSS rules we need for our front page.
The full CSS rules are then loaded at the end of the page - just in case UnCSS missed a browser specific or Javascript triggered rule, and to get the files into the cache.
What's deprecated is the hosted version of the optimization modules: PageSpeed Service: https://developers.google.com/speed/pagespeed/service/Deprec...
i am nouman deaf