Hacker News new | past | comments | ask | show | jobs | submit login
Google recommends inlining small CSS (developers.google.com)
251 points by jayfk on Jan 12, 2016 | hide | past | favorite | 136 comments



This is probably not a very good general recommendation, but inline CSS actually makes quite a bit of sense to me when using React/Redux.

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.


I hear this all the time but it's hard to giving up the C in CSS, cascading.

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.


> I hear this all the time but it's hard to giving up the C in CSS, cascading.

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.


The hard part of the cascading in CSS for a page is that it is global in scope. In the current landscape of complex html/javascript applications this global nature tends to snowball.

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 remember when a colleague first showed me BEM and I was really excited. Then came a deadline and any chance of optimizing our styles flew out the window. Complicated further by the fact that we have no designer on the team.

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.


You should see the examples on the page. It's more like

  <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...


Could be a little simpler if you're using an ES6 transpiler.

  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.

[1] https://github.com/FormidableLabs/radium


Thanks for that insight. I haven't really given this enough of thought until now.

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.


+1 for (s)css-ing as normal and adding state-dependent styles as necessary. I've yet to see a better approach.


This article doesn't say to use `style` attributes inline. It's talking about inlining a `<style>` element in the initial HTML page.


Can I see please some examples of those JS-powered CSS components in the wild?


This is the part that surprised me,

> 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?


Only if you have specified Content-Security-Policy headers in your response, without also specifying "unsafe-inline": http://www.html5rocks.com/en/tutorials/security/content-secu...


What potential security vulnerability do inline styles have?


CSP is mainly a defense against arbitrary HTML getting injected into your website via poor validation, buggy scripts, etc. It's not a replacement for validation, but it's a failsafe when there's inevitably a bug. So the purpose of CSP is to block regular XSS like <script>alert("XSS!");</script>, and anything that works similarly. This isn't saying that inline script tags are a security vulnerability per se, just that they're a tool an attacker can use. CSP then also allows you to restrict <script src="..."> tags to trusted origins.

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.


Would that block injection like Comcast does for bandwidth notifications? http://blog.ryankearney.com/2013/01/comcast-caught-intercept...


No, because Comcast can just drop the CSP header from the HTTP stream (and you can believe that whatever developer has been ordered by management to implement this will quickly Google CSP, figure out that it's in their way, and drop the header).

The solution for network-level tampering and end-to-end authenticity is HTTPS. CSP just protects you against mistakes on the legitimate server.


[deleted]


CSP has a directive called "form-action" that limits the URI in form submission. So at least you can only submit forms to known destinations.


... which means if you use something like React and do not inject HTML or use innerHTML or other eval-type junk then you don't actually need to worry much about allowing inline CSS or inline JavaScript.

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.'


Right, in a perfect world, where all code deployed to production (including third-party libraries, legacy code that hasn't been touched in years, etc.) is free of security bugs, there's not much benefit to CSP.


It's mostly the combination with other things: the ability to hide or position elements on the page is commonly exploited by XSS, malware, adware, etc. If someone can inject JS or HTML into the page, they can do things like put an opacity:0 submit button over the control the user thought they were clicking on.

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.


If you have a cross-site scripting hole, an attacker could use inline CSS to create a smoother experience for the visitor.


In the pre-IE8 days, you could include CSS expressions within CSS that let you execute arbitrary Javascript when the CSS was evaluated. This was a very common vector for Internet worms; UGC sites would think they were safe because they stripped out <script> tags, javascript: URLs, and inline event handlers (onload was another common attack vector), but then an attacker would add a custom style attribute with a CSS expression and pwn your computer.

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?


CSS is powerful. It's possible to both steal data and in some browser to execute JS through CSS injections.

(JS execution is mostly possible in obsolete browser versions though)


If guess you could irritate users or trick them into clicking something they don't want if you are able to position elements on the site, maybe DoS the browser or fake the identity in a comment box. CSS is quite powerful.


thank you so much for the link, I wasn't aware of this. It's a very easy way to help harden the webpage! (especially because I can do this via headers)


I do not understand this particular example. They replace 4 lines of external CSS + 1 line of loading by 1 line of internal CSS + 2 lines of tags + 11 lines of JavaScript which then asynchronously loads 3 lines of CSS.

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.


The article is about optimizing the delivery of the CSS content, not about making it clear or concise or anything else.

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.


Because small doesn't mean 4 lines, they just used 4 lines for the example.

Think of this like a "Hello World" for inlining CSS.


In that case (as others have stated) they should really precise what do they mean by small. I am convinced that a single network call (preceded by JavaScript overhead) dwarfs any reasonable amount of CSS code you could put in a single HTML file.


It will, but it's still a net win because Google's not actually optimizing for time to load. They're optimizing for time to usability. Moving all of the non-essential CSS out of the head and into a post-load request increases the total request time but decreases the time until the user can begin interacting with the page.

It's still drastic overkill for almost everyone except Google, but it does make sense for their use case.


Interesting. The sample code includes this bit:

      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?


Yep, you're right that that's how jQuery works [1]. I'm not an expert in this, but I would expect requestAnimationFrame to be quicker than DOMContentLoaded, because it should occur before a paint [2], rather than after the event fires, which is presumably afterward. If the stylesheet is in cache, this gives the browser a chance to load it before the first render, to prevent a flash of unstyled content.

[1] https://github.com/jquery/jquery/blob/dabd5ba96c05279b3ffb05...

[2] https://developer.mozilla.org/en-US/docs/Web/API/window/requ...


> I've gotten used to using jQuery's `$(document).ready(..)`

FYI `$(document).ready(foo)` is the same as `$(foo)`

https://api.jquery.com/jQuery/#jQuery3


In my experience--not that I'm a prolific JavaScript developer or anything--people tend to write out $(document).ready anyway because it makes their intent clearer. Personally, I have to do a little mental work every time I trip over the shortcut and prefer seeing $(document).ready.


Javascript is the wild west of styles, this isn't valid advice.

$(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.


One is just as valid as the other. You are mistaking your preference as a standard.


Well, at least camel case is generally agreed upon. Meanwhile, I wonder if anyone anywhere takes advantage of the breadth of unicode support for variable names.


I expect this to be on / before the first draw event, whereas the 'load' event takes place later (I presume)


The problem i've always had with this, and the "above the fold" rule as it appears in the pagespeed insights tool, is the definition of "fold" varies wildly.

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.


I fear that we're on the verge of an era of 'fold-sniffing'. Actually, there are plenty of examples of annoying 'lazy-loading' scripts that defer image loading until images are visible, which just result in loads of stuttering page scrolls, waiting for images to appear. If I'd wanted an annoying interuption-filled streaming experience, I'd be watching netflix, not browsing your website...


Does this have any negative effects on browser caching?


The only part of the process that's a bit weird is loading style sheets programmatically. But I think people normally do that by adding a link tag to the DOM, so it should use browser caching as usual.

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.


Yes, bundling can potentially negatively impact caching. In the worst case, the bundles are mostly the same. Also, if your leaf component style files change rapidly, you'll invalidate the hashes on large bundles pretty frequently.

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.


> If the external CSS resources are small

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).



Although they seem to be saying that something is wrong with google app engine rather than http/2.


Indeed, just logic


Offered example is missing this in the "you can inline" snippet:

    <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.


FTA: Note that the web platform will soon support loading stylesheets in a non-render-blocking manner, without having to resort to using JavaScript, using HTML Imports.

https://w3c.github.io/webcomponents/spec/imports/#link-type-...

All is not lost, it seems.


This is like 15 years overdue.


This is rude, there are many reasons and needs for no JS. A good example is Tor, where turning off JS helps with privacy.


I think grandparent is being sarcastic.


I agree that Google's recommendation here is a poor one in most cases.

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.


The problem is basically telling whether your challenges are like Google's. An external link requires a separate request, possibly even separate DNS lookups, server connection, SSL negotiation, etc. and nothing will render until those complete.

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.


You're absolutely right.

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.


Yeah, this is a really hard thing to get right in general guides or tutorials since there are so many assumptions underlying the decisions and people might end up reading one far enough in the future that thing have changed – we saw that with connection limits and caching esoterics which became obsolete once IE6 disappeared.

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.


You can automate this with the prioritize_critical_css filter in the PageSpeed module: https://developers.google.com/speed/pagespeed/module/filter-...

(Disclaimer: this is what I work on.)


Over time I've developed some opinions not shared by most. I only use a framework when under extreme duress. I use static pages wherever possible. I measure payload size.

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 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.

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.


Yes, that's the standard answer: good structure costs very little now but pays off greatly in maintenance and upkeep.

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.


Who are these non-JS users. Can you point to some statistics here? Using developer time on it seems more wasteful than trying to support old versions of IE.



Interesting but that was over 2 years ago and frankly even if it is still 1.1% since I write web applications not sites I'm not devoting any time to supporting people without JS.

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 know what you mean. The key is to remember that semantic HTML is responsive by default. If you are struggling to get an eefect to work with CSS, that is a code-smell that you are hurting more than helpinh your site.

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.


This makes perfect sense for classes like ".article51_footer_wrapper_margin50", look up the rule, and sure enough it looks like `.article51_footer_wrapper_margin50 { margin-bottom: 50px; }`

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.


Except that class does not make sense. What happens when design changes and margin is now 40px?


Precisely. It doesn't need a class or external CSS rule - just a style attribute (unless it's for a pseudo state, and then it has to be external, but should use a better name).


style attributes don't work with CSP though, which I imagine is important to google


Note that TFA is about using a style tag rather than a separate CSS file. It actually discourages the style attribute.


But TFA justifies avoiding the attribute because it "often leads to unnecessary code duplication" which is irrelevant "if it is only applied in one specific place across the entire site". It also mentions CSP as a reason to avoid the style attribute; can anyone explain what this means? Is this actually going to have a practical effect, and what does an inline style attribute have to do with security policy?


Are there any findings about whether such godawful class names affect rendering performance? I mean just matching strings such as this one:

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.


Class names are interned (see https://en.wikipedia.org/wiki/String_interning), so string length does not affect rendering performance.


> How can code so complicated lead to such bland looking pages?

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.


Also, since they are talking about optimization, I wonder why they make embedded fonts a requirement to view their plain-text page. I disable loading of fonts because it's useless and often slows everything down, and this is how their page look without these fonts: http://i.imgur.com/oDO8gRt.png


I imagine the vast majority of web users have font loading enabled so they optimised and tested for that.


So, ... screw the minority? Seriously, one of the benefits of the web stack is that it makes it very easy to cater for a wide variety of capabilities, rather than resorting to "Best viewed with Internet Explorer 5"-type behaviour.


What browser doesn't support fonts?

If web developers had to support every permutation of turning off cookies, fonts, images, JavaScript, stylesheets etc. you'd never get anything done.


laurent123456's doesn't. And I wouldn't be surprised if there weren't countless mobile phones, console browsers, etc. that didn't.

You don't need to support every permutation of each technology; provide base functionality, and enhance it using each, if it's available.


I love how they, in that example, use JS to load the rest of the CSS. Seriously?


Seriously.

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.


I guess it is time for this one again: http://idlewords.com/talks/website_obesity.htm

if the CSS isn't needed immediately, simply don't load it :)


> CSS loading/parsing is render blocking.

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.


In a few hours, I'm launching a very large website that relies heavily on LoadCSS(). Page load times have been excellent in the pre-public phase, even though our critical styles contain a mountain of Autoprefixer-generated flexbox prefixes.

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.


My understanding is that concatenation will be become an anti-pattern with http/2, but not `<script async..>`, `<script defer..>`, or loadCSS.


"Too many devs spoiling the broth" in a nutshell.

Over-engineered absurdity


I remember a CSS class in some enterprise software I was working on several years ago:

  /* bold */
  .bold {
    font-weight: bold !important;
  }
It has became my favourite real-world example of CSS misusage :)


I agree with jdudek here. While I'd never use important, I usually have a lot of small utility classes like bold, italics, uppercase, truncated etc.

I don't see what's wrong here - they come in handy when you need a one-time style alteration.


The intentions are baked into your class name, if you were to change the style later and favor underlining rather than bold text, it would require a change to the HTML (or some rather misleading code).

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 once semi-started questioning whether I had gone colorblind or taken acid or something after having to work on a page that had style classes named after cerrain colors like "red", or "yellow", but there were no such colors on the screen. Incidentally, they had also ended up being reused to do some position and size styling, as well. Just complete malarky.

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."


There's nothing fundamentally wrong with having such utility classes. It could have a distinct use, especially for Javascript. It's just you shouldn't use such a class solely for design purposes, for the reasons you point out.


Yes using something like "strong" rather than "bold" as they did in the HTML spec.

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.


Is there an accessibility issue? You are using style to bold text, but bolding text is almost always a semantics issue of wanting to emphasize the text, not merely make it look different just for style reasons. So someone with a screen reader would have a far more difficult time getting the correct semantics from this page.

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.


If you want to actually emphasize a bit of text then you should wrap it with the appropriate tags. Using font-weight is usually just a design decision for the visual, not necessarily to emphasize the text.


One can argue if it’s a misuse or not. It’s quite handy to have such utility classes that rely on !important and can be used in markup directly. I have plenty of those in my stylesheets.

[1] http://davidtheclark.com/on-utility-classes/


Like your article. Especially agree with this phrase "authoring and maintenance considerations should trump kilobyte savings" (within boundaries of course).


Others have mentioned this is not necessarily a mis-use. I'll add that what I see here is potentially an override style that can be toggled dynamically. In that case, this may be the right thing to do, the !important declaration lets this rule collide and win over conflicting font-weight rules without having to keep track of which order the conflicting rules were declared in; they might be in separate files.

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.


I agree, it is much easier and consistent to toggle a class with Javascript than to mess with the style attribute. For example, toggling one class in three is easier to deal with than removing/adding one property in three in a style attribute.


Crazy off topic, but similar misusage:

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_


It's quite common to have such classes if you work with some kind of CMS system. In one of my previous companies we had bunch of similar classes that allowed basic layout adjustments (like margins, paddings, font-sizes). It's quite handy if you want to just edit the html and do not touch the css files at all.


That totally depends on your CSS pattern.

But I think the comment was overkill.


Note they mean inlining the css rules in a <style> block.

Not inlining the css as the style attribute of a tag.

The goal is not to have to fetch a second css page.


That is not the goal. Read TFA; their example specifically still loads small.css by dynamically creating a <link> element after pageload (in a RequestAnimationFrame or onLoad).

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.


If you have single-page web apps, you might as well inline your entire site's CSS, since it's never going to look for the CSS again.


Not necessarily. If the app changes seldomly, you could reuse a CSS file across multiple sessions, whereas the HTML (i.e. "GET /") is probably always served up fresh.

That does not apply, of course, if your initial HTML page is a static asset, too.


I did that for a single page web app once, but I took it a step further and inlined the JS too. I was surprised how much I enjoyed developing that way, and how much it didn't bother me. I kept libraries such as Jquery separate. Just the code I was editing I kept all inline in one large HTML file.

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.


I would probably want to fight you after reading this code.


This is basically what webpack's css-loader does.


    <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>.


Or, you know, put it at the bottom of the HTML since it will take 5ms between the moment where the browser receive <html> and </htm>


It may take a lot longer than that, since the browser is parsing as it goes. A SCRIPT tag in the HEAD will run synchronously, blocking parsing of the page and delaying initial render. For a tiny script that defers work, this is not a problem. But you want to schedule the stylesheet to load ASAP, in case it is cached, so it's actually potentially a human-noticeable difference to get that function on the queue before the BODY begins parsing.


A <script> tag will block DOM tree construction and rendering in browsers but will not block scanning ahead for things to load (and at least in Firefox won't even block tokenization of the HTML). So if you have a <link rel="stylesheet"> at the end of <body> it will likely start loading even before the scripts before it have had a chance to load and run.

A bigger problem is that in some browsers (not Firefox, but iirc yes Chrome) that stylesheet load will then itself block rendering.


if you use the google pagespeed apache/nginx module it has an inline_css filter which does this for you, no need to cause yourself a maintenance problem.


Whatever happened to the programming rule of don't micro-optimize until you've measured the performance? There seems to be a lot of recommendations to do ugly things to websites in the name of optimization, but they still add complications that are hard to understand. Pictures used to by supposed to be optimized by pre-scaling them to the size they'd be displayed at. Now we have retina displays and that doesn't work anymore. You have to do more complicated things instead. HTML and co has become very low level-like and almost complex enough that perhaps humans shouldn't be doing it. It reminds me of the days of assembly language and all the ugly little tricks to squeeze out more clock cycles that are now handled by compilers.


Most of these recommendations are based on measurements. I recall a coworker doing several experiments on Google Search about inlining CSS vs. making a separate request, and the break-even point was surprisingly high (~10K or so of CSS).

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.


Which mandates 'unsafe-inline' if you're using a content security policy (CSP).

>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...


I'd also like to throw this into the conversation:

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.


Important flagged CSS declarations trump those inline style ones anytime of the day. Also, limiting the options available to your end users without solid and good reasons is not a sound strategy as it may prove inconvenient for them and endanger the product's image.


I think that this is the wrong way for most websites to do CSS, as it contradicts both minimization+concatenation and HTTP2 best practices. If you have just one CSS file that's heavily cached and 100 KB (because you base64ed your webfonts to reduce request count), you should be fine.

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.


OK, so this part is new to me:

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?


Their point seems to be that inlining a class name means the class will only be defined once, but the case of an inlined style means the style information must be duplicated for each appearance. The style approach hits all the bad buttons -- the load is larger and slower, and its execution is slowed compared to a single class definition that's referred to multiple times.

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.


I think this Google rule is too specific and in the same time too general for being alive.

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 )


(Disclaimer: I'm not a coder, so I easily get overwhelmed by what others might see as very simple)

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 :)).


While you're correct in observing that the first example is shorter and potentially easier to read at a glance, there is a method to the madness in the second. They inlined the CSS needed for content above the fold which speeds up load times theoretically. They then use JS to load the rest of the CSS later on so they can control exactly when the stylesheet is loaded...just linking like one would normally do would negate the perceived benefit. The end result should be comparable overall load times but the end user should perceive a slight decrease since important information is styled immediately. So yeah, the second is a little more confusing and in this case is drastic overkill, but their point still stands.


I think this has been for a long time now and I expect to see everyone speak about how this is a bad recommendation. If the above-the-fold content can extracted with a gulp/grunt plugin and injected it gets even better. These are extreme measures needed for performance profits and anyone can choose to take them or simply ignore


Sometimes I wonder, if you can make the content above the fold load instantly, why can't you do that for the whole page?


Depends how big the page is ;)


Google's point here is to load a header really fast, the user will get this feeling that some progress happened, JavaScript will load the rest of the CSS after, while the rest of the page is getting loaded/rendered...

Still, I won't use their method.


We inline the front page CSS on https://pdftables.com/, both for user experience and for SEO reasons.

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.


is there a tool that'll find all the style attributes and compile those into a css file?


#AlphaBetFail - teach people how to do it correctly, teach them not to hack stupid ass inline CSS styles from 1996.


that suggestion has been around for a while


yeah this is not new was a recommendation from https://developers.google.com/speed/pagespeed/insights/ which I thought was now depracated, so must have been around for a while. I think it's a recommendation of http://yellowlab.tools/ too which is great.


PageSpeed Insights (the analysis tool) is not deprecated. The optimization modules, mod_pagespeed and ngx_pagespeed, are also not deprecated.

What's deprecated is the hosted version of the optimization modules: PageSpeed Service: https://developers.google.com/speed/pagespeed/service/Deprec...


the makes perfect same talk does need the is search hacker very like power you help me please

i am nouman deaf




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: