Little CSS Stuff Newcomers Get Confused About

Published by Chris Coyier

If you're a pro, it's easy to forget the confusion you felt when you just started learning CSS. Just for fun, let's try and remember some of those little weird confusing moments. I'll start us out by listing some random ones I remember and have picked up on while helping others recently. Then you folks take it from there in the comments.

These aren't huge big things like broken layouts in IE or which vendor prefixes should you be using. It's the little fundamental stuff, like tiny differences in syntax that change meaning in a big way.

Tag qualifying

What's the difference between these two things?

.class    {   }
p.class   {   }

The first one will select any element with that class name. The second one will only select paragraph elements with that class name.

The first is more generically useful. The styling you apply with that class may be useful to multiple types of elements. Even if it's not today, it might be tomorrow. It's also faster for the browser to understand and apply.

It's a fairly rare case that you'd want to use the second example. It would only be if you wanted to re-use the same class name for multiple elements but have them to different things.

p.stand-out { background: yellow; }
span.stand-out { font-weight: bold; }

Selector order matters

Why are these so different?

.class div { color: red; }

div.class  { color: green; }

The first example there is very different because of the space character between .class and div. The stuff before the space and the stuff after the space select different elements. The first part is "select any element with this class name" and the second part is "select any div". Put them together with a space and you get "select any div that is a descendant of any element with this class name".

The second doesn't involve any of that descendant business. It's a tag-qualified selector like discussed above.

If the above CSS was the only CSS on the page, the results would be like this:

<div class="class">
   <h2>
      <div>Would be red</div>
   </h2>
   <div>Would be red</div>
   Would be green
</div>
<div>Would be black</div>

Why use ID's at all?

It seems like as far as CSS is concerned, using classes and using ID's is the exact same thing.

#id    { color: red; }
.class { color: green; }

It's just an attribute and it's a seemingly arbitrary difference in syntax depending on which one you use. The results are predictable:

<div id="id">Would be red</div>
<span id="id">Would be red</span>

<div class="class">Would be green</div>
<span class="class">Would be green</span>

You might have learned ID's are "supposed" to be unique, as in, only have one element per page that uses it. But you've slipped up before and it doesn't seem to matter, the CSS applies just fine.

Then you start getting conflicting information. Some tools and philosophy teach that ID's aren't good for styling. Some articles tell you they are the most efficient. Perhaps you work with a JavaScript developer who tells you they need ID's on everything because it makes their job way easier.

Confusion abound here. Turns out, everybody is kinda right. Here are the facts:

  • CSS doesn't care much which you use, as far as actually applying styling. ID's are technically faster for a browser rendering engine, but other than the most extreme of circumstances you'll probably never notice a speed difference.
  • JavaScript cares very much about ID's. It can be noticeably faster for JavaScript to find an element by an ID. And this is where the "uniqueness" is very important. JavaScript will only find the "first" element with that ID, so if you have multiple on the page, confusion may ensue.
  • ID's have an infinitely higher specificity value than classes. If there is an element with an ID and a class and they both apply styles, the styles applied by the ID will take precedence over the styles applied by the class. This can be useful, this can be a hindrance.

My personal philosophy is to use ID's on stuff that I absolutely know there will only ever be one of and will not benefit from properties from a class name shared with other elements.

Buried hovers

What's going on here?

div           { color: red; }
div:hover div { color: green; }

:hover is a selector which only applies itself when the mouse is over a particular element. What is weird here is that you don't necessarily have to apply styles to that element being hovered over. In this case, we are applying styling only to descendant divs when the parent div is hovered. So:

<div>

   I will be red all the time

   <div>
      I will be red, unless that top
      div is hovered (but not necessarily me)
      and then I'll be green.
   </div>

   I will be red all the time

</div>

Whitespace doesn't matter

This:

div{color:red}

Is the exact same as:

div            {
      color       :       red

}

You do need spaces in selectors to make decendent selectors (e.g. ulli { } is absolutely not the same as ul li { }) but other than that you should use whitespace however makes looking and working with your CSS comfortable.

Notice the missing semicolon on that property in the example above. You can omit that if it's the last property in the group. Personally I never do as if you add more property/values later and forget to add the semicolon to the previous line, that's a problem. Because whitespace is so free, it will continue to read the next line as part of the value of the previous line.

Example of the problem:

div {
  -webkit-border-radius: 10px
  -moz-border-radius:    10px
  border-radius:         10px
}

The whitespace is fine. The no-semicolon on the last one is fine. But the first two property/value pairs don't have semicolons and will totally screw up and not work.

Property overrides

What font-size is the div going to have?

div {
   font-family: Sans-Serif;
   font-size: 18px;
   font-weight: bold;
   font-style: italic;
   color: red;
   margin: 0 0 20px 0;
   font-size: 21px;
   padding: 10px;
}

It's going to be 21px. You've accidentally listed it twice and the second one is going to win.

Order in CSS file matters

If you have two selectors that have the exact same specificity like this:

.red   { color: red; }
.green { color: green; }

And then they apply to the same element, the selector later in the CSS will always win. Class name order in HTML doesn't matter:

<div class="red green">Will be green</div>
<div class="green red">Will be green</div>

What makes for a semantic class name?

The previous example used "red" and "green" as class names. That's not very semantic. Why not? That's a whole ball of yarn, for next week! ish!