views:

425

answers:

5

I have a question about css selectors.

Say I have the following html

<div class="message">
  <div class="messageheader">
    <div class='name'>A news story</div>
  </div>
</div>

In the css I could refer to the class called name either like this

div.message div.messageheader div.name {}

or

.name {} /* ie *.name{} */

Is one way better than the other?

I understand that if I have an additional "instance" of the class called name, ie

<div class="message">
   <div class="messageheader">
      <div class='name'>A news story</div>
   </div>
</div>

<a class='name'>A news story</div>

I could use div.message div.messageheader div.name {} to refer the first instance and a.name {} to the second instance, but I am interested in the initial scenario only.

+3  A: 

If you are only interested in the initial scenario using .name is just fine. In fact, best practice with CSS is to always start more generic and focus as you go.

also, doing things like div.* are unnecessary unless you have the same class on a different element and want to make them different. If you are nesting classes, it is even more unneccessary. .messageheader .name will offer the same targeting.

Remember CSS does mean cascading. If you make everything so targeted you'll have to redefine every element.

Jeremy B.
+2  A: 

In my opinion, it's really up to you. One way is shorter, but the other is more precise although reliant on the markup staying mostly the same. If it's a complex project, then maybe being more specific is the right way to go. Otherwise, be a bit more relaxed. Try and find a balance.

Remember though, it's important to make use of the cascade in CSS. Why add classes and ids to things that don't really need it?

dylanfm
+1  A: 

In general specificity is favourable, but at a heirarchy level more than a unit level. What I mean by that is that 'div' is superflous, and perhaps damaging (see next paragraph) but #foo .bar .baz is good practice.

In general I try and get people to think about CSS in OO terms. If you're defining the style as a class make sure that it is behaving as a class. In this instance asserting div.foo instead of just .foo is a bit like having defined a subclass. It's fine if that's what you intend. Always always think about potential issues with future mark-up. Ideally you want future code to auto-inherit exactly what it needs, neither polluted by a vague CSS assertion, nor missing something because of an overly specific assertion.

In practice I find you usually favour the form:

#foo .bar {}

Reserving root level classes for only the most generic of styles.

annakata
A: 

I find that using both methods together can help the logical organisation of your CSS. Use the generic ".class" for properties that you want to apply to ALL items of that class and the more specific "p.class" for a specific type object of the class. For example:

<style>
div.product {
float: left;
padding: 1em;
border: 1px solid blue;
}
.price { 
color: #009900;
}
p.price {
text-align: right;
}
</style>

<div class="product">
    <p>Lorem ipsum <span class="price">&pound;8.99</span> dolor sit amet.</p>
    <p class="price">&pound;5.99</p>
</div>

The answer to your question is that neither way is better, they just do different things. By all means use both! Leveraging the power of different selector types is an important aspect of good CSS and a great way to keep redundancy at bay. Other useful memthods are the use of multiple classes on one object (e.g. <p class="someClass someOtherClass">), combining class AND id on objects (they are not mutually exclusive) and using the parent/child relationship of your HTML to avoid "overclassing" (e.g. ul.someClass li {} instead of ul li.someClass {}) whenever possible. Happy coding!

Ola Tuvesson
+1  A: 

I agree with the answer of Jeremy B, but I want to add something.

In your example you can refer to the class called name either like this

div.message div.messageheader div.name {}

or

.name {}

or

div.name

The first makes sense just if you want to override a less specific rule. The second is generic. The third, as you said, is good if you want apply different styles to different elements using the same class (but in this last case there is a good chance that you did something wrong in assigning your classes).

I know it's only an example, but in your code I see too much classes. Remember that is a good thing to use element selectors when possible. I.e. if you want to give some style to that div, or to all the divs inside a div with class "messagehader", you should use this selector:

div.messageheader div

You could also remove the class messageheader, and select that div with:

div.message div

And so on.

Obviously, you will need to use some classes in your page, but don't give a class to everything. In a lot of cases is not necessary.

alexmeia