Mark1

Over time, a developer will reach a point where he or she will need to rethink the time-consuming slow zones in the development process. Often these slow zones are aspects that are overlooked—maybe it is something the developer doesn't enjoy doing each and every time. But with each and every time comes a chance to experiment in the hopes of turning a rocky road into a fast lane.

CSS was once that rocky road for me. Writing line after line, refreshing, and testing just took up a lot of time. As my development skills grew, so did the way I write CSS. As a Rails developer, it is tempting to use tools, Ruby gems or other dynamic alternatives to generate CSS in an unconventional way. Before considering dynamic alternatives, we should first take a second look at our CSS file and see how we can improve.

Lets say for the header we have the following:

div#header {
   width: 800px;
   background: url(/images/header.jpg) no-repeat;
}

div#header h1 {
   font-size: 24px;
   font-family: Arial, sans;
   color: #333333;
}

div#header ul#nav {
   width: 800px;
}

div#header ul#nav li {
   padding: 3px 5px;
   border: 1px #6699FF solid;
}

div#header ul#nav li a {
   color: #000033; 
   text-decoration: none;
}

div#header ul#nav li a:hover {
   text-decoration: underline;
}

Nothing special here; just basic CSS. This way of writing CSS is common, as it is found in most textbooks and tutorials. We start with a selector, then a few style declarations for the element specified in the selector. I had written CSS this way for years, until my stylesheets became huge documents with thousands of lines. There had to be a better way.

So I started experimenting with how I organized my CSS. With a few simple changes, I was able to write CSS much faster, significantly reducing development time—time that was then spent on more important aspects of the application. I started by not writing every declaration on a new line, but instead keeping them on one line like so:

div#header { width: 800px; background: url(/images/header.jpg) no-repeat; }

div#header h1 { font-size: 24px; font-family: Arial, sans; color: #333333; }

div#header ul#nav { width: 800px; }

div#header ul#nav li { padding: 3px 5px; border: 1px #6699FF solid; }

div#header ul#nav li a { color: #000033; text-decoration: none; }

div#header ul#nav li a:hover { text-decoration: underline; }

By not creating a new line for each declaration, I have cut the number of lines in my CSS file by 70 to 80 percent, thus turning a CSS file with over 2500 lines to one with about 500. Keeping our declarations on the same line as the selector is a small step that will only lead to more experimentation.

So now we have a selector with all its declarations on one line, then a new line and so on. If we remove the new line between each selector, it cuts the number of lines in half:

div#header { width: 800px; background: url(/images/header.jpg) no-repeat; }
div#header h1 { font-size: 24px; font-family: Arial, sans; color: #333333; }
div#header ul#nav { width: 800px; }
div#header ul#nav li { padding: 3px 5px; border: 1px #6699FF solid; }
div#header ul#nav li a { color: #000033; text-decoration: none; }
div#header ul#nav li a:hover { text-decoration: underline; }

But removing all the blank lines makes it so hard to read. If we have hundreds of lines, it would be a nightmare for us and other developers to read. So let's line up our declarations to make our selectors easier to find:

div#header                   { width: 800px; background: url(/images/header.jpg) no-repeat; }
div#header h1                { font-size: 24px; font-family: Arial, sans; color: #333333; }
div#header ul#nav            { width: 800px; }
div#header ul#nav li         { padding: 3px 5px; border: 1px #6699FF solid; }
div#header ul#nav li a       { color: #000033; text-decoration: none; }
div#header ul#nav li a:hover { text-decoration: underline; }

Now our selectors are much easier to spot, and the one line code is much easier on the eyes. This experimentation is starting to become interesting. Very interesting. Take a second look at the code we have typed above. There is now a visible pattern with the selectors, and, with patterns, we can read the code much faster, quickly finding the one selector we need. But that's not all! We are also showing inheritance. For example, the ul#nav belongs to div#header. The ul#nav has li elements with links in them as well. With this structure, we don't have to keep switching between our stylesheets and html pages—everything we need to know is in the CSS. Previously, we would have had to scroll back and forth to notice this. But since the selectors look like a staircase, we can easily find the child elements. This gives writing one line CSS a bigger advantage over traditional multiline CSS in terms of organization. But as always, we can take it a step further.

What if we have a selector with many child elements? For example, the selector that ends with a:hover is currently our largest selector. Long selectors will lead to the need to scroll sideways, which we should try to avoid as much as possible. Also, long selectors may make it hard to keep track of which declaration belongs to which selector due to huge gaps of space between the two.

Now let's review our CSS code. Currently all belongs to #header, which is a id and therefore unique. A h1 in #header will be dark gray and using Arial, while elsewhere it wouldn't inherit those styles. There is a nav in #header, which is also unique. So a li with the selector in #header #nav or just #nav will have the same styles. Whereas we were previously too specific with our styles, let's now be less specific by starting our selectors with a common parent.

div#header        { width: 800px; background: url(/images/header.jpg) no-repeat; }
div#header h1     { font-size: 24px; font-family: Arial, sans; color: #333333; }
ul#nav            { width: 800px; }
ul#nav li         { padding: 3px 5px; border: 1px #6699FF solid; }
ul#nav li a       { color: #000033; text-decoration: none; }
ul#nav li a:hover { text-decoration: underline; }

There is now a smaller gap, making our selectors and declarations easy to follow, but we lose the pattern and visible inheritance. To fix this, let's add a new line between the #header and ul#nav. Let's also re-adjust the space between the selectors and declarations to the longest selector accordingly.

div#header    { width: 800px; background: url(/images/header.jpg) no-repeat; } 
div#header h1 { font-size: 24px; font-family: Arial, sans; color: #333333; } 

ul#nav            { width: 800px; } 
ul#nav li         { padding: 3px 5px; border: 1px #6699FF solid; } 
ul#nav li a       { color: #000033; text-decoration: none; } 
ul#nav li a:hover { text-decoration: underline; }

Great! Now our code is organized into chunks by the common parent, which increases the visible organization of our code. Just by reading the very first item in the selector, we know that everything in the chunk belongs to that parent. For example, the first chunk styles everything relating to #header and in the second chunk, all styles relate to #nav. Once again, if this was multiline we would have to scroll up and down to find this information, while with one line, if we wanted to style the #nav, we would just skip the whole #header chunk.

The one line CSS method came about after many years of writing CSS. For me, it has greatly increased the speed of which I write and edit CSS because of the visible grouping and visible inheritance. The method described here isn't right or wrong by any means, and it may not be ideal for everyone. At the end of the day, writing one-line or multi-line CSS is a matter of personal preference—since they both will render the same to the end user. Writing one-line css is a example I wanted to share on how the simplest code reorganization can lead to faster and more efficient development. Next time there is a slow zone in your development process, I highly recommend to give your code a second look and experiment with it's organization, the smallest steps can travel the farthest.




RSS Feed


CATEGORIES


ARCHIVES


BOOKMARKED