-
Notifications
You must be signed in to change notification settings - Fork 286
Markup » Void elements
This page provides markup guidance on void elements in HTML documents — that is, the area
, base
, br
, col
, embed
, hr
, img
, input
, link
, meta
, source
, and track
, wbr
elements — while explaining the context for the checker “Trailing slash on void elements has no effect and interacts badly with unquoted attribute values” message.
In the HTML Standard, the section defining requirements for the start tag of an element includes the following paragraph:
If the element is one of the void elements, or if the element is a foreign element, then there may be a single U+002F SOLIDUS character (
/
), which on foreign elements marks the start tag as self-closing. On void elements, it does not mark the start tag as self-closing but instead is unnecessary and has no effect of any kind. For such void elements, it should be used only with caution — especially since, if directly preceded by an unquoted attribute value, it becomes part of the attribute value rather than being discarded by the parser.
Note, in particular, the standard states the following two points about trailing slashes (/
U+002F SOLIDUS characters):
- Trailing slashes in void-element start tags do not mark the start tags as self-closing.
- Trailing slashes directly preceded by unquoted attribute values become part of the attribute value.
The following sections provide a few more details about those two points.
What the quoted paragraph above from the HTML standard is saying is that, to mark up, for example, an hr
element, both of the following are allowed:
-
Start tag without trailing slash:
<hr>
-
Start tag with trailing slash:
<hr/>
However, what the standard also explicitly states is that in the <hr/>
case, the trailing slash does not mark the start tag as self-closing.
In other words, the standard states that you can use a trailing slash in a void-element start tag for literally any purpose except to mark the start tag as self-closing.
So, for example, the following are all acceptable reasons for using a trailing slash in a void-element start tag —
- ✅ I use a trailing slash because I like how it looks.
- ✅ I use a trailing slash because I run my HTML markup through a formatting tool that’s hardcoded to add trailing slashes to all void-element start tags, without any option for me to prevent the tool from doing that.
- ✅ I use a trailing slash because I write a lot of JSX code, and JSX requires the trailing slash — without any option for me to prevent JSX from doing that — so for consistency with what I’m accustomed to in JSX, I follow that same style in actual HTML documents.
However, the following reason does not concur with what the HTML standard states —
- ❌ I use a trailing slash to mark start tags as self-closing.
For more about this, see the Promoting the right mental model for void elements section.
Consider the following two cases for marking up an img
element for the image at http://www.example.com/logo.svg
:
-
img
element without trailing slash:<img alt=SVG src=http://www.example.com/logo.svg>
-
img
element with trailing slash:<img alt=SVG src=http://www.example.com/logo.svg/>
In the first case (without the trailing slash), http://www.example.com/logo.svg
becomes the value of the src
attribute in the DOM, as expected.
However, in the second case (with the trailing slash), http://www.example.com/logo.svg/
unexpectedly becomes the value of the src
attribute in the DOM — which breaks display of the image. See https://software.hixie.ch/utilities/js/live-dom-viewer/?saved=10856 for a live demo of that problem.
And that’s why the HTML standard states that trailing slashes should be used only with caution — to avoid cases like the one above, where the trailing slash can unexpectedly become part of an attribute value.
This section provides how-to info on configuring particular tools to not add trailing slashes to void elements.
-
Prettier is hardcoded to add trailing slashes to all void-element start tags, and provides no option for users who want the choice of not having trailing slashes in void elements — though there is a highly-upvoted issue that’s been open since 2018 asking for such an option. There is a community-maintained plugin to not use trailing slashes in void elements.
-
VS Code, with the Prettier plugin installed, adds trailing slashes to all void elements. But you can prevent that — by adding the following to your
settings.json
file:"editor.formatOnSave": true, "[html]": { "editor.defaultFormatter": "vscode.html-language-features" }
-
Autoptimize can be configured to output void elements without trailing slashes, by using a filter with the
autoptimize_html_after_minify
hook — like this:add_filter( 'autoptimize_html_after_minify', function( $html ) { return str_replace( '/>', '>', $html ); } );
-
Joomla adds trailing slashes to void elements output by, for example,
$doc->addHeadLink
— but there’s an open issue asking for that behavior to be made optional. -
Symfony adds trailing slashes to
input
elements — but there’s an open issue suggesting that be changed. -
Hugo has a
{{ hugo.Generator }}
call which causes ameta
element to be output with a trailing slash. To avoid that, rather than using that call, you can instead use this HTML markup:<meta name="generator" content="Hugo {{ hugo.Version }}">
-
Umbraco Forms adds trailing slashes to
input
elements; a related issue was closed without a fix, with this comment:there is as discussed the option of taking copies of the view files, saving them on disk in the expected locations, and updating them to your preference. For Forms 10, the default theme views are shipped as part of a Razor Class Library, but you can get copies of them for reference/adapting via the documentation.
-
ASP.NET Core has a mechanism for automatically adding a CSRF token to a document, and that mechanism creates an
input
element with a trailing slash; a related issue was closed without a fix.
If you want to persistently suppress/filter/ignore the “Trailing slash on void elements has no effect” messages from the checker, you can use the Message Filtering button in the checker UI:
After you do that, the “Trailing slash on void elements has no effect” messages will be persistently filtered out for all future documents you check.
When using the checker from the command line, you can suppress/filter/ignore the “Trailing slash on void elements has no effect” messages using the --filterfile
or --filterpattern
command-line options.
And when running your own instance of the checker service, you can suppress/filter/ignore the “Trailing slash on void elements has no effect” messages using one of the several different mechanisms provided.
When learning about HTML, teaching about HTML, and designing HTML tools, it’s important to have and promote the right mental model about how HTML actually works.
And the way HTML works is that there’s a discrete set of void elements, hardcoded into HTML parsers, and people who write HTML must learn and remember which elements those are — without any trailing slash needing to be added to those elements to indicate they are special.
Using trailing slashes in void elements (and teaching others to use trailing slashes, and making your tools output trailing slashes) promotes a misleading mental model of HTML where the trailing slash looks like it has some special significance — when in fact, as the HTML standard says, it’s “unnecessary and has no effect of any kind”.
For more explanation, see the following: