• Multiple classes in Internet Explorer

    Jan 16 2006

    I recently discovered the power of using multiple classes. That is, using more than one class on a single element. The class attribute simply accepts multiple classes separated by a space. For example, you can do something like this:

    <style>
    .box { border: 1px solid black; }
    .small { width: 400px; }
    .large { width: 800px; }
    </style>
    
    <div class="small box">
    <div class="large box">

    This is a great way to organize your CSS. For example, you can have a set of classes to define font styles and another set of classes to define box sizes. Then you can use them together in different combinations.

    The class names "small" and "large" aren't totally clear, since they refer specifically to small and large box sizes. It'd be great if I could write "large title" and have it affect the font size instead of the width. So, I tried to change the definition by combining multiple classes in a single selector:

    .box { border: 1px solid black; }
    .box.small { width: 400px; }
    .box.large { width: 800px; }
    
    .title { color: blue; font-family: Arial; }
    .title.small { font-size: 10px; }
    .title.large { font-size: 20px; }

    When I tried this in Firefox, everything worked great. Unfortunately, Internet Explorer doesn't support this. In fact, Internet Explorer will just look at the last class in the list. So, it will interpret the last example as if we had written this:

    .box { border: 1px solid black; }
    .small { width: 400px; }
    .large { width: 800px; }
    
    .title { color: blue; font-family: Arial; }
    .small { font-size: 10px; }
    .large { font-size: 20px; }

    Small boxes will have small fonts, large boxes will have large fonts, small titles will be 400px wide, large titles will be 800px wide. Very unfortunate.

    Once again, Internet Explorer ruins all the fun. Well, there's an up side to this. When we use "small" to affect the width in one place, and the font size in another place, we make it harder to understand and maintain the CSS. And isn't that supposed to be the point of using CSS?

    Besides, not all is lost. We just have to come up with better names. We can still do this:

    .border { border: 1px solid black; }
    .small-box { width: 400px; }
    .large-box { width: 800px; }
    
    .title { color: blue; font-family: Arial; }
    .small-text { font-size: 10px; }
    .large-text { font-size: 20px; }

    It sure isn't as pretty to write something like class="border small-box". But at least then we can use our "small-box" class in places that don't have borders, or use the "border" class to give a border to something without a fixed width.

    In conclusion, avoid the .class1.class2 syntax altogether. It's not supported by Internet Explorer, and it makes code harder to read and manage. However, using multiple classes is completely supported and will make your CSS cleaner and more reusable.

  • Comments

    1. Ben Evans at 4:23pm on January 16, 2006

    In your html file, put the following code to reference your stylesheets (i hope your comment box allows the less than / greater than signs)...

    <link href="style.css" type="text/css" rel="stylesheet" media="screen, projection" />
    <!--[if IE]>
    <link href="ie.css" type="text/css" rel="stylesheet" media="screen" />
    <![endif]-->

    The comment block that contains the if IE and the second link tag will be treated as comments by non IE browsers, and IE will load the additional stylesheet.

    In your normal stylesheet, set your styles normally. You will override those styles for IE in the second stylesheet, which you can do like so...

    * html body div#box_feature
    {
    height: 100px;
    }

    * html body div.table_login
    {
    width: 160px;
    }

    As you can see, IE does let you do the parent.child syntax, but you have to do the entire path from the root (*) down the DOM tree to the child you want to set.

    2. Ravi Sagar at 3:20am on December 12, 2008

    I have two CSS classes: sticky and node-teaser. My goal is to apply both the classes.

    It doesn't work in IE. It treats both classes separately and apply to every id that has either of the tags.

    Still searching for the solution on the net :)

    3. no at 9:59am on April 15, 2009

    multiple classes are failure in IE

    4. yareckon at 10:51am on September 18, 2009

    I think it's important to distinguish that IE has a problem reading CSS, not html.  It doesn't have a problem realizing that an element has more than one class....

    <p class="new important">  will be affected by  .new {} rules  and .important{} rules just fine in IE -- it understands that the paragraph has both classes.

    But you cannot write .new.important {} to distinguish between
    <p class="new important"> and <p class="old important"> in IE, because IE just reads that last .important {} part of the CSS selector and doesn't see .new. 

    In other words, you can't use this css to single out those cases that have both classes.

    If the properties you are setting in .new and .important don't conflict -- say font-weight: and height: -- you don't have a problem.

    It's when you need to set the exact same CSS property -- say width: -- to three mutually exclusive values for these cases:
    class="new"
    class="important"
    class="new important"
    then you have a problem that is CSS proof.... you need to rework your html
    (maybe add a wrapper, invent class="new-important" ?)

    5. Jesse Skinner at 10:55am on September 18, 2009

    @yareckon - That's exactly right. Thanks for the clarification.

    6. Eugene Kerner at 8:01pm on December 2, 2009

    IE is broken in so many ways and multiple classes is one.
    Multiple classes in IE have differenet behaviour accross version.
    For example IE6 doesnt recognise whitepace in the class attr and only selects the last class defined.
    And since many people are still on IE6 I recommend waiting a few years before using multiple classes in IE.
    Best Regards,
    Eugene.

    7. DarX at 9:53am on June 14, 2010

    @Eugene  "For example IE6 doesnt recognise whitepace in the class attr and only selects the last class defined."

    Wrong. I have IE6 SP 1 running in VMware and it has no problem reading multiple classes in the class attribute. E.g.:
    <a class="button small red">...</a>
    Now what doesn't work in IE6 (and for that matter any IE version including IE9 atm.) is selecting multiple classes at once like:
    .button.small.red {...}
    IE will read it as:
    .red {...}
    Therefore if you have a stylesheet like:
    .button.small.red {...}
    .button.large.red {...}
    All small buttons will be large.
    Because of this, and as the article describes, you SHOULD use multiple classes but NOT select multiple classes. So instead of the above I would use:
    <a class="button button_small button_small_red">...</a>
    And:
    .button_small_red {...}
    .button_large_red {...}
    It's not pretty in the HTML, but in the CSS it's just about changing dots into underscores.
    This WORKS in IE. It even works in IE5...

    - DarX

    Commenting is now closed. Come find me on Twitter.