3
<style type="text/css">
 <!--    
    div:nth-child( 3n + 2 ) { background-color: green }
 -->
</style>

<div>
    <div>one</div>
    <div>two</div>
    <div>three</div>
    <div>four</div>
    <div>five</div>
    <div>six</div>
    <div>seven</div>
    <div>eight</div>
    <div>nine</div>
    <div>ten</div>
    <div>eleven</div>
</div>

Why is the outer div affected by this style sheet rule even though it hasn't got a sibling and is the only child of a parent element?

BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
  • 1
    Are there any other `div` elements on the page that this div would be a child of? From the code you posted I can't recreate your error. – Bad Wolf Sep 02 '13 at 18:46
  • No other div elements only those posted. – Volker Ackermann Sep 02 '13 at 18:49
  • But there is another style sheet : div { width: 150px; height: 150px; text-align: center; padding: 30px; border: thin; border-style: solid; margin: 20px; } – Volker Ackermann Sep 02 '13 at 18:50
  • 2
    Are you sure that `div` is the only child of its parent? Because your given code makes it appear like the `style` element is a sibling, yet neither element has a parent, and I'm not sure if that's intentional. – BoltClock Sep 02 '13 at 18:51
  • 1
    What DOCTYPE are you using, and exactly where is this `style` element? (Is it outside the `head`? Inside the `body`?) Can we see a whole, complete document, please? – Matt Gibson Sep 02 '13 at 18:56
  • The styles are in a seperate file. – Volker Ackermann Sep 02 '13 at 19:02
  • The outer Div has got seven other sibblings that are not divs. Does that affect this rule? The outer div has got 5

    1

      and one element.
    – Volker Ackermann Sep 02 '13 at 19:14
  • Of course that affects the rule. `:nth-child()` is not [`:nth-of-type()`](https://developer.mozilla.org/en-US/docs/Web/CSS/:nth-of-type). – Matt Ball Sep 02 '13 at 19:19
  • 2
    @Volker Very much so. Please try to use complete, minimal examples that show the problem whenever you can. – Matt Gibson Sep 02 '13 at 19:27

4 Answers4

6

Because of the <style> element, the outer <div> does match the selector. :nth-child is 1-indexed, so nth-child(3n+2) matches elements at indices 2 (n=0), 5 (n=1), 8 (n=2), ... and the presence of that <style> tag in your HTML means that the parent <div> is indeed at index 2 (remember, we start counting at 1).

See what happens when you move the <style> tag: http://cssdesk.com/PEBpL

You can solve this with a more-specific selector, optionally with more-specific HTML as well.

Matt Ball
  • 354,903
  • 100
  • 647
  • 710
  • 1
    Is that link demonstrating what happens when the style element is removed (i.e. the expected results)? – BoltClock Sep 02 '13 at 18:49
  • Would this not suggest that adding an extra `
    ` in between the `
    – Matt Gibson Sep 02 '13 at 19:07
  • Oddly, that seems to work when the style is in a separate CSS file, but not when the `style` element is in the body, as it looked like it might have been from the question (even with the `scoped` attribute in an HTML5 document.) Adding anything other than a `
    ` seems to work, though. And now I'm quite confused.
    – Matt Gibson Sep 02 '13 at 19:17
  • 2
    Aha! Ignore me, I've been confused by testing using `
    ` (invalid and treated as a opening tag) rather than `
    `.
    – Matt Gibson Sep 02 '13 at 19:25
2

As @MattBall said:

(Demonstration:)

http://jsfiddle.net/pbMM8/ With style element in the document.

http://jsfiddle.net/hd4xy/ With the separated css.

UPDATE In case you don't want or can't separate the style, consider adding an extra div to the css rule.

div div:nth-child( 3n + 2 ) { background-color: green }

As you can see at: http://jsfiddle.net/J8SQJ/

Ofir Baruch
  • 10,323
  • 2
  • 26
  • 39
1

The problem does not occur in any valid HTML document. But if your document contains any non-whitespace content before the <style> tag, then things change. Such content implicitly closes the head element and starts the body element. The style element is then taken as the first child of body (which is invalid HTML, but works just fine as such in practice), making your div the second child and thereby matching the selector div:nth-child( 3n + 2 ) (for n = 0).

A solution is to fix the HTML syntax so that style is in the head element. Use http://validator.w3.org to check the syntax.

In addition to this, it is safer to assign a class or an id attribute to the outer div, say <div class=foo>, and use a selector like .foo > :nth-child(3n+2), which matches specific children of an element in a specific class.

Jukka K. Korpela
  • 195,524
  • 37
  • 270
  • 390
0

The outer div is the eighth sibbling in the document. Which means the nth-child( 3n + 2 ) applies correctly.

<body>

<p></p>
<p></p>
<p></p>
<p></p>
<p></p>

<ul></ul>

<table></table>

<div>
    <div>one</div>
    <div>two</div>
    <div>three</div>
    <div>four</div>
    <div>five</div>
    <div>six</div>
    <div>seven</div>
    <div>eight</div>
    <div>nine</div>
    <div>ten</div>
    <div>eleven</div>
</div>

</body>