
This article is intended for people familiar with CSS syntax and usage. If you are new to CSS, see Adrian Senior's excellent article, CSS: An Introduction, in the articles section of CMX.
One of the touted benefits of CSS is that it reduces total page weight, and thus download time, both at first page load, and even more on subsequent loads due to style sheet caching. This is true, but often a sizable fraction of the first load savings is lost because of highly redundant CSS code.
Well that's all over. Now you will learn some "secrets" of efficient CSS coding, enabling you to pare that style sheet right down to the bare bones. To be sure, you won't achieve huge savings doing this, but for some highly competitive sites every little bit counts.
There are several areas where byte-busting can happen, including shorthand properties, multiple declarations, default values, inheritance, and white space.
A couple of the CSS shorthand properties have been touched on in Zeroing page margins, but there's a lot more to be said about the subject.
Commonly used shorthand properties include:
The list items above are linked to relevant parts of the W3C CSS 2 specifications.
For example, the font property is a shorthand property for setting font-style, font-variant, font-weight, font-size, line-height, and font-family all at once. Not all of them must be used within the shorthand property, however. When values are omitted from a shorthand form, each "missing" property is assigned its initial value, such as these found in the W3C specifications for the font property . If many of the font-related properties are being controlled, use of this property can cut a substantial number of bytes from a style sheet.
The background and list-style properties work in a similar way. The remaining shorthand properties in our list involve the four sides of a CSS box and are somewhat different than the others.
The four sides of any block level element (divs, tables, lists, paragraphs, etc.) may each have margins, borders, and padding, in varying widths set individually for each side. In the case of borders, border-style and border-color may also be apportioned separately for each side. If all these properties are explicitly spelled out, a rule set can get quite lengthy. Using shorthand rules makes it possible to drastically reduce the load.
When one of these "box-side" properties is required and all sides are to be the same, just use the basic shorthand property like so:
margin: 5px;
border-width: 5px;
padding: 5px;
Note: border-style must also be set in order for borders to show. This can be done by using the border-style property, or by setting a style with the border property. Using border-width alone will result in no borders being displayed.
If, however, some sides need different values, a CSS feature we call the "clock" comes into play. Just imagine a box as the face of a clock. When the hands are straight up, they point to the top of the box. This is the first shorthand value given. Next comes the 3 o'clock position, which is the right side of the box. Then 6 o'clock is the box bottom, and finally the 9 o'clock position indicates the left side.
Let's look at an example. On our page we want a box with a 10px top margin, a 5px right margin, a 3px bottom margin, and no left margin at all. Here's how the margin shorthand property would be written:
margin: 10px 5px 3px 0;
In the property declaration, these values must be separated by
spaces, and only spaces. Also, some unit of measurement must be given for each
value unless the value is zero.
Note that the zero sized margin is defined as 0 ,
because when any value is zero it doesn't matter what unit you use. A zero amount
of any unit (px, em, %, etc.) is equal to a zero amount of any other unit.
The various box-side shorthand properties allow even more compression when some of the sides are the same. As mentioned earlier, when all sides are to be the same, a single value will be applied to all. However, if the top and bottom of the box is to be one way, while the left and right sides should be different, the margin code might be written as follows:
margin: 10px 5px;
This code sets the top and bottom margins to 10px, and the side margins to 5px. One last trick is possible if the top and bottom are different but the sides are the same. With a 10px top margin, 5px left and right side margins, and a 20px bottom margin we can write:
margin: 10px 5px 20px;
It all depends on the number of values applied to the shorthand property and their order. Remember, one value = all sides; two values = top and bottom, sides; three values = top, sides, bottom; and four values = follow the clock face. There, that wasn't so tough was it?
This same clock shorthand method can be used with border shorthand properties as well as padding. border-width , border-color , border-style , and padding work just like margins do. There is a difference with the border property, however. The border property sets the border-width, border-style, and border-color for all four sides of a box.
This works great if all four borders are to be the same, but what if they must be different? Do we go back to using the good old border-top, border-right and so forth? Well, we could. Fortunately, there is a somewhat more efficient way to do it.
Let's say the borders of our box should all be the same style and color, but of differing widths. The most efficient way is to use the basic border shorthand to define the border-width, border-style, and border-color; as usual, then use the border-width property separately to override the different border widths as follows:
border: 10px solid red;
border-width: 10px 5px 3px 0;
If all the border properties are different for the four sides this method won't be much help, but that is not the typical situation. If border-style or border-color is the variable property, then this method can be modified to work with those properties just as with border-width .
Now we'll take a look at another situation where writing efficient CSS can make a difference.
Let's say we have six absolutely positioned divs (layers in Dreamweaver), and they are all the same other than being spaced out across the top of the page. Because they are given different page placements, they must each be given an individual class or ID, but all the rest of their properties are the same.
A layout editor will likely write the CSS for each ID separately, including all the font rules, text rules, position declaration, and so forth. It seems silly to keep repeating those exact same rules for all those divs, doesn't it? Well it is. Here's how to condense the rules for those divs to the bare minimum:
#first {left: 0;}
#second {left: 100px;}
#third {left: 200px;}
#fourth {left: 300px;}
#fifth {left: 400px;}
#sixth {left: 500px;}
#first, #second, #third, #fourth, #fifth, #sixth {
position: absolute;
top: 0;
width: 75px;
font-size: .9em;
font-weight: bold;
text-align: center;
line-height: 1.4em;
background-color: silver;
color: navy;
padding: 5px;
border: 1px solid navy;
}
By listing all the similar div ID's, separated by a comma and a following space, the rule block gets applied to all the ID's at once. It's clear that if these properties were to be repeated for each ID, the CSS would become quite bloated. This is perhaps the single most effective way to reduce the size of a style sheet.
Note: Make sure that the last ID selector does not have a comma following it, as shown in the code sample for the multiple-ID rule set. While some browsers may still display the divs, others will consider it an error and will not display the divs at all.
Many CSS properties have initial default values that will be used for an element if no declarations are made that override the defaults. For example, each padding property, padding-top , padding-right , padding-bottom , and padding-left have an initial value of 0 . If no padding is desired on a given element, the padding property may be omitted.
Note: Shorthand properties, such as the ones
we have been discussing, do not, in and of themselves, have default values.
The various values are generally taken from the individual properties the shorthand
version represents. While many of the default values listed in the CSS 2 specification
Property Index are none
or 0 , browsers themselves often
set different default values for some properties depending on the element.
Examples: The Opera browser sets 8px padding on the body element. h1-h6
headings, as well as paragraphs, generally have default non-zero
margins. The use of non-zero default
margins or padding for lists and list-items
varies among browsers.
Another way to avoid writing redundant code is to be aware of properties that inherit from a parent element to a child element or elements. There are quite a few inherited properties, but many of these are little-used properties like voice-family . The list of commonly used properties that inherit is fairly short, so here it is (alphabetically):
In certain older browsers, the inheritance feature can be buggy, but the modern browsers generally have no trouble with correct inheritance. By knowing what inherits, one can skip writing excess code. Again, for the full listing see the CSS 2 Property Index.
This is not the CSS white-space property, which has certain specific values, but rather it is empty space within a style sheet itself. This space generally comes in the form of line-feed characters that cause a new line, and spaces used within a line to aid readability. Although removing such spaces can save a few bytes, the savings are usually very small.
If these empty spaces are removed, the CSS will become very difficult to read, making later changes difficult. If the job requires every single excess byte to be excised, you could create a "master" CSS file that is easy to read. Then, make a copy, and remove all the white space for the file that is used "live." If changes must be made at a later time, the easy-to-read master gets the changes and a new copy is again cleaned of white space and used for the "live" version.
Beware! Some spaces are required in CSS coding, and removing those will alter the CSS rules, leading to less than desirable results. When the W3C specifications use the wording "space separated," then the spaces are required. The most common place we find this is between values in shorthand properties. The descendant combinator, sometimes referred to as a descendant selector, is a space character, so removing all spaces in selectors is also not a good idea. Perhaps removing white space is best left to the fanatics, eh?
You have learned a number of ways to make your style sheets more efficient. The benefits of using these techniques on a regular basis include not only bytes saved when the style sheets are downloaded, but also clean, generally easy-to-follow code that is easy to change if it later becomes necessary. Even if you build your style sheets in a layout editor, you can edit the "final product" to be more efficient using the methods outlined in this article.
Keywords
CSS, cascading style sheets, shorthand property, shorthand properties, default values, selectors, inheritance, font, margin, border, padding, list-style, background, border-width, property, properties.