4

My question should be pretty strait forward. For some reason I can't wrap my head around it today.

I'm making a menu with a structure like so

<div class="wrapper"> <ul> <li class="menu-item"><a href="#">Menu Item</a> <div class="inner"> <a href="#">Login</a> </div> </li> </ul> </div> 

I am trying to target the login link using the following css selector:

.inner a{} 

The selector is working, however the following selector is taking css presidence, and overriding the above selector:

li.menu-item a{} 

I'm totally baffled. Why would the second selector take style preference over the first? How would you guys recommend I target the above "a" elements?

4
  • 3
    Which selector comes last? Commented May 8, 2013 at 16:15
  • @j08691 Doesn't matter, a rule with two type selectors and a class selector beats a a rule with one and a class selector, whatever the order. Read up on CSS Specificity. Commented May 8, 2013 at 16:19
  • 1
    @robertc - thanks, but I know all about CSS specificity. I was simply asking a question. Commented May 8, 2013 at 16:20
  • In the line-up, the .inner a{} came last. Commented May 8, 2013 at 16:32

5 Answers 5

11

Why would the second selector take style preference over the first?

Because the second selector is more specific than the first. The first contains one class and one type selector while the second has one class and two type selectors.

To calculate specificity, think of an selector as consiting of four numbers, all starting at (0,0,0,0)

  • Inline styles have the highest specificity and would take the place of the first number (1,0,0,0).
  • ID's count as the second number (0,1,0,0)
  • Classes, pseudo-classes (other than :not()) and attribute selectors count as the third number (0,0,1,0)
  • Type selectors and pseudo-elements - e.g. div {} or ::after{} count as the fourth (0,0,0,1)

Also:

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the detailed post. Info about CSS I obviously need to store away.
3

CSS Selectors have a "weight" system attached to them,

  • Element, Pseudo Element: d = 1 – (0,0,0,1)
  • Class, Pseudo class, Attribute: c = 1 – (0,0,1,0)
  • Id: b = 1 – (0,1,0,0)
  • Inline Style: a = 1 – (1,0,0,0)

so your first selector has a score of (0,0,1,1) while your second selector has a score of (0,0,1,2) which is higher and thus takes precedence

Comments

1

That is because li.menu a contains three parts to idendtify the element: the parent element (li), the parent class (menu-item) and the element (a). Your intended selector only has two, so you could modify it to this:

li.inner a{} 

And it should work.

Edit:

I knew I'd answered this before: Why does my HTML not use the last style defined in the CSS?

1 Comment

Thanks for the tip. The following selector is working for me, div.inner a{}
0

CSS precedence is won by the DOM object with the highest specificity.

So what earns specificity?

Element Selector -- 1 Class Selector -- 10 ID Selector -- 100 Inline Selector -- 1000 

In your example: .inner a would be 11 points

a(1) + .inner(10) = 11 

li.menu-item a is 12 points

li(1) + .menu-item(10) + a(1) = 12 

So that's why the second will be what's shown. To make the correct style show, just make it more specific, for example use .menu-item .inner a

There's a very good article about this here. http://www.stuffandnonsense.co.uk/archives/css_specificity_wars.html

Comments

0

You can apply the CSS only to the anchors inside each element, like this:

li.menu-item > a{} .inner > a 

Doing it this way, the rules of "li.menu-item a" will not interfere in the other anchor.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.