CSS Coding Guidelines are intended to make it easier to read our work, both for colleagues when we are away, and for ourselves in a year's time. The Guidelines also answer newbie questions and provide best practices, in order to reduce the learning curve.
You are reading the annotated version. It contains explanations. For a rule and example overview, see the summary instead.
Suggestions are welcome.
Know your CSS
CSS basics, from the Web Standards Curriculum.
Avoid depending on CSS for critical functionality
Hackers can easily change or turn off or change your CSS. You should not allow that to lead to a corruption of critical data. If something critical should be invisible, then keep it out of the data you send to the client. When data comes back from the user, or when the user starts up instructions that lead to critical changes, the software developer should always double-check it by a secondary, tamper-resistant method.
Get along with clients on all kinds of devices
Like so:
Get along with CMS implementors
Adding CSS to your web pages
Preferably, you put CSS rules in their own file, using the .css extension: "myStyle.css?versionNumber". Combine various CSS files into a single one and minify the result. You can then add a reference to that file to your web page using the HtmlLinkElement. Put that tag in the page's HtmlHeadElement unless you have compelling reasons not to (and if so, do document those). Like so:
If you find yourself needing to add CSS material into the web page directly, be nice to the HTML parser and let it know that it can skip the contents of your HtmlStyleElement. We do that, compliant to the W3C-recommendation, by enclosing the CSS in a CDATA section. Like so:
Why a CDATA section?
It tells the HTML parser to skip its contents.
Why the multiline instead of single-line comments?
The comments are needed because the CSS parser breaks on the CDATA tags. Single-line comments do not work in CSS. Besides, multiline comments work in Javascript as well, meaning you have to remember fewer guidelines.
On version numbers in file names
For download speed, web masters tend to cache as much as possible, as long as possible. If your file name doesn't change, some systems fail to recognise that the file's content changed. The easiest way to fix that? Add a version number. You can use a native timestamp from your programming language, and for hand-coding you can use a universal date-time format, like so:
Start big, end small
Blatantly copied from WNAS CSS Coding Conventions: start defining the largest elements, and work your way towards more specificity. At the top of your CSS we should find html and body, and as we read our way down, the elements and selectors should become smaller and more specific. This puts your CSS in the same cascade order as the HTML document.
Wrong:
Better:
On tables
Quite a bit of discussion has been going on about the use of tables in HTML, and whether or not tables can (and should) be displayed using CSS alone. Here's our rule of thumb: use tables for tabular data.
It is likely the HTML developer will wind up using non-tabular elements for non-tabular formatting. We prefer the use of semantically relevant elements, like article, aside, header, footer, hgroup, menu, and structurally relevant CSS properties like column-width, but we have to consider that some browser versions may never support those.
Avoid procedural rules where declared rules work
Sometimes we want to use Javascript (libraries) to set CSS or create animations. From experience we fathom that javascripted procedures take more time than native ones. Thus if you can use a CSS rule declaration instead of a scripted procedure, do so. (Do take ease of development into consideration, and talk to the Javascript developers.)
In the same line of thinking: if you must use Javascript to set CSS, do so by adding or removing a CSS class, rather than each property individually (or the whole CSS rule for that element at once). That allows the browser to prepare its rendering, and thus provide a snappier visual response.
Use short-hand notation where possible
Short-hand notation diminishes the chance of scattered rules. Bonus: short-hand is easier to understand, because the brain can take all that information at once. (Note that this guideline doesn't discuss variable and method naming.)
Example of full notation:
Example of short-hand notation:
However, when setting just one property, using short-hand is wrong, because it will overrule the other implied properties.
Remember a background colour
Browsers like Microsoft Internet Explorer do not necessarily take white as the page's background colour. Instead, they take whatever background colour the computer's user has set. That could be black, for people with hindered eye-sight. They could have set a white text colour. Thus, your CSS must always define both a background colour and a foreground colour for texts. The background colour is one of the most-forgotten settings, leading to black text (developer choice) on black backgrounds (visitor choice), making a web site utterly unusable. What a visitor can't see, doesn't exist. Help the visitor: provide a background colour.
Wrong:
Better:
Even better:
Remember contrast
You may think: the visual designer defined the contrast levels, so why should I have to look out for this? Well, that's because the visual designer may have forgotten, or the visual's gamma changed during the transfer from one OS to the next, leading to less contrast than intended. Since you are the one who changes the visual design into reality, it is your job to make sure that your creation can be seen and read. Too low a contrast on texts will lead to visitors leaving. If you spot this flaw, contact the designer and get it corrected.
Colour Contrast Check
Put rule properties together that make sense together
Some guidelines impose an alphabetical sorting order, adding an exception for groups of things that make sense to be grouped (like dimensions). We seek to remove that exception by making it the rule: group stuff together as it makes sense to do so, and be consistent about it. Whether some selectors and properties make sense together, depends on the web page, so it will differ per project.
Wrong:
Better:
On whitespace and block style for selectors and properties
Table-like whitespace and alphabetical arrangements are said to provide a cleaner look. Unfortunately, alphabetical arrangements only make a logical sense, not a semantical one. And CSS properties aren't tabular data: you aren't going to be doing much subtraction and addition, apart from maybe sizes, paddings, and margins. If the data isn't tabular in comprehension, don't make it look tabular either, otherwise you confuse your coworkers.
If you must make your CSS properties easy to compare, you can use whitespace to make your code look like a spreadsheet. Like this:
Provide semantically relevant class names and element IDs
Name classes and elements after what they are used for in the web page. Be as specific as needed. "#box15 .blue2" provides little semantic information (even if the page shows differently-coloured Tupperware...). What proves semantically relevant, depends on the type of page.
Use camel casing for class names and element IDs
Normally we would add a space to signify the start of new words. Since CSS class names and element IDs must not contain spaces, we advise camel-casing: concatenate all the words in a class name and start each word with a capital letter, except for the very first one, which must start with a lower case letter. Avoid underscores, hyphens, and other marks. These are camel-cased, and on some pages also semantically relevant class names:
Why camel casing?
Because we advise the same in our guidelines for Javascript, XSLT, C#, and PHP. Fewer exceptions leads to fewer mistakes.
Use consistent colour value casing
Some guidelines will tell you to use upper case for hexadecimal colour values. Since all browsers we tested don't care, this guideline also doesn't care, as long as you stick with the choice you made.
Prepend your CSS files with a JavaDoc-like comment block
Preferably one that holds useful information, e.g.:
The information you include should be relevant and helpful for your coworkers. It should identify how and where this file is used, and who to contact in case of questions. We can imagine that some stylesheets are used across multiple templates in a site, whereas others apply to only a single page, regardless of template.
Use a CSS validator
It will find grammatical and some usability errors. It will not find functional errors. Use common sense and browser-comparison services for functional testing.
CSS basics, from the Web Standards Curriculum.
Avoid depending on CSS for critical functionality
Hackers can easily change or turn off or change your CSS. You should not allow that to lead to a corruption of critical data. If something critical should be invisible, then keep it out of the data you send to the client. When data comes back from the user, or when the user starts up instructions that lead to critical changes, the software developer should always double-check it by a secondary, tamper-resistant method.
Get along with clients on all kinds of devices
- Measure in em fractions or percentages where possible. This will ensure cross-resolution compatibility.
- Otherwise, measure in point units rather than pixel units. The amount of pixels per inch (resolution) changes constantly, from one device to the next. The amount of points per inch is fixed, regardless of resolution.
- Measure your font sizes either completely relatively (in % or em), or completely absolutely in points. Combinations will lead to unexpected results. Since some visual elements may require specific heights and widths and need to fit words as well, we suggest to define all measurements in points. (Apply CSS3 and vendor-specific techniques to reduce the dependency on images for these elements.)
- Limit the width of the main content based on readability and usability. A paragraph of text stretched out over the full width of a 26" screen (yes, it does happen), tends to scare readers away. (Let this coincide with providing a view-port meta setting in HTML, to allow scaling and zooming devices like iPads to quickly determine the optimal viewing size.)
- Avoid browser hacks inside the CSS. If necessary, use vendor-specific prefixes, and put them in their own highly visible place, and document them well. If possible, use Html or CSS Conditional Comments, or even Javascripted feature detection.
- If you provide vendor-specific rules, do so for all vendors, instead of just 1 or 2, and provide the general rule as well, as the last of the set. Currently known vendor prefixes: -moz, -ms, -o, -webkit. Yes, that's 4. Keep them in alphabetical order for easier maintenance and testing. Always end the series with the generic rule.
- Keep in mind that hand-held devices tend to sport zooming browsers: images optimized for internet usually scale badly; instead use CSS3 and vendor-specific techniques where possible.
- Always provide CSS rules for printing. Get your client to determine which elements need to show up in print.
Like so:
/* Samples taken from Zjramble5, used with permission */
body {
max-width: 600pt;
margin-left: auto;
margin-right: auto;
}
button {
font-size: 14pt;
height: 28pt;
font-weight: bold;
margin: 0;
padding: 0pt 4pt;
width: auto;
min-width: 49pt;
text-align: center;
cursor: pointer;
-webkit-tap-highlight-color: rgba(4,96,179,0.3);
-webkit-appearance: none;
color: #fff;
background-color: #000;
background-image: url(myBadlyShapedLowResButtonImage.png);
background-image: -ms-linear-gradient( rgb(255,255,255),
rgba(255,255,255,0));
background-image: -moz-linear-gradient( rgb(255,255,255),
rgba(255,255,255,0));
background-image: -o-linear-gradient( rgb(255,255,255),
rgba(255,255,255,0));
background-image: -webkit-gradient(linear, 0% 0%, 0% 100%,
from(rgb(255,255,255)),
to(rgba(255,255,255,0)));
background-image: linear-gradient( rgb(255,255,255),
rgba(255,255,255,0));
-moz-text-shadow: 0pt -1pt 1pt #111;
-ms-text-shadow: 0pt -1pt 1pt #111;
-o-text-shadow: 0pt -1pt 1pt #111;
-webkit-text-shadow: 0pt -1pt 1pt #111;
text-shadow: 0pt -1pt 1pt #111;
}
Get along with CMS implementors
- CMS implementors have to deal with the limits of their CMS. Some CMS'es do not allow us to set IDs on individual HtmlElements, simultaneously allowing us to set CSS classes instead. This comes into factor in elements like page headers and menus: those menus can generally be changed by the editors. What may seem like a fixed listing of pages turns out to require complete dynamics: pages change their titles, positions, contents, visibility... all that needs to be catered into your CSS.
- CMS editors can change page titles and descriptions. What may seem like fixed widths and heights due to Visual Designs, may require dynamic width and height flexibility.
- Most CMS-es can resize images to fit the Visual Design, either automatically or manually, but take into consideration that those resizers tend to measure in pixels.
- Most CMS-es will specify whether some elements are to be shown or hidden, based on search criteria, personalisation, or publication dates. Take that into consideration when designing element and word flow.
- Some CMS-es allow editors to specify whether some elements are to be shown or hidden. Programmatically, those differences may be rendered using the same HTML template. Take that into consideration when designing element and word flow.
- On indentation. Most CSS generators group rules about the same element. Do repeat that. Some CSS generators like to indent follow-up rules concerning child elements or pseudo selectors. Avoid that. Those indentations may confuse your colleagues when they need to study and sometimes amend your work via a CMS. CMS-es tend to be built with ease of article editing in mind, not CSS-editing.
- Maximize cascades, reduce overrides. Changing site-wide settings should be easy (maximize cascades), and changing individual specifics should also be easy (reduce overrides). Think about the cascading order: don't let the style of 1 irrelevant element on 1 page define the style for the whole site.
- CMS-es tend to sport their own Wysiwyg editor, that sometimes allows users to add their own class names for elements. Together with the CMS implementor and the HTML developer, define a space for these user-added elements inside the page html, and prevent cross-contamination of style rules by using selectors that are as specific as possible.
- Provide a CSS for the CMS' Wysiwig editor, that reflects the visual display of the web page.
- If possible, concatenate multiple files into 1, in cascade order. This reduces the amount of work for the CMS implementor and the maintenance crew. Avoid @import: actually copy and paste instead, to decrease the number of roundtrips from browser to server, and thus increase speed.
Adding CSS to your web pages
Preferably, you put CSS rules in their own file, using the .css extension: "myStyle.css?versionNumber". Combine various CSS files into a single one and minify the result. You can then add a reference to that file to your web page using the HtmlLinkElement. Put that tag in the page's HtmlHeadElement unless you have compelling reasons not to (and if so, do document those). Like so:
<link rel="stylesheet" title="myStyle" media="all" type="text/css" href="myStyle.css?20111020T1616" />
If you find yourself needing to add CSS material into the web page directly, be nice to the HTML parser and let it know that it can skip the contents of your HtmlStyleElement. We do that, compliant to the W3C-recommendation, by enclosing the CSS in a CDATA section. Like so:
<style type="text/css" id="myStyle">/* <![CDATA[ */
body{
background-color: #fff;
color: #000;
}
/* ]]> */</style>
Why a CDATA section?
It tells the HTML parser to skip its contents.
Why the multiline instead of single-line comments?
The comments are needed because the CSS parser breaks on the CDATA tags. Single-line comments do not work in CSS. Besides, multiline comments work in Javascript as well, meaning you have to remember fewer guidelines.
On version numbers in file names
For download speed, web masters tend to cache as much as possible, as long as possible. If your file name doesn't change, some systems fail to recognise that the file's content changed. The easiest way to fix that? Add a version number. You can use a native timestamp from your programming language, and for hand-coding you can use a universal date-time format, like so:
my-style.css?20111017T1530
Start big, end small
Blatantly copied from WNAS CSS Coding Conventions: start defining the largest elements, and work your way towards more specificity. At the top of your CSS we should find html and body, and as we read our way down, the elements and selectors should become smaller and more specific. This puts your CSS in the same cascade order as the HTML document.
Wrong:
a{}
li{}
ul{}
p{}
body{}
html{}
Better:
html{}
body{}
div{}
p{}
ul{}
li{}
a{}
On tables
Quite a bit of discussion has been going on about the use of tables in HTML, and whether or not tables can (and should) be displayed using CSS alone. Here's our rule of thumb: use tables for tabular data.
It is likely the HTML developer will wind up using non-tabular elements for non-tabular formatting. We prefer the use of semantically relevant elements, like article, aside, header, footer, hgroup, menu, and structurally relevant CSS properties like column-width, but we have to consider that some browser versions may never support those.
Avoid procedural rules where declared rules work
Sometimes we want to use Javascript (libraries) to set CSS or create animations. From experience we fathom that javascripted procedures take more time than native ones. Thus if you can use a CSS rule declaration instead of a scripted procedure, do so. (Do take ease of development into consideration, and talk to the Javascript developers.)
In the same line of thinking: if you must use Javascript to set CSS, do so by adding or removing a CSS class, rather than each property individually (or the whole CSS rule for that element at once). That allows the browser to prepare its rendering, and thus provide a snappier visual response.
Use short-hand notation where possible
Short-hand notation diminishes the chance of scattered rules. Bonus: short-hand is easier to understand, because the brain can take all that information at once. (Note that this guideline doesn't discuss variable and method naming.)
Example of full notation:
.myBlock { background-color: transparent; background-image: url(myImage.png); background-attachment: scroll; background-repeat: no-repeat; background-position: center center; }
Example of short-hand notation:
.myBlock { background: transparent url(myImage.png) scroll no-repeat center center; }
However, when setting just one property, using short-hand is wrong, because it will overrule the other implied properties.
Remember a background colour
Browsers like Microsoft Internet Explorer do not necessarily take white as the page's background colour. Instead, they take whatever background colour the computer's user has set. That could be black, for people with hindered eye-sight. They could have set a white text colour. Thus, your CSS must always define both a background colour and a foreground colour for texts. The background colour is one of the most-forgotten settings, leading to black text (developer choice) on black backgrounds (visitor choice), making a web site utterly unusable. What a visitor can't see, doesn't exist. Help the visitor: provide a background colour.
Wrong:
body{
font-size: medium;
padding: 8pt;
}
p{
padding: 8pt;
margin: 8pt 0pt 16pt;
color: #000;
}
a{ color: blue; }
Better:
body{
font-size: medium;
padding: 8pt;
background-color: white;
}
p{
padding: 8pt;
margin: 8pt 0pt 16pt;
color: #000;
}
a{
color: blue;
background-color: white;
}
Even better:
body{
font-size: medium;
padding: 8pt;
color: #000;
background-color: white;
}
p{
padding: 8pt;
margin: 8pt 0pt 16pt;
}
a{
color: blue;
background-color: white;
}
Remember contrast
You may think: the visual designer defined the contrast levels, so why should I have to look out for this? Well, that's because the visual designer may have forgotten, or the visual's gamma changed during the transfer from one OS to the next, leading to less contrast than intended. Since you are the one who changes the visual design into reality, it is your job to make sure that your creation can be seen and read. Too low a contrast on texts will lead to visitors leaving. If you spot this flaw, contact the designer and get it corrected.
Colour Contrast Check
Put rule properties together that make sense together
Some guidelines impose an alphabetical sorting order, adding an exception for groups of things that make sense to be grouped (like dimensions). We seek to remove that exception by making it the rule: group stuff together as it makes sense to do so, and be consistent about it. Whether some selectors and properties make sense together, depends on the web page, so it will differ per project.
Wrong:
p.error{
color: #111;
border: none;
text-decoration: underline;
padding: 8pt;
background-color: #ecc;
font-style: italic;
}
Better:
p.error{
color: #111;
background-color: #ecc;
font-style: italic;
text-decoration: underline;
padding: 8pt;
border: none;
}
On whitespace and block style for selectors and properties
- Do not use spaces inside class names or element IDs, for those spaces already act as selector separators (but you knew that already).
- Group rules about the same selector together, dividing it from the rest with blank lines.
- Put each selector in a groups of selectors on its own line.
- Put each property on its own line, unless you require the spatial benefits of comparison.
- Provide spaces after operators and before opening braces, except when the operator is part of a pseudo-selector.
/* no comparison needed */
fieldset {
background-color: #ddd;
color: #000;
border: 1pt solid black;
border-radius: 5pt;
margin: 8pt;
padding: 8pt;
}
Table-like whitespace and alphabetical arrangements are said to provide a cleaner look. Unfortunately, alphabetical arrangements only make a logical sense, not a semantical one. And CSS properties aren't tabular data: you aren't going to be doing much subtraction and addition, apart from maybe sizes, paddings, and margins. If the data isn't tabular in comprehension, don't make it look tabular either, otherwise you confuse your coworkers.
If you must make your CSS properties easy to compare, you can use whitespace to make your code look like a spreadsheet. Like this:
/* comparison needed */
fieldset#gameStart { background-color: #ffc; }
fieldset#gameActive { background-color: #9d9; }
fieldset#gameOver { background-color: #600; color: #fff; }
Provide semantically relevant class names and element IDs
Name classes and elements after what they are used for in the web page. Be as specific as needed. "#box15 .blue2" provides little semantic information (even if the page shows differently-coloured Tupperware...). What proves semantically relevant, depends on the type of page.
Use camel casing for class names and element IDs
Normally we would add a space to signify the start of new words. Since CSS class names and element IDs must not contain spaces, we advise camel-casing: concatenate all the words in a class name and start each word with a capital letter, except for the very first one, which must start with a lower case letter. Avoid underscores, hyphens, and other marks. These are camel-cased, and on some pages also semantically relevant class names:
leftSidebarBlock
footerServiceLink
newsArticleButton
Why camel casing?
Because we advise the same in our guidelines for Javascript, XSLT, C#, and PHP. Fewer exceptions leads to fewer mistakes.
Use consistent colour value casing
Some guidelines will tell you to use upper case for hexadecimal colour values. Since all browsers we tested don't care, this guideline also doesn't care, as long as you stick with the choice you made.
Prepend your CSS files with a JavaDoc-like comment block
Preferably one that holds useful information, e.g.:
/**
* myStyle.css
* @use For template: thisPageType
* @author Our company <us@here.now>
*/
The information you include should be relevant and helpful for your coworkers. It should identify how and where this file is used, and who to contact in case of questions. We can imagine that some stylesheets are used across multiple templates in a site, whereas others apply to only a single page, regardless of template.
Use a CSS validator
It will find grammatical and some usability errors. It will not find functional errors. Use common sense and browser-comparison services for functional testing.
Need problem solving?
Talk to me. Let's meet for coffee or over lunch. Mail me at “omegajunior at protonmail dot com”.