We often start our CSS clean, simple and with good intentions, but as teams grow and we continue to deploy our code, it's usually the style sheets that suffer. Developers scroll to the bottom of a CSS file, adding in their new bits as they go, with blatant disregard to the structure or rules that have gone before.
I thought I was the only person who was tired of the sight of a relatively simple landing page with 3,000-plus lines of badly written, inconsistent code, often scattered with the dreadful !important declaration. However at conferences I've spoken to many people with the same passionate hatred as me, from small startups to tech giants.
Our style sheets are becoming monsters we need to tame. Daniel Eden recently spoke at the dotCSS conference about the same problems at Dropbox, and how his job is now focused on re-architecting the company's CSS codebase.
So how do we solve this issue? Where do we even start? One solution is to bin the CSS and start again. Hey, why not do a full redesign of the website while you're there? Although this seems like a fun project, it doesn't really solve the issue. It just sweeps it under the rug for another year, until the same thing happens again. This is where linting can be your springboard to maintainable CSS.
Linting your CSS doesn't have to be hard. If you're working on a small, uncomplicated project it's as simple as manually copying and pasting your CSS into the CSSLint website. The strapline of this website will sum up your reaction as you parse your first CSS file: 'Will hurt your feelings (And help you code better)'.
Don't be put off by the errors or warnings you first encounter; the key is to learn why your code is producing these errors, why they are important, and (of course) how to fix them. At the time of writing the most recent stable version of Bootstrap (v3.3.6) produced three errors and 247 warnings.
The next step is to customise your linting rules. CSSLint breaks all its rules down into six distinct sections: errors, compatibility, accessibility, maintainability and duplication, performance and OOCSS. Each section's rules can be individually turned off or on, depending on your project.
For example, one of the rules states that you must not use box-sizing in your code, as it's not supported by IE7 and below. Most companies have ditched support for this browser (I'm so sorry if yours hasn't, I'll give you a hug if we ever meet), therefore this rule is not needed. Switch it off and suddenly the warnings on Bootstrap will go down to 225. Not bad at all.
Here you need to be strategic; you can't just make all your CSS pass linting by switching off rules that give errors or warnings. Instead you should comb through the list of rules given by CSSLint and decide which you want to throw errors, which you want as warnings and which you are happy to let lie. At Holiday Extras we did just that: the UI team discussed how important each of the rules were and agreed which ones we should adhere to.
If your project uses a task runner like npm, gulp or Grunt, then the manual process of linting can be taken away with a few simple commands. Here we will use npm to install CSSLint globally.
npm install -g csslint
This installs the CSSLint CLI from the npm repository and allows you to run linting on the command line. You or your team can now check the status of your work as you go, which is much better than being alerted to all the errors after hours of development time.
To run CSSLint on the command line:
csslint [options] [path-to-file]
This will report all the errors and warnings according to the default settings. However, you can customise the rules by passing in a comma-separated list of options to the linter.
--warnings= --errors= --ignore=
For example, if you wanted any use of the !important declaration to throw an error, you would write:
csslint --errors=important [path-to-file]
This is great for customisation, but with over 30 rules to pick from your command line is going to get pretty hectic pretty quickly. However, it's likely you are going to be using the same rules over and over again – this is where we can create a CSSLint config file.
You will need to create a .csslintrc file in the root of your project or wherever you will be running the CSSLint command from. CSSLint always checks the current working directory to see if there is a .csslintrc file present, and uses these rules over the default settings.
Command line arguments will override anything that's in the file, so if you need to tweak some rules for a specific project, then I would suggest doing that, rather than changing the rules in your config file. The linting config file we use at Holiday Extras can be found here.
All these tools are very helpful for solving the problem of messy style sheets and maintainability, but you may still come up against some resistance from some developers who will grumble about their code taking longer to deploy. People don't like change, and in this case may get around it by simply not running linting on their files.
If you have continuous integration tools like Travis or CircleCI (both free if your project is open source) set up, you can get them to do the legwork. If someone deploys CSS that fails linting, these tools will fail the build and alert you or your team to the error. Nothing should go through a pull request without first getting the big green light from your CI tool.
If you use a preprocessor like Sass, Less or PostCSS, then of course there is a linting tool out there for you to use. Most are based on CSSLint but there are a few exceptions with different rules. Before you rely on these in your projects, you need to ensure you are using them for the right reasons.
If it's code quality you are after, and your linting rules mainly fall in the maintainability and duplication section, then linting your unprocessed code is perfect. If you're looking to ensure the code being served has a high level of performance, then it would be more beneficial to lint your processed CSS, as that's what the browser will be consuming and where performance matters most.
This is only the start of a long road to ensuring your CSS stays beautiful. We always want to take pride in our work, and nobody wants to re-factor code just because it has become a monstrous mess. You may clash with a few developers along the way, but it's surprising how quickly linting conditions people to code for the better.