How I structure CSS files
Yesterday I was having dinner with my coworkers (company party!!) and between some bottles of wine, Italian food and Bocce, Marcus Schaefer commented that my CSS are really organized and I briefly explained why I do this way to him and thought that it was a good subject for a blog post…
The purpose of this post is to explain a little bit my workflow and how I setup my CSS files and why I do this way. I’ve been using almost the same structure on the past 3-4 years and it has been working pretty well, it’s the way that I find more productive/organized for my way-of-thinking/workflow and I’ve never seen someone writing about and/or using the same approach.
Keep in mind: each person has their own opinions/preferences and my setup may not fit other people’s workflows…
How it all started…
I still remember the first time I saw a tableless website, I was looking at the source code to try to figure out how to replicate a roll-over effect and at that time I didn’t even knew that CSS could be used for other stuff besides changing the scrollbar and link colors.. I thought that they were using some kind of magic and that I would never learn how to do those things… - It was back on 2004 and I had just started my Graphic Design Bachelor after graduating as a Technician on a Business Management school (together with high school), so I wasn’t coding that much back then… - Almost 1 year later I started reading many tutorials/articles (specially on a Brazilian website called Maujor) and coded my first tableless website, after that CSS became my favorite web technology and remain as so until now…
My default.css file
IMPORTANT: My default.css file evolved over time and it became the basis.css framework. Info about the way I order rules still relevant but I’m not using this default.css file anymore.
All my projects starts with the exact same CSS file called “default.css” that stays on my computer desktop all the time and that is also the preset for new CSS files on my Eclipse preferences.
After reaching a stable version (or after some good progress on the development) I usually also add a date after the @version number like: @version 0.3 (2010/06/17) and update the version number at each update, just to remind when the file was created/modified.
PS: the “Awesome Website” really makes part of my default.css file, just to start the project with some positive thinking
– I replace it with the project name at the beginning of the development so I don’t forget it.
The order is important!
One of the most important things is to keep the code organized in a logical way, so you can browse it quickly and avoid overwriting rules that you don’t want.
I always separate the rules based on the type (reset, tags, generic classes, structure) and also based on the order-of-appearance on the markup. – e.g. #wrapper should come before #header, ul should come before li, and so on…
I also “group” the rules by “categories” (separated by space) so everything from the footer will be at the same place…
Rules that applies to all pages should come before specific ones.
Why do I follow this specific order?
One of the hardest things to understand and to master in CSS is specificity – of course it loses for the box-model, float, overflow and display modes.. but still hard – so if you keep this order is less-likely that you will get confused about what is being overwritten since the most specific also are the last rules on the file.
Reset
Nowadays most people already knows what it is and uses some kind of CSS reset to reduce the browser incompatibilities, the most popular ones are Eric Meyer’s and YUI reset.
Why create a custom reset instead of using YUI or Eric Meyer’s?
Before reading some article a long time ago (maybe 2006-2007) I was using the simplest technique possible to reset the browsers default properties: *{margin:0; padding:0} – but as the article pointed out, this isn’t good for performance and you can end-up changing more than you actually want, so I decided to stop using this technique. At that time I thought that Meyer’s approach was too big and that he was doing way more than I needed, so I decided to code my own stripped-down version (it was simpler than my current one)…
Some time ago I even started to create custom resets based on the tags that I will use on the project; I start with all of them and delete the ones I’m not using (specially for mobile websites), since mobile devices has a very limited performance.
Edit: I went back to Meyer’s reset since it is very stable and well known. Another option is to use normalize.css instead of resetting your styles.
General Tags
All HTML tags that needs some generic/default styling goes here. I don’t use any CSS class or ID here.
Generic Classes
Styles shared among multiple elements and/or classes that are used on more than one section/page/html block for instance .last, .odd, .error, etc..
Structure/Content
Styles that define the page structure and/or are directly related with the page content – e.g. #wrapper, .mainNav, etc..
Hacks
I usually use this part to add browser specific (basically IE) hacks during the development phase, after finishing the development I usually remove the code from this section and add it as a separate file using conditional comments. – I’ve stopped using conditional comments and moved back to CSS hacks, conditional comments usually causes more problems than it solves, I also stopped separating hacks from regular styles to avoid duplicating selectors which could make changes be out-of-sync. Usually a simple website (my portolio, my blog, etc) doesn’t require hacks, but sometimes there is no way to avoid it..
This website has a list of the most common IE 6-7 CSS bugs and how to solve them. Avoid using hacks whenever possible.
Debug
Styles used for debugging purposes, removed before deployment.
Why all the properties are on the same line
A couple years ago I was using almost the same conventions but instead of keeping all the rules of the selector on the same line I was breaking each property into a new line, so why did I stopped doing like this?
- Avoid scrolling
- I’m sure a lot of people will find it harder to read, other will find it easier, it all depends on your preferences. If you don’t like it just use a CSS formatter. – I think it saves me some good amount of time.
- Performance (File Size)
- Not really a valid point since you could do the same thing before deploying the site but that way I don’t even bother compressing my CSS files since it is already kinda compressed. – view comment #3 for more details
- I’ve got used to it
- After the first project there’s no way back…
- Changing properties isn’t that common
- Finding the property is way easier than to find the proper selector – it’s hard to have more than 10 properties for a single selector
- Easier to find the proper selector
- You can browse the file quicker since many selectors are on the “same fold”.
Nowadays I’ve been working on larger projects so I’m breaking my CSS into multiple files and keeping each rule in a separate line, only using the single-line approach in small projects (so I keep the amount of lines small). added 2012/03/13
When the project/file is too big
Most of the time my projects have a single CSS file (avoid multiple HTTP requests, cached between pages, etc..) but when the file start to get too big (more than 300 lines) and a specific section/page that the user may not go to (e.g. shopping cart) has a lot of different rules (e.g. 25% of the file size), I usually split that section into a new file to save bandwidth and also because it helps to keep the files organized and makes the CSS easier to read/maintain – when the file is too big you end up scrolling too much and getting lost.
If the file starts to get too big it is a good idea to check if all the rules are really being used, there are a couple tools that can help you like Page Speed and CSS usage.
In case your project is really big instead of just using “comments” to split sections of your file split them into different files (reset.css, general.css, generic.css, structure.css, home.css, contact.css, etc..). Consider using a build tool like Ant, make, rake to concatenate your CSS files for deployment. I’ve been using the RequireJS optimizer to merge @import(ed) stylesheets.
To sum up
I consider organization as being a really important skill for developers since it makes debugging/maintenance/collaboration easier and it’s something that I try to keep on all projects but don’t take it too serious, of course a crazy deadline and/or lots of changes requests can make everything “go down the toilet” and also if you are doing something really simple there’s actually no need… It’s just an advice and I hope it’s useful for someone, at least for me it was a HUGE change/improvement on my workflow.
To cite a friend: “The only thing worse than other people’s code, is your own code 6 months later.” — Zeh Fernando
Read More
- CSS Guidelines by csswizardy (external)
- CSS naming conventions by necolas (external)
- SMACSS: Scalable and Modular Architecture for CSS (external)
That’s it!
Changelog
- 2010/07/16:
- added some notes about larger projects and why I keep all properties on the same line.
- 2010/11/11:
- updated
default.cssand added new notes about hacks and debug sections. - Edit 2011/01/09:
- updated
default.cssand moved it to GitHub to make updates easier, updated “hacks” section and added info about build tools and split files to “big projects”. - 2011/05/03:
- Added note about going back to Meyer’s reset.
- 2011/07/20:
- Info about default.css becoming the basis.css framework.
- 2012/03/13:
- Added “Read More” section and info that on large projects I break each rule into a separate line.