0

I am digging into the difference between child and descendant selector. Accordingly to the documentation that I found and to this question CSS Child vs Descendant selectors I write this example:

<div>
    <h2>h2 1</h2>
    <h2>h2 2</h2>
    <section>
    section
        <h1>h1 section's son
            <h2>h2 section's nephew</h2>
        </h1>
        <h2>h2 section's son</h2>
    </section>
    <h2>h2 3</h2>
    <h2>h2 4</h2>
</div>

css:

section > h2 {
    color:red;
}

(fiddle here:http://jsfiddle.net/armdan/ksB6f/1/)

I expected that in this example the "h2 section's nephew" will not be selected, but it is selected and it becomes red. I don't understand what I am missing.

Community
  • 1
  • 1
Daniele Armanasco
  • 7,289
  • 9
  • 43
  • 55

2 Answers2

3

It is probably because it is invalid for h1 to contain a h2. If you change the h1 to an element that can contain h2, like a div, it works as you expect:

<div>
    <h2>h2 1</h2>
    <h2>h2 2</h2>
    <section>
    section
        <div>h1 section's son
            <h2>h2 section's nephew</h2>
        </div>
        <h2>h2 section's son</h2>
    </section>
    <h2>h2 3</h2>
    <h2>h2 4</h2>
</div>

http://jsfiddle.net/Z5CeB/

Background: the HTML5 spec for h1 says that it can only contain text and "phrasing elements", which are:

  • a
  • em
  • strong
  • small
  • mark
  • abbr
  • dfn
  • i
  • b
  • s
  • u
  • code
  • var
  • samp
  • kbd
  • sup
  • sub
  • q
  • cite
  • span
  • bdo
  • bdi
  • br
  • wbr
  • ins
  • del
  • img
  • embed
  • object
  • iframe
  • map
  • area
  • script
  • noscript
  • ruby
  • video
  • audio
  • input
  • textarea
  • select
  • button
  • label
  • output
  • datalist
  • keygen
  • progress
  • command
  • canvas
  • time
  • meter
joews
  • 29,767
  • 10
  • 79
  • 91
  • 1
    Yes and this has always been true even before HTML5. Note that while introducing another heading tag after an unclosed heading tag causes that to close because of this rule, that does not make the closing tag optional - it is still required. – BoltClock Dec 01 '13 at 11:00
  • Thank you, it's exactly what I was missing. Now I inspect the DOM and I see that the browser puts the h2 nephew as a direct child of the section! – Daniele Armanasco Dec 01 '13 at 11:02
2

There are a few things...

  1. <h2> cannot be contained inside <h1>.
  2. section > h2 selects the <h2>, that's directly under <section> and not as a grand child element. In the latter case, you need to use section h2.

Workarounds would be changing your code this way to make it semantic:

<div>
    <h2>h2 1</h2>
    <h2>h2 2</h2>
    <section>
    section
        <h1>h1 section's son</h1>
        <h2>h2 section's nephew</h2>
        <h2>h2 section's son</h2>
    </section>
    <h2>h2 3</h2>
    <h2>h2 4</h2>
</div>
Praveen Kumar Purushothaman
  • 164,888
  • 24
  • 203
  • 252
  • 1
    "that's directly under `
    ` and not as a child element" A child element by definition is one that *is* directly under another element.
    – BoltClock Dec 01 '13 at 10:59