A while ago I came across Harry Roberts‘s article about his HTML/CSS coding style, which just happened to be around the time I was researching style guides for work. I decided for the time being a written style guide was overkill for our team, but I definitely have my own personal style that’s developed over the years.
My three-part tweet could pretty well sum up how this is going to go.
Google’s HTML/CSS style guide (http://google-styleguide.googlecode.com/svn/trunk/htmlcssguide.xml) is solid and pretty consistent with my personal style. – 1
Although I’m not a fan of omitting optional tags, while hypocritically omitting other optional items (attributes, self-closing, etc.) – 2
And more closely using BEM might violate shortest class/ID naming scheme. Although their application-specific prefix follows the same idea. – 3
Jon Faustman, Twitter 2 3
Tabs or spaces?
The correct answer is soft tabs. Four spaces to a tab, to be exact.
I have invisibles turned on, and I hate seeing that damn tab. Two spaces is just too small for my liking, it’s less discernible.
Of course this (and the majority of this article) comes down to personal preference. Just don’t mix and match. If you’re collaborating and somebody is already using one style, stick to it…unless you’re willing to convert the entire project.
HTML
I’m a big fan of whitespace in code, it’s much more readable. To achieve that, I indent child elements and tend to have a line break (or rather two) after inherently block elements. Although I’m picky about this.
I don’t use a new line on the first child of an element; in that case I’ll put the opening tag directly under its parent. In the same vein, I stack closing tags together. That makes it easier for me to distinguish hierarchy. Here’s an example from this site:
<a href="<?php the_permalink(); ?>" class="article">
<article <?php post_class(); ?> id="post-<?php the_ID(); ?>">
<h1 class="article__title"><?php the_title(); ?></h1>
<time class="article__date" pubdate datetime="<?php the_time('Y-m-d H:i'); ?>"><?php the_time('M') ?><i class="article__date--day"><?php the_time('j') ?></i><i class="article__date--year"><?php the_time('Y'); ?></i></time>
<div class="article__content lead">
<?php the_excerpt(); ?>
</div><!-- /article__content -->
</article>
</a>
If I wasn’t selectively adding new lines on inherent block elements, the code would look like this:
<a href="<?php the_permalink(); ?>" class="article">
<article <?php post_class(); ?> id="post-<?php the_ID(); ?>">
<h1 class="article__title"><?php the_title(); ?></h1>
<time class="article__date" pubdate datetime="<?php the_time('Y-m-d H:i'); ?>"><?php the_time('M') ?><i class="article__date--day"><?php the_time('j') ?></i><i class="article__date--year"><?php the_time('Y'); ?></i></time>
<div class="article__content lead">
<?php the_excerpt(); ?>
</div><!-- /article__content -->
</article>
</a>
It’s still perfectly readable (maybe even moreso) but the first example is easier for me to visually parse hierarchy.
Speaking of visually parsing, perhaps you noticed <!-- /article__content -->
. I use a HTML comment to denote the closing tag on divs and spans (although it might be time to include HTML5 elements as well). It’s something I picked up (from Dan Cederholm, I believe) a long time ago and it’s stuck with me.
Sure, most text editors can fold blocks, but what about when you’re viewing live source code? That’s also why I use a HTML comment as opposed to a server side comment. I find them super helpful for collaboration or debugging.
One thing I miss about XHTML is its structure. It had a very defined structure: lowercase everything, close all elements (in the order they were opened), quote all attribute values, do not minimize attributes; if you don’t follow the structure do not pass go, do not collect $200.
Of course in HTML5 you can use XHTML’s structure, but it’s not forced upon you…and since it’s not, I don’t. I do; however, lowercase everything, quote all attribute values and close all elements except for self-closing tags.
Not quoting attributes seems like a recipe for disaster, especially in collaboration. Say somebody adds another class name in an unquoted class attribute – boom, problems. I do have a debate with a co-worker whether to use single or double quotes, I prefer double but again that’s just preference.
There is a whole host of optional tags that can be omitted, and a whole host of rules when it’s allowed. For simplicity and readability I do not omit tags.
<ol>
<li>One</li>
<li>Two</li>
<li>Three</li>
</ol>
Is more preferable to me than:
<ol>
<li>One
<li>Two
<li>Three
</ol>
There are some things I do omit. I already mentioned that I omit self-closing tags, e.g. <img src="" />
. I also omit type attributes for styles sheets and scripts, as well as attribute boolean values (minimizing) – selected="selected"
always just seemed silly to me.
CSS
/* Links */
a {
color: #00f;
font-weight: bold;
}
a:visited {
color: #800080;
}
a:active,
a:focus,
a:hover {
background-color: #fff;
color: #f00;
-moz-text-shadow: 1px 0 1px rgba(0,0,0,.5);
-webkit-text-shadow: 1px 0 1px rgba(0,0,0,.5);
text-shadow: 1px 0 1px rgba(0,0,0,.5);
}
This fake code snippet should pretty accurately reflect my CSS style. I used to prefer one-line CSS, but that eventually faded in favor of more readability.
I alphabetize declarations (and vendor prefixes by its standard property), using a single space after the property, always include a semi-colon directly after the value, and use the same indentation (four space soft tabs for each level) that I do for HTML.
I include a space after a selector and before the declaration block. Each selector and declaration go on their own lines.
I group related rules together in sections, denoted with a comment. I leave a blank line between each ruleset, but separate sections by two blank lines.
I omit units for 0 values.
I use the most appropriate color format for the job (preferring hex shorthand), although I’m not a huge fan of color keywords. Although I prefer hex color shorthand, I only use shorthand when it’s appropriate; otherwise you may add additional properties to override later.
Naming
I am a huge fan of BEM. It’s certainly changed my opinion towards using classes and OOCSS. I won’t get too much into BEM right now, but the naming scheme goes like .block__element--modifier
. This can produce longer selector names than you might normally use, but it’s definitely worth the tradeoff.
I also like to prepend classes with the project or app name. For a project foo, a class name could end up being .foo-block__element--modifier
. Long, but worth it. The project name will stop it from conflicting with other stylesheets, while BEM will quickly identify how it’s used inside the project.
If I’m not using BEM, then I like to keep my class names short but descriptive. Class names don’t have to be semantic, but they should be useful.
One thing you won’t see me do is over qualify a selector. That’s one thing that bothers me. Why would you purposefully write ul.foo
instead of just .foo
? It’s more fragile and has more specificity. Of course you might need to do that to override specificity, but it shouldn’t be the norm.
Sass
// Links
a
color: #00f
font-weight: bold
&:visited
color: #800080
&:active,
&:focus,
&:hover
+text-shadow(1px 0 1px rgba(0,0,0,.5)
background-color: #fff
color: #f00
For the most part, I write my Sass similar to my CSS. Other than the format itself, the big difference is in the declaration order. Since @include
and @extend
may contain several different properties, I like to put them first. This is also helpful if I need to override a property from a mixin.
You might also notice the lack of line breaks between selectors, but that’s because I like to use nesting to reference the parent selector. Unrelated selectors are treated the same as I would treat them in CSS.
Since I do use Sass’s indented syntax, I used to go nesting crazy. I’ve since got that under control and prefer not to nest more than two layers deep. Any more than that and it’s a good candidate to be rewritten.
Sass’s CSS output used to be less than optimal to me, as it did’t produce my preferred format exactly, but in the end it doesn’t matter. Most likely the code will be minified for production anyway (which Sass’s output style can easily do for you).
Be pragmatic not dogmatic
Whether it’s a branding style guide or a coding style guide (and perhaps moreso the coding style guide) it’s much better to be pragmatic than dogmatic. Having defined rules will only get you so far, eventually you have to ship code.
If you have disagreements or optimizations on an established style guide, talk it out – there should always be room for change.
Much like Sass’s output, Django’s HTML output used to drive me crazy, but it’s just not worth worrying about. You control what you can, and you let other things slide. You’ll be hard pressed to find frameworks that comply with your style guide, but in the end harnessing their power is completely worth it.
I love seeing company’s style guides and comparing my personal style against them. I’m planning on making a small style guide for this site as well.
(Edit 2013-07-31): I’ve added a style guide for the site.