12:53
0

A lot of times I see CSS that has been written by other people, usually people who are just starting out, and it’s terrible. That’s not to say it’s invalid, although that sometimes is the case, what I mean is that the way it’s composed makes it very difficult to read and/or understand.
This article is aimed at helping people improve the code they write, whether they're beginners who haven’t had the chance to learn these lessons themselves yet, or elite 12th dan webdev masters who may have missed a trick or two. Of course, that’s not to say I’m such a master, far from it, but I do have knowledge that can help others, and I hope to share it with you now!
How to Format CSS

It was a while before I discovered that spreading the code out wouldn’t be the end of the world. Now I write code more like this:
selector{
  property:value;
  another-property:another-value;
}
There are, of course, many more ways to write the code, some of which include indenting the property with a tab instead of two spaces, separating the colon and value with a space, and putting a space or new line between the selector and opening brace. All of these are perfectly valid ways of writing code to increase readability, so if your code is difficult to read, try spreading it out and see if it makes a difference. Don't just do it for yourself, but for other people who may try to read your code as well.
That’s a big key point actually, and it applies to all languages. Don’t be afraid to use CSS comments to clarify the code where necessary. It should be possible to come back to code written months ago and just pick up where you left off, but more important than that, it should be written so that people who have never seen it before can pick it up and modify it without investing too much time figuring out how it works first.
One final point under this heading...as a method of good practice, I recommend always always always including the semi-colon after a rule. In CSS the semi-colon is a delimiter so that you can write more than one rule on a line, but in the example, I gave each rule its own line while still including the semi-colon. The reason for that is because sometimes if I ever need to test out a rule quickly, it’s easy to just tack it on the end of a line after another rule. Another reason is that sometimes I may want to use inline styles on elements using the style attribute. Since I'm used to writing the semi-colon after every rule, I include it automatically.

How to Pick ID’s & Classes

When it comes to ID’s and classes for elements, pick something very short, but at the same time, make it descriptive. Too long and the CSS becomes difficult to read, too short and the CSS becomes cryptic. Try to pick just one word, or at the most two words, to describe what that particular element is for.
As far as case goes, I prefer to keep mine all lower case with only alphabetical characters and the hyphen. Having one naming convention and sticking to it prevents any confusion relating to referencing elements later down the line, much like choosing between the .htm and .html file extension for stand-alone pages.

How to Write CSS Selectors

This really depends on the markup--I would suggest splitting the page up into several sections and sub-sections and assigning ID's to them. For example, on this page, these are the sections I would use:
  1. #htmlgoodies-com - On the body element for user style sheets.
    1. #header
      1. #logo
      2. #search
    2. #content
      1. #breadcrumbs
      2. #content-ads
    3. #sidebar
      1. #navigation
      2. #sidebar-ads
    4. #earthweblinks
    5. #footer
This is a common technique because it allows for quick and easy referencing of each of the sections with CSS. When the CSS for these sections is written, it is best to always use the complete selector for the section being referenced (except for the body ID), for example:
#sidebar #navigation ul li a{
  property:value;
}
As opposed to this:
#navigation a{
  property:value;
}
Both methods may have the same effect when the code is written, however, at a later date the markup could change. Say for example that another <a> element is added to the #navigation section, outside of the list and needs different rules applied to it, the old code would need to be modified, or perhaps all of the rules would have to be overridden with new rules.
By using the complete selector, it's all but guaranteed that the rules will not have any unforeseen effect on some other code elsewhere, or on code that is written at a later date. Apart from that, it increases readability and understanding of the code enormously, merely by looking at the selector it is possible to see what specific piece of markup a selector is referencing.
Keep the rules for each of the sections together, perhaps even writing a little comment at the beginning of the group to make it easy to spot when scrolling through code. Also, keep the selectors in the same order as the markup they reference, in other words, for this markup:
<div id="example">
  <h2>Heading</h2>
  <p>Lorem.</p>
  <ul>
    <li>...</li>
  </ul>
  <p>Ipsum.</p>
</div>
The CSS selectors would be in this order:
  1. #example
  2. #example h2
  3. #example p
  4. #example ul
  5. #example ul li

Separating Design from Layout

CSS makes it possible to separate presentation from markup, and that’s a very good thing. Unfortunately though, design and layout are still mixed in with each other. When writing the CSS, create the layout first, get all the boxes to line up where you need them to line up, then start a new CSS file or put some line breaks and a comment in, and begin the code for the design.
If there's a layout bug that needs fixing, I know I don’t want to be picking through design rules to find the layout rules, and vice-versa. It’s much more efficient to have only the relevant code on-screen, rather than having to sift through to find it.

Pseudo Classes for Links

Everyone loves :hover on links, it’s an easy way of highlighting the current link that a users mouse is over, it makes the page seem a lot more dynamic and lively. However, a lot of people tend to forget about the other pseudo classes and just use a and a:hover. A handy tip to remember the others with is LoVe/HAte; L for :link, V for :visited, H for :hover and A for :active. Not only does it list other pseudo classes, it shows the order in which they should be specified to avoid counter-intuitive effects.
Unfortunately that doesn’t include F for :focus, which is equally as important as :hover, therefore I would be more than happy to see the LoVe/HAte mnemonic die a death tomorrow. When using :hover, please don’t forget about :focus. Not all users use the mouse to activate links, some users tab through links on the keyboard, :focus is integral to demonstrating which link will be activated upon pressing enter.
Generally when I’m writing out code for links, I write the selectors like so:
#somewhere a,
#somewhere a:link,
#somewhere a:visited{
  property:value;
}
 
#somewhere a:focus,
#somewhere a:hover,
#somewhere a:active{
  property:another-value;
}
When writing them out like that, it’s really not necessary to include the :link and :visited pseudo classes, however I do it anyway because it helps me remember them. The selector #somewhere awill apply to all links in #somewhere, no matter what their state, then for the :focus, :hover and :active states, the second rule kicks in and over-rides the first to indicate which link the user has activated or could activate.

Forget About Old Browsers

At least as far as CSS is concerned, that is. Don’t try and write CSS that caters to Netscape 4 and IE 4--there’s really no point. The user base for those browsers is increasingly smaller and smaller and they probably don’t support enough CSS for most modern layout methods.
So how is it possible to prevent these old browsers from seeing the CSS? Well, there’s a very handy way of calling a style sheet that was introduced with CSS version 2. Netscape 4 doesn't support it and IE 4 doesn’t support it properly, that means it can be exploited to block those browsers. It’s called importing and it works like so:
<style type="text/css">
  @import '/path/to/stylesheet.css';
</style>
It’s as simple as that really, but do note the use of SINGLEquotes and NO brackets around the location of the style sheet. Take a look at this list of CSS filters, using the @import method with single quotes will prevent Netscape 4, IE 4 and also IE 4 and 5 for Mac from receiving and applying the styles.
IE on Mac is notoriously buggy, and I would judge it to be more trouble than it’s worth, after all, IE for Windows is bad enough. The users of IE on Mac are also vanishingly small since it is so old, and to be honest it’s hard to see why anyone would want to use a Mac but then use a Microsoft browser.
We aren’t shutting anyone out though--the users of those browsers will still get the markup which will be displayed with the default browser styles. If the markup has been written correctly then the page should display itself just fine. Of course it won’t have a design, but there has to be a trade-off. Is it really worth spending a lot of extra effort to get old browsers dancing to a new tune, just so a few more users can see the design? In my opinion, no.

Correcting for IE

Always write the code for standards compliant browsers first, then correct it for IE at the end, never the other way around. By composing for standards compliant browsers first, forward compatibility is almost a given.
Don’t correct for IE in the same style sheet used for other browsers though, give IE it’s own style sheet. Here’s how to do that:
<!--[if IE]>
  <style type="text/css">
    @import 'iestyle.css';
  </style>
<![endif]-->
The code used there is called a conditional comment and it’s IE specific. To other browsers it’s just like any other comment and will be ignored, but to IE it’s like an if statement. If the condition specified is met, it will apply the code contained in the comment, if it is not, then it won’t. This particular comment is quite simple, it basically says, "If the browser is IE, apply this code." Since it is only IE that understands these conditional comments, the browser will always be IE and will therefore apply the code.
I don’t want to go into too much detail about these comments, (there’s more here if you’re interested), but conditional comments can also be used to single out particular versions of IE if required.
In the IE style sheet, I recommend the use of three CSS hacks. Normally I don’t like to use hacks, but in the latest version of IE (version 7 beta 2 at the time of writing), they have all been fixed, and therefore it becomes possible to single out individual versions of IE from within CSS (providing it’s an IE-only style sheet like in this case). Therefore these are the hacks I recommend:
/*
  No hack, all versions
  will apply these rules.
*/
#somewhere{
  property:value;
}
 
 
/*
  *7 hack
  Only versions 5.5 and higher will
  apply these rules, 5.0 will not.
*/
html*#somewhere{
  property:value;
}
 
 
/*
  Simplified box model hack
  Only versions 6 and higher will apply
  these rules, 5.0 and 5.5 will not.
*/
#s\omewhere{
  property:value;
}
 
 
/*
  Child selector
  Only versions 7 and higher will apply
  these rules, 5.0, 5.5 and 6 will not.
*/
html>body #somewhere{  
  property:value;
}
By using an IE only style sheet for fixes, it should be possible to create an entirely hack free style sheet for standards compliant browsers. Such a style sheet would be fairly robust and therefore unlikely to break when future versions of browsers are released, the same goes for the IE sheet too, since IE 7 is not susceptible to any of the hacks used, future versions won’t be either.

Summary

By combining all of these methods, it is possible to create straight forward, easy to read, easy to understand and robust CSS. If the code is clear then it becomes much easier to work with, and more thought can be devoted to creating your masterpiece.

0 comments:

Post a Comment

Adz