A device agnostic approach to inlining CSS

Orde Saunders' avatarPublished: by Orde Saunders

A performance recommendation that has been getting a lot of attention recently is inlining CSS required to render "above the fold" content. Whilst the principle behind this technique is valuable, my experience of implementing it has led me to the conclusion that the focus on "above the fold" is fundamentally at odds with how I build device agnostic websites.

What is "above the fold"?

The term originates from newspapers and refers to the top half of the front page. When papers are folded in half for display the content above the fold would be all a potential customer would see.

When applied to the web it is used to denote the content at the top of a page that would be visible in the browser's viewport.

Variable viewports

Whilst in any given single instance of a browser the above the fold content is easy to define it's hard to know what will be above the fold in general.

With fluid layouts the height of content will typically vary with the width: as the width reduces, the height will increase as the content reflows. This means that we can't just say that fold occurs at a given number of pixels from the top of the screen, we have to define both width and height.

How variable are viewports?

Most analytics packages will collect data on screen size so we can look at this and see what this data tells us about the distribution of different sizes. Looking at my own analytics I can see that in 8,392 visits over a three month period there were 177 discrete screen sizes (width x height) and only 1% had a unique screen size (one visit with that screen size) which suggests that it might be possible to make some generalisations. The visualisation of this data shows the variety of distinct screen sizes.

Screen size visualisation

However, screen size isn't actually the measurement we're after, what we are interested in is the browser viewport - the area of our web page that is visible on screen. In addition to the standard screen size data I also collect information on the viewport size. From this I can see that in the same 8,392 visits there were 4,344 discrete viewports (width x height) and 42% had a unique viewport (only one visit with that viewport). When visualised on the same scale as the screen size data it shows that, rather than a series of distinct values, the range of viewports more closely approximates a continuum.

Viewport size visualisation

When we look at screen size it appears that generalisations might be possible but when we look at the variety in viewport data - which is ultimately what we're interested in - it is clear that anything but the broadest, and therefore least useful, generalisation isn't going to effectively cover our needs.

Where is "above the fold"?

As well as borrowing a convenient fixed area from print, the term "above the fold" also refers to a clearly defined location: the top of the page. Translating this to the web it is similarly interpreted as the top of the page. However, a web page isn't like a stack of folded newspapers where you know that's exactly how people will first interact with the content - on the web it is possible that people will start their interaction in a location other than the top of our page. For example, if I link to the conclusion of this article then the "above the fold" content now includes the footer.

Additionally, even with simple responsive layouts - such as the one used on this site - we move items around in the layout, a pattern that will only increase as new layout technologies become available. Again taking this page as an example, there is some additional content that appears below the main section for narrow viewports but for wide viewports it moves to a side bar. Even when taking a typical aspect ratio that is wider than it is high, if the viewport is wide enough to use the sidebar layout then the previous "footer" content now has a good chance of being "above the fold".

Even on a basic content site with a simple responsive layout we have now reached a situation where we are effectively having to prioritise the whole page!

A different approach

We've now reached the conclusion that, by taking a visually led approach, we have to prioritise the whole page which is clearly not viable - we need a different approach.

Once we stop thinking about delivering a visually complete rendering of a section of the page we can look at the problem from a fresh perspective.

Problem description

What is inlining CSS "above the fold" trying to accomplish, what is the fundamental practical problem we are trying to solve?

Problem description

When the page initially loads we want the user to see styled content. In order to reduce the page weight, and to leverage browser caching, we don't deliver the full set of styles with the initial page load, we deliver an initial subset and bring in the remainder at a later time.

Progressive enhancement

To me this suggests taking a progressive enhancement approach: there is an initial subset which is subsequently enhanced. Normally progressive enhancement is thought of as a JavaScript technique but applying it to CSS is a foundation of how I build device agnostic and responsive layouts.

Bringing in items that affect layout at a later time is also something we have seen before with placeholders for lazy loaded content. In order to minimise visually jarring layout reflows we need to establish layout as early as possible.

What we need is to deliver the minimum CSS required to make the page layout viable. It's impossible to provide one size fits all guidelines as different sites will have different needs. However, this baseline CSS is likely to include the core typography, colours and layout.

I appreciate this isn't easy - it's not something you are likely to be able to do with a Grunt plugin, you are going to have to have an in-depth understanding of your visual design and your CSS and how the two are interrelated. You will need to know what is the absolute minimal core of your visual design and how that is described by CSS. From this you can deliver the CSS that describes this core and the enhanced CSS that completes the visual design.

Fault tolerance

In order to load the enhanced CSS asynchronously we need to use JavaScript which introduces a dependency between CSS and JavaScript which breaks the web's fundamental separation of concerns: presentation is now dependent on behaviour.

If we were inlining only the styles for "above the fold" then when JavaScript fails the page is left with only the top of the page styled. By contrast if we are inlining a baseline CSS that covers the whole page then the page is still styled, albeit to a lower fidelity.

Conclusion

Whilst above the fold may be a well defined term, in this context it's not useful. The fundamental technique of inlining CSS into the page has a lot of value for performance but, as we move towards a device agnostic web, the idea of optimising for a notional "fold" is a retrograde step.

By taking a broader, progressively enhanced, approach we arrive at a solution that is more fault tolerant, backwards compatible and future friendly.

Thanks

Thanks to Ben Seven (@ben_seven) for his help in preparing this article.