List of Html5 Elements That Can Be Nested Inside P Element

List of HTML5 elements that can be nested inside P element?

The HTML5 spec tells us that the <p> element's content model is phrasing content. Phrasing content is defined by the spec:

3.2.5.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 (if it contains only phrasing content)
  • abbr
  • area (if it is a descendant of a map element)
  • audio
  • b
  • bdi
  • bdo
  • br
  • button
  • canvas
  • cite
  • code
  • command
  • datalist
  • del (if it contains only phrasing content)
  • dfn
  • em
  • embed
  • i
  • iframe
  • img
  • input
  • ins (if it contains only phrasing content)
  • kbd
  • keygen
  • label
  • map (if it contains only phrasing content)
  • mark
  • math
  • meter
  • noscript
  • object
  • output
  • progress
  • q
  • ruby
  • s
  • samp
  • script
  • select
  • small
  • span
  • strong
  • sub
  • sup
  • svg
  • textarea
  • time
  • u
  • var
  • video
  • wbr
  • text

  • div nested in p

    The <div> tag, like <p> is a block level element, which means that it is designed to contain it's own block of with newlines around it. Trying to nest a <div> inside of a <p> is not likely to do what you want as it doesn't make much sense. A <p> is a paragraph, and it should contain no block level elements. This question may would be related:

    https://stackoverflow.com/questions/4291467/nesting-block-level-elements-inside-the-p-tag-right-or-wrong

    Try using <span> instead, because <span> is an inline element, which is designed to be displayed inside of a paragraph. If you really do need multiple block level elements there, consider not using the <p> there at all, or using them as the inner most block level element rather than an outer element.

    Nesting block level elements inside the p tag... right or wrong?

    Syntactically, a div inside a p is invalid in all standards of HTML. Moreover, when using a conforming HTML parser, 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.

    Semantically, the correct choice depends on the content that you are marking up. You will need to show at least a sample full paragraph and possibly the content surrounding it to be sure of providing sufficient information for the correct semantic mark-up to be determined.

    However, given that both <div> and <span> are semantics free, and that CSS in no way can ever change that, if you are certain that the contents of the <p> tag truly form a paragraph, and that <span style="display: block"> gets you the presentational effect that you are seeking, then that is valid HTML and would be a wholly appropriate solution.

    Targeting descendants of paragraph p elements

    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>

    Nesting p won't work while nesting div will?

    Because a paragraph is a paragraph .. and that's how HTML is defined (and HTML is not XML).

    Any <p> (or other block-level element) will implicitly close any open <p>.

    Per 9.3.1 Paragraphs: the P element of the HTML 4.01 specification:

    The P element represents a paragraph. It cannot contain block-level elements (including P itself).


    Note that this is how the HTML is parsed and that even a <div> would have implicitly closed the paragraph!

    However, a <span> with display:block; would not have closed the <p> as a <span> is not a block-level element.

    That is, the CSS is irrelevant at this stage of the HTML processing and the CSS is irrelevant to the DOM/parser when determining if an element is a block-level element or not. Consider the case when CSS is applied dynamically or through a not-yet-loaded-stylesheet: the applied CSS does not alter the DOM.


    While the HTML5 (working-draft) specification does not include the language above in the HTML4 specification, it does go on to define a paragraph as a container for phasing content and further has a section on paragraphs.

    The accepted answer to List of HTML5 elements that can be nested inside P element? says that <p> elements cannot nest in HTML5. The key phrase from the documentation is: "Runs of phrasing content [which does not include <p> elements] form paragraphs". Furthermore, HTML5, trying to be backwards-compatible in many aspects, has a rationale on "Restrictions on content models and on attribute values":

    Certain elements are parsed in somewhat eccentric ways (typically for historical reasons), and their content model restrictions are intended to avoid exposing the author to these issues.

    This behavior is referenced from a HTML5 WG wiki entry on flow content:

    HTML5's restrictions on nesting of p elements and on what p elements may contain, are due to, quote: “peculiarities of the parser” that causes p to be auto-closed ..

    Should ol/ul be inside p or outside?

    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.

    p tag not containing ul tag

    Please see the answer from a similar question: List of HTML5 elements that can be nested inside P element?

    Only phrasing content can be in between the <p> tag and is described as follows:

    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.

    Why p nested in span leads for a block element?

    You simply cannot nest a p element inside a span element. The span element's content model should be phrasing content, which excludes elements such as p and heading elements. Since the span element's end tag is not omissible (i.e. it is required), the p element's start tag does not implicitly close the span element, so you get a validation error. However, browsers try to recover from the error, and they still render the p element as a block element.

    To avoid this type of error in the future, I recommend validating HTML code using the W3C's HTML Validator and consulting the consulting the HTML5 specification (or a similar reference) about content models.

    Why can't I nest div inside p?

    In the beginning, there was the Standard Generalized Markup Language (SGML). SGML defined some aspects of the syntax like punctuation and tags, but each user application defined parts of the syntax such as tag names, attributes, nesting.

    Decades later, SGML was simplified to create the XML standard. The way XML is used today for many application-specific data formats is similar to how SGML was used in the past. SGML and XML are essentially meta-languages - they are a syntax template for many application-specific languages.

    HTML was initially designed as an application of SGML, hence understanding the history of HTML requires knowledge of some rules of SGML. SGML was intended to be editable in a text editor, so it included many features that reduced code to make human writing and reading more convenient. Just a few examples:

    • Some elements like <br> are self-terminating, thus never have a corresponding </br> end tag.
    • Some elements like <tbody> are implicitly inserted, e.g. <table><tr><td></td></tr></table> becomes <table><tbody><tr><td></td></tr></tbody></table>.
    • Some elements like <p> cannot nest in each other, so starting one will terminate the old one: <p><p> becomes <p></p><p></p>.

    These element/tag-level syntax features are enabled/disabled through the SGML declaration and document type definition (DTD). HTML up to version 4.01 certainly had a DTD, and this was considered as the source of truth on how a parser should interpret markup code. The DTD can also tell us things like (not an exhaustive list):

    • What attributes each element is allowed to have.
    • Whether an attribute is optional, required, or has a default value.
    • Distinctions between PCDATA and CDATA, which affects how characters are escaped.
    • Exactly what elements are allowed to nest within what.

    The DTD is where we can find our answer, at least historically speaking for HTML 4.01 Strict:

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

    <!ENTITY % inline "#PCDATA | %fontstyle; | %phrase; | %special; | %formctrl;">

    <!ENTITY % fontstyle
    "TT | I | B | BIG | SMALL">

    <!ENTITY % phrase "EM | STRONG | DFN | CODE |
    SAMP | KBD | VAR | CITE | ABBR | ACRONYM" >

    <!ENTITY % special
    "A | IMG | OBJECT | BR | SCRIPT | MAP | Q | SUB | SUP | SPAN | BDO">

    <!ENTITY % formctrl "INPUT | SELECT | TEXTAREA | LABEL | BUTTON">

    The code above says that a <p> element can only contain %inline content, which is further defined as any of #PCDATA, %fontstyle, %phrase, %special, %formctrl. The definitions of the latter 4 are a set of 31 elements like <tt>, <strong>, <img>, <textarea>, etc. Notice that these so-called inline elements do not include block elements like <div>, <ul>, and so on - so in other words, <p> cannot contain <div>.

    I don't know how the details of how the SGML parser behaves in every situation, but it looks like when one element is not allowed to contain another, the first element is terminated and then the second element begins. This explains why <p><div></div></p> becomes <p></p><div></div><p></p>.

    Fast forward to HTML5, which is not based on SGML anymore. Although HTML5 is a bespoke, one-of-a-kind syntax standard, it is intended to be backward-compatible with HTML 4. HTML5 replicates the semantics of correct HTML 4 code, and additionally mandates a uniform way to parse erroneous markup code ("tag soup") so that all browsers behave the same. So the interpretation of <p><div></div></p> is still unchanged from the SGML days.

    For <p> in particular, the rule is explained very clearly here here:

    A p element's end tag can be omitted if the p element is immediately followed by an address, article, aside, blockquote, details, div, ...

    Also, <p> is only allowed to contain "phrasing content" (note the lack of <div>):

    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, abbr, area (if it is a descendant of a map element), audio, b, bdi, bdo, br, button, canvas, cite, code, data, datalist, del, dfn, em, embed, i, [...], autonomous custom elements, text



    Related Topics



    Leave a reply



    Submit