Best Way to Structure a CSS Stylesheet

Best way to structure a CSS stylesheet

I've never been actually taught, however I can let you know how I organise my CSS documents. As you say, I like to divide it up into "geographical" areas... i.e. the rules that apply to the header, the side bars, the main content, the footer, etc. And then, below these I add very specific rules, say if I need to style a form or a table on a particular page. Finally I add a "General Gubbins" section at the bottom when I add generic rules that may apply across the board.

Oh yes, I also like to add the designer's palette to the top for quick reference.

For example...

/*
PALETTE:
dark grey : #555555;
pink : #d93575;
*/

/* HEADER */
#header {...}
#header ul {...}

/* SIDE BAR */
#side {...}
#side ul {....}

/* CONTENT */
#content{...}
#content p {....}

/* FOOTER */
#footer{...}
#footer div {....}

/* FORMS */
form {...}
input {...}

/* GENERAL GUBBINS */
.center {...}
strong {...}
floatleft {...}

How should I organize the contents of my CSS file(s)?

Have a look at these three slideshare presentations to start:

  • Beautiful Maintainable CSS
  • Maintainable CSS
  • Efficient, maintainable, modular CSS

Firstly, and most importantly, document your CSS. Whatever method you use to organize your CSS, be consistent and document it. Describe at the top of each file what is in that file, perhaps providing a table of contents, perhaps referencing easy to search for unique tags so you jump to those sections easily in your editor.

If you want to split up your CSS into multiple files, by all means do so. Oli already mentioned that the extra HTTP requests can be expensive, but you can have the best of both worlds. Use a build script of some sort to publish your well-documented, modular CSS to a compressed, single CSS file. The YUI Compressor can help with the compression.

In contrast with what others have said so far, I prefer to write each property on a separate line, and use indentation to group related rules. E.g. following Oli's example:

#content {
/* css */
}
#content div {
/* css */
}
#content span {
/* css */
}
#content etc {
/* css */
}

#header {
/* css */
}
#header etc {
/* css */
}

That makes it easy to follow the file structure, especially with enough whitespace and clearly marked comments between groups, (though not as easy to skim through quickly) and easy to edit (since you don't have to wade through single long lines of CSS for each rule).

Understand and use the cascade and specificity (so sorting your selectors alphabetically is right out).

Whether I split up my CSS into multiple files, and in what files depends on the size and complexity of the site and the CSS. I always at least have a reset.css. That tends to be accompanied by layout.css for general page layout, nav.css if the site navigation menus get a little complicated and forms.css if I've got plenty of CSS to style my forms. Other than that I'm still figuring it out myself too. I might have colors.css and type.css/fonts.css to split off the colors/graphics and typography, base.css to provide a complete base style for all HTML tags...

Is this how you would structure your CSS stylesheet?

That's similar to how I structure mine, however, I find that using sub-headings is the best way to do it, so I use this structure:

/*************************
* GLOBAL *
*************************/

/* All of the common stuff goes here under the appropriate sub headings */

/* Heading formatting */

/* Text formatting */

/* Form formatting */

/* Table formatting */

/* etc */

/*************************
* LAYOUT *
*************************/

/* All the layout things go here under sub-headings */

/* Header */

/* Left Sidebar */

/* Right Sidebar */

/* Footer */

/*************************
* NAVIGATION *
*************************/

/* I put navigation separate to the layout as there can be a number of navigation points under their sub-headings */

/* Main (horizontal) Navigation */

/* Left Navigation */

/* Right Navigation */

/* Breadcrumb Navigation */

/*************************
* FORMS *
*************************/

/* Any form formatting that varies from the common formatting, if there are multiple differently formatted forms, then use sub-headings */

/*************************
* TABLES *
*************************/

/* Same deal as forms */

/*************************
* LISTS *
*************************/

/* Same deal as forms and tables */

/*************************
* CONTENT *
*************************/

/* Any specific formatting for particular pages, grouped by sub-headings for the page the same way as forms, tables and lists */

/*************************
* CSS SUPPORT *
*************************/

/* This is for any special formatting that can be applied to any element on any page and have it override the regular formatting for that item. For example, this might have things like: */

.float-right { float: right; }
.float-left { float: left; }
.float-center { margin-left: auto; margin-right: auto; }
.clear { clear: both }
.clear-block { display: block }
.text-left { text-align: left }
.text-right { text-align: right }
.text-center { text-align: center }
.text-justify { text-align: justify }
.bold { font-weight: bold }
.italic { font-style: italic }
.underline { border-bottom: 1px solid }
.nopadding { padding: 0 }
.nobullet { list-style: none; list-style-image: none }

/* etc */

Hope that helps.

I generally don't recommend writing on a single line like that though, or like suggested in the link Adam posted, they get very difficult to skim over if they get long. For the examples above, it was just quicker to type them that way so I didn't have to indent every line.

For formatting I would recommend this structure:

.class {
width: 200px;
height: 200px;
border: 1px solid #000000;
}

And so on, I put the structure of the class or ID at the top, then any other formatting, like the font etc below that. Makes it very quick and clear to skim over.

Managing CSS Explosion

This is a very good question. Everywhere I look, CSS files tend to get out of control after a while—especially, but not only, when working in a team.

The following are the rules I myself am trying to adhere to (not that I always manage to.)

  • Refactor early, refactor often. Frequently clean up CSS files, fuse together multiple definitions of the same class. Remove obsolete definitions immediately.

  • When adding CSS during fixing bugs, leave a comment as to what the change does ("This is to make sure the box is left aligned in IE < 7")

  • Avoid redundancies, e.g. defining the same thing in .classname and .classname:hover.

  • Use comments /** Head **/ to build a clear structure.

  • Use a prettifier tool that helps maintain a constant style. I use Polystyle, with which I'm quite happy (costs $15 but is money well spent). There are free ones around as well (e.g. Code Beautifier based on CSS Tidy, an open-source tool).

  • Build sensible classes. See below for a few notes on this.

  • Use semantics, avoid DIV soup - use <ul>s for menus, for example.

  • Define everything on as low a level as possible (e.g. a default font family, colour and size in the body) and use inherit where possible

  • If you have very complex CSS, maybe a CSS pre-compiler helps. I'm planning to look into xCSS for the very same reason soon. There are several others around.

  • If working in a team, highlight the necessity of quality and standards for CSS files as well. Everybody's big on coding standards in their programming language(s), but there is little awareness that this is necessary for CSS too.

  • If working in a team, do consider using Version Control. It makes things that much easier to track, and editing conflicts that much easier to solve. It's really worth it, even if you're "just" into HTML and CSS.

  • Do not work with !important. Not only because IE =< 7 can't deal with it. In a complex structure, the use of !important is often tempting to change a behaviour whose source can't be found, but it's poison for long-term maintenance.

Building sensible classes

This is how I like to build sensible classes.

I apply global settings first:

body { font-family: .... font-size ... color ... }
a { text-decoration: none; }

Then, I identify the main sections of the page's layout—e.g. the top area, the menu, the content, and the footer. If I wrote good markup, these areas will be identical to the HTML structure.

Then, I start building CSS classes, specifying as much ancestry as possible as long as it is sensible, and grouping related classes as closely as possible.

div.content ul.table_of_contents 
div.content ul.table_of_contents li
div.content ul.table_of_contents li h1
div.content ul.table_of_contents li h2
div.content ul.table_of_contents li span.pagenumber

Think of the whole CSS structure as a tree with increasingly specific definitions the further away from the root you are. You want to keep the number of classes as low as possible, and you want to repeat yourself as seldom as possible.

For example, let's say you have three levels of navigational menus.
These three menus look different, but they also share certain characteristics. For example, they are all <ul>, they all have the same font size, and the items are all next to each other (as opposed to the default rendering of an ul). Also, none of the menus has any bullet points (list-style-type).

First, define the common characteristics in a class named menu:

div.navi ul.menu { display: ...; list-style-type: none; list-style-image: none; }
div.navi ul.menu li { float: left }

then, define the specific characteristics of each of the three menus. Level 1 is 40 pixels tall; levels 2 and 3, 20 pixels.

Note: you could also use multiple classes for this but Internet Explorer 6 has problems with multiple classes, so this example uses ids.

div.navi ul.menu#level1 { height: 40px; }
div.navi ul.menu#level2 { height: 20px; }
div.navi ul.menu#level3 { height: 16px; }

The markup for the menu will look like this:

<ul id="level1" class="menu"><li> ...... </li></ul>
<ul id="level2" class="menu"><li> ...... </li></ul>
<ul id="level3" class="menu"><li> ...... </li></ul>

If you have semantically similar elements on the page—like these three menus—try to work out the commonalities first and put them into a class; then, work out the specific properties and apply them to classes, or, if you have to support Internet Explorer 6, ID's.

Miscellaneous HTML tips

If you add these semantics to your HTML output, designers can later customize the look of web sites and/or apps using pure CSS, which is a great advantage and time-saver.

  • If possible, give every page's body a unique class: <body class='contactpage'> this makes it very easy to add page-specific tweaks to the style sheet:

    body.contactpage div.container ul.mainmenu li { color: green }
  • When building menus automatically, add as much CSS context as possible to allow extensive styling later. For example:

    <ul class="mainmenu">
    <li class="item_first item_active item_1"> First item </li>
    <li class="item_2"> Second item </li>
    <li class="item_3"> Third item </li>
    <li class="item_last item_4"> Fourth item </li>
    </ul>

    This way, every menu item can be accessed for styling according to its semantic context: Whether it's the first or last item in the list; Whether it's the currently active item; and by number.

Note that this assigning of multiple classes as outlined in the example above does not work properly in IE6. There is a workaround to make IE6 able to deal with multiple classes. If the workaround is not an option, you will have to set the class that is most important to you (item number, active or first/last), or resort to using IDs.

How to Organize CSS with BEM?

Try different approaches, and use whatever works best for you. Don't be afraid to experiment. If you're already comfortable with SASS, and want some inspiration, here's my usual strategy:

/* file: _block-name.scss */

.block { // selector for the block

font-size: 12px; // example property

&__element { // nested selector, equivalent to: 'block__element'

background-color: white; // example property

&--modifier { // nested selector, equivalent to: 'block__element--modifier'

border: 2px solid red; // example property

}

}

}

Every block level element has its own file as an .scss partial. Nested selectors (provided by SASS) are used to target all elements and modifiers of that block.

This approach lends itself well to component-based frameworks like React (where each component is assigned its own BEM block-level selector), but it also works standalone.

If you look up BEM SASS in your search engine of choice you can find lots of other (perfectly valid) approaches to organizing your CSS with BEM. :)

How do you structure css files for a web project?

A css file for each .aspx page seems to defeat its purpose, namely reusability, etc. I suppose if each page is really that unique from a style perspective, maybe it's necessary, but I'd work on getting away from that format.

I usually have a master css file, then perhaps additional ones for other major portions of my site (such as a private administration section, etc.)



Related Topics



Leave a reply



Submit