CSS must pass through a relatively complex pipeline, just like HTML and JavaScript. The browser must download the files from the server and then proceed to parsing and applying them to the DOM. Due to extreme levels of optimisation, this process is usually pretty fast – for smaller web projects not based on frameworks, CSS usually makes up just a small part of total resource consumption.

Frameworks upset this equilibrium. Include a JavaScript GUI stack like jQuery UI, and watch CSS, JS and HTML sizes skyrocket. Often, developers usually feel the pinch last – when seated behind a powerful eight-core workstation with T3 internet, no one cares about speed. This changes as latencies or CPU-constrained devices come to play.

Optimising CSS requires a multi-dimensional approach. While hand-written code can be slimmed down using various techniques, going over framework code by hand is inefficient. In these cases, using an automated minimiser yields better results.

The following steps will take us on a journey through the world of CSS optimisation. Not every single one might be directly applicable to your project, but do keep them in mind.

01. Use shorthand

Shorthand can make your CSS files much smaller

The fastest CSS clause is one that never gets parsed. Using shorthand clauses, such as the margin declaration shown below, radically reduces the size of your CSS files. A lot of additional shorthand forms can be found by googling 'CSS Shorthand'.

p { margin-top: 1px; margin-right: 2px; margin-bottom: 3px; margin-left: 4px; } p { margin: 1px 2px 3px 4px; }

02. Find and remove unused CSS

If code's not doing anything, get rid of it

Eliminating unneeded parts of your mark-up obviously causes immense speed gains. Google's Chrome browser has this functionality out of the box. Simply go to View > Developer > Developer Tools and open the Sources tab in a recent version, and open the Command Menu. After that, select Show Coverage and feast your eyes on the coverage analysis window highlighting unused code on the current webpage.

03. Do it in a more comfortable fashion

Use Web Performance Audit to easily trim redundant code

Navigating through the line-by-line analysis is not necessarily comfortable. Chrome's Web Performance Audit returns similar information – simply open it from the toolbar, View > Developer > Developer Tools > Audits and let it run. When done, a list of problematic elements will pop up.

04. Be aware of the problems

Keep in mind that an automatised analysis of a CSS can always lead to errors. Perform a thorough test of the entire website after replacing your CSS files with the minified ones – one never knows what mistakes the optimiser caused.

05. Inline critical CSS

Loading external stylesheets costs time due to latency – anyone remember the 'flash of unstyled content'? The most critical bits of code can therefore go into the header tag. Make sure not to overdo it, however. Keep in mind that the code must also be read by humans performing maintenance tasks.

<html> <head> <style> .blue{color:blue;} </style> </head> <body> <div class="blue"> Hello, world! </div>

06. Permit antiparallel parsing

@import adds structure to your CSS code. Sadly, the benefits are not for free: as imports can nest, parsing them in parallel is not possible. A more parallelisable way uses a series of <link> tags, which the browser can fetch at once.

@import url("a.css"); @import url("b.css"); @import url("c.css"); v<link rel="stylesheet" href="a.css"> <link rel="stylesheet" href="b.css"> <link rel="stylesheet" href="c.css">

07. Replace images with CSS

Years ago, a set of semi-transparent PNGs to create translucent effects on websites was commonplace. Nowadays, CSS filters provide a resource-saving alternative. As an example, the snippet accompanying this step ensures that the picture in question appears as a grayscale version of itself.

img { -webkit-filter: grayscale(100%); /* old safari */ filter: grayscale(100%); }

08. Use colour shortcuts

Common wisdom teaches that six-digit colour descriptors are the most efficient way to express colours. This is not the case – in some cases, shorthand descriptions or colour names can be shorter.

target { background-color: #ffffff; } target { background: #fff; }

09. Eliminate unneeded zeros and units

CSS supports a wide variety of units and number formats. They are a thankful target for optimisation – both trailing and following zeros can be removed, as is demonstrated in the snippet below. Furthermore, keep in mind that a zero always is a zero, and that adding a dimension does not add value to the information contained.

padding: 0.2em; margin: 20.0em; avalue: 0px; padding: .2em; margin: 20em; avalue: 0;

10. Eliminate excessive semicolons

This optimisation is somewhat critical, as it affects changes of code. CSS' specification lets you omit the last semicolon in a property group. As the savings achieved by this optimisation method are minimal, we mention this mainly for those who are working on an automated optimiser.

p { . . . font-size: 1.33em }

11. Use a texture atlas

Loading multiple small sprites is inefficient due to protocol overheads. CSS sprites combine a series of small pictures into one big PNG file, which is then broken apart via CSS rules. Programs such as TexturePacker simplify the creation process greatly.

.download { width:80px; height:31px; background-position: -160px -160px } .download:hover { width:80px; height:32px; background-position: -80px -160px }

12. Chase down the px

One neat way to increase performance uses a specialty of the CSS standard. Numeric values without a unit are assumed to be pixels – removing the px saves two bytes for each number.

h2 {padding:0px; margin:0px;} h2 {padding:0; margin:0}

13. Avoid expensive properties

Analysis has shown some tags to be more expensive than others. The list accompanying this step is considered to be especially performance-hungry – avoid them when given the opportunity to do so.

border-radius box-shadow transform filter :nth-child position: fixed; etc.

14. Remove whitespace

Whitespace – think tabs, carriage returns and spaces – makes code easier to read but serves little purpose from a parser's point of view. Eliminate them before shipping. An even better way involves delegating this job to a shell script or similar appliance.

Comments also serve no purpose to the compiler. Create a custom parser to remove them before delivery. Not only does that save bandwidth but it also ensures that attackers and cloners have a harder time understanding the thinking behind the code at hand.

16. Use automatic compression

Yahoo's user experience team created an application that handles many compression tasks. It ships as a JAR file, available here, and can be run with a JVM of choice.

java -jar yuicompressor-x.y.z.jar Usage: java -jar yuicompressor-x.y.z.jar [options] [input file] Global Options -h, --help Displays this information --type <js|css> Specifies the type of the input file

17. Run it from NPM

Should you prefer to integrate the product into Node.JS, visit npmjs.com/package/yuicompressor. The badly maintained repository contains a set of wrapper files and a JavaScript API.

var compressor = require('yuicompressor'); compressor.compress('/path/to/ file or String of JS', { //Compressor Options: charset: 'utf8', type: 'js',

18. Keep Sass et al in check

Sass can get needlessly complex, so optimise it if you can

While CSS selector performance is not nearly as critical as it was some years ago (see resource), frameworks such as Sass sometimes emit extremely complex code. Take a look at the output files from time to time and think about ways to optimise the results.

19. Set up caching

An old adage claims that the fastest file is one that never gets sent across the wires. Making the browser cache requests achieves this efficiently. Sadly, the setup of the caching headers must take place on the server. Make good use of the two tools shown in the screenshots – they provide a swift way to analyse the results of your changes.

20. Bust the cache

Designers often dislike caching due to fear of problems with upcoming changes. A neat way around the problem involves including tags with the file name. Sadly, the scheme outlined in the code accompanying this step does not work everywhere as some proxies refuse to cache files with 'dynamic' paths.

<link rel="stylesheet" href="style.css?v=1.2.3">

21. Don't forget the basics

Optimising CSS is just part of the game. If your server does not use HTTP/2 and gzip compression, a lot of time is lost during data transmission. Fortunately, fixing these two problems is usually simple. Our example shows a few tweaks to the commonly used Apache server. Should you find yourself on a different system, simply consult the server documentation.

pico /etc/httpd/conf/httpd.conf AddOutputFilterByType DEFLATE text/html AddOutputFilterByType DEFLATE text/css

This article was originally published in issue 282 of creative web design magazine Web Designer. Buy issue 282 here or subscribe to Web Designer here.

Related articles: