CSS Classes & SubClasses

Viewed 402707

Is it possible, other than what I'm doing because it doesn't seem to work, to do this? I want to be able to have subclasses that are under a class to use the CSS specifically for that class.subclass.

CSS

.area1
{
    border:1px solid black;
}
.area1.item
{
    color:red;
}
.area2
{
    border:1px solid blue;
}
.area2.item
{
    color:blue;
}

HTML

<div class="area1">
    <table>
        <tr>
            <td class="item">Text Text Text</td>
            <td class="item">Text Text Text</td>
        </tr>
    </table>
</div>
<div class="area2"> 
    <table>
        <tr>
            <td class="item">Text Text Text</td>
            <td class="item">Text Text Text</td>
        </tr>
    </table>
</div>

So that I can just use class="item" for the elements under the parent css class "area1","area2". I know I can use class="area1 item" to get this to work, but I don't understand why it has to be so verbose about it. Shouldn't the css subclass look at what parent class it is under in order to define it?

Note: this works in IE (using 7 right now), but in FF it does not, so I'm assuming this isn't a CSS standard way of doing something.

12 Answers

Just need to add a space:

.area2 .item
{
    ...
}

FYI, when you define a rule like you did above, with two selectors chained together:

.area1.item
{
    color:red;
}

It means:

Apply this style to any element that has both the class "area1" and "item".

Such as:

<div class="area1 item">

Sadly it doesn't work in IE6, but that's what it means.

Your problem seems to be a missing space between your two classes in the CSS:

.area1.item
{
    color:red;
}

Should be

.area1 .item
{
    color:red;
}

Just put a space between .area1 and .item, e.g:

.area1 .item
{
    color:red;
}

this style applies to elements with class item inside an element with class area1.

Just put a space between your classes

.area1 .item
{
    ...
}

Here's a very good reference for CSS Selectors.

That is the backbone of CSS, the "cascade" in Cascading Style Sheets.

If you write your CSS rules in a single line it makes it easier to see the structure:

.area1 .item { color:red; }
.area2 .item { color:blue; }
.area2 .item span { font-weight:bold; }

Using multiple classes is also a good intermediate/advanced use of CSS, unfortunately there is a well known IE6 bug which limits this usage when writing cross browser code:

<div class="area1 larger"> .... </div>

.area1 { width:200px; }
.area1.larger { width:300px; }

IE6 IGNORES the first selector in a multi-class rule, so IE6 actually applies the .area1.larger rule as

/*.area1*/.larger { ... }

Meaning it will affect ALL .larger elements.

It's a very nasty and unfortunate bug (one of many) in IE6 that forces you to pretty much never use that feature of CSS if you want one clean cross-browser CSS file.

The solution then is to use CSS classname prefixes to avoid colliding wiht generic classnames:

.area1 { ... }
.area1.area1Larger { ... }

.area2.area2Larger { ... }

May as well use just one class, but that way you can keep the CSS in the logic you intended, while knowing that .area1Larger only affects .area1, etc.

you can also have two classes within an element like this

<div class = "item1 item2 item3"></div>

each item in the class is its own class

.item1 {
  background-color:black;
}

.item2 {
  background-color:green;
}

.item3 {
  background-color:orange;
}

The class you apply on the div can be used to as a reference point to style elements with that div, for example.

<div class="area1">
    <table>
        <tr>
                <td class="item">Text Text Text</td>
                <td class="item">Text Text Text</td>
        </tr>
    </table>
</div>


.area1 { border:1px solid black; }

.area1 td { color:red; } /* This will effect any TD within .area1 */

To be super semantic you should move the class onto the table.

    <table class="area1">
        <tr>
                <td>Text Text Text</td>
                <td>Text Text Text</td>
        </tr>
    </table>

Additionally to the space needed between the nested classes:

.area2 .item
{
    ...
}

There is a css precompiler called Sass that could help you with the verbosity of css. It uses the extension .scss, you can search for the complete way to use it, but when using, the sintaxis of your code could be reduced to something like:

.area1
{
    border:1px solid black;
    .item
    {
        color:red;
    }
}

.area2
{
    border:1px solid blue;
    .item
    {
        color:blue;
    }
}
Related