The following is an extract from our book, CSS Master, written by Tiffany Brown. Copies are sold in stores worldwide, or you can buy it in ebook form here.
CSS File Organization
Part of a good CSS architecture is file organization. A monolithic file is fine for solo developers or very small projects. For large projects—sites with multiple layouts and content types, or multiple brands under the same design umbrella—it’s smarter to use a modular approach and split your CSS across multiple files.
Splitting your CSS across files makes it easier to parcel tasks out to teams. One developer can work on typography-related styles, while another can focus on developing grid components. Teams can split work sensibly and increase overall productivity.
So what might a good file structure that splits the CSS across files look like? Here’s a structure similar to ones I’ve used in recent projects:
- reset.css: reset and normalization styles; minimal color, border, or font-related declarations
- typography.css: font faces, weights, line heights, sizes, and styles for headings and body text
- layouts.css: styles that manage page layouts and segments, including grids
- forms.css: styles for form controls and labels
- lists.css: list-specific styles
- tables.css: table-specific styles
- carousel.css: styles required for carousel components
- accordion.css: styles for accordion components
If you’re using a preprocessor, such as Sass or Less, you may also want to include a _config.scss or _config.less file that contains color variables and the like.
In this structure, each CSS file has a specific and narrow scope. How many files you’ll ultimately end up with depends on how many visual patterns or components are called for by your site’s design.
CSS frameworks such as Foundation and Bootstrap use this approach. Both become quite granular with separate files for progress bars, range inputs, close buttons, and tooltips. This allows developers to include only the components that they need for a project.
Note: Pattern Libraries
A closely related concept to splitting CSS across files like this is the pattern library. A great primer on the subject is Anna Debenham’s “Getting Started with Pattern Libraries.”
How many files?
Even though we’re using several CSS files for development, we’re not going to serve all of them to the browser in this form. The number of HTTP requests that we’d require would make our site take lonegr to load. Instead, we’ll concatenate our smaller CSS files into a few larger ones for production.
Concatenation in this context, means combining multiple files into a single CSS payload. It eliminates the need for @import
statements or multiple link
elements. Current browsers have limits on how many files they can download at once. We can use concatenation to reduce the number of network requests, getting your content to users in less time.
Often your web development framework will handle concatenation as part of its asset management features, such as Ruby on Rails. Some content management systems do the same, whether as a core feature or an add-on. Preprocessors—introduced in Chapter 9 also make concatenation easy. If neither preprocessors nor development frameworks are part of your workflow, chances are that your operating system has a concatenation utility that you can use instead.
For Mac OS X or Linux, concatenate files using the cat
utility:
cat file1.css file2.css > combined-output-file.css
Using Windows? Try the type
utility:
type file1.css file2.css > combined-output-file.css
You can also write your own concatenation script using Bash, PHP, Python, or another scripting language of your choice.
Note: CSS Optimization
Concatenation is one aspect of CSS optimization. It’s just as important to minify your files to remove excess characters and whitespace. Minification tools are covered in Chapter 3.
So how many files should you use? That’s where it gets tricky. The current best practice is to identify your critical path CSS—the minimum amount of CSS your page needs to render—and embed it in your pages using the style
element. Additional CSS files should be loaded using JavaScript. Addy Osmani’s presentation “CSS Performance Tooling” provides an excellent overview of this technique and some tools you can use to implement it. Also see the Filament Group’s loadCSS.
If your content will be served using the SPDY or HTTP/2 protocols, concatenation may be unnecessary. With HTTP/1.1, browsers download assets sequentially; the next request begins when the previous one ends. Under that model, reducing the number of network requests improves site performance; however, SPDY and HTTP/2, can download multiple assets at once. As a result, there is no real benefit to reducing the number of requests. There is, however, a cost to sending more bytes than necessary to render the page. William Chan’s “HTTP/2 Considerations and Tradeoffs” explains this in greater detail. The best approach would be to identify if your server is serving HTTP/2 and, if so, check whether more of you users will benefit from actually splitting your assets down and only loading that which the page needs, or continuing to work in the old way. If you’re interested in learning more about performance optimization methods, the SitePoint book Lean Websites is a useful resource.