363

Which is standard compliant between these two?

<p>Text text text ...
    <ol>
        <li>First element</li>
    </ol>
</p>
<p>
    Other text text ...
</p>

OR

<p>
    Text text text ...
</p>
<ol>
    <li>First element</li>
</ol>
<p>
    Other text text ...
</p>
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
dynamic
  • 46,985
  • 55
  • 154
  • 231
  • Go here: http://validator.w3.org/, upload your html file, and it will tell you what is valid and what is not. – hidden Apr 15 '11 at 19:44

4 Answers4

508

The short answer is that ol elements are not legally allowed inside p elements.

To see why, let's go to the spec! If you can get comfortable with the HTML spec, it will answer many of your questions and curiosities. You want to know if an ol can live inside a p. So…

4.5.1 The p element:

Categories: Flow content, Palpable content.
Content model: Phrasing content.


4.5.5 The ol element:

Categories: Flow content.
Content model: Zero or more li and script-supporting elements.

The first part says that p elements can only contain phrasing content (which are “inline” elements like span and strong).

The second part says ols are flow content (“block” elements like p and div). So they can't be used inside a p.


ols and other flow content can be used in in some other elements like div:

4.5.13 The div element:

Categories: Flow content, Palpable content.
Content model: Flow content.

leo
  • 8,106
  • 7
  • 48
  • 80
s4y
  • 50,525
  • 12
  • 70
  • 98
  • 12
    @link: Yes, w3.org is a tad bit technical. Still, there's no doubt about what's correct when and if you've understood them. – nyson Mar 12 '13 at 10:14
  • 5
    I think @Sid explaining the spec and some of its terms is definitely helpful. If he went a bit further it would a great answer. He could also explicitly answer the question :). I added an edit for that. – studgeek Mar 26 '13 at 23:06
  • 1
    awful to read? don't think so, go to `4.4.1 The p element`, the author even talk about `fantastic sentences` or something like that – Jaime Hablutzel Apr 05 '14 at 05:27
  • @nyson I am starting to read into the specs more carefully to be a great HTML author and holy cow, you are not kidding. "The content model of a transparent element is derived from the content model of its parent element: the elements required in the part of the content model that is "transparent" are the same elements as required in the part of the content model of the parent of the transparent element in which the transparent element finds itself." – tylerism Sep 16 '15 at 16:25
  • 2
    @dynamic I always go to [MDN's HTML reference](https://developer.mozilla.org/en-US/docs/Web/HTML) for easier to read documentation. – Bonk Jun 01 '17 at 16:14
  • @tylerism I would recommend against reading the HTML spec like a book, but rather referencing the part of it you need when you come up against a specific question. The spec has a lot of detail, much of which won't be important to you and can be overwhelming. – Mark Sep 19 '17 at 14:24
  • It's interesting if you try to do this, Chrome will actually adjust the HTML and close the `p` tag before the `ul` – AaronLS Sep 05 '19 at 21:34
  • 1
    @AaronLS Kind of! When a browser gives you back HTML (e.g. in the developer tools, or from `.innerHTML`), it's being re-generated from the element tree. So, Chrome isn't adjusting the HTML so much as creating a valid tree from the original HTML, then generating new HTML from that tree. – s4y Sep 06 '19 at 13:31
  • @s4y So it's only a developer console cleanup? I assumed it was an intermediate cleanup, so that the HTML rendering engine doesn't have to handle bad HTML. I could imagine it simplifies the rendering step if it can make assumptions that the HTML meets specs, so first some cleaning occurs(closing unmatched tags for example). – AaronLS Sep 06 '19 at 15:43
  • @AaronLS Ah, you’re right, it is an early step. In fact, here’s the code where the parser adds fake end tags (look for calls to `ProcessFakeEndTag()`: https://chromium.googlesource.com/chromium/src/+/e95ebd03113de43fa6ae6a130642b4feb37a2f7f/third_party/blink/renderer/core/html/parser/html_tree_builder.cc#544. I more meant that after the original HTML is parsed, the browser doesn’t necessarily keep it — what you see in the dev tools is generated from the DOM tree, just like parsing some JSON and then serializing it again gets rid of formatting quirks in the original. – s4y Sep 06 '19 at 20:32
  • @AaronLS: The only bad part of the HTML is the orphaned end tag after the creation of a p and ul element side by side from the otherwise valid

      ...
    . That orphaned end tag then [results in the creation of an empty paragraph](https://stackoverflow.com/questions/11570902/why-does-a-stray-p-end-tag-generate-an-empty-paragraph).
    – BoltClock Sep 08 '19 at 10:13
  • @BoltClock The bad part of the html is that a ul is inside a p element. It's not valid per spec, which was explained in the answer. Are you disagreeing with me or the answer? Chrome closes the first p tag to resolve the So you end up with two empty p tags. `

      ...
    ` is converted to `

      ...

    `. It was just an idle observation, one you can verify easily. I didn't think we'd go down such a nuanced rabbit hole about it. I try to keep comments succinct so I didn't cover every nuance of something that one can observe in the browser themselves.
    – AaronLS Sep 09 '19 at 04:40
  • @BoltClock The example you linked is a totally different scenario. That is just a case of mismatched tags. I'm talking about the context of this question, where your tags are properly balanced, but you have a ul in a p. In that case Chrome sees that's not valid per spec, closes the first p tag to ensure the ul is no longer inside the ul, then also fixes the closing tag. – AaronLS Sep 09 '19 at 04:43
  • 1
    @AaronLS: My point is that Chrome doesn't think the ul is inside the p in the first place. If the end tag were not in the source, for example, then it would just see a ul following a p - a perfectly valid scenario - not "a ul inside a p that's missing an end tag". The mismatch is in the author's intentions, I guess. But sorry for dragging this out more than necessary. – BoltClock Sep 09 '19 at 04:53
  • @BoltClock Did you test that? Create a source file with a structure of `

      ...
    ` and see what Chrome does with it.
    – AaronLS Sep 27 '19 at 22:29
  • I get that a list cannot be a child of a p, but I tend to use p's to group logically related things... what semantic markup would you use to link a list to a preceding paragraph? – djfm Jun 27 '21 at 23:34
  • @djfm I think it depends on the nature of the grouping. Does the grouping say something that the ordering (of the list appearing immediately after the paragraph) doesn't on its own? i.e. CSS lets you select `p + ul` because adjacency can be meaningful. If that's not enough, a `section` element could be appropriate, or a `div`… but it all depends on what you're trying to accomplish. – s4y Jun 28 '21 at 04:20
  • @s4y thanks, I went for a section in my case. I basically have a sentence that says something like "here are the rules to follow in that case" and then a ul of the rules. The ul by itself loses half of the meaning, and the p loses half of the information. I went for a section. I don't think it matters too much though, it was more out of intellectual curiosity. – djfm Jun 28 '21 at 14:28
  • @djfm That sounds perfect. Another option to consider could be a `dl` element. – s4y Jun 28 '21 at 15:14
55

The second. The first is invalid.

  • A paragraph cannot contain a list.
  • A list cannot contain a paragraph unless that paragraph is contained entirely within a single list item.

A browser will handle it like so:

<p>tetxtextextete 
<!-- Start of paragraph -->
<ol>
<!-- Start of ordered list. Paragraphs cannot contain lists. Insert </p> -->
<li>first element</li></ol>
<!-- A list item element. End of list -->
</p>
<!-- End of paragraph, but not inside paragraph, discard this tag to recover from the error -->
<p>other textetxet</p>
<!-- Another paragraph -->
Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
9

actually you should only put in-line elements inside the p, so in your case ol is better outside

Kris Ivanov
  • 10,476
  • 1
  • 24
  • 35
4
<p>tetxetextex</p>
<ol><li>first element</li></ol>
<p>other textetxeettx</p>

Because both <p> and <ol> are element rendered as block.

David
  • 1,101
  • 5
  • 19
  • 38