Outside my element: A CSS Trick

I have a little CSS trick that I’d like to share. It’s a little embarrassing because CSS/HTML and all that goodness certainly aren’t my forte. Also, this is a pretty basic trick, but maybe it’ll help someone.


Hopefully if this is completely inappropriate, or if there’s a better way, someone will point me in the right direction.


The goal is to reduce the repetition of common style elements by leveraging the fact that multiple class selectors can be specified on an element by separating them with spaces. For example, you might have a list of items that relies on the following two styles (only relevant parts are shown):

.row, .lastRow{border-bottom:1px solid black; …  }
.lastRow {border-bottom:0px;}

The .row and .lastRow class selectors share a lot of styles in common (not shown here), such as padding, width and height. However, the last row doesn’t have a bottom border (because it just looks stupid). An alternative approach to the above styles (and yes, I realize you could just use jQuery) is to use more generic, and thus more reusable, styles:

.row {border-bottom:1px solid black; …. }
.last {border-bottom:0px;}

It might look similar, but look at how they are applied:

<div class=”row”> … </div>
<div class=”lastRow”> … </div>

Vs

<div class=”row”> … </div>
<div class=”row last”> … </div>

The difference is still pretty subtle. But what if we build up an arsenal of generic rules:

.left{float:left;display:block;}
.right{float:right;display:block;}
.clear{clear:both;}
.centered{text-align:center;}
.bold{font-weight:bold;}
.hidden{display:none;}
.noborder{border:none;}

.list .last {border-bottom:0px;}
.callout .last{margin-bottom:10px;}


You no longer have to worry about so many specific rules:

<div class=”list”>
<div class=”row bold”>
<div class=”centered”>Id</div>
<div>Name</div>
</div>
<div class=”row”>
<div class=”centered”>1</div>
<div>Sam</div>
</div>
<div class=”row last”>
<div class=”centered”>2/div>
<div>Galen</div>
</div>
</div>

This entry was posted in Uncategorized. Bookmark the permalink. Follow any comments here with the RSS feed for this post.

17 Responses to Outside my element: A CSS Trick

  1. Richard Collette says:

    There is not much point to creating styles that simply mirror CSS. You might as well use a style attribute on the HTML element.

    However, a use case where multiple classes on an element makes sense is to represent state so that state/properties/metadata can be represented in presentation. For example you might have an input element that is both .required and/or .invalid in a given moment. How that state is represented in the UI is abstracted by CSS. Even when it is not directly related to presentation, using CSS classes to represent multiple state facets can be useful for jQuery based selection and behavior attachment.

  2. Good post! Keep the good work!

  3. Jeremy says:

    You know, it seems so obvious, but damned if that wouldn’t make my css a little more concise for just that example (last row not having a bottom border). Nice lil’ tip

  4. Nik Radford says:

    Aye, tables should be used when tables make sense. Showing data in a table form.

    Tables should not be used for layout purposes.

    So don’t be afraid to use a table if you need to 😛

  5. JMag says:

    seems like alot of redundant code to me. Like some previous comments hinted you could use selectors, and don’t worry – it works in Opera…

    Roughly you could do something like the following.

    html goes:

    some text

    Css:
    div.list {}
    div.list > div {border-bottom: 1px #000 solid;}
    div.list div.last {border-bottom: 0;}
    .centered {text-align: centered;}

    My question is – if you’re doing sort of a table and presenting tabular data, why not use a table? After all, that is what it’s designed for :>

    On another note, read up on css specificity, that might help. I got loads of stuff to say about this but must stop myself.

    For the interested, check out these guys at the forefront of GUI development and accessibility on the web:
    http://www.456bereastreet.com/
    http://meyerweb.com/

  6. Mike Rundle says:

    If you want to make your code a little more extensible, I’d get rid of the “last row” being spit out from the backend and instead target the last row in the table unobtrusively using jQuery (or your JS library of choice) and add the class dynamically. Same with things like “first row” or even/odd assignment. Then, you don’t have to mess with any presentation stuff on the backend as you output your table. Better separation of content from style.

  7. Sean says:

    Last I checked Opera has something like 2.5% market share? If something works in FF, Safari, and IE7+ then in my mind that counts as “it works.”

  8. Stephen says:

    @ aaronjensen: yep, like most things, but I’m hoping ie6 becomes more redundant in the next year.. plus I imagine most of the people who run ie6 are probably part of the masses who pirated windows xp.. and they can go to hell.

  9. abhimanyu says:

    Hello dude
    in this concept the main probelm is that opera dont support double class impleamntation i mean class=”a b”.so its specific to firefox and ie(newer version)

  10. Aaron Jensen says:

    Stephen,

    Yes, those are great as long as you’re willing to accept the fact that they do not work in IE6.

  11. Stephen says:

    I like multiclass selectors, ie:

    .class1.class2 {
    .. do ..
    }

    Where the styles are applied only to elements which have BOTH classes applied.

  12. Mark Nijhof says:

    Just don’t lose sight of what you are doing, debugging CSS (even with FireBug) is no fun.

  13. Richard Smith says:

    Just be careful not to go overboard with this technique – while the row and last classes are quite useful (even if, as Ryan points out, you could use the pseudo classes), bold and centered aren’t such a good idea.
    It’s not a good idea because you’re putting the formatting into lockstep with the markup – breaking this link is part of the point of using CSS.

    Far better to embed the semantics into the markup. In your example “row bold” would become “row header” & “centered” would become “id” (or “personId” or whatever it means). That way, a search and replace on “bold” classes to “italic” when you decide to alter the look & feel becomes change the CSS rule for “.header”. Much easier :)

  14. James Curran says:

    But by defining class names specifically tied to their design element, you are merely moving the design out of the style sheet and back into the content.

    This is defeating the entire purpose of stylesheets. You might as well just use and

    tags.

  15. Vlad says:

    Good tip! Some people frown on using “left”, or “right”, or “top”, etc in CSS naming. Not me — provided the style is specific enough that it will only apply to related scenarios, but nothing more. Hope that is relatively clear. :)

  16. Elijah Manor says:

    Good stuff! Thanks for the tip.

    By the way, there is a new version of the SyntaxHighlighter… I haven’t yet upgraded to it on my blog, but it has some nice features. http://is.gd/itaQ

    Keep up the good work!

    http://twitter.com/elijahmanor
    http://zi.ma/webdev
    http://zi.ma/techtwitterings

  17. Ryan Riley says:

    Depending on your browser, you can use CSS selectors. For the last element, you’ll need the :last-child selector, which is part of the CSS3 selectors. In IE, you may need something like the ie7-js library from Dean Edwards. I’ve used this to great effect in the past, though it does add a slight bit of load time.