HTML provides two general elements, where div
is a natural block element, and span
is a natural inline element. All other elements are similarly assigned to be a natural block or inline.
Now, while both can be made by css display
to be any of inline
, inline-block
or block
, they are still treated for enclosure purposes as their natural selves, hence the warning messages. Leopards and spots sort of thing.
However, css is only meant to be for making what an element looks like (presentation), but not actually be like (functionality), so it doesn't change an element's basic nature, though that gets very fuzzy in practice. A span
made block
becomes a bully that kicks everything else off the line, which is very un-inline
sort of behaviour.
So, to mitigate against possible conflicts between their natural and css-induced behaviours, it is better to allow:
div
or any natural block tag to only ever be block
or inline-block
.
span
or any natural inline tag to only ever be inline
or inline-block
.
This will also mitigate against tending to build page structures that will likely end up churning out error and warning messages.
Basically, NEVER embed a natural block tag inside a natural inline tag, at any depth.
Why there is a really a distinction is perhaps due to a simplistic idea of what HTML was going to be used for when it was first dreamed up.
Certainly, framework makers got around a lot of these what-to-embed-where problems by just using myriads of div
s everywhere, and 'divitis' was born, and still alive and well in every framework. Just have to press F12
in a browser on almost any commercial web page and drill down through a dozen div
s. This very page has 15 unbroken levels of div
s.
It is not hard to see why just settling on div
s made sense. For example, a p
tag may have a bunch of links to various sites, and that is ok because inline links are allowed in a block p
. However, if not wanting to have query variables visible in those urls, then button
s are required. If only one, then the p
can be put inside a form
, as a p
cannot contain a form
.
The formaction
attribute on a button can be used to target a url other than the form default, but it still does not allow independent forms, each with their own set of hidden inputs. A button can use the form
attribute to use it with a form that isn't an ancestor, but it can get messy to keep track of.
For multiple links to different sites to appear as part of one paragraph though, the only way is to use a div
instead of the p
and then wrap each button
in its own form
set to inline
. Most frameworks have to cope with so much more complex scenarios that nested div
s are the only way to go.
It meant that they really only had to manage one tag per purpose and manage it as if it was an isolated environment. So what was meant to be an occasionally-used functional grouping tag became the web's Lego block. And none of them are going to risk breaking their frameworks by converting to HTML5 semantic tags in a hurry. In the end, semantic tags only really work for fairly static content rather than rich interactive sites.