Targeting descendants of paragraph

elements

2019-09-21 00:36发布

问题:

When I do the following only the word, 'Celebrities', gets a red color.

body > p * {
  background-color: red;
}
<body>
  <p>I have met many <span>Celebrities</span> in my lifetime.
    <p>They</p> all were rich! I have a list
    <ul>
      <li>one</li>
      <li>two</li>
      <li>three</li>
    </ul>
  </p>
</body>

Why is, 'Celebrities', the only thing in red?

From my understanding of descendant selectors the <span>, <ul> and <p> inside the first <p> should be red, right?

If I modify the above as follows it works, why?

body > div * {
  background-color: red;
}
<div>I have met many <span>Celebrities</span> in my lifetime.
  <p>They</p> all were rich! I have a list
  <ul>
    <li>one</li>
    <li>two</li>
    <li>three</li>
  </ul>
</div>

回答1:

p tags cannot be nested inside other p tags. When it parses your markup, it is inserting a (missing) closing p tag before the nested p tag.

<p>I have met many <span>Celebrities</span> in my lifetime. <p>
<p>They</p>


回答2:

This is your code:

<p>I have met many <span>Celebrities</span> in my lifetime.
    <p>They</p> all were rich! I have a list 
    <ul>
       <li>one</li>
       <li>two</li>
       <li>three</li>
    </ul>
</p>

But, because the HTML is invalid, this is how the browser parses it:

Notice how the top-level paragraph element is closed before the next paragraph begins.

This behavior is actually defined in the spec:

4.4.1 The p element

Tag omission in text/html

A p element's end tag may be omitted if the p element is immediately followed by an address, article, aside, blockquote, div, dl, fieldset, footer, form, h1, h2, h3, h4, h5, h6, header, hgroup, hr, main, nav, ol, p, pre, section, table, or ul, element, or if there is no more content in the parent element and the parent element is not an a element.

In other words, a paragraph element doesn't need a closing tag when followed by a div or another p because a closing tag will be assumed by the browser.

The browser also provides an opening <p> tag for the stray </p> tag at the end.

This is why your descendant selector doesn't work. CSS is forced to see these elements as siblings, not descendants.

According to the spec, a paragraph element can only contain phrasing content.

3.2.4.1.5 Phrasing content

Phrasing content is the text of the document, as well as elements that mark up that text at the intra-paragraph level. Runs of phrasing content form paragraphs.

a, code, span, input and textarea are examples of phrasing content.

The p and ul are not phrasing content. They are flow content:

3.2.4.1.2 Flow content

Most elements that are used in the body of documents and applications are categorized as flow content.

article, section, footer, div, p and ul are examples of flow content.

Your second example works because the container is a div, which can contain flow content.