194

As far as I know, this is right:

<div>
  <p>some words</p>
</div>

But this is wrong:

<p>
  <div>some words</div>
</p>

The first one can pass the W3C validator (XHTML 1.0), but the second can't. I know that nobody will write code like the second one. I just want know why.

And what about other tags' containment relationship?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Henry H Miao
  • 3,420
  • 4
  • 20
  • 26
  • 11
    Because `

    ` is a block level element, and is (supposed to be) used for displaying text, it won't allow other block level elements inside it, but only inline ones like `` and ``.

    – Bojangles Dec 06 '11 at 09:46
  • 30
    JamWaffles: That `p` is a block level element has nothing to do with it. `div` is also one and allows other blocks. – Joey Dec 06 '11 at 10:03
  • 1
    possible duplicate of: http://stackoverflow.com/questions/4967976/what-are-the-allowed-tags-inside-a-li (unflagged): any decent answer to that will answer how to read the HTML spec and thus also answer this. – Ciro Santilli OurBigBook.com Jun 17 '14 at 15:52
  • 2
    Declaring the div's style as inline doesn't work either. – Triynko Dec 14 '15 at 21:03

6 Answers6

224

An authoritative place to look for allowed containment relations is the HTML spec. See, for example, http://www.w3.org/TR/html4/sgml/dtd.html. It specifies which elements are block elements and which are inline. For those lists, search for the section marked "HTML content models".

For the P element, it specifies the following, which indicates that P elements are only allowed to contain inline elements.

<!ELEMENT P - O (%inline;)*            -- paragraph -->

This is consistent with http://www.w3.org/TR/html401/struct/text.html#h-9.3.1, which says that the P element "cannot contain block-level elements (including P itself)."

Colin Campbell
  • 2,376
  • 1
  • 13
  • 5
  • 83
    I have a habit of avoiding the specs, the most authoritative documents we have for things like this, because they aren't fun to read. +1 for actually reading them, understanding them, and using them to answer questions. – Stoutie Oct 02 '12 at 17:18
  • 3
    Is this still valid for HTML 5? The spec linked specifically references HTML 4, and [HTML 5 doesn't have a document type definition](http://stackoverflow.com/q/4053917/1157054). – Ajedi32 Jun 16 '15 at 13:33
  • 2
    @Ajedi32 Yes, [here](http://www.w3.org/TR/html-markup/p.html#p). HTML5 has renamed lots of terminology, but "Permitted contents: phrasing content" means the same as the `%inline` bit above. See also Oriol's answer. – Mr Lister Jan 18 '16 at 14:04
  • 1
    @Stoutie Right with ya, that's why Stack Overflow exists. – Captain Hypertext Oct 12 '16 at 20:39
  • But that's not consistent with div inside div being ok, by this explanation. – Ellis Jun 28 '23 at 07:24
74

In short, it is impossible to place a <div> element inside a <p> in the DOM because the opening <div> tag will automatically close the <p> element.

defau1t
  • 10,593
  • 2
  • 35
  • 47
  • 2
    Ah, this explains why there's a huge space before a div inside a p, because the p actually ends just before the div. – AaronLS Feb 19 '14 at 15:55
  • 2
    You *can* place a `div` element inside a `p` *in the DOM*, e.g. `myP.appendChild(myDiv)`. But a HTML parser won't do it. – Oriol Sep 01 '16 at 21:27
  • 1
    Dont do that. You have no idea how that will respond in future browsers. Technology is changing constantly. There may be a dynamic html parser that will make that invalid one day. The goal in web dev is to create things that have the ability to be both desireable and somewhat compatible. If you can bypass what the browser allows, its safe to say you cannot ensure that it will work forever. Just use a span guys... If you need a div, stop using the p tag. –  Nov 03 '17 at 18:37
53

According to HTML5, the content model of div elements is flow content

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

That includes p elements, which can only be used where flow content is expected.

Therefore, div elements can contain p elements.


However, the content model of p elements is 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.

That doesn't include div elements, which can only be used where flow content is expected.

Therefore, p elements can't contain div elements.

Since the end tag of p elements can be omitted when the p element is immediately followed by a div element (among others), the following

<p>
  <div>some words</div>
</p>

is parsed as

<p></p>
<div>some words</div>
</p>

and the last </p> is an error.

Nils Lindemann
  • 1,146
  • 1
  • 16
  • 26
Oriol
  • 274,082
  • 63
  • 437
  • 513
  • But if in CSS if I set div to be inline why it's not respecting that? – Sanjay Jan 05 '18 at 23:26
  • 1
    Since CSS values are applied after dom Parsing... even if we make `div as inline in CSS` its is no use, as new parsed structure is ```

    Text

    some words

    ``` is my understanding correct ?
    – Sanjay Jan 05 '18 at 23:39
  • @Sanjay Yes, looks like you are right. And moreover, during my observations, if you put inside

    and then set span's display to "block", it will be rendered as a typical block element without such an effect.

    – Andrew Naumovich May 28 '18 at 19:49
3

Look at this example from the HTML spec

<!-- Example of data from the client database: -->
<!-- Name: Stephane Boyera, Tel: (212) 555-1212, Email: sb@foo.org -->

<DIV id="client-boyera" class="client">
<P><SPAN class="client-title">Client information:</SPAN>
<TABLE class="client-data">
<TR><TH>Last name:<TD>Boyera</TR>
<TR><TH>First name:<TD>Stephane</TR>
<TR><TH>Tel:<TD>(212) 555-1212</TR>
<TR><TH>Email:<TD>sb@foo.org</TR>
</TABLE>
</DIV>

Did you notice something? : There was no closing tag of the <p> element. a mistake in the specs ? No.

Tip #1: The closing tag of <p> is OPTIONAL

You may ask: But then how would a <p> element knows where to stop?

From w3docs:

If the closing tag is omitted, it is considered that the end of the paragraph matches with the start of the next block-level element.

In simple words: a <div> is a block element and its opening tag will cause the parent <p> to be closed, thus <div> can never be nested inside <p>.

BUT what about the inverse situation ? you may ask

well ...

Tip #2: The closing tag of the <div> element is REQUIRED

According to O’Reilly HTML and XHTML Pocket Reference, Fourth Edition (page 50)

<div> . . . </div> Start/End Tags Required/Required

That is, the <div> element's end will only be determined by its closing tag </div> hence a <p> element inside is will NOT break it.

Mossab
  • 818
  • 8
  • 13
-1

After the X HTML, the conventions has been changed, and now it's a mixture of conventions of XML and HTML, so that is why the second approach is wrong and the W3C validator accepts the things correct that are according to the standards and conventions.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
geekdev786
  • 33
  • 1
  • 6
-7

Because the div tag has higher precedence than the p tag. The p tag represents a paragraph tag whereas the div tag represents a document tag.

You can write many paragraphs in a document tag, but you can't write a document in a paragraph. The same as a DOC file.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Gaurav Agrawal
  • 4,355
  • 10
  • 42
  • 61