After learning a little bit more about web accessibility last year I had been exploring some of the less common HTML elements, and making changes to this website, like wrapping the text of the posts on this blog in
<article> tags and adding a
<main> tag in the website’s layout templates (this website is built using Eleventy).
I had previously done some work to make sure that
<figcaption> elements were layed out nicely for images with associated captions, and I had been impressed with various Recurser’s implementation of footnotes or sidenotes1, and have been thinking it would be interesting to see what other interesting layouts were possible with just HTML.
I could, element by element, continue to add support (mostly by making CSS updates for each element to fit in with the rest of my style choices) as I came across specific needs for them, but not one to shy away from an exhaustive exploration, I decided to write this post and attempt to use every element.
A goal of the post, was to avoid delaying other future posts with CSS updates on a previously unused element, but in reality it took a year and a half to make all the updates for just this post! I am using the MDN Web Docs list of HTML elements as a reference which has more than 100 tags divided into a few categories, which I will also use in this post. Many of the tags like
<html> don’t make sense to include in the text of a blog post, but if you’re viewing this post on patrickweaver.net, then every one of the elements is used somewhere on this page.
I didn’t have to make any changes to the
<html> tag for this post, but one thing I don’t always remember to include is the
lang property (in this case
I wasn’t familiar with the
<base> tag before writing this post, though I’ve now added one with relative links to my layout templates. This caused a few issues with things like local development, and relative links, though they were easily resolved. The rest of the metadata tags are familiar and were already here.
Like the Document metadata tags, in the layout, though it was interesting to read the documentation and learn about attributes, like
onbeforeprint that provides functionality I’ve used more hacky methods to accomplish previously, and
onblur, whose primary utility seems to be annoying popups.
Headers and Document Organization
When I first looked at the list I assumed that
<address> would be designed exclusively for mailing addresses, but was surprised to see that it can be used for email addresses, and even links. I updated the email address on the About page of site site, but I’ll add an
<address> below also:
As I mentioned above, I updated the blog post page template to use the
<article> tag, but reading the documentation, I’m now wondering if it would fit on every page of the site.
I’m now using
<aside> elements, which represent,
a portion of a document whose content is only indirectly related to the document’s main content, to wrap around my footnotes at the bottom of this page (though I may try to style them as sidenotes in the future). The current design of this website doesn’t have a
<footer>, but I’ve added one to this blog post, and while I had a
<header> element on the page header previously, I now know that more than one is acceptable so there is one around the header section of each blog posts as well.
As part of the style update and cleanup of this site that inspired this post I realized I was often using headers with incorrect hierarchy, which I cleaned up. Though I never reached 6 levels of headers, the closest I got was
<h3> in some of the blog posts with multiple sections and subsections.
How to use top level headings
It is a little bit unclear how to use
<h1> tags in a post like this from just the MDN documentation. This tip from the W3C suggests different implementations for pages with standalone, or collection content, which would make it difficult to use the same templates and styles for different pages on this site.
How I decided to handle it
Before writing this post I had updated the site to use
<h1> for the name of the site (my name) at the top,
<h2> for the section name, for this page, “Blog”, and
<h3> for the title of what would be the
<article> on a page. However, after reading the documentation and the tip above, I decided to update the hierarchy and use
<h1> for different things on different pages, and use classes for styles, which is probably more in line with the separation of concerns of HTML and CSS (which means this paragraph is below an
Sometime between when I started this experiment in early 2022 and when I published it in Summer 2023
<search> were added to the MDN documentation (which I realize is not the official spec). I’ve added an
<hgroup> around the heading of this section, with a subtitle
<search> is a semantic element that indicates that an input can be used for search, not for search results (with the exception of quick results that populate within a form ). While a
<search> element that contains a
<search> element anywhere else, neither MDN’s header search, or google.com use it in 2023.
<main> element was one of the initial curiosities that led me down the path of reading about and implementing every element, though it wasn’t until I read through the MDN list that I added a
<nav> element around the menu at the top of this page. I’ve added
<section> elements to this post, but I’m not sure how often I will use them elsewhere. One reason is that it makes it harder to mix and match HTML and markdown with visually clear nesting in the document where I am writing this post.
I had previously used
<blockquote> for embedding tweets into blog posts, but for this post I decided to add styles for standalone quotes. I didn’t know about the
cite property or
<cite> element until reading the docs more closely:
<dt> are elements that, after finding out about them when first looking into more obscure HTML elements, I was very surprised to have not known about sooner. Although, it’s unclear from the documentation whether lists like the links on the current version of my portfolio page should use
<dl> (I’m currently using
<ul>). I am curious how
<ul> became part of almost every “Intro to HTML” class, but
<dl> is relatively obscure. It’s also strange that
<ul> have default margins, but for
<dl> the margin is on
HTML list elements
- Description list
- Ordered list
- Unordered list
<div> has acquired a bad reputation on the modern web due to overuse, so I was surprised to be using relatively few
<div> elements, though once I started using elements that I wanted to style together, I ended up with around 20. It shows how unnecessary most
<div>s probably are, though this site has minimal generic “sections”.
Among the first more obscure elements that I added to this site were
<figure>. I was adding some blog posts that had originally been published on Medium, and wanted to add captions below images in a web-semantically correct way. Though after reading the documentation, which says
<figure> can be used for,
image, illustration, diagram, code snippet, etc., I realized that there are a lot of places where I currently have code blocks that I could be using them.
I have always liked
<hr> elements a lot, but I’m never sure when to use them. The documentation says,
While it may still be displayed as a horizontal rule in visual browsers, this element is now defined in semantic terms, rather than presentational terms, so if you wish to draw a horizontal line, you should do so using appropriate CSS which made me revisit the
<hr> styles on this site and I decided to include an emoji in an
hr:after rule, though I should check how that works on a screen reader.
The items in the (inline styled) lists of elements on this page are of course
<li> elements, though I had never looked at the documentation until now. It’s interesting that the same
<li> element is used in both
<ul> lists, with quirks like
The value attribute has no meaning for unordered lists, but is not used to wrap the
<dd> elements in a
I had not encountered
<menu> before writing this post, and I was initially surprised that it survived to HTML 5 (while
<menuitem> didn’t) because modern browsers treat it as essentially a
<ul>. Researching further on Wikipedia I read:
<ul> are some of the HTML elements I used in my earliest web pages, and more recently I try to use
<ul> with CSS in places that are semantically lists, but might not be styled like a traditional list.
I was surprised not to find more guidance on using
<p> tags on the MDN docs, something I wonder often when adding non long form text to a website is, “is this really a paragraph?” But, it seems like as far as HTML is concerned, if it’s not a heading, then probably!
Before reading the documentation I had really only considered using
<pre> tags along with
<code> tags for code blocks, but the example used on MDN is used to show how
<pre> can display meaningful whitespace for things like:
Inline Text Semantics
As with other very common tags I was curious to get to the documentation for
<a> to see if there was anything I was unaware of, or had been using incorrectly. I was surprised to discover that
<a href="#">link</a> links to the top of the page after years as just using it as a placeholder when I didn’t know the URL yet.
<abbr> seems likely to be the least used tag, especially because the MDN documentation doesn’t make a great case for it
the purpose of this element is purely for the convenience of the author.
The distinction between
<strong>, as the docs have it, is not what I had previously thought (that
<strong> was the HTML5 replacement for
<b>). I think the distinction is more nuanced and overlapping than the technical nature of the documentation is really able to convey. The way I will probably explain it to other people in the future is that, for the most part, you should use
<b> for single words (or compound words), and
<strong> for whole sentences or phrases. This is more a rule of thumb and bypasses the actual distinction. The documentation reads:
But I can’t think of many instances where I would want to draw attention to a word, where that word is not more important than other words. The recommendation seems to be from a reality where, for the most part, all words are of equal importance, but deserve different amounts of attention, which doesn’t seem very common.
I’ll probably think of
<b> from now on as the HTML tag with a similar effect as the quotation marks used for “emphasis” you might see on signage that can cause intergenerational confusion.
<bdi> is a tag for a concept that I hadn’t considered until now, text whose direction might (or might not) differ from the direction of the surrounding text. The examples on the documentation are all names, but could stand in for any user inputted text. In the future I will probably try to wrap any tags, like the ones controlled by the input below, that might contain arbitrary user inputted unicode characters in a
<bdi> tag just to be safe.
Hello, , thanks for reading!
<bdo> I will probably use less often because I don’t work with RTL languages often, but it is still good to know how to handle small amounts of RTL text, like this link to the page for HTML on the Farsi Wikipedia: اچتیامال.
<br> is interesting to me, because for a time (a long time ago) it seemed to be as misused as
<div> has been recently, but, as CSS has gotten more robust that is probably less often the case; though I wonder if it is still taught early in HTML classes. It’s interesting that the example use case in the docs is poetry because it makes me wonder how the grey area between a paragraph and a standalone line was considered in creating the HTML spec. It also seems like a
<pre> tag might be a better fit in some cases.
<q> are interesting because they try to add HTML semantic elements for meaning that is also conveyed by visible punctuation in most languages. It’s the kind of redundancy that underscores repetitiousness of working with computers (the default style for cite uses italics while
q adds quotation marks not in the text.).
I’ve clearly used many
<code> elements in this post so far, but reading the documentation made me wonder whether the recently released Markdown support in Google Docs uses
<code> for text, but on inspecting the HTML of a Doc, I remembered that
<canvas> is used to render the document now.
Occasionally the MDN documentation examples are difficult to mentally translate to real-world use cases.
<data> is one of these, where the only examples show a
<data> element with a
value property with product IDs wrapped around product names In that case the IDs seem either, user facing, in which case it would probably be better to display them to the user, or non user facing, in which case, I’m not sure who the “data” is for. Interestingly,
<data> doesn’t seem to appear in the W3C HTML5 specification.
<dfn> is another strange element because it seems like it is misnamed, as it wraps, not the definition of a term, but instead that term within the definition. It does only seem to have been part of the never officially adopted HTML 2.0 proposal, and it exemplifies the academic nature of the early web. The HTML Tags: Past, Present, Proposed page on martinrinehart.com defines HTML 2.0 as
There never was an HTML 2.0 standard, but these all shaped browser development in the late 20th century with references to several RFC documents.
<i> bring up similar usage questions as
<strong>, but in my opinion with even more nuance, especially, as the documentation notes, with other more specific tags like
<cite> that also by default italicize text in most browsers. The rule of thumb from above also for the most part fits here,
<em> for single words, and
<i> for sentences or phrases, though the examples in the documentation seem to mostly use
<i> for drawing attention to potential confusion, as in,
The word the is an article.
<kbd> is another tag that makes me wonder about the conceptual boundaries of the usage of the tag. It is intended for specifying keys on a computer keyboard, for example: to type the
< character used for (the non escaped) version of the tags in this post, I press Shift + , (the styles here on
<kbd> are applied through custom CSS). But I’m curious if it would also be appropriate to put a
<kbd> around something like Right click (in this case I used
<mark> is interesting because it suggests a 2-way authoring web that was originally envisioned, but failed to come to fruition, with usage notes like,
Think of this like using a highlighter pen in a book to mark passages that you find of interest. The yellow here is the default style in all major browsers.
<ruby> all relate to rendering “ruby” or “agate” fonts, which are the smallest legible text used in print. They are used in HTML to,
provide pronunciation, translation, or transliteration information for East Asian typography. Because I don’t read any East Asian languages, I’ll use the same example as the MDN docs do below. Interestingly,
<rp> is used to hide parentheses characters, which are included in the source. It’s surprising to me that there is an element to hide these characters in a very rare instance, but we still rely on CSS to hide content visually (but still show it to screen readers).
<s> is the strikethrough element, which should be used to indicate text that is not accurate or relevant, but was previously. Along with
<menu> it is one of two elements (or according to MDN 3 with
<u>) that were deprecated in HTML 4.01, and un-deprecated and redefined in HTML5. The redefinition changes the use of the tag from presentational, which should now be achieved with CSS, to relevant to the context of the text. However, some screen readers don’t announce the strikethrough, which seems potentially confusing. I’ve added the CSS recommended by the MDN docs to my website, so the strikethrough should be announced here.
<s>is used for presentation
- HTML 5:
<s>is used for removed text
<samp> is another element I wasn’t aware of before reading the MDN docs. It is used for rendering the output of a computer program, which I had previously just used
<code> for (I just updated my Raspberry Pi blog post to use
<samp>). Another example is below:
<small> is used to render smaller text, which is something I would usually have done with CSS. The MDN docs don’t provide much clarity about which strategy to use:
Authors are encouraged to use their best judgement when determining whether to use . I will probably continue to use CSS for the most part since the effect seems to be presentational for the most part.
<small> or CSS.
<span> is a very familiar element, but reading the documentation made me wonder for the first time why HTML and CSS allow contradictory element styles like a
<div style="display: inline" />
<span style="display: block" />. Though the
<div> breaks the parent
<p> tag, while the
<span> does not.
<sub> (used for footnotes here) and
<sup> (used in the equation below) are more elements I probably have used the CSS implementations of previously (though it is appropriate for presentation only super or subscript.)
<time> seems like a helpful element for creating semantic HTML, but even Google doesn’t seem to use it in search results. I’ve updated the dates on my blog posts to use it.
<u> has probably my favorite quote from the MDN docs,
Most of the time, you actually don’t want to use Their strongest recommendation seems to be indicating spellling errors.
<var> is a way to indicate semantically that a string is a variable for either math or programming. For example, rendering the pythagorean theorem uses both
<sup>: a2 + b2 = c2.
<wbr> was also a new element until now, but it solves a problem I have hit many times before, breaking long “words” at certain points, specifically URLs. If I put a
<wbr> element at clear break points in this URL: https://www.patrickweaver.net
Though including hyphen characters in the URL also creates clear breakpoints in modern browsers. I did have to wrap the URL above in a special scrollable
<p> to prevent it from breaking the layout of the rest of the page.
Image and Multimedia
<map> are elements that I hadn’t been familiar with previously, even though I had made a few image map type websites in the days before CSS 3. It seems like an indication of how seldom they are used these days that the tools for debugging the boundaries of
<area> elements are hard to use. One
<area> border at a time will display while using tab focus, but styling the elements does not work (unless there is a
display hack I couldn’t figure out). It’s also somewhat strange that
<area> is essentially an
<a> with a shape.
<area>s on each tag linking to MDN) of a handwritten HTML document I made for June 3rd’s HTML Day Freewrite in SF.
<audio> is one of the classic multimedia HTML 5 tags so I’ve used it before, but thinking about it now, it’s surprising I don’t see them more often in the 2020s. I would guess that there are more in use than I thought, for example, the Bandcamp player uses a hidden
<audio> element even though the UI is a custom mix of
<div>s inside a
<table> oddly enough.
<img> is of course one of the first elements I used, but I was curious what properties could be used with it that I might not have heard of.
srcset, used for specifying multiple sizes of the same image to load at different screen resolutions, was one of those. I’ve created a demo below, which goes against the spirit of
The image below has 3 images provided to its
- A yellow background and a monospace font that is 300 pixels wide and should render when the page is less than 520 pixels wide
- A blue background and a serifed font that should render when the page is between 520 and 800 pixels wide
- A green background and a script font that should render when the page is greater than 800 pixels wide.
I have tested it, and it does work, but it takes a lot of forethought to make sure that you will be able to load the correct image. Things like the browser’s cache, and scaled displays will change the behavior. If you want to see the effect you will probably need to load the page in a private window on a non scaled or “retina” display.
It’s interesting that while both
<video> are less widely used than
<img> even after their introduction in HTML 5, the distribution of videos online seems to be centralized, mostly on YouTube, while audio is more decentralized, with people serving individual files when distributing things like podcasts, even though the audio player that is often used is not on the web.
One reason for this may be that there are still some quirks with
<video> elements. For example, there is a
<figcaption> accompanying the video above, but when I initially tried creating the element with a self closing tag it did not render. Also, as I’m writing this, Safari does not support the video at all, likely because of the development server I am using not supporting the “Range” request header. I am curious to find out whether the hosted version of the site (on GitHub pages) will support playing the video in Safari. I thought that I might have a similar issue with
<track>, but that just turned out to be me not setting up my Eleventy build correctly for
It is somewhat surprising that
<object> have not been deprecated since most of their uses have been superseded by specific tags like
<iframe>. Maybe eventually they will be, or they will just live on in the name of backwards compatibility.
<iframe> it’s also interesting that the very 90s name “iframe” (“inline frame”, not “iPod Frame” or something, and I was surprised to learn does render
display: inline) has survived while
<frame> was deprecated in HTML 5. I thought that
<iframe> might be a way to force the
srcset example above to render the smaller images on a high DPI display, but even at 150px wide on my device the large image still renders:
<picture> is a tag that is, with
<source> actually intended for layout tricks like the
srcset experiment I tried above, rendering different versions of an image in different situations. The image below should show an icon of a computer when used with a mouse/trackpad, or an icon of a phone when used with a touch screen (using the
pointer media query to determine), and should fall back to an image of a red circle with a line through it when neither media query is appropriate. The responsive design developer tools in your browser should trick it, though interestingly, not when inspecting an element.
<portal> is one of the more mysterious sounding elements, and seems intended for the iPad-style link previews that I’ve seen implemented on some websites on hover, but also come with SPA-like performance benefits. It unfortunately is still an experimental feature and isn’t (as of 2023) enabled by default in any browsers. It seems that it used to be an available experimental flag in Chrome, but today in 2023 it is not available at chrome://flags. I’ll include one below in case it works for future readers! I did try it in an very old Chromium version I still had installed.
<portal> doesn’t seem to be part of the HTML 5 Spec, I’m not sure why it’s included in the MDN documentation.
SVG and MathML
This is an interesting section of the documentation because it pairs one of the most ubiquitous elements with one of the most obscure.
<svg> elements are everywhere, especially that tools like Figma and Sketch have made them easy to prototype and export. Pairing them with
<math> in the documentation evokes a more artisanal, hand-crafted
<svg> that is relatively uncommon these days. I’ve gone hand-crafted here and drawn some
<math> is really a wrapper element for other non HTML elements from the MathML namespace, so I guess I don’t have to include every possible child element here. I’ll stick to something simple:
I did a deep dive into
<canvas>, specifically drawing crisp lines in 2020 while I was at Recurse Center. One thing I wasn’t familiar with before reading the MDN docs though, was that there is a maximum size for a
<canvas> element in each browser (though all modern browsers it is about 32 thousand pixels in each dimension). Below is a re-implementation of
There were a lot of tags that I expected to feel a little out of date when I started this post, but
<script> wasn’t one of them, but now that I have written most of the post, and have created a few
<script> tag by build tools and it ends up feeling more like boilerplate than a “markup” tag.
On the other hand, for most of the interactive websites I’ve made, I’ve rarely included a
<noscript> tag with the exception of those minified and compiled single page apps where the user would likely get a blank page if it weren’t for the
<noscript> tag (and even then, probably less often than I should have, though I’ve made sure to include one with every
<script> tag here).
Another set of elements
I had never come across before reading the MDN documentation,
<ins> seem to be intended for
creating a word processor. Reading about them led to yet another round of, “ I wonder if these are used in rendering Google Docs? .”
It’s not a new insight that
<table> elements were overused for layout purposes on the early web, but an irony that I’m only realizing now is that recently, as the web has gotten more and more populated by data, that
<table> elements have become rarely used, probably mostly due to their clunky default design, but probably also because one main goal of creating a web UI for the data that is otherwise probably stored in database tables, is to create a different view of the same data.
I don’t have any tabular data as this is an exclusively document based blog post, but below I’ve added a table with some custom CSS and “data” on emoji that is likely only accurate for the Apple emoji set in 2023. I wasn’t familiar with
<colgroup> before, but I don’t know that there are many cases where I would use them rather than a more custom, non
|Emoji with leaves||🥭||🌱||🍂||🍀||🪴|
|Emoji with fruit||🍒||🫐|
|Emoji with slices||🍰||🥪||🥒|
I have usually used
<form> and it’s associated elements when submitting the form would redirect to a new page, not for in-page user interaction, but either is valid. I would guess the form elements are probably the most important for accessibility so I will likely refer to the documentation whenever implementing one in the future.
<summary>were being considered for the HTML spec today, if they would be withdrawn in favor of a similar effect using CSS.
I wasn’t aware of the HTML only
alert(), but still simple, because while
alert() is styled by the browser
<dialog> can be styled with CSS.
🤠 🌴🌴🌴 🌴 🌴 🌴 👇 🌴 🌴 👇 🌴 🌴 🌴 🌴 👢 👢 the palm sheriff
Class syntax at that) was necessary to get web components to render, but after reading more about the Shadow DOM, it makes sense, because HTML has no built in way to encapsulate styles, though it does seem to be somewhat similar conceptually to
I’ve used web components below to create a table of contents for this post below, though I’m not making the best use of them. One thing I couldn’t quickly figure out how to do, when compared to components from frontend frameworks, is pass in properties that are themselves used as properties of elements in the child template, so in the list below I have to pass a full
<a> element into each child (which renders the
<li>), to be able to set the correct
href property. Someday after finishing this post I will read more about web components and maybe figure out something I’m missing now.
Table of Contents
Obsolete and Deprecated Elements
There are of course a few deprecated HTML elements, so why not include them here at the end.
Everyone’s favorite is of course,
Many of the elements, like
<font> (used above),
<strike> are examples of layout related functionality that has been moved to CSS rather than
have HTML handle it. The narrow box below has an example of
This sentence is wrapped in a
This sentence is wrapped in a
There are some other strange ones as well though. I couldn’t implement
<shadow> here because they were never fully implemented part of the web components spec. I’ll add some below anyway though.
<dir> is a very webserver version of
<ul> for listing directories. Since my Eleventy static site generator does use directories here’s a list:
Some of deprecated elements won’t render without some extra work, for example
<frameset> are designed to be used instead of a
<body>, for I guess some kind of collage web page made up of other pages. I’ve ironically only been able to use them inside of an
I expected that
<image> wouldn’t work since the MDN documentation says:
This does not appear to have been part of any formal specification. It was mentioned in HTML+ Discussion Document - Dave Raggett, November 8, 1993 (Section 5.9 - Images), but was not part of the first revision of HyperText Markup Language Specification - 2.0 in 1994.
But it does seem to work in some browsers in 2023, though this might be just a fallback for potential confusion with
An icon of a fax machine
One of the more interesting browser compatibility stories of the deprecated elements is
<menuitem>, which supposedly was partially supported in Firefox versions 8 - 84, but I couldn’t get an example to work in any of the older versions I installed locally (even with editing
about:config). The examples imply that the
type=context) and child
<menuitem> elements shouldn’t render until the element whose
contextmenu property is right clicked, but as you can see below, the items always render:
It’s surprising that
<noembed>, essentially a
<noscript> style fallback, was deprecated while
<embed> was kept in the spec. Here’s my
<embed> from above, but this time with a
<noembed> child. There is also
<noframes> which I included above with the
It’s unclear why
<param> ever existed instead of just using attributes on the
<object> element. When I started this blog post it was listed in the “Embedding Content” section, but by the time I finished it was deprecated. Here is one below:
<plaintext> is another weird one, and notable among the deprecated elements in that it works. It is another one I am going to have to wrap in an
<iframe> because otherwise the rest of the page would be rendered as the source code:
<tt>, used in a similar way, have closing tags
A few of the deprecated elements have just been replaced by newer additions to the spec.
<rtc> were used for displaying pronunciation of East Asian characters, but it seems like the spec was simplified. Here is the example from MDN:
I consulted a few other lists of HTML tags after realizing that the
<!-- comment --> tag wasn’t in my list from MDN (there’s one below this paragraph)
An older list from MDN in 2013 has elements like
<blink>, and for accessibility reasons,
almost all browsers currently ignore this element. I’ll add one hidden below if you can find a very old browser that supports it:
Also on the list is
<spacer>, which doesn’t work in modern browsers and,
would now be done
Then there’s others like
<bgsound> (2013 docs) that seems to have never been implemented (except maybe in Netscape?), but alludes to a vision for a much more multimedia enabled web documents, and
Another attempt at
I’m surprised it seems to still work!
And of course
<applet>, but I’m not even going to try with that one.