Don't write headings in CSS
Just split sections into files. Any CSS comments, should be just that, comments.
reset.css
base.css
somepage.css
someotherpage.css
some_abstract_component.css
Use a script to combine them into one; if necessary. You can even have a nice directory structure as well, and just have your script recursively scan for .css
files.
If you must write headings, have a TOC at the start of the file
The headings in the TOC should be perfectly equal to headings you write later. It's a pain to search for headings. To add to the problem, how exactly is anyone suppose to know you have another header after your first header? ps. don't add doc-like * (star) at the start of each line when writing TOCs, it just makes it more annoying to select the text.
/* Table of Contents
- - - - - - - - -
Header stuff
Body Stuff
Some other junk
- - - - - - - - -
*/
...
/* Header Stuff
*/
...
/* Body Stuff
*/
Write comments with or within the rules, not outside the block
First off, when you edit the script there is a 50/50 chance you'll pay attention to what is outside the rule block (particularly if it's a big glob of text ;) ). Secondly there is (almost) no case where you would need a "comment" outside. If it is outside, it is 99% of the time a title, so keep it like that.
Split the page into components
Components should have position:relative
, no padding
and no margin
, most of the time. This simplifies % rules a lot, as well as allowing for much simpler absolute:position
'ing of elements, since if there's a absolute positioned container the absolute positioned element will use the container when computing top
, right
, bottom
, left
properties.
Most DIVs in a HTML5 document are usually a component.
A component is also something that can be considered a independent unit on the page. In laymen's terms treat something like a component if it makes sense to treat something like a blackbox.
Going with the QA page example again:
#navigation
#question
#answers
#answers .answer
etc.
By splitting the page into components, you split your work into manageable units.
Put rules with a cumulative effect on the same line.
For example border
, margin
and padding
(but not outline
) all add to the dimensions and size of the element you are styling.
position: absolute; top: 10px; right: 10px;
If they are just not that readable on one line, at least put them in close proximity:
padding: 10px; margin: 20px;
border: 1px solid black;
Use shorthand when possible:
/* the following... */
padding-left: 10px;
padding-right: 10px;
/* can simply be written as */
padding: 0 10px;
Never repeat a selector
If you have more instances of the same selector, there's a good chance you'll inevitable end up with multiple instances of the same rules. For example:
#some .selector {
margin: 0;
font-size: 11px;
}
...
#some .selector {
border: 1px solid #000;
margin: 0;
}
Avoid using TAGs as selectors, when you can use id/classes
First off the DIV and SPAN tags are the exception: you should never use them, ever! ;) Only use them to attach a class/id.
This...
div#answers div.answer table.statistics {
border-collapse: collapsed;
color: pink;
border: 1px solid #000;
}
div#answers div.answer table.statistics thead {
outline: 3px solid #000;
}
Should be written like this:
#answers .answer .statistics {
border-collapse: collapsed;
color: pink;
border: 1px solid #000;
}
#answers .answer .statistics thead {
outline: 3px solid #000;
}
Because the extra dangling DIVs there add nothing to the selector. They also force a unnecessary tag-rule. If you were to change, for example, .answer
from a div
to a article
your style would break.
Or if you prefer more clarity:
#answers .answer .statistics {
color: pink;
border: 1px solid #000;
}
#answers .answer table.statistics {
border-collapse: collapsed;
}
#answers .answer .statistics thead {
outline: 3px solid #000;
}
The reason being the border-collapse
property is a special property that only makes sense when applied to a table
. If .statistics
is not a table
it should not apply.
Generic rules are evil!
- avoid writing generic/magic rules if you can
- unless it's for a CSS-reset/unreset, all your generic magic should apply to at least one root component
They don't save you time, they make your head explode; as well as make maintenance a nightmare. When you're writing the rule, you may know where they apply, however that has no guarantee your rule won't mess with you later on.
To add to this generic rules are confusing and hard to read, even if you have some idea of the document you're styling. This is not to say you shouldn't write generic rules, just don't use them unless you truly intend for them to be generic, and even them add as much scope information into the selector as you can.
Stuff like this...
.badges {
width: 100%;
white-space: nowrap;
}
address {
padding: 5px 10px;
border: 1px solid #ccc;
}
...has the same problem as using global variables in a programing language. You need to give them scope!
#question .userinfo .badges {
width: 100%;
white-space: nowrap;
}
#answers .answer .userinfo address {
padding: 5px 10px;
border: 1px solid #ccc;
}
Basically that reads as:
components target
---------------------------- --------
#answers .answer .userinfo address
-------- --------- --------- --------
domain component component selector
I like using IDs whenever a component I know is a singleton on a page; your needs may be different.
Note: Ideally, you should write just enough. Mentioning more components in the selector however is the more forgiving mistake, compared to mentioning less components.
Lets assume you have a pagination
component. You use it in many places across your site. This would be a good example of when you would be writing a generic rule. Lets say you display:block
the individual page number links and give them a dark gray background. For them to be visible you have to have rules like this:
.pagination .pagelist a {
color: #fff;
}
Now lets say you use your pagination for a list of answers, you may encounter something like this
#answers .header a {
color: #000;
}
...
.pagination .pagelist a {
color: #fff;
}
This will make your white links black, which you don't want.
The incorrect way to fix it is:
.pagination .pagelist a {
color: #fff !important;
}
The correct way to fix it is:
#answers .header .pagination .pagelist a {
color: #fff;
}
Complex "logic" comments don't work :)
If you write something like: "this value is dependent on blah-blah combined with height of blah-blah", it's just inevitable you'll make a mistake and it will all fall down like a house of cards.
Keep your comments simple; if you need "logical operations" consider one of those CSS templating languages like SASS or LESS.
How do you do I write a color pallet?
Leave this for the end. Have a file for your entire color pallet. With out this file your style should still have some usable color-pallet in the rules. Your color pallet should overwrite. You chain selectors using a very high level parent component (eg. #page
) and then write your style as a self sufficient rule block. It can be just color or something more.
eg.
#page #header .description,
#page #categories .description,
#page #answers .answer .body
{
color: #222; background: #fff;
border-radius: 10px;
padding: 1em;
}
The idea is simple, your color pallet is a stylesheet independent of the base style, which you cascade into.
Less names, requires less memory, making the code easier to read
Using fewer names is better. Ideally use very simple (and short!) words: text, body, header.
I also find combination of simple words is easier to understand then having a soup of long "appropriate" words: postbody, posthead, userinfo, etc.
Keep the vocabulary small, this way even if some stranger coming in to read your style-soup (like yourself after a few weeks ;)) only needs to understand where words are used rather where every selector is used. For example I use .this
whenever a element is supposedly "the selected item" or "the current item", etc.
Clean up after yourself
Writing CSS is like eating, sometimes you leave a mess behind. Make sure you clean up that mess, or the garbage code will just pile up. Remove classes/ids you don't use. Remove CSS rules you don't use. Make sure everything is nice a tight and you don't have conflicting or duplicated rules.
If you, as I suggested, treated some containers as black-boxes (components) in your style, used those components in your selectors, and kept everything in one dedicated file (or properly split a file with a TOC and headers), then your work is substantially easier...
You can use a tool such as the firefox extension Dust-Me Selectors (tip: point it to your sitemap.xml) to help you find some of the junk hidden in your css nukes and carnies.
Keep a unsorted.css
file
Say you are styling a QA site, and you already have a stylesheet for the "answers page", which we will call answers.css
. If you now need to add a lot of new css, add it to the unsorted.css
stylesheet then refactor into your answers.css
stylesheet.
Several reasons for this:
- it's faster to refactor in after you're finished, then it is to search for rules (that probably don't exist) and inject code
- you will write stuff that you will remove, injecting code just makes it harder to remove that code
- appending to the original file easily leads to rule/selector duplication
simplicity
,complexity
,maintenance
,structure
andrefactoring
. – cherouvim