Skip to content

Instantly share code, notes, and snippets.

@jacopotarantino
Created May 9, 2019 18:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jacopotarantino/bc9be0eef82a632b7adb7fe19224dad4 to your computer and use it in GitHub Desktop.
Save jacopotarantino/bc9be0eef82a632b7adb7fe19224dad4 to your computer and use it in GitHub Desktop.
Proposal: split CSS files by media query

I've seen others struggle(and have struggled myself) with media queries and gigantic CSS files separately and together. I recently learned that CSS import statements support media queries and have done so for a long time (see: https://developer.mozilla.org/en-US/docs/Web/CSS/@import). In other implementations I've seen this ability being used for including external stylesheets into a stylesheet the developer actually controls. I'd like to propose a system where developers use CSS imports by default in order to minimize the amount of data sent to clients and in order to better structure our CSS. An example index.css file and small.css (included file) is show in this gist. Structuring our files this way means that the initial CSS payload is only 306 bytes. Anything more than that is only included if it's relevant to the current client. We can also inline this initial block into the <head> of the html removing a single network request from the initial render of the site. All in all, this means we can deliver an absolute minimum of data to the client and nothing that's irrelevant.

The best part of this strategy in my opinion is that this can be achieved today using the same automated parsing and transforming scripts that we already use for typical frontend work. We can use Webpack to sort our media queries, group them by same-query, strip away the duplicated queries, write the styles to files named based on those queries, and finally list the files to include by media query in the generated index file.

// possible other common rules go here.
// perhaps CSS that is required for a faster initial render...
body {
background: skyblue;
}
@import 'common.css';
@import 'small.css' (min-width: 480px);
@import 'medium.css' (min-width: 768px);
@import 'large.css' (min-width: 1024px);
@import 'print.css' print;
body {
padding: 20px 30px;
}
// rules in this file are included *after* rules in previous files and so should override by nature (cascading).
// no need to repeat the media query because we already wrote it in the index file.
// these styles *only* get downloaded and used if the client matches the media query.
body {
padding: 20px;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment