Consider the following semi-minimal example, paying particular attention to the paragraph elements:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<style>
h4 { display: inline-block; }
spoiler { background-color: black ; }
spoiler:hover { background-color: inherit; }
</style>
<title>Paragraphs Test</title>
</head>
<body>
<p><h4>Heading</h4>: This is a paragraph.</p>
<p>The following is <spoiler>spoilered text</spoiler>.</p>
</body>
</html>
When I run this through W3 Validator, I get one error for each paragraph:
No
pelement in scope but apend tag seen.
From line 12, column 46; to line 12, column 49
paragraph.</p>↩ <
Elementspoilernot allowed as child of elementpin this context. (Suppressing further errors from this subtree.)
From line 13, column 25; to line 13, column 33
lowing is <spoiler>spoile
I did my best to understand what the standard says on the contents of <p>: the required contents must be "Phrasing Content" which cannot be <h4>. It can be an "Autonomous Custom Element", which is a custom element with no extends option.
I don't really understand how this applies for this situation. It seems to me like any inline/block-inline element should be able to go inside <p>—the prototypical example being the contrast between <div> (block) and <span> (inline): the former can't go in, but the latter can.
In the first case, I'm explicitly marking <h4> inline. Albeit, I guess since it isn't mentioned as being allowed, I guess I'm just not allowed to do this, arbitrarily? However, in the second case, I'm using a custom element, and I'm not using extends (at least explicitly? Not even sure what it is!). Moreover custom elements are apparently display: inline by default. So why doesn't that work?
Sooo, why does the above example of putting elements inside paragraphs not work? And, how can I get what I want? (Obviously, in a way that doesn't give up semantics, like the following would: <p><b>Heading</b>...</p>, <p>...<span class="spoiler">...</span>.</p>)
Note: this is not a duplicate of e.g. "HTML tags inside paragraph <p>", which was about un-semantically nesting <p> inside <p>.
For the first line—
—you answered yourself already. Indeed,
<h4>is not listed as valid within a phrasing context, so you just can't do it. In fact, the<p>element, when it encounters a<h4>inside it, will auto-close itself first. Thus, you can't use<h4>inside<p>: if you try, the<p>will close itself first, and then when you try to close it later it fails because you're not in a paragraph anymore.The stuff you said about inline elements vs. block elements is just wishful thinking, and you knew it at the time. The standard doesn't care about the
displayof the element for this purpose, so you shouldn't either.Putting aside the wisdom of these design choices, or any exonerating historical circumstances explaining how they arose, your options are prettymuch just to use
<b>, or something more sophisticated like a styled<span>. This is exactly what you said would be admitting defeat, but the standard says no.For the second line—
—you were very nearly right. You can have "Autonomous Custom Elements" inside phrasing contexts. However, as MDN will highlight, custom elements must have a dash, per the grammar. If you rewrite your example from
<spoiler>to<spo-iler>, for example, it will work great. You might have thought a little harder when you noticed that your IDE wasn't highlighting it.This one, though, you can be forgiven for not getting immediately. The validator's error ("Element
spoilernot allowed as child") is hilariously misleading. It's not that the element isn't allowed as a child, it's that it isn't an element at all. In my view, the error message should be corrected, and so you will be submitting a bug report.