April 25th, 2007 - by Paul OB

Anyone who has worked with CSS for website design will realize what an art it really is. There’s almost always half-a-dozen different ways to achieve the same result. It’s the skilled CSS artist that will be able to achieve the optimum result with the least amount of code, while also keeping the code well-modularized, easing future maintenance.

This article will teach you the technique of using space separated classes thereby allowing you to be a better CSS artist. To show off this technique we will first style and then swap around four floated columns without breaking a sweat.

First we need some sample HTML to play with and just by luck I happen to have some right here:

  1. <div id="wrapper1">
  2. <div class="fl one">One</div>
  3. <div class="fl two">Two</div>
  4. <div class="fl three">Three</div>
  5. <div class="fl four last">Four</div>
  6. </div>

And here is the CSS to go with it:

  1. .fl{
  2. width:100px;
  3. height:100px;
  4. line-height:100px;
  5. float:left;
  6. margin:0 10px 0 0;
  7. border:1px solid #000;
  8. text-align:center;
  9. position:relative;
  10. }
  11. .one{background:blue}
  12. .two{background:green}
  13. .three{background:yellow}
  14. .four{background:red}
  15. .last{margin-right:0}
  16. #wrapper1 {
  17. border:10px solid #ccc;
  18. float:left;
  19. width:438px;
  20. clear:left;
  21. margin:0 0 10px 0;
  22. }

Spaces in Classes, Oh My!

In case you haven’t come across space separated classes then it may be prudent to explain how they are used as it can considerably help modularize your code, cut down on the code itself and ease maintenance. Most of the time when we add a class to an element it looks like the below:

  1. <p class="test">test</p>

However, you can add more classes to that p tag by using a space separated list. Take the following styles for example:

  1. .c1{color:red;margin:10px;}
  2. .c2{font-weight:bold}
  3. .c3 {margin:0}
  1. <p class="c1">This is red with a 50px left margin</p>
  2. <p class="c1 c2">This is red with a 50px left margin and bold</p>
  3. <p class="c1 c2 c3">This is red and bold and only a 10px margin because I canceled out the left margin</p>

As you can see we can add as many classes as we want (within reason) to modularize the code where necessary.

Now getting back to the original code in this demo you can see that I used a class called .fl which sets all the main properties for the four floated boxes.

  1. .fl{
  2. width:100px;
  3. height:100px;
  4. line-height:100px;
  5. float:left;
  6. margin:0 10px 0 0;
  7. border:1px solid #000;
  8. text-align:center;
  9. position:relative;
  10. }

This will give us four floated boxes but we also want each box to have a different colour and the last one not to have a margin. Therefore let’s add the following classes:

  1. .one{background:blue}
  2. .two{background:green}
  3. .three{background:yellow}
  4. .four{background:red}
  5. .last{margin-right:0}

That should be pretty self-explanatory – all we have to do now is add the extra classes to the elements and remember to use a space as a separator; like below:

  1. <div class="fl four last">Four</div>

There are three classes in the above div tag (fl, four and last) which are all separated by a space. This means that each of the three classes will apply their styles to the content as required and as defined in the stylesheet.

  • The first class (.fl) floats the elements and describes all the other css properties in that style rule as shown above.
  • The second class (.one or .two or .three or .four) simply supplies the background colour.
  • The third class (.last) simply cancels out the right margin on the last float so that it hugs the parent wrapper nicely.

This method allows us to minimize the code and use common styles in the class called .fl and then we simply supply any differences in a separate class. We could even cancel out any previous styles (as we have done with .last) as the cascade will still work as normal. Styles later in the selection will over-ride the earlier ones where there are conflicts to be resolved.

I should point out that you can’t do this with ID’s as this technique is only for classes; don’t get confused and try the same thing with ID’s because it won’t work. Space separated classes are well supported in all modern browsers and quite a few of the old ones so you can use them quite safely and effectively.

Now Back to The Demo

Now let’s get back to the floats and apart from what I just mentioned the layout is pretty straight-forward. We have created a wrapper that holds our four 100px floats which I have very cleverly numbered from 1 to 4 as seen in the screenshot below:

f1.gif

Don’t Like It? Then Change It Around!

The first thing we are going to do using only relative positioning is to swap around float 1 and float 4.

This is easier than you might think – we only change the stylesheet as follows:

.four{left:-336px}
.one{left:336px}

We have already applied relative positioning to .fl so we simply need to swap the positions of boxes 1 and 4. Using the left property we simply drag No.4 backwards by 336px and push No.1 forwards 336px. The 336px is a simple calculation derived from the width of our element including borders and margins multiplied by the number of elements we wish to move across.

(100 + 2 + 10) * 3 = 336px

Since we are using relative positioning nothing else on the page will react in any way to the movement of our floats. The results can be seen in the screenshot below:

f2.gif

Floats numbered 1 and 4 have swapped positions with minimum effort and without changing the HTML at all.

But Can You Do It Backwards?

Next we will swap floats 2 and 3 around while leaving floats 1 and 4 in their new positions.

As these 2 floats are next to each other we only need to move them 112px (see previous calculations above) to make them change position.

.two{left:112px}
.three{left:-112px}

That wasn’t hard was it? The result of this can be seen below. We have completely reversed the order of our floats so that they now start at 4 and descend to 1.

f3.gif

This technique is so simple and so subtle that it often gets overlooked. Of course we could go on arranging those 4 elements into quite a few more permutations and all using the same simple logic. If we combine the movement of the floats with a change in size and some negative margins then we have the basis of a multi-functional layout that can be shaped in many different ways.

Stop I Want To Get Off

I have put up a demonstration here – you can click the numbers to change the pattern. I got bored and gave up at 13 different layouts but you can copy the code to play around with it and see how many more ways you can move things around.

With CSS you are limited only by your own imagination. Have Fun.


Be Sociable, Share!

18 Responses to “Optimize Your CSS with Multi-Class Elements”

1 Golgotha

I think people could miss the real beauty of this article and just see it as swapping boxes around.

The beauty is how small and optimized your CSS code is. I could have done the same thing to make my boxes work the same, but my CSS code would have been twice yours.

Nice article Paul.

2 trovster

It’s always good to tell people about little things in HTML/CSS which they might miss. But you’ve got some issues in these examples.

Your first example should be a list of links. No point using multiple classes if you’ve got unsemantic mark-up.

I use multiple classes on my lists very often. I add a class of ‘f’ and ‘l’ to the first and last list-items, respectively, for :first-child & :last-child emulation in Internet Explorer. I also add a class of ‘odd’ so I can do stripey tables/lists with ease. So often I end up with class=”f odd”.

Also, I should mention, selecting multiple classes in IE can give some unexpected results. For example .red.blue {color: purple;} IE will apply that to any element with JUST the blue class. The rule is, with multiple class CSS selectors, IE will apply the selector to an element with the last class.

3 Paul OB

Hi Trovster thanks for your comments.

I think you missed the point as the first example is not a list of links but an example of a four column layout as shown in the very last full demonstration. The first example was just a set up for the final demo. Therefore the example I gave is correct for its intended purpose.

Also thanks for pointing out the dot.notation addressing of classes which was in my article but seems to have been cut out of the edit in error. I will reproduce it below until the editor replaces it above :)

Paul
—————————————-
Without wishing to confuse too much
there is another technique of targetting these classes as follows (but there is a drawback so read on).

.fl.four.last {color:orange}

(Note that in the css there are no spaces between the selectors). The above would style .last only if the element contained the classes of .fl and .four as well (although they could be in any order and not just as shown e.g. <div class="four fl last">). However this technique is seldom used because IE6 and under have a bug and only recognise the
last selector when addressed this way and would style .last regardless. Therefore I would advise against this method of addressing the classes for the time being and use the simpler method of targeting as used in the main demo.
———————————

4 Golgotha

Yep, Paul is innocent! I cut that out of his article :)

5 Sherwin Techico

Great write-up Paul. I knew this place is special as soon as I recognized that ever-so-special SN “Paul OB” of SPF =)

Meanwhile, any work arounds for JS to suppose these as in obj.className? That would be a great find indeed.

6 Paul OB

Hi Sherwin,

Thanks for the comments.

As you know JS isn’t my area but I wonder if Dean Edwards ie7 script doesn’t already address these issues.

http://dean.edwards.name/IE7/compatibility/

Haven’t had time to check at the moment :)

7 Sherwin Techico

Thanks Paul (again) for the pointer/URL. I’ll be sure to take a look at it in the AM.

8 CSS The Star Matrix Pre-loaded

[...] (onestar) is the default rating. (If you haven’t come across multiple classes before then read this article which explains them in detail.) The onestar class could be changed to another classname to reflect [...]

9 dotnetuncle - Interview Questions

Is it possible to inherit class two & three & one together? If yes, what will be the back color.
Cheers!

10 Paul OB

Hi,

I’m not quite sure what you mean by “inherit one two and three together” exactly but I’ll have a guess at what you mean.

If you set an element with three classes and there are conflicts within the classes. e.g if as you say you set the background colour for all three different classes then the normal rules of the cascade will apply and classes later in the html get priority.

so if you said:

.one{color:red}
.two {color:blue}
.three{color:green}

…class=”one two three” – then the text will be green

…..class=”two three one” – then the text will be red.

Its just the normal rules of the cascade and where there are conflicts with elements of all the same weight then the class that comes later in the html has priority.

I hope that’s what you were asking.:)

11 Brandon Livengood

Nice article Paul.

12 Yuri

Hi man, really cool article, thanks :)

Yuri

13 Bryce

I know I’m a bit late to the party, but Paul’s comments in #10 are incorrect. In the case of a “tie”, it’s the order of the CSS, not the class name. In that example, class=”two three one” and class=”one two three” will both result in green text. If you want it to be red, you’d have to reorder the CSS rules to have .one be last.

14 azrael_valedhel

Now this is something I will use right away. :) So simple, and so usable – it scares me I didnt even know about it.
Thanks!

15 Paul OB

Yes Bryce is correct in post 13 and it’s the css order not the class order in the html that matters. I don’t know what I was thinking – apologies for mis-information.

16 Jay Adkins

Nice article! Also, the comments about the order above are very helpful. Thanks guys!

17 solarian

Thank you! I found in this article exactly what I needed!

18 Funslinger

Yes, Bryce is right. But I disagree with this part of the CSS specification. The order of the declarations in the stylesheet shouldn’t matter. The order of the classes should be the priority. That way the coder has more flexibility with styling. Plus, it removes the burden of having to position the declarations in the “correct” order.

My Nook reader actually does it this way which suits me just fine.

Share your thoughts...

mulberry sale spyder womens jacket cheap new balance 574 mulberry outlet cheap new balance 574 arcteryx outlet mulberry sale spyder womens jacket mulberry sale spyder womens jacket mulberry outlet mulberry outlet new balance 574

Popular Articles

Top 10 Commentators


Subscribe to this feed! Subscribe by Email!

Random Bits Podcast

You need to download the Flash player from Adobe

Blogs Worth Reading