I've been unable to find a definitive answer to whether custom tags are valid in HTML5, like this:
<greeting>Hello!</greeting>
I've found nothing in the spec one way or the other:
http://dev.w3.org/html5/spec/single-page.html
And custom tags don't seem to validate with the W3C validator.
The Custom Elements specification is available in Chrome and Opera, and becoming available in other browsers. It provides a means to register custom elements in a formal manner.
Custom elements is a part of a larger W3 specification called Web Components, along with Templates, HTML Imports, and Shadow DOM.
However, from this excellent walk through article on Google Developers about Custom Elements v1:
Some Resources
To give an updated answer reflecting modern pages.
Custom tags are valid if either,
1) They contain a dash
2) They are embedded XML
This assumes you are using the HTML5 doctype
<!doctype html>
Considering these simple restrictions it now makes sense to do your best to keep your HTML markup valid (please stop closing tags like
<img>
and<hr>
, it's silly and incorrect unless you use an XHTML doctype, which you probably have no need for).Given that HTML5 clearly defines the parsing rules a compliant browser will be able to handle any tag that you throw at it even if it isn't strictly valid.
Basic Custom Elements and Attributes
Custom elements and attributes are valid in HTML, provided that:
x-
data-
For example,
<x-foo data-bar="gaz"/>
or<br data-bar="gaz"/>
.A common convention for elements is
x-foo
;x-vendor-feature
is recommended.This handles most cases, since it's arguably rare that a developer would need all the power that comes with registering their elements. The syntax is also adequately valid and stable. A more detailed explanation is below.
Advanced Custom Elements and Attributes
As of 2014, there's a new, much-improved way to register custom elements and attributes. It won't work in older browsers such as IE 9 or Chrome/Firefox 20. But it allows you to use the standard
HTMLElement
interface, prevent collisions, use non-x-*
and non-data-*
names, and define custom behavior and syntax for the browser to respect. It requires a bit of fancy JavaScript, as detailed in the links below.HTML5 Rocks - Defining New Elements in HTML
WebComponents.org - Introduction to Custom Elements
W3C - Web Components: Custom Elements
Regarding The Validity of The Basic Syntax
Using
data-*
for custom attribute names has been perfectly valid for some time, and even works with older versions of HTML.W3C - HTML5: Extensibility
As for custom (unregistered) element names, the W3C strongly recommends against them, and considers them non-conforming. But browsers are required to support them, and
x-*
identifiers won't conflict with future HTML specs andx-vendor-feature
identifiers won't conflict with other developers. A custom DTD can be used to work around any picky browsers.Here are some relevant excerpts from the official docs:
W3C - HTML5: Conforming Documents
WhatWG - HTML Standard: DOM Elements
I would like to point out that the word "valid" can have two different meanings in this context, either of which is potentially, um, valid.
Should an HTML document with custom tags be considered valid HTML5? The answer to this is clearly "no." The spec lists exactly what tags are valid in what contexts. This is why an HTML validator will not accept a document with custom tags, or with standard tags in the wrong places (like an "img" tag in the header).
Will an HTML document with custom tags be parsed and rendered in a standard, clearly-defined way across browsers? Here, perhaps surprisingly, the answer is "yes." Even though the document would not technically be considered valid HTML5, the HTML5 spec does specify exactly what browsers are supposed to do when they see a custom tag: in short, the custom tag acts kind of like a
<span>
- it means nothing and does nothing by default, but it can be styled by HTML and accessed by javascript.This is actually a consequence of the accumulation of the content model of the elements.
For example, the root element must be an
html
element.The
html
element may only contain A head element followed by a body element.The
body
element may only contain Flow content where flow content is defined as the elements: a, abbr, address, area (if it is a descendant of a map element), article, aside, audio, b, bdi, bdo, blockquote, br, button, canvas, cite, code, command, datalist, del, details, dfn, div dl, em, embed, fieldset, figure, footer, form, h1, h2, h3, h4, h5, h6, header, hgroup, hr, i, iframe, img, input, ins, kbd, keygen, label, map, mark, math, menu, meter, nav, noscript, object, ol, output, p, pre, progress, q, ruby, s, samp, script, section, select, small, span, strong, style (if the scoped attribute is present), sub, sup, svg, table, textarea, time, u, ul, var, video, wbr and Textand so on.
At no point does the content model say "you can put any elements you like in this one", which would be necessary for custom elements/tags.