Relaxing author requirements to allow arbitrary content in `span`

In today’s web development it is common to build reusable components (the exact technology matters little) that may accept arbitrary children or parents. This means that the element used to implement this component needs to be as neutral as possible. For this, span is typically preferred. It would be possible to use div but it has downsides, notably its default block styling and the fact that it will close p if the tree is serialised to HTML.

The only downside to span is that it is considered an error as per Restrictions on content models and on attribute values. While it works perfectly well, developers are then dismayed to find out that the validator disagrees with them. Here is the example that prompted this post but it is not at all the only one, I’ve seen this complaint crop up several times over the past month. It’s a shame to get developers to fix something that’s not a problem.

This rule is meant “to avoid misuse of elements with defined meanings” but span “doesn’t mean anything on its own” and simply represents its children.

I would therefore suggest changing span's content model to take flow content instead of phrasing content.


If it works perfectly well in practice, then it would make sense to file an issue directly on HTML 5.2

I understand that, but I thought that a community discussion might be a good idea.

I think a community discussion is essential for this question.

But the community are welcome, and encouraged, to discuss issues in the Working Group. Having them on github is meant to facilitate that.

If something clearly needs a lot of effort, e.g. because it has no implementation, or doesn’t have a proper specification, then it will almost certainly be marked as “needing incubation”. But where it’s a case of deciding whether to make a spec change that has implementation experience, I’d generally recommend raising the issue - although of course discussion elsewhere, including here, is also reasonable.

[sorry, this is getting a bit meta…]

In other words, make the SPAN a more generic container that could be used as both SPAN and DIV.

Indeed, this works at least in Firefox, Chrome, IE11, and Edge: SPAN can contain block-level elements like P and DIV, and that’s not affected by browser’s HTML-error-correction mechanism. (But otherwise we could just introduce a new generic element instead of reusing SPAN, so there is a solution anyway.)

Regarding your linked example (the react-typewritter discussion), I’m not sure I understand how changing <span>’s content model would fix their issue. They want to be able to nest <p>s inside their component, but at the same time, they want to be able to have any element as parent.

But that is impossible! If a component nests <p>s, then it itself cannot be nested in, say, a <p> or a <h1> element. Instead, it must be nested in an element like <div> or <section>. This issue it unrelated to whether a <div> or <span> is used as a basis for the component, I think.

To clarify, for the use case of having a neutral element as a basis for a component, neither <span> nor <div> can satisfy all requirements, and the only workaround I can think of is to use the Shadow DOM. And since Shadow DOM currently isn’t widely supported, component authors have to define limits, e.g. if they want their component to be able to have any parent, they just cannot nest <p>s or other block elements.

“There are limitations” and “That is impossible” are two different notions. The likelihood that you would want arbitrary parents and children at the same time are relatively slim.

This does not solve the general problem that p sucks. The problem it solves is that of reporting an error that isn’t one.

I think it’s worth checking if there are any accessibility concerns with changing this. I’m particularly wondering around screenreaders which may have expectations about phrasing vs flow content.

It’s always worth checking, but a screen reader that relied on this being correct would likely be a rather poor screen reader as it would run afoul of numerous issues in the real world.

I have not noticed any issue with screen readers. <span> elements are typically not included in the accessibility tree. I always thought that the span error was a parser constraint? If parsers don’t do anything weird, then it should be fine.

1 Like

@robin Developers would like to avoid validation errors, yes. But the main question is, “are they misusing the <span> element?” To answer that, we need good use cases, which demonstrate that nesting block-level elements in <span> can be a valid pattern.

The provided example needs clarification; it is not clear what exactly they are trying to achieve. Their intent seems to be using <span> as a basis for an inline-block component. Does that sound right?

You don’t need more use cases than already exist. The development process is simple:

  1. I need a (sufficiently) generic container.
  2. We have div and span.
  3. div has the wrong default rendering, span is perfect.
  4. Oh, the W3C people are telling me it’s wrong.

This is not about developers wanting to avoid validation errors; it’s about the validation error being unjustified. Validation guides behaviour, it’s there that lies the onus of proving it is useful.

I read the topic and still I don’t catch the issue causing it, but that’s probably because I didn’t look thoroughly enough at the original example.

What I understand is that you need a span generic element because its parent element can be everything.

This means that you are not going to redefine the content model for span only. Because if you have a tree like this

+ span
   + p 

then you are going to state that, with enough nesting depth, anything can contain anything. Which subverts the content model concept itself, at least when it comes to more generic situations. I think the error is in the fact that you have too little control over the outer container. If you had a div generic container and forced its content to have at least a p element, everything could work in a more consistent way IMHO.

div […] has downsides, notably its default block styling

This downside can be solved by CSS I suppose, at least if IE<7 Support is not your primary concern.

Content models are shallow by definition, so what you state is not the case. There is no “subversion”. The example you give could not be produced by parsing.

I think the transparent content model would be more appropriate. @leaverou proposed a concept for <group> a while back.

It’d be nice to have a universal wrapper element for things like being able to anchor UI components around unknown content such as when dealing with user input in CMSs.

My understanding as a lay person was that DIV and span did very different things.

DIV was for all intents and purposes block level layout. (equivalent to sectional/paragraph formatting on a word processor)

SPAN was for inline-formatting ( typically the character formatting options on a word processor.)

Having something that was an intermediate, might be useful, but isn’t that what a DIV with inline block is for?

(Aside: HTML currently seems to lack the ability to flow around an arbitrary block in the way that some Desktop publishing programs can. Granted this isn’t a major issue given the direction mobile content is going -> i.e flexible.)

I would certainly support a <group> element that is default inline-block. The uses would be widespread and obvious.

1 Like

I’d rather it were display: contents, but that’s an entirely separate discussion.

Had to look that one up - I’d never heard of it before. Yes, that would certainly be the better option.

A <group> or even <fragment> element with display: contents; would be so incredibly useful - I’ve been wishing for something similar for a long, long time.