In HTML, which element cannot include some other specific elements?
html
Solution
Are you talking about HTML5? Since that spec is supposed to supersede any other at this time, we'll stick with that.
I'm not going to go through each individual element, but if you need to look something up, here is the reference:
http://www.w3.org/TR/html5-author/
The section that talks about "Content Models,"
a description of the element's expected contents
is here: http://www.w3.org/TR/html5-author/content-models.html
You can see some examples in the specs for specific elements:
http://www.w3.org/TR/html5-author/the-html-element.html#the-html-element (the `html` element):
A `head` element followed by a `body` element.
Specific Examples
- http://www.w3.org/TR/html5-author/the-a-element.html#the-a-element
- http://www.w3.org/TR/html5-author/the-span-element.html#the-span-element
- http://www.w3.org/TR/html5-author/the-br-element.html#the-br-element
`a`
We learn from the first link (on the `a` element) that its content model is Transparent, but only if there is no Interactive Content descendant.
By looking at the definitions of "Transparent," a we see that `a` inherits its Content Model from its parent. That means that your initial definition is incorrect and `a` can indeed contain a `div`, but only if its parent can. The docs above even include an example of nested "Transparent" content model elements.
Since `a` cannot contain any "Interactive Content" model elements, it cannot contain a `button` element at all. This makes sense because there would be a conflict as to which element actively responded to a click.
`span`
When we take a look at the second link, `span`, we see that its Content Model is "Phrasing Content," which is basically text and markup for paragraph-level text. The definition is not entirely specific, but it does include a guideline:
Most elements that are categorized as phrasing content can only contain elements that are themselves categorized as phrasing content, not any flow content.
Since `div` does not have a "Phrasing Content" model (it's "Flow Content,") `span` cannot contain it. This means that the `span` should follow the above rule and only contain any other "Phrasing Content" elements and/or embedded content or Text. If the above rule is broken, it will be listed specifically on the "Content Model" description of the element (remember the special rules for the `a` element about "Interactive Content.") `span` has none.
`br`
The third link, `br`, says that the Content Model is "Empty." Unfortunately, the W3C does not include a specific definition for that, but I think it's fairly obvious: it can contain no descendants at all. Not even text nodes. Any "Empty" Content Model element does not have a closing tag (you would write it as `<br>` not as `<br></br>`).
Your Questions
Are the rules above accurate?
First rule (inline vs. block)
What you've said is misleading. HTML has no concept of `inline` vs. `block` elements. These are CSS styles. Most browsers have a default setting for an element's `display` style as `inline` or `block` depending upon whether it is a "Phrasing" or "Flow" Content Model respectively (as a general rule; there is nothing hard and fast about that) or just traditionally.
If you want to say that "Phrasing Content" elements cannot contain "Flow Content" elements then you would be correct because that is in the spec specifically. This also works practically because `span` cannot contain `div` (as you indicate).
However, saying that `a` should not include any `div` is wrong. `a` can include `div` as long as its parents can. If `a` is contained in a `span`, it cannot contain `div`. However, if `a` is contained in `body` or another `div`, it can.
As for Browsers "being forgiving," this is all very convenient for many developers who cannot take the time to create valid HTML, but it can be a pain for those of us who do want to take the time. Browsers usually don't alter the "HTML structure" as you say -- what they alter is the DOM. Also node that the web vendor spec is a little different from the "Web author" spec I posted above, but we are the authors.
Second Rule (`p` containing `p`)
This is true because of an important point I left out: `Context`.
From the `p` element spec:
Contexts in which this element can be used: Where flow content is expected.
Since `p` is "Phrasing Content," that means that another `p` cannot be put inside of a `p` because "Phrasing Content" is expected, not "Flow Content."
Any Other Rules?
The HTML5 spec has a huge number of elements, so I simply cannot go into all of those details here. I went into details about `span` and `a` contents vs. `div` as well as `p` because you brought those up specifically. Look at how long this answer is!
What you are going to need to do is take a look at whatever elements you have questions about in the spec itself. Take a look at the Context and Content Model sections to see whether or not your use of the element is valid.
In Summary
Refer to the spec when you have a question about how the element should work. To answer questions about how you should use the element (with respect to its container and contents), look at:
- Contexts in which this element can be used:
- Content model:
This tells you what can contain the element, what it can contain, and when.
If you have questions about whether your HTML is valid, you can always use the very nice W3C markup validation service:
http://validator.w3.org/
If you are using Chrome, you can take a look at the Chrome Inspector (F12) and compare the output DOM to the source HTML itself. You will notice for example that Chrome will automatically close nested `p` tags when it generates the DOM.
Problem
For example, in HTML 4.01, 1) inline elements in general cannot include other block elements (example: a `<span>` or `<a>` should not include any `<div>`.) But this rule is more forgiving, as most browsers won't alter the HTML structure like in rule 2 below. (And many browsers nowadays will handle the desired result of a `<div>` being inside of an `<a>` tag.) 2) `<p>` elements cannot include any `<p>` element. If any `<p>` appears before the closing of a previous `<p>` element, then the previous one will be immediately closed. This rule seems more strict as it alters the structure of the HTML document. Are the rules above accurate, and are there other rules stating an element cannot include other elements? (as offsprings).