How to structure your CSS

How to structure your CSS

Freelance interface and frontend developer Mike Byrne, also part of the Area 17 technical team, explains how he structures his CSS and why

This article first appeared in issue 218 of .net magazine - the world's best-selling magazine for web designers and developers.

As an experienced frontend developer, I’ve been writing CSS documents for 10 years now and it feels like I’ve been refining my method on every site I build. For most of this time I’ve been the sole frontend developer on a build and so my methods have been learned as needs must, rather than through any formal training or communication with other frontend developers. I have often wondered how other frontend developers go about doing their CSS and how it compares to how I do it; for all I know I’ve been doing it wrong for years ...

So in this article I’m going to talk about how I structure my CSS and why, for you to agree with or disagree with. It’s not to say this is the way to do your CSS, but it’s certainly a way that’s worked out pretty good for me.

My approach

The very first thing I do at the start of a job is to consume as much of the available artwork and any spec documents as possible. Usually I get the designer and a project manager to talk me through the artwork and their expectations. We discuss any interactions, any potential issues, browser expectations and generally I ask lots of questions. This is where I begin to think about what classes, what div structures and if I have any CSS from other projects I can port across to this new project. I’m engaging my brain to pre-problem solve the CSS for the site. If there’s something that I’m not sure about, now’s the time to do some research and maybe do some rough tests.

This whole process is easier on smaller websites and on websites built using the waterfall method of production – because the chances are you’ll have a lot of artwork available. If you develop using an Agile method, it can be trickier. This means more guesswork and leaning on your experience. It will also mean more CSS refactoring and the need to really communicate with the designers on the job. If you’re not sure what I mean by Agile and waterfall, you probably work waterfall and might want to check out an Agile method, such as scrum.

My CSS structure

I start every job now, as I have for years, with my own HTML boilerplate (download the source files above). I do this simply because I know what’s in it; because I put it there. I quite like the HTML5 boilerplate and have nicked things from it. My base has evolved from my experience. It doesn’t include any layout structures simply because I rarely seem to work with layouts that suit a solution like that.

I started to do this structure, partly because I like a little bit of discipline and order, and partly because of the nightmares I’ve had on the sustainability of websites as they have grown or changed. My old method was just to write CSS on an “as needed” basis; that is, if I was looking at the main navigation, I’d style that. And then next on the page might be the featured articles, so I’d style that.

And then next might be the news listing, so I’d style that. My CSS documents grew large, became confusing and shared styles became hard to manage.

The major files in my CSS boilerplate are:

  • cssLoader.css
  • common.css
  • application.css

And then a couple of folders:

  • /stylesheets/modules/
  • /stylesheets/pages/

cssLoader.css is just a stub file that loads in other CSS documents, using @import. This file is for development and not the production server because @import does funny things in Internet Explorer that can cause a loading flash.

This is the CSS loader stub file, which loads in the rest of the site’s CSS documents
This is the CSS loader stub file, which loads in the rest of the site’s CSS documents

There’s also a limit of 32 imported files for IE, so I usually have a counter that I manually update – if I reach the limit I refactor things.

common.css is my resets plus classes that crop up in nearly every job that I do CSS. The reset used is basically the Eric Meyer reset, updated by Rich Clark for HTML5.

My common.css; resets styles and sets up some standard CSS that I use on all of my sites
My common.css; resets styles and sets up some standard CSS that I use on all of my sites

I then have some classes to float things, including a variation for images and a couple of methods to clear the floats.

Sometimes overflow: auto; doesn’t cut it and you need a good old <br class=”floatClear” /> or a <div class=”cleaner” />.

In here, too, are some simple text align classes and setting up of a style-able <hr /> (by wrapping it in a div).

The remaining classes are practical; hide an element, get rid of a border or background, bold text and a simple error class.

I use these so often that when I edit someone else’s CSS I forget that such classes aren’t standard CSS classes – a bit like base JavaScript functions such as split() or toString().

This file doesn’t change between jobs and if I do update it I use the updated version as the standard version in future jobs.

I use application.css as the central CSS for the whole site – styles that are defined here will be used on every page of the site and refined later, in other documents.

Importantly, I split up the CSS, with comments, so it is easier to find things in the future. I split this CSS up into these consistent sections:

  • fonts
  • body
  • layouts
  • general styles
  • custom classes
  • div specific styles
  • page specific styles (optionally)

First thing I’ll put in this CSS is any font-face CSS, usually generated with Font Squirrel. It’s good to get fonts downloading nice and early.

Then I start to style the site. I start to look at the main structures of the site – the headers, the footers, the columns and so on – and get them into place. On some pages I may need to modify some of these: this I worry about later.

general styles is where I set up the site wide styles for text elements, forms and links. Again, different pages and different parts of pages will need their own styles so we’ll modify these styles later.

Quite often the sites we build have a recurring set of things, buttons that look a certain way or chevron background boxes with dotted borders and so on, but they appear, looking similar, in multiple places. So I group these kinds of styles in my “custom classes”. Sometimes these styles get tweaked later but generally it saves you re-writing the same style over and over.

My div specific styles, which I guess I should rename element specific styles in this modern HTML5 world – is where I style the HTML that sits inside those site wide areas like the header and footer. So now, rather than just giving the div#footer or footer its dimensions, borders and so on, I’m going to style the lists, paragraphs and so on inside of the footer.

At this point, the site will have a set of basic styles that will look consistent throughout the site; it will have its nice header, navigation and footer with maybe some columns and styled text styles. The individual pages might not yet fully resemble the page designs, but even in their “un-styled” form, they should look like they fit into the site. We can get to writing the custom CSS for each module and each page later.

Styling the individual modules/pages

Now I start to style the individual pages of the site. I either do this in my page specific styles in the application.css if it’s one of those three- to five-page sites, or within CSS documents in the modules and pages folders if it’s something larger. Splitting the CSS up into separate documents in a structured folder system easily allows multiple FE developers to work on the same site at the same time and allows whomever looks at the CSS to find the bits they need to edit more easily. Rather than having one 11,000-line CSS document (yes, I’ve been there), picking through several smaller CSS documents is much easier.

Modules

To me, a module is one of those bits of HTML that gets used in multiple places around a website, but is a bit more involved than just a specific link style. So on the DFI website many pages have a Spotlight or Press module in the right-hand column that appears on multiple pages of the site.

DFI had many repeated bits of HTML modules to style; the Press and Spotlight modules are on many page
DFI had many repeated bits of HTML modules to style; the Press and Spotlight modules are on many page

I try to group similar types of modules together in one place, so those that I call touts will all live in touts.css.

Typically I’ll have CSS documents in my modules folder to stay organised and are called simple names such as:

  • lists.css
  • touts.css
  • comments.css
  • detail.css
  • listing.css

Lists.css is where I style all those article listing type lists. If, say, it was a website that sold CDs and DVDs and the design had a different design for the listing of each, I’d have a ul.listing_cd and a ul.listing_dvd styled up here.

detail.css and listing.css is where I style a basic page of each type. So, following the CD and DVD shop site idea, I’d style a basic listing and item detail page. Okay, so CD and DVD listing pages might have different elements or designs, or we might have to add tweaks for featured CDs, featured DVDs, sale products and so on. But I’ll worry about these later: as long as the basic listing and detail pages are styled I know that any new filter types of the listing will at least have some basic styles and won’t look too out of place on the site.

And now we style the specific pages themselves, things that haven’t been covered by application, modules and only appear in a specific place/section of the site. So here I’ll end up with a list of CSS documents a bit like this:

  • home.css
  • about.css
  • privacy.css
  • featured.css

To make this work, I add a helper class to either the body, or the main container of the HTML, for each page. Doing this automatically in an application based on the controller name is simple. The BE developers I work with do this automatically, but sometimes I get them to tweak the class names.

If the page needs some tweaks, make a CSS, make sure it’s linked in the loader (I still forget from time to time and wonder what I’ve done wrong ...) and get tweaking the styles. The header on the homepage is larger? Cool:

  1. .home h1 { font-size: 72px; }

And keep going until you’re done. This method has worked well for me over the years, but I do change it from time to time and I’d welcome any discussion on it. Look me up on Twitter and tell me what you think.

18 comments

Comment: 1

Really?!

Have I missed something here?

Are you serious?

So many HTTP requests! This can't really be the 'best' way to organise your CSS!

I would advocate no more than four files at most for any given page: One for truly global styles (CSS reset, font settings etc), one for modules used in a subsection of the site, one for section-wide settings (universal colour scheme for a particular section of the site for example) and one (but only if absolutely necessary) for page specific settings.

Any other sub-division of style sheets should be marked with good, concise commenting.

Redundant HTML should also be avoided at all costs. ? Not in my code!

I've been writing CSS for about 10 years too and this is the kind of stuff that I stopped doing about 8 years ago - overly verbose and badly optimised.

Comment: 3

You can just merge all these files together with .htaccess, you should. Same for your scripts.

If not, this is not the right way to go.

Comment: 4

@ JoshuaSortino

I tend to practice a 'write as live' policy - that way I can guarantee that the behaviour of any of my CSS will not change when recombined or recompiled in any way - development only is not an excuse for this kind of bad practice.

@ seom

I'd be happier if that were mentioned and covered in the article but it's not.

There are a large number of letters from new developers asking for advice that are published by .net. To publish this kind of uninformed bad practice under the banner of "Tutorials" with such a definitive headline is just arrogant and disrespectful.

I can see the advances we've made towards making semantic and standardised pages the norm in the last few years evaporating over night as hundreds of new developers think that this article defines the sort of standards we should adhere to.

.net, if you're listening, sort yourselves out and talk to some real developers - the kind that actually code every day and not the kind that spend their lives just talking about it!

Comment: 5

This article is very juicy. I don't understand why you are complaining...

Comment: 6

This article is great. It does things a bit differently than I do, but I enjoy seeing another perspective with some little tricks. It also helps to have ideas that you're trying out re-affirmed by other developers once in a while.

I'm a real developer and I deal with this every day. If you can't -- note that I'm not saying if you don't -- develop CSS in separate files and understand how to merge them together via cache, pagespeed, or sass/less compilation, you should probably look in to it. I deal with this exact material for the majority of my time at my day job and I found a lot of value here.

More articles like this one, please!

Comment: 7

@7hz — This kind of approach works very well for large projects employing teams of developers. Granted, this approach may be a little impractical for smaller static sites, but as indicated by the project mentioned in the article, that isn't the kind of project Mike works on, or the type of project his framework was designed to accomodate.

This approach is actually reflected quite clearly in the new asset structure defined by Rails 3.1. Any issues caused by the number of HTTP requests are removed by minifying each CSS and merging into a single file prior to a code deployment.

Comment: 8

I'm glad my article stimulated some conversation - thanks for your comments.

@7hz

It should be noted that in the printed version there was an "expert tip" block that talked about this structure being for development only and the need to use asset packers or at the least concatenate/minify the CSS for production. There was also a "pros and cons" and a "top tips" block haven't been reproduced on the web article; those missing blocks talk about your concerns. For me, the pros out weigh the cons here, but I'm always willing to learn.

@mechler

I'm really loving SASS at the moment!

Comment: 9

As a junior front-end developer, I really enjoyed this article. I sometimes do things in a very ad-hoc way which is, needless to say, a bad way of doing things. It's nice to see someone, who has been in the industry for a while, discuss basics such as structuring CSS files.

The agency I'm in uses the @import method, and I feel it really provides my understanding of the styling of larger sites, especially when multiple people are working on one project.

To only read one article, such as this, and take it as gospel would be utterly stupid of me. I naturally read as much as I can everyday on these subjects and best practices and am well aware of the issue with HTTP requests and @import. We minify everything when the project is nearing completion to resolve this.

I suppose the title is somewhat misleading as it sounds like a tutorial, but having actually read the article from start to finish I am aware this is not "the only way you should be doing things".

Thanks for the great article. Will reread it in the future no doubt.

Comment: 10

It seems to me all approaches advocating extensive use of multiple stylesheets or modular stylesheeting are all trying to counter the fundamental issue presented by the method of laying out every single style on it's own line - resulting is supermassively long stylesheets that are hard to navigate or understand (unless you do what Mike is doing here).

There's a very simple way around this - just stop doing it. Laying out every single style on it's own line is not a standard, it's a convention, and you don't have to use it. I've gone into this in a (slightly confusing) article you can read here: http://www.ghldigital.com/index.php/articles/article/slicss_a_single_lin...

Despite this, Mike, thanks for this article - I learned a couple of tricks.

Comment: 11

I don't really agree with including all different style sheets, even if just for development, surely you can just comment your stylesheet accordingly and have a good structure set out in 1 sheet.

Comment: 12

@ayoungh Using multiple includes becomes a HUGE advantage when working with a team using version control. Imagine working with someone else constantly overwriting or merging changes... because everything is in one damn file. It not fun. :P

For production, using SASS or LESS to compile these includes into one, minified CSS is the way to go.

There is no end-all-be-all way of organizing CSS. There are best practices and patterns to follow, for sure. But really, you should have your own method (based on best practices/patterns), and tweak on a per-project basis.

Comment: 13

Interesting read and I too setup my CSS files in a similar fashion. I usually end up with the following:

1 CSS file for resets - usually the Eric Meyer version as mentioned above
1 CSS file for common styles - basically the general style of the website, headers, footers, fonts, etc
And an optional CSS file for each page where the common file is not enough.

Up until now though I haven't tried compiling them into one file in production so I will definitely be looking into SASS and LESS to see what they offer.

Comment: 14

Holy cow... all those @imports!!!!

I agree that modularised CSS is the way forward - I've been using it on the ecommerce platform I work on for a couple of years now.

I hope you're using a framework or a server-side combiner/minifier to serve up a single CSS file to the users!

Comment: 15

In the print version of the article there was a block discussing the the need to some method to concatenate and minify the CSS. For example; in the rails apps we build, we typically use Jammit and I guess in rails 3.1 we'll use its in built method.

@jchilders makes a good point; "But really, you should have your own method (based on best practices/patterns), and tweak on a per-project basis."

@grazlewacky I've tried both and multiple lines just feels easier for me as I find them easier and less intimidating to read - having big blocks of CSS without white space makes me reach for the return key. Fortunately its easy to convert between the two to keep both sides happy.

@diggersworld SASS is brilliant.

Comment: 16

In the print version of the article there was a block discussing the the need to some method to concatenate and minify the CSS. For example; in the rails apps we build, we typically use Jammit and I guess in rails 3.1 we'll use its in built method.

@jchilders makes a good point; "But really, you should have your own method (based on best practices/patterns), and tweak on a per-project basis."

@grazlewacky I've tried both and multiple lines just feels easier for me as I find them easier and less intimidating to read - having big blocks of CSS without white space makes me reach for the return key. Fortunately its easy to convert between the two to keep both sides happy.

@diggersworld SASS is brilliant.

Comment: 17

my css is very simple, your css is very pro. I love it ^^

Comment: 18

Very intuitive. I usually tend to stick to three, while I do understand this process.
common.css - resets/system settings
index.css - index page is usually different than all other pages as it's the splash page
application.css - across the site
July issue on sale now!

The Week in Web Design

Sign up to our 'Week in Web Design' newsletter!

Hosting Directory
.net digital edition
Treat yourself to our geeky merchandise!
site stat collection