Putting <div> inside <p> is adding an extra <p> [duplicate]

From http://webdesign.about.com/od/htmltags/p/aadivtag.htm

In HTML 4, the DIV element cannot be inside another block-level element, like a P element. However, in HTML5 the DIV element can be found inside and can contain other flow content elements, like P and DIV.

I have something like this inside a form

<p> <label...> <input...> </p>

but when Rails auto-generates an error_explanation div wrapping the input, the one paragraph turns into two, and I see this in Firebug:

<p> <label...> </p> <div...> <input...> </div> <p> </p>

Also, if I just add a simple

<p> <div> test </div> </p>

the same issue occurs (JSFiddle) and it gets rendered in the DOM as

<p> </p> <div> test </div> <p> </p>

Why?

Update: I e-mailed the author of the article and she made the appropriate changes.


From the fine specification:

p – paragraph

[...]

Permitted contents

Phrasing content

And what is this Phrasing content? Phrasing content:

Consists of phrasing elements intermixed with normal character data.

Normal character data is just that: unmarked up text. Phrasing elements are:

a or em or strong ... [a bunch of other elements none of which are div]

So, <p><div></div></p> is not valid HTML. Per the tag omission rules listed in the spec, the <p> tag is automatically closed by the <div> tag, which leaves the </p> tag without a matching <p>. The browser is well within its rights to attempt to correct it by adding an open <p> tag after the <div>:

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

You can't put a <div> inside a <p> and get consistent results from various browsers. Provide the browsers with valid HTML and they will behave better.

You can put <div> inside a <div> though so if you replace your <p> with <div class="p"> and style it appropriately, you can get what you want.

Your reference at about.com disagrees with the specification at w3.org, your reference is misleading you.


While this is a rather old question, I thought I'd share my solution to the problem to help other people who may stumble upon this page on google.

As has been said, it is not permitted to put block elements inside a p-tag. However, in practice, this is not actually entirely true. The actual display value is in fact entirely irrelevant; the only thing that is considered is what the default display value is for the tag, e.g. "block" for divs and "inline" for spans. Changing the display value will still make the browser prematurely close the p-tag.

However, this also works the other way around. You can style a span-tag to behave exactly like a div-tag, but it will still be accepted inside the p environment.

So instead of doing this:

<p>
   <div>test</div>
</p>

You can do this:

<p>
   <span style="display:block">test</span>
</p>

Just remember that the browser validates the content of the p environment recursively, so even something like this:

<p>
   <span style="display:block">
       <div>test</div>
   </span>
</p>

Will result in the following:

<p>
   <span style="display:block"></span>
</p>
<div>test</div>
<p>
</p>

Hopefully this will help someone out there :)


The webdesign.about.com page is simply wrong; they probably misunderstood the HTML5 drafts. Allowing DIV inside P would cause great confusion; I don’t think it has even ever been considered during HTML5 development.

If you try to use DIV inside P, the DIV start tag will implicitly close the P element. This probably explains the things you’ve seen.

To avoid the problem, do not use P if the content contains, or may contain, a DIV element. Use DIV instead.


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.

<P> won't allow other element inside it. only <span> and <strong> element allowed.In <p></p> we can add only text related tags. refer this link to know more