Avoiding chained classes: still relevant?

Skip to first unread message


Dec 13, 2012, 11:08:38 PM12/13/12
to object-or...@googlegroups.com
I'm curious about a rule about disallowing adjoined classes from CSS Lint. The explanation (https://github.com/stubbornella/csslint/wiki/Disallow-adjoining-classes) speaks about IE6's lack of support for chained classes like .foo.bar { ... }.

Now that some have begun dropping IE6 support, is this rule still relevant? Are there other pros and cons to consider when using chained classes? I can see two:

When outlining a list of navigation items that each need their own class (perhaps for sprited backgrounds or similar), like so:
  <li><a class="home on" ...>Home</a></li>
  <li><a class="about" ...>About</a></li>

Having the chained class allows for excellent symmetry in the CSS:.home {background-position:0 0;}
.home {background-position: 0 0;}
.home:focus {background-position: 0 -20px;}
.home.on {background-position: 0 -40px;} /* Follows the psuedo-class code neatly */

At CSS Dev Conf, Jon Rohan spoke about chained classes potentially overflowing the hashes, at least in webkit, for some very large DOMs. He mentioned this happens in Webkit, but he didn't mention if this was alleviated by splitting classes with a space (i.e. is .foo .bar {} more performant or the same as .foo.bar {}), so I'm not sure if this is a full con. Also, it seems this would only happen to truly large DOMs with lots of the same element.

John Slegers

Mar 27, 2013, 7:38:08 AM3/27/13
to object-or...@googlegroups.com
I can't say I'm sure about this, but I think I read somewhere that selectors with chained classes are slower.

Another reason to avoid chained classes (besides lack of IE6 support) is the impact on inheritance.

Consider the following two examples.

Example 1 :

<div class="menu">
. . <h2 class="header">My menu</h2>
. . <ul class="left nav">
. . . . <li class="active"><a>Item 1</a></li>
. . . . <li><a>Item 2</a></li>
. . </ul>

Example 2 :

<h2 class="menu-header">My menu</h2>
<ul class="left nav menu">
. . <li class="active"><a>Item 1</a></li>
. . <li><a>Item 2</a></li>

By adding the class "menu" to the navigation element's container (as shown in example 1), you allow the definition of the menu object to go beyond just your navigation element. As a consequence, the menu's header can be styled with the ".menu . header" selector (or with the ".menu h2" selector if you aren't strict in your use of OOCSS).

In example 2, your menu object is restricted to your navigation element. You need a seperate "menu-header" class (or equivalent) to define the header. Not only does this make your code less clean, is makes the menu's header unable to inherit any shared markup from the "menu" class. As a consequence, you'll need more CSS to achieve the same result when header and navigation element share styling.

The architecture of Cascade Framework is entirely based on this mechanism, providing you optimal flexibility and modularity.

Reply all
Reply to author
0 new messages