2

It is not valid to nest a block level element such as p directly inside an inline element such as b.

However, using css such as display: inline-block or position: absolute is can be conceptually sound to have block level content inside an inline context.

Browsers largely accept such block level elements in an inline element, but under some circumstances, the invalid construct causes real problems:

<p><span><p></p></span></p>

The above example would not be parsed as three nested elements; the innermost <p> would instead implicitly close the outer <p>, regardless of CSS. You can see a jsbin demo of that.

Is there some way of using intermediate elements to validly place block level elements in an inline element?

If that's not possible, is there an invalid but functional workaround for the majority of cases (preferably also for the tricky <p> tag)?

To be clear, I'm looking for a generic solution that doesn't require invasive changes to document structure (i.e. "just use span everywhere, for everything" is not an attractive solution). I want to embed an unknown (dynamically generated) document fragment with potentially block-level content - so fixing the fragment to exclude block level elements is infeasible.


Related: (address the validity of direct nesting mostly)

Maroun
  • 94,125
  • 30
  • 188
  • 241
Eamon Nerbonne
  • 47,023
  • 20
  • 101
  • 166

2 Answers2

1

The W3C validator (in XHTML mode) lists the following elements as valid between a <span> and a <p>:

  • object
  • ins
  • del
  • map
  • button

A page using these as inline-to-block spanners validates in XHTML Strict, but not in HTML 5. Of these tags, I would favor object, since it has the least semantic baggage.

HTML 5 seems to have discarded the inline vs. block distinction in favor of a more complex system, in which there are several different categories of element, and which children an element can have depends on what its ancestors are. Of these elements, ins, del and map now accept the same kind of children that their parent element accepts, and button only accepts "phrasing content" (the closest thing to inline elements). The error message for object doesn't make much sense, but as near as I can gather, it's inheriting the parent element's restrictions while also imposing some restrictions of its own.

As near as I can tell, there's no way to escape from phrasing content once you're in it (short of an iframe and a new document), so the answer to this question is no, can't be done in HTML5 (as of this writing).

Brilliand
  • 13,404
  • 6
  • 46
  • 58
  • That said, I think a native inline-block container element is sorely needed; anything with `display: inline-block` turns into a semantic mess otherwise. – Brilliand Apr 19 '13 at 19:37
  • yeah, it's a weird ommission, isn't it? – Eamon Nerbonne Apr 20 '13 at 13:46
  • It should be noted that it's not just a simple matter of declaring an element to be inline but accepting blocks itself. Since HTML isn't XHTML, there are some rules about self-closing elements, and in particular, `

    ` closes when a block level element is encountered. Currently, parsers *always* do that, and the hypothetical inline-block element would make that considerably more complex. Similar issues exist for tables and quite a few others.

    – Eamon Nerbonne Apr 20 '13 at 13:50
  • The nesting problem is certainly not an impossible problem to solve, but given this analysis and the likelihood these changes were made for simplicity, I'm not holding my breath for a real solution other than using XHTML, and that seems to be a low priority at the moment. – Eamon Nerbonne Apr 20 '13 at 13:52
  • It is important to note that while `

    ` (**for example**) is *formally* valid in XHTML 1.0, this is only because **DTDs are incapable of expressing the rules here**. The [text of the specification](https://www.w3.org/TR/html4/struct/text.html#h-9.4) says *The INS and DEL elements must not contain block-level content when these elements behave as inline elements.* so this kind of nesting is formally valid but still non-conforming and wrong. Similar rules apply to at least most of the other cases. The reason that it is invalid in HTML 5 is because 5 abandons DTDs.
    – Quentin Mar 25 '18 at 13:41
0

Semantically is wrong and I think HTML5 allows block elements inside < a > tags only (as far as I know).

In other words, you can make your html code work as you want by changing the css, but that doesn't mean your html code is correct. You also should consider SEO and Accessibility issues that will arise.

m.spyratos
  • 3,823
  • 2
  • 31
  • 40
  • I think the bulleted list was a list of links to related questions, and is not intended to be answered here. – BoltClock Jan 18 '13 at 12:14
  • I replaced "See also" with "Related" to clarify that these are *not* questions I'm asking. It is clearly not valid for inline elements to have block level children; these related questions examine that in sufficient detail. – Eamon Nerbonne Jan 18 '13 at 12:48
  • Thanks Eamon, but still this is the answer to your questions. I wouldn't go down the road to suggest you an invalid way (if exists) to do this. – m.spyratos Jan 18 '13 at 13:23
  • That's not particularly helpful, nor is it the only answer possible; (I'm interested in descendants, not necessarily children). – Eamon Nerbonne Jan 18 '13 at 13:48
  • Maybe you should reconsider what you are trying to do. Is this the only way to do it? Maybe someone else can help you then... With my answer I am trying to prevent you from coding wrong, which you shouldn't. – m.spyratos Jan 18 '13 at 14:02
  • Sure, and I'd like to accept an answer - but the child vs. descendant distinction matters; and there's a long tradition of invalid html (including this site, for instance), so telling dangerous errors from merely unfortunate errors also matters. – Eamon Nerbonne Jan 18 '13 at 14:12