# entry

guid: https://htmhell.dev/adventcalendar/2022/13/
title: One day we'll have a fully customisable select
author: ;Manuel Matuzovic
link: https://htmhell.dev/adventcalendar/2022/13/
hash: �E�L��SUN3 E`
attributes: {"enclosures":[]}
content:
<p>Today, I want to  look at a proposed HTML feature that may end up replacing a lot of <code>&lt;div&gt;</code>s-based custom input components: <code>&lt;selectmenu&gt;</code>.</p>
<h2 data-sanitized-id="css-is-awesome">CSS <em>is</em> awesome</h2>
<p>I realise this calendar is about HTML. And I'll get to that. But first, let me start with CSS. CSS is fantastic, because it has allowed us to decide what our websites look like for over 25 years. This wasn't a given. Before CSS, you could only define the structure of your pages and browsers would decide their appearance.</p>
<p>Fast-forward to today, CSS not only exists, it has become extremely versatile. We have grids, custom properties, transforms and much more, and it is all pretty compatible across different browsers. The basic principle of CSS stays: styles are hints. What websites look like is a combination of the preferences of users, browsers and web developers.</p>
<p>But maybe in your design system, your select has a very specific style. Shadows  around the listbox, brand-specific whitespace settings… or your select contains more than just strings of text, like flags with country names or avatars with user names. The <code>&lt;select&gt;</code> element won't let you go that far with CSS. Enter <code>&lt;selectmenu&gt;</code>.</p>
<h2 data-sanitized-id="the-parts-of-lessselectmenugreater">The parts of <code>&lt;selectmenu&gt;</code></h2>
<p>The <a href="https://open-ui.org/prototypes/selectmenu/"><code>&lt;selectmenu&gt;</code> element</a> is a new HTML element proposed by the <a href="https://open-ui.org/">Open UI Community Group</a>. It has not yet landed in the <a href="https://html.spec.whatwg.org/">HTML Specification</a>, but it is being prototyped in <a href="https://www.chromium.org/Home/">Chromium</a>. You can test it by turning the “Experimental Web Platform Features” flag on (go to about:flags and search for this flag).</p>
<p>When you use a <code>&lt;selectmenu&gt;</code>, you'll find it is comprised out of different parts:</p>
<p><img src="https://htmhell.dev/images/advent2022/13/parts.jpg" alt="rendering of a selectmenu with arrows pointing to its individual parts; the closed part is called button, the icon within it marker, the value within it selected-value and the expanding part listbox"></p>
<ul>
<li><code>&lt;select&gt;</code> - the root element</li>
<li><code>&lt;button&gt;</code> - the button you click to open the select</li>
<li><code>&lt;selected-value&gt;</code> - the currently selected value</li>
<li><code>&lt;marker&gt;</code> - the arrow that is in the button</li>
<li><code>&lt;listbox&gt;</code> - the popover that opens when you click the button</li>
<li><code>&lt;option&gt;</code> - the options within the listbox (just like in regular <code>&lt;select&gt;</code>)</li>
<li><code>&lt;optgroup&gt;</code> - an optional way of grouping options (just like in regular <code>&lt;select&gt;</code>)</li>
</ul>
<p>From: <a href="https://open-ui.org/prototypes/selectmenu">Anatomy of the selectmenu</a></p>
<h2 data-sanitized-id="styling-lessselectmenugreater">Styling <code>&lt;selectmenu&gt;</code></h2>
<h3 data-sanitized-id="styling-parts">Styling parts</h3>
<p>In <a href="https://www.w3.org/TR/css-shadow-parts-1/">CSS Shadow Parts 1</a>, currently a Working Draft (eg <a href="https://www.w3.org/2021/Process-20211102/#rec-track">not yet a full-blown standard</a>), a new pseudo element is introduced to allow styling parts of shadow roots: <code>::part()</code>.</p>
<p>Wait, wasn't Shadow DOM something Web Components-specific? Yes. But how  <code>&lt;selectmenu&gt;</code> is implemented in the browser, is kind of Web Component-like. You could see it as a Web Component that ships with the browser.</p>
<p>With <code>::part</code>, you can style the different parts as they are described above, for instance, to style the listbox, you would do:</p>
<pre data-sanitized-class="language-css"><code data-sanitized-class="language-css"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token selector">selectmenu::part(listbox)</span> <span data-sanitized-class="token punctuation">{</span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token property">box-shadow</span><span data-sanitized-class="token punctuation">:</span> 3px 3px 3px 3px hotpink<span data-sanitized-class="token punctuation">;</span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token punctuation">}</span></span></code></pre>
<p>Or maybe you want to change what the arrow looks like:</p>
<pre data-sanitized-class="language-css"><code data-sanitized-class="language-css"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token selector">selectmenu::part(marker)</span> <span data-sanitized-class="token punctuation">{</span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token property">box-shadow</span><span data-sanitized-class="token punctuation">:</span> 3px 3px 3px 3px hotpink<span data-sanitized-class="token punctuation">;</span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token punctuation">}</span></span></code></pre>
<p>(The <code>&lt;marker&gt;</code>  is not yet added to the selectmenu explainer, but it was <a href="https://github.com/openui/open-ui/issues/548#issuecomment-1262650219">confirmed in an Open UI meeting</a></p>
<h3 data-sanitized-id="styling-states">Styling states</h3>
<p>You will also be able to style a selectmenu based on whether it is open or closed, using the <code>:open</code> pseudo class:</p>
<pre data-sanitized-class="language-css"><code data-sanitized-class="language-css"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token selector">selectmenu</span> <span data-sanitized-class="token punctuation">{</span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token property">border</span><span data-sanitized-class="token punctuation">:</span> 2px solid black<span data-sanitized-class="token punctuation">;</span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token punctuation">}</span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token selector">selectmenu:open</span> <span data-sanitized-class="token punctuation">{</span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token property">border-color</span><span data-sanitized-class="token punctuation">:</span> hotpink<span data-sanitized-class="token punctuation">;</span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token punctuation">}</span></span></code></pre>
<p>Or maybe you want a different marker when it is open:</p>
<pre data-sanitized-class="language-css"><code data-sanitized-class="language-css"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token selector">selectmenu::part(marker)</span> <span data-sanitized-class="token punctuation">{</span></span><br><span data-sanitized-class="highlight-line">// regular</span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token punctuation">}</span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token selector">selectmenu::part(marker):open</span> <span data-sanitized-class="token punctuation">{</span></span><br><span data-sanitized-class="highlight-line">// open</span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token punctuation">}</span></span></code></pre>
<img src="https://htmhell.dev/images/advent2022/13/openclosed.jpg" loading="lazy" alt="two selectboxes, the first is closed, the second is open. the closed one has selector selectmenu::part(marker):closed, the open one has selectmenu::part(marker):open">
<p><em>Different icons on opened and closed states</em></p>
<p>There will also be a <code>:closed</code> pseudo class, to style the closed state. It would be equivalent to <code>:not(:open)</code>. The <code>:open</code> and <code>:closed</code> pseudos are defined in the <a href="https://www.w3.org/TR/selectors/#open-state">Element Display State section of Selectors, Level 4</a>.</p>
<h2 data-sanitized-id="customising-beyond-just-styling">Customising beyond just styling</h2>
<p>You can also replace the parts shown above with random markup of your own. The parts shown above are exposed as “slots”, meaning you can add your own tree structure in your markup and use that to replace a part.</p>
<p>For instance, this is how you  would replace the icon with something else:</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>selectmenu</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>div</span> <span data-sanitized-class="token attr-name">slot</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>marker<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token comment">&lt;!-- your own selectmenu open icon goes here --&gt;</span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>div</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>selectmenu</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<p>This uses whatever is inside this <code>div</code> instead of the default marker in the button to open a selectmenu.</p>
<p>In principle, <code>&lt;selectmenu&gt;</code> will allow you to do things like this with each of the parts, so that you could replace the button or the options. This gives developers a lot of power,  and with that comes responsibility. So a word of warning: nesting the wrong kind of elements into parts can quickly lead to a “HTMHell”. For instance, what if you put more than just text inside of an <code>option</code>—say, avatars—but browsers and assistive technologies expect just text? Or what if you put a <code>button</code> in an <code>option</code>? Nested interactive elements like that risk breaking the experience for end users, in ways that the browser or assistive technologies can't magically fix, so beware.</p>
<h2 data-sanitized-id="current-status">Current status</h2>
<p>Selectmenu is currently being “incubated” at the Open UI Community Group and prototyped behind a flag in Chromium.</p>
<p>What about other browsers and browser engines? I'm not sure what will happen in Safari or Webkit, but folks from Firefox (Mozilla) join the Open UI calls. Quoting from the “The Declarative Web” part of Mozilla's vision for the open web:</p>
<blockquote>[on the web, built-in controls are] often insufficiently styleable and have inconsistent internal structures across browsers, which makes it difficult to make them visually consistent with the rest of the Web page. We want to fill these gaps, and are pleased to see the OpenUI effort already making progress in this space.</blockquote>
<p>For <code>&lt;selectmenu&gt;</code> to become a reality, it would need to go into the standards and then get browser implementations. At this time, it's hard to say when that will be the case.</p>
<h2 data-sanitized-id="summary">Summary</h2>
<p>So, in summary: <code>&lt;selectmenu&gt;</code> is a new proposal that would add a new control to the web platform that is like <code>&lt;select&gt;</code> by default, but can be styled and customised in pretty much any way you want. I'm particularly excited about the ability to use <code>::part()</code> to style parts, and slightly worried about the ability to replace parts completely as that may break accessibility if it is replaced with the wrong things.</p>
<p>You can play with <code>&lt;selectmenu&gt;</code> today in Microsoft Edge Canary or Google Chrome Canary and <a href="https://github.com/openui/open-ui/issues/new">file issues</a> against the Open UI repository.</p>


guid: https://htmhell.dev/adventcalendar/2022/14/
title: Table Like It's 2023
author: ;Manuel Matuzovic
link: https://htmhell.dev/adventcalendar/2022/14/
hash: 93[�a-�����u��
attributes: {"enclosures":[]}
content:
<p>In this article:</p>
<ul>
<li><a href="https://htmhell.dev/adventcalendar/2022/14/#hello-website-builders!">Hello, Website Builders!</a></li>
<li><a href="https://htmhell.dev/adventcalendar/2022/14/#a-little-history">A little history</a></li>
<li><a href="https://htmhell.dev/adventcalendar/2022/14/#what-is-a-table?">What is a table?</a></li>
<li><a href="https://htmhell.dev/adventcalendar/2022/14/#who-benefits-from-tables?">Who benefits from tables?</a></li>
<li><a href="https://htmhell.dev/adventcalendar/2022/14/#what-does-a-table-look-like?">What does a table look like?</a></li>
<li><a href="https://htmhell.dev/adventcalendar/2022/14/#what-does-a-table-sound-and-feel-like?">What does a table sound and feel like?</a></li>
<li><a href="https://htmhell.dev/adventcalendar/2022/14/#(re)learning-tables-(1994-2022)">(Re)learning tables (1994 - 2022)</a></li>
<li><a href="https://htmhell.dev/adventcalendar/2022/14/#wcag-levels-unlocked">WCAG levels unlocked</a></li>
<li><a href="https://htmhell.dev/adventcalendar/2022/14/#when-tables-get-complicated">When tables get complicated</a></li>
<li><a href="https://htmhell.dev/adventcalendar/2022/14/#go-forth-and-make-good-tables">Go forth, and make good tables</a></li>
<li><a href="https://htmhell.dev/adventcalendar/2022/14/#learn-html-(including-tables)-for-free">Learn HTML (including tables) for free</a></li>
<li><a href="https://htmhell.dev/adventcalendar/2022/14/#testing-tools">Testing tools</a></li>
<li><a href="https://htmhell.dev/adventcalendar/2022/14/#special-thanks">Special thanks</a></li>
<li><a href="https://htmhell.dev/adventcalendar/2022/14/#about-amy-carney">About Amy</a></li>
</ul>
<h2 data-sanitized-id="hello-website-builders!">Hello, Website Builders!</h2>
<p>Hey, you. Yes, you. Let's talk about tables on the web.</p>
<p>It's almost 2023. Yet tabular data is still being delivered in ways that aren't accessible. From a visually disabled person's perspective, it's horrifying.</p>
<p>Data tables aren't given semantic HTML to clarify its information relationships. Table markup is still used for page layouts, yet they're aren't flagged as such. The <a href="https://almanac.httparchive.org/en/2022/accessibility#tables">Web Alamanac</a> reported how infrequent <code>caption</code> (a table's title) and <code>role=presentation</code> (indicating layout-only) were used in 2022 to improve accessibility.</p>
<p>I'm embarrassed on behalf of my fellow developers, who should be more up-to-date with their craft and aware of current standards and best practices. My hope is to persuade you to make better choices as you build your website.</p>
<h2 data-sanitized-id="a-little-history">A little history</h2>
<p><a href="http://www.barrypearson.co.uk/articles/layout_tables/history.htm">Table markup has been available since 1994</a>, despite not being an <a href="https://www.w3.org/TR/2018/SPSD-html32-20180315/#table">official HTML 3.2 recommendation</a> until 1997. If you were writing front-end code at that time, you probably did what a lot of us did: use <code>table</code> for layout AND tabular data. We didn't have many alternatives then. It didn't help that the specification stated that tables could be used for "layout purposes."</p>
<p>But that was then. We have better options now. HTML 4.01 gave us separate stylesheets. CSS iterations have given us multiple ways to layout pages, including:</p>
<ul>
<li>CSS grid,</li>
<li>flexbox,</li>
<li>multi-columns, and</li>
<li>positioning rules.</li>
</ul>
<p>Yet, 28 years later, the inaccessible tables I've seen (and remediated) have me scratching my head. Are today's developers learning from old knowledge delivered in tutorials and Stack Overflow answers? Despite reliable, easy-to-access resources, like <a href="https://developer.mozilla.org/en-US/">MDN (Mozilla Developer's Network)</a>, table and data abuse are still happening.</p>
<h2 data-sanitized-id="what-is-a-table?">What is a table?</h2>
<p>To know when and how to use a table, you need to understand what a table is. A table is for tabular data.</p>
<p>WHATWG's (Web Hypertext Application Technology Working Group) <a href="https://html.spec.whatwg.org/multipage/tables.html#tables">HTML Living Standard states about tables</a>, "The table represents data with more than one dimension, in the form of a table."</p>
<p>If you're less familiar with the HTML Living Standard, you may recognize MDN. <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/table">MDN describes an HTML table</a> as, "tabular data — that is, information presented in a two-dimensional table comprised of rows and columns of cells containing data."</p>
<h2 data-sanitized-id="who-benefits-from-tables?">Who benefits from tables?</h2>
<p>Ok, maybe you already <em>know</em> what a table is.</p>
<p>But do you know who benefits from proper table markup and styling? By "proper table markup", I mean the <code>table</code> element, not <code>div</code> or <code>img</code> elements.</p>
<p>Generally, people with visual and cognitive disabilities benefit.</p>
<p>Specifically, people who:</p>
<ul>
<li>use a screen reader,</li>
<li>magnify their screen,</li>
<li>use Windows High Contrast Mode,</li>
<li>use dark mode,</li>
<li>use custom stylesheets,</li>
<li>copy &amp; paste,</li>
<li>import data into other programs, and</li>
<li>save pages as PDFs.</li>
</ul>
<p>To be honest, I'm hard-pressed to find anyone who doesn't benefit from thoughtful markup and styling of table data.</p>
<h2 data-sanitized-id="what-does-a-table-look-like?">What does a table look like?</h2>
<p>By this point, we know a table looks like a 2D grid of rows and columns. Is there more to consider? Yes!</p>
<p>We want to help people make visual sense of a table. To be more inclusive, content creators, designers, and developers should evaluate their choices when it comes to:</p>
<ul>
<li>contrast between background color and foreground text,</li>
<li>font family, size, and spacing,</li>
<li>border visibility, color, and thickness,</li>
<li>color choices that can be overwritten by custom stylesheets and Windows High Contrast Mode, and</li>
<li>hover-activated changes that exclude keyboard and mobile device users.</li>
</ul>
<p>As someone visually disabled, who needs strong contrast and screen magnification, I need borders that stand out. When I magnify my screen, a solid line guides me along each row. As I rely on strong contrast between background, border, and text, I need borders and backgrounds to <em>not</em> be a light gray. Not to mention, if I use Windows High Contrast Mode that day, your background colors will disappear.</p>
<h2 data-sanitized-id="what-does-a-table-sound-and-feel-like?">What does a table sound and feel like?</h2>
<p>But what about people who don't rely on visual cues? Specifically, people who rely on text-to-speech (screenreader) software to read content and convey the context of the content (headings, tables, images, etc.).</p>
<h3 data-sanitized-id="screen-reader-semantics">Screen reader semantics</h3>
<p>A table is self-explanatory by conveying its child relationships between data points. Cells are associated with the column and row they sit in. HTML elements have this accessibility built-in.</p>
<p>I highly recommend you watch Léonie Watson's demonstration "How screen readers navigate data tables", approximately 2 minutes to watch.</p>
<div data-sanitized-class="video">
<iframe width="560" height="315" src="https://www.youtube.com/embed/X1KR4u94cho" title="YouTube video player" frameborder="0" allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="" sandbox="allow-scripts allow-same-origin"></iframe>
</div>
<p>You should also read her <a href="https://tink.uk/how-screen-readers-navigate-data-tables/">accompanying blog post about how screen readers navigate data tables</a>.</p>
<h3 data-sanitized-id="screen-reader-keyboard-shortcuts">Screen reader keyboard shortcuts</h3>
<p>Did you know screen readers allow users to navigate with keyboard shortcuts? They can jump from table to table and interact with columns, rows, and cells within a table.</p>
<p>WebAIM provides helpful instructions on how to get started to test with a screen reader:</p>
<ul>
<li><a href="https://webaim.org/articles/jaws/">Using JAWS to Evaluate Web Accessibility</a></li>
<li><a href="https://webaim.org/articles/nvda/">Using NVDA to Evaluate Web Accessibility</a></li>
<li><a href="https://webaim.org/articles/voiceover/">Using VoiceOver to Evaluate Web Accessibility</a>:</li>
</ul>
<p>If you need a better sense of which screen readers are used the most, checkout <a href="https://webaim.org/projects/screenreadersurvey9/#primary">WebAIM's latest Screen Reader User Survey</a>.</p>
<p>Don't forget about mobile screen reader users. They have access to touch gestures to quickly jump between tables and navigate within a table, too. But some mobile device users pair their phone or tablet with a keyboard, giving them access to keyboard commands.</p>
<h3 data-sanitized-id="learn-more-about-the-screen-reader-users-experience">Learn more about the screen reader user's experience</h3>
<p>Feel intimidated by screen readers? Check out these resources to get an introduction to screen readers and how people use them:</p>
<ul>
<li><a href="https://webaim.org/techniques/screenreader/">Designing for Screen Reader Compatibility</a></li>
<li><a href="https://youtu.be/8Rn5pXCdZWU">W3C Web Accessibility Perspectives: Text to Speech (YouTube)</a></li>
</ul>
<p>Your markup choices can make or break a user's experience.</p>
<h2 data-sanitized-id="(re)learning-tables-(1994-2022)">(Re)learning tables (1994 - 2022)</h2>
<p>This is my largest section, by far. If you feel you need to move forward, here is my TL;DR (too long, didn't read):</p>
<ul>
<li>It's <strong>OK</strong> to use <code>table</code> in 2023! Make that tabular data make sense to everyone.</li>
<li>It's <strong>not</strong> OK to arrange tabular data in <code>div</code>s and <code>span</code>s, or other unrelated markup.</li>
<li>It's <strong>not</strong> OK to use an <code>img</code> of a table, which is inaccessible for many folks.</li>
<li>Update your table model knowledge; some elements and attributes have changed in the past 28 years.</li>
</ul>
<p>If you're still with me, here we go.</p>
<p>As I said, a lot has changed since 1994. We have more HTML elements to construct more meaningful (context for content) webpages. Styles have broken free from the building blocks of HTML to create a separate layer of aesthetics.</p>
<h3 data-sanitized-id="when-should-you-use-a-table?">When should you use a table?</h3>
<p>Maybe you're still torn about if you should use a table or not.</p>
<p>Here's a few questions you can ask yourself:</p>
<ul>
<li>Do I have tabular data (grid of items related to one another)?</li>
<li>Do I have an image (<code>img</code>) of a table?</li>
<li>Does my table element have a <code>role=presentation</code> attribute on it?</li>
<li>Does my table use obsolete attributes, like <code>border</code>, <code>cellspacing</code>, or <code>cellpadding</code> with a value of 0?</li>
</ul>
<p>If you said, "yes" to the first two items, then you probably should use <code>table</code>. If you said, "yes" to the last two items, you probably should use CSS to design your layout instead.</p>
<p>Speaking of CSS, today we have the advantage of separating architecture from aesthetics. Several HTML table attributes are now obsolete, to be replaced by CSS properties. Let's dive into the HTML building blocks, then bring up the decorative part again.</p>
<h3 data-sanitized-id="how-to-markup-tables">How to markup tables</h3>
<p>Ready to make that table now?</p>
<p>Let the HTML Living Standard be your guide:</p>
<p>"Expected children [of the table model] include, in this order:</p>
<ol>
<li>optionally a <code>caption</code> element,</li>
<li>followed by zero or more <code>colgroup</code> elements,</li>
<li>followed optionally by a <code>thead</code> element,</li>
<li>followed by either zero or more <code>tbody</code> elements OR one or more <code>tr</code> elements,</li>
<li>followed optionally by a <code>tfoot</code> element, optionally intermixed with one or more script-supporting elements."</li>
</ol>
<p>What does that look like for those who write or generate HTML?</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>table</span><span data-sanitized-class="token punctuation">&gt;</span></span> <span data-sanitized-class="token comment">&lt;!-- required --&gt;</span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>caption</span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>caption</span><span data-sanitized-class="token punctuation">&gt;</span></span> <span data-sanitized-class="token comment">&lt;!-- optional, but ensure table has an accessible name --&gt;</span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>colgroup</span><span data-sanitized-class="token punctuation">&gt;</span></span> <span data-sanitized-class="token comment">&lt;!-- 0 or more --&gt;</span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>col</span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>col</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>col</span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>col</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>col</span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>col</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>colgroup</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>thead</span><span data-sanitized-class="token punctuation">&gt;</span></span> <span data-sanitized-class="token comment">&lt;!-- thead optional --&gt;</span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>tr</span><span data-sanitized-class="token punctuation">&gt;</span></span> <span data-sanitized-class="token comment">&lt;!-- tr required --&gt;</span></span><br><span data-sanitized-class="highlight-line">      <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>th</span> <span data-sanitized-class="token attr-name">scope</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>row<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>th</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">      <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>td</span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>td</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>tr</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>thead</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>tbody</span><span data-sanitized-class="token punctuation">&gt;</span></span> <span data-sanitized-class="token comment">&lt;!-- tbody optional, 0 or more --&gt;</span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>tr</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">      <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>th</span> <span data-sanitized-class="token attr-name">scope</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>row<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>td</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">      <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>td</span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>td</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>tr</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>tbody</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>tfoot</span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>tfoot</span><span data-sanitized-class="token punctuation">&gt;</span></span> <span data-sanitized-class="token comment">&lt;!-- tfoot optional --&gt;</span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>table</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"></span></code></pre>
<h3 data-sanitized-id="a-note-about-table-model-elements">A note about table model elements</h3>
<p>If you started coding tables in the 1990s, you may feel that table markup was simpler then. Did you know <a href="https://www.w3.org/TR/html4/">HTML 4.01</a> introduced new elements for row and column groups to the table model?</p>
<p>If you haven't already, consider adding these elements (from the HTML Living Standard) to your toolbox:</p>
<ul>
<li><a href="https://html.spec.whatwg.org/#the-colgroup-element">colgroup</a></li>
<li><a href="https://html.spec.whatwg.org/#the-col-element">col</a></li>
<li><a href="https://html.spec.whatwg.org/#the-thead-element">thead</a></li>
<li><a href="https://html.spec.whatwg.org/#the-tbody-element">tbody</a></li>
<li><a href="https://html.spec.whatwg.org/#the-tfoot-element">tfoot</a></li>
</ul>
<p>The ability to group rows and columns are useful for granular styling or organization of data. They are not essential for accessibility at this time.</p>
<h3 data-sanitized-id="a-note-on-deprecated-attributes">A note on deprecated attributes</h3>
<p>Even in 2022, I've seen old attributes hanging around that have been dumped in the obsolete bin. It's time for a markup refresh, if you're still using obsolete attributes.</p>
<table>
  <caption>Obsolete (deprecated) table attributes</caption>
  <thead>
    <tr>
      <th scope="col">Elements</th>
      <th scope="col">Attributes</th>
    </tr><tr>
  </tr></thead>
  <tbody>
    <tr>
      <td>table</td>
      <td>align, bgcolor, border, cellspacing, cellpadding, frame, rules, summary, width</td>
    </tr>
    <tr>
      <td>caption</td>
      <td>align, valign</td>
    </tr>
    <tr>
      <td>colgroup</td>
      <td rowspan="4">align, bgcolor, char, charoff, valign</td>
    </tr>
    <tr>
      <td>thead</td>
    </tr>
    <tr>
      <td>tbody</td>
    </tr>
    <tr>
      <td>tfoot</td>
    </tr>
    <tr>
      <td>tr</td>
      <td>align, bgcolor, char, charoff, valign</td>
    </tr>
    <tr>
      <td>th</td>
      <td rowspan="2">align, nowrap, valign, width, height</td>
    </tr>
    <tr>
      <td>td</td>
    </tr>
  </tbody>
</table>
<p><a data-sanitized-id="wcag"></a></p>
<h2 data-sanitized-id="wcag-levels-unlocked">WCAG levels unlocked</h2>
<p>The appropriate use of the <code>table</code> element now welcomes everyone to your site and app. But you get something out of it, too! Your project has come further in achieving accessibility success and unlocking new levels of the Web Content Accessibility Guidelines (WCAG).</p>
<p>Here are some WCAG success criteria (SC) you've managed to tackle with your user-driven approach:</p>
<ul>
<li><a href="https://www.w3.org/WAI/WCAG21/Understanding/info-and-relationships.html">Info and Relationships (1.3.1, Level A)</a></li>
<li><a href="https://www.w3.org/WAI/WCAG21/Understanding/meaningful-sequence.html">Meaningful Sequence (1.3.2, Level A)</a></li>
<li><a href="https://www.w3.org/WAI/WCAG21/Understanding/parsing.html">Parsing (4.1.1, Level A)</a></li>
</ul>
<p>Depending on your content, design, table width, and approach, you <em>may</em> have even covered:</p>
<ul>
<li><a href="https://www.w3.org/WAI/WCAG21/Understanding/resize-text.html">Resize Text (1.4.4, Level AA)</a></li>
<li><a href="https://www.w3.org/WAI/WCAG21/Understanding/images-of-text.html">Images of Text (1.4.5, Level AA)</a></li>
<li><a href="https://www.w3.org/WAI/WCAG21/Understanding/visual-presentation.html">Visual Presentation (1.4.8, Level AAA)</a></li>
<li><a href="https://www.w3.org/WAI/WCAG21/Understanding/images-of-text-no-exception.html">Images of Text - No Exception (1.4.9, Level AAA)</a></li>
<li><a href="https://www.w3.org/WAI/WCAG21/Understanding/reflow.html">Reflow (1.4.10, Level AA)</a></li>
<li><a href="https://www.w3.org/WAI/WCAG21/Understanding/non-text-contrast.html">Non-text Contrast (1.4.11, Level AA)</a></li>
<li><a href="https://www.w3.org/WAI/WCAG21/Understanding/text-spacing.html">Text Spacing (1.4.12, Level AA)</a></li>
</ul>
<p>No guarantees on those "bonus" criteria. But they are worth learning and exploring how to apply in the context of your page and website.</p>
<p>Go, you!</p>
<h2 data-sanitized-id="when-tables-get-complicated">When tables get complicated</h2>
<p>Sometimes you don't want to reach for <code>table</code> because it's complicated, for one reason or another:</p>
<ul>
<li>You were given a graphic of a table, rather than text content, and don't have an easy way to make it real text, despite the existence of <a href="https://www.lireo.com/extracttable/">ExtractTable, which converts data from images</a>.</li>
<li>You're using a framework like Rails or a CMS like WordPress that generates HTML, and you can't edit it or it's difficult to edit.</li>
<li>You struggle with CSS.</li>
<li>The default design is ugly and doesn't "fit" into your site's design.</li>
</ul>
<p>Maybe at this point, you've gotten past those issues, and you're really trying. But sometimes tables are just... hard. You've been asked to put form inputs in there. Your table needs to be dynamically sortable. Or you have loads of information, but it barely fits on a large viewport, and horizontally overflows on a small viewport.</p>
<p>It's OK to get frustrated. We've all encountered challenges when given a complex design idea. And some solutions are imperfect.</p>
<p>What I'm sharing in this article is meant to lead you in the right direction. Categorizing and building things is hard in real life.</p>
<p>You could learn from Adrian Roselli, who has tackled some of the hard issues:</p>
<ul>
<li><a href="https://adrianroselli.com/2020/02/block-links-cards-clickable-regions-etc.html#Update02">Block Link, Cards, Clickable Regions, Row, Etc. - March 31, 2020 update</a></li>
<li><a href="https://adrianroselli.com/2019/05/uniquely-labeling-fields-in-a-table.html">Uniquely Labeling Fields in a Table</a></li>
<li><a href="https://adrianroselli.com/2022/01/accessible-cart-tables.html">Accessible Cart Tables?</a></li>
<li><a href="https://adrianroselli.com/2019/09/table-with-expando-rows.html">Table with Expando Rows</a></li>
<li><a href="https://adrianroselli.com/2018/02/tables-css-display-properties-and-aria.html">Tables, CSS Display Properties, and ARIA</a></li>
<li><a href="https://adrianroselli.com/2020/11/under-engineered-responsive-tables.html">Under-Engineered Responsive Tables</a></li>
<li><a href="https://adrianroselli.com/2022/07/its-mid-2022-and-browsers-mostly-safari-still-break-accessibility-via-display-properties.html">It’s Mid-2022 and Browsers (Mostly Safari) Still Break Accessibility via Display Properties</a></li>
</ul>
<p>And there are others to learn from, too:</p>
<ul>
<li><a href="https://www.matuzo.at/blog/highlighting-columns/#table1-occurrences?ref=bestwebsite.gallery">Highlighting columns in HTML tables by Manuel Matuzovic</a></li>
<li><a href="https://www.scottohara.me/blog/2019/04/19/tabled-tables.html">Unintentionally tabling table semantics by Scott O'Hara</a></li>
<li><a href="https://inclusive-components.design/data-tables/">Data tables by Heydon Pickering</a></li>
</ul>
<h3 data-sanitized-id="other-things-to-beware">Other things to beware</h3>
<p>You've done your research, you've created solutions, but sometimes you still run into problems. Keep these things in mind:</p>
<ul>
<li>Nested tables can break a screen reader user's experience. Try rearranging your table, or make multiple tables to keep them simple.</li>
<li>Tables with lots of columns are hard to wrangle for the different screen sizes out there. There is no perfect solution. Experiment with ways to help the data reflow and stack without losing its context and relationships.</li>
<li>Changing the CSS <code>display</code> value on the <code>table</code> element breaks the semantics of the table  and breaks a screen reader user's experience.</li>
<li>In Safari 16, VoiceOver for Mac will read a <code>caption</code> as the table's name, but will not see a nested heading level in:
<ul>
<li>the Web Rotor headings list, and</li>
<li>the "next heading" keyboard shortcut.</li>
</ul>
</li>
<li>HTML generators and Markdown commonly exclude some table elements and attributes, like caption and scope.</li>
</ul>
<h2 data-sanitized-id="go-forth-and-make-good-tables">Go forth, and make good tables</h2>
<p>Whew! I feel like I could jabber on and on about the importance of table markup.</p>
<p>However, here are the main things I want you to remember :</p>
<ul>
<li>Don't use <code>table</code> for layouts.</li>
<li>Avoid nesting tables and simplify data relationships, where possible.</li>
<li>Ensure each table has an accessible name, whether it be:
<ul>
<li><code>table &gt; caption</code></li>
<li><code>table aria-label={Table name}</code></li>
<li><code>figure &gt; figcaption + table</code>;</li>
<li><code>h{#} id={table-name}</code> + <code>table aria-labelledby={heading id}</code> (use with caution).</li>
</ul>
</li>
<li>This shouldn't have to be said, but don't ARIA overload a table.</li>
<li>Test your work with a screen reader or, even better, a proficient screen reader user.</li>
<li>Take a deep breath and try not to overthink it.</li>
</ul>
<p>I urge you in the coming year, use real tables for tabular data!</p>
<h2 data-sanitized-id="learn-html-(including-tables)-for-free">Learn HTML (including tables) for free</h2>
<ul>
<li><a href="https://developer.mozilla.org/en-US/docs/Learn/Getting_started_with_the_web/HTML_basics">HTML basics on MDN</a></li>
<li><a href="https://www.30daysofhtml.com/">30 Days of HTML by Jen Kramer</a></li>
<li><a href="https://www.w3.org/WAI/tutorials/tables/">Tables Tutorial by W3C-WAI</a></li>
<li><a href="https://webaim.org/techniques/tables/">WebAIM's Creating Accessible Tables</a></li>
<li><a href="https://www.w3.org/WAI/WCAG21/quickref/?currentsidebar=%23col_customize&amp;tags=tables">How to Meet WCAG Quick Reference: tables tag filter</a></li>
<li><a href="https://websitesetup.org/html-tutorial-beginners/">Beginner's Guide to Writing Good HTML by Bruce Lawson</a></li>
<li><a href="https://thegymnasium.com/courses/GYM/107/0/about">Modern Web Design by Aaron Gustafson (sign-up with Aquent Gymnasium)</a></li>
<li><a href="https://web.dev/learn/html/">Learn HTML by Estelle Weyl</a></li>
</ul>
<h2 data-sanitized-id="testing-tools">Testing tools</h2>
<ul>
<li><a href="https://pauljadam.com/bookmarklets/tables.html">Paul J. Adam's Tables Bookmarklet for Accessibility Testing</a></li>
<li><a href="https://wave.webaim.org/">WebAIM's WAVE tool</a></li>
</ul>
<h2 data-sanitized-id="special-thanks">Special thanks</h2>
<p>This write-up wouldn't be possible without the generous time and critical review from my friends and accessibility allies:</p>
<ul>
<li><a href="https://www.lireo.com/">Deborah Edwards-Oñoro</a></li>
<li><a href="https://incl.ca/">Nic Steenhout</a></li>
<li><a href="https://adrianroselli.com/">Adrian Roselli</a></li>
<li><a href="https://www.matuzo.at/">Manuel Matuzovic</a></li>
</ul>


guid: https://htmhell.dev/adventcalendar/2022/15/
title: Get that marquee ✨AeStHeTiC✨
author: ;Manuel Matuzovic
link: https://htmhell.dev/adventcalendar/2022/15/
hash: ��AP.�h�G�
attributes: {"enclosures":[]}
content:
<p>With the current <a href="https://www.urbandictionary.com/define.php?term=Y2K%20aesthetic">Y2K fashion trend</a> and JLo being back together with Ben Affleck, the 2000s are having a revival this year. Many brands are jumping onto the boat by creating websites with an “old-school” vibe.</p>
<p>
<img src="https://htmhell.dev/images/advent2022/14/sepronic_world.jpg" alt="SEPRONIC WORLD by Thea Wood on Behance" width="740" height="246">
</p>
<p><a href="https://www.behance.net/gallery/116549859/SEPRONIC-WORLD?tracking_source=search_projects_recommended%7Cwindowsxp"><em>SEPRONIC WORLD by Thea Wood on Behance</em></a></p>
<p>The <code>marquee</code> element is an old web dev community favourite, fitting the 2000s aesthetic. However, this HTML element is deprecated and should not be used on modern websites. If you still want to achieve that unique <code>marquee</code> aesthetic, this article is here to help. First, we learn about the history of the marquee element and look at the pros and cons. Then <a href="https://htmhell.dev/adventcalendar/2022/15/#the-alternative">we code an alternative</a> with CSS and JavaScript.</p>
<h2 data-sanitized-id="the-marquee-element">The Marquee element</h2>
<p>The <code>marquee</code> element has never been a standard HTML element and is even classified as a non-conforming feature in HTML5. This means it is entirely obsolete and must not be used, according to the <a href="https://www.w3.org/Consortium/">World Wide Web Consortium (W3C)</a>. Microsoft introduced the <code>marquee</code> element in Internet Explorer version 2.0, which was launched in 1995. Since then, it was quickly integrated into other browsers, although it never made it to the HTML specification.</p>
<h3 data-sanitized-id="but-what-does-it-do?">But what does it do?</h3>
<p>When text or an image is placed inside a <code>marquee</code> element, it moves across the page infinitely, per default horizontally, from right to left.</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token comment">&lt;!-- This scrolling text goes from right to left --&gt;</span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>marquee</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  Newsflash: JLo and Ben Affleck got married!</span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>marquee</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<div data-demo="Demo of a standard marquee">
  NEWSFLASH: JLo and Ben Affleck got married!
</div>
<p>With the help of attributes, the content within the element can also scroll right, up or down. You can even control what happens when the corner of the screen is reached, how fast the animation is or if it has is a delay.</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token comment">&lt;!-- Using an attribute to change the scroll direction --&gt;</span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token comment">&lt;!-- This scrolling text goes from top to bottom. The "scrollamount" attribute controls the speed. --&gt;</span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>marquee</span> <span data-sanitized-class="token attr-name">direction</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>down<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">scrollamount</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>1<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  Be prepared for low-rise jeans, Y2K is back.</span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>marquee</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<div data-demo="Demo of a marquee scrolling top to bottom">
  Be prepared for low-rise jeans, Y2K is back.
</div>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token comment">&lt;!-- Using an attribute to change the scroll behaviour --&gt;</span></span><br><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>marquee</span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token attr-name">direction</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>up<span data-sanitized-class="token punctuation">"</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token attr-name">behavior</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>alternate<span data-sanitized-class="token punctuation">"</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token attr-name">width</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>250<span data-sanitized-class="token punctuation">"</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token attr-name">height</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>200<span data-sanitized-class="token punctuation">"</span></span></span><br>  <span data-sanitized-class="token special-attr"><span data-sanitized-class="token attr-name">style</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span><span data-sanitized-class="token value css language-css"><span data-sanitized-class="token property">border</span><span data-sanitized-class="token punctuation">:</span>solid</span><span data-sanitized-class="token punctuation">"</span></span></span><span data-sanitized-class="token punctuation">&gt;</span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>marquee</span> <span data-sanitized-class="token attr-name">behavior</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>alternate<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token comment">&lt;!-- This image bounces from the edges of the screen --&gt;</span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>img</span> <span data-sanitized-class="token attr-name">height</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>40<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">src</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>https://www.freeiconspng.com/uploads/dvd-logo-png-33.png<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token punctuation">/&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>marquee</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>marquee</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<div data-demo="Demo of a marquee with a picture and different scroll behavior">

  
    
    <img width="85" src="https://htmhell.dev/images/advent2022/14/dvd-logo-png-19280.png">
  

</div>
<h3 data-sanitized-id="the-popularity-of-marquee">The popularity of <code>marquee</code></h3>
<p>Although the marquee element was never accepted as a standard, people loved using it on their websites. It could be easily implemented and offered a bit of fun, way before CSS animations were a thing. <code>Marquee</code> was often used for under-construction pages or websites with headlines. Text or images moving across the screen served as a successful attention grabber.</p>
<p>You may be asking yourself why the <code>marquee</code> element gets a wave of attention now, in 2022. As the Y2K trend has a revival within fashion, brands also want to bring retro vibes and aesthetics to their websites. What better markets ultra-low-rise jeans than a website with blinking, colourful images and moving text? Well, you probably have guessed it: a website that uses modern user experience and accessibility practices to be enjoyable for everyone. Moving content grabs your attention, but it is also very distracting. Surfing the web should be a pleasant experience for every individual.</p>
<h3 data-sanitized-id="some-reasons-against-marquee">Some reasons against <code>marquee</code></h3>
<p>Although moving text at high speed over a screen may sound compelling to try out the <code>marquee</code> element in your next web project, you really shouldn't. Here are some reasons for you if you are not convinced yet:</p>
<h4>1. Officially deprecated</h4>
<p>The usage of the <code>marquee</code> element is no longer recommended. It is officially marked as deprecated, meaning modern browsers might still support it for compatibility purposes. However, the element could be removed anytime, and newer or better alternatives are available. So, it should definitely not be used anymore.</p>
<h4>2. Not accessible</h4>
<p>The <code>marquee</code> element was launched without ever being tested properly, specifically regarding accessibility. This resulted in issues for people with visual impairments and cognitive disabilities. In addition, the element doesn't clearly define what its content is. It can be just text, an image, a link or something else. When assistive devices like screen readers don't know how to announce a website's content, their users might miss it or don't understand its purpose.</p>
<p>Automatically scrolling text can be unreadable by some people and severely distracting. Especially users with attention deficits have a hard time concentrating on other parts of the website when some content is moving or blinking. Some users also experience nausea from animated content. Such content can also cause problems for people using assistive technology to surf the web. These problems occur regardless of scrolling speed.</p>
<p>The latest version of the <a href="https://www.w3.org/TR/WCAG22/">Web Content Accessibility Guidelines (WCAG 2.2)</a> clearly presents recommendations to avoid the distraction of users during their interaction with a website. The <a href="https://www.w3.org/TR/WCAG22/#pause-stop-hide">success criterion 2.2.2</a> states that moving, blinking and scrolling information needs a mechanism to be paused or stopped. This rule applies if the animation:</p>
<ol>
<li>starts automatically</li>
<li>lasts longer than five seconds</li>
<li>is presented parallel with other content</li>
</ol>
<p>This requirement is Level A, meaning it is the minimum level of accessibility. Many users with disabilities will find it very difficult or impossible to access information. All websites should at least satisfy the minimum accessibility criteria.</p>
<h4>3. Usability problems</h4>
<p>The human eye is attracted to movement. As the content within the <code>marquee</code> element is constantly moving, it can be distracting for anybody, not just people with disabilities. Therefore using the marquee element results not only in accessibility but also in usability problems on a website.</p>
<p>When text inside a <code>marquee</code> element contains a link, additional problems occur. Clicking on a moving link is more complicated than clicking on static text. Depending on the speed and length of the scrolling text, some users may be unable to do so.</p>
<p>Users can also have difficulties printing a website if its content is not always fully visible. When multiple attempts are needed to complete the printing task, it makes it very inefficient, if not impossible.</p>
<h2 data-sanitized-id="the-alternative">The Alternative</h2>
<p>If you still want to get the "marquee aesthetic", there is a way without using the element. CSS <a href="https://drafts.csswg.org/css-animations/">animations</a> are a more suitable method. Creating the scrolling effect with CSS needs a bit more code to implement than using a single line of HTML. However, CSS is still the recommended practice as it is used to style content and create presentational effects, whereas HTML is not. In addition, CSS can be used to create more powerful and advanced animations. So let's get right into it.</p>
<h3 data-sanitized-id="replacing-the-marquee-element">Replacing the <code>marquee</code> element</h3>
<p>As a first step, we choose a standard HTML element instead of the <code>marquee</code> element. Depending on the type of content we want to animate, a different HTML element will be appropriate.</p>
<p>For the first example, we want to animate text. Therefore, we use the <code>p</code> element. We wrap this element inside a <code>div</code> container and add a class called <code>marquee-alternative</code>. This class name is arbitrary and was just added to style and animate our fake marquee with CSS later.</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>div</span> <span data-sanitized-class="token attr-name">class</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>marquee-alternative<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>p</span><span data-sanitized-class="token punctuation">&gt;</span></span>Newsflash: JLo and Ben Affleck got married!<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>p</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>div</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<h3 data-sanitized-id="styling-the-fake-marquee-element">Styling the fake marquee element</h3>
<p>The classic HTML <code>marquee</code> element typically moves across the screen's whole width. To recreate this original effect for our fake marquee element, we first set the <code>overflow</code> to <code>hidden</code> on the <code>div</code> container, which has the class <code>marquee-alternative</code>. This makes sure that no unwanted vertical scrolling is possible. We also assure the container has a <code>width</code> of <code>100%</code>.</p>
<pre data-sanitized-class="language-css"><code data-sanitized-class="language-css"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token selector">.marquee-alternative</span> <span data-sanitized-class="token punctuation">{</span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token property">overflow</span><span data-sanitized-class="token punctuation">:</span> hidden<span data-sanitized-class="token punctuation">;</span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token property">width</span><span data-sanitized-class="token punctuation">:</span> 100%<span data-sanitized-class="token punctuation">;</span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token punctuation">}</span></span></code></pre>
<p>The <code>p</code> element inside the <code>marquee-alternative</code> container needs some basic styling as well. To remove all unwanted default spacing of the <code>p</code> element, we set the <code>margin</code> to <code>0</code>. We also set the <code>width</code> to <code>fit-content</code>. This assures that the <code>p</code> element has the length of its content. This is important as we want the text of our fake marquee element to loop through without any delay. If the <code>p</code> element had the whole width of the screen (100%), there would be a few seconds where our marquee text is not visible after it left the screen.</p>
<pre data-sanitized-class="language-css"><code data-sanitized-class="language-css"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token selector">.right-to-left p</span> <span data-sanitized-class="token punctuation">{</span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token property">margin</span><span data-sanitized-class="token punctuation">:</span> 0<span data-sanitized-class="token punctuation">;</span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token property">width</span><span data-sanitized-class="token punctuation">:</span> fit-content<span data-sanitized-class="token punctuation">;</span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token punctuation">}</span></span></code></pre>
<h3 data-sanitized-id="adding-movement-with-css">Adding movement with CSS</h3>
<p>We can use CSS animations to move our fake marquee element over the screen. To create an animation, we use the<code>@keyframes</code> directive. Our custom animation called <code>marquee-right-to-left</code> starts at <code>100vw</code> (far right) and ends at <code>-100%</code> (far left). This means that our fake marquee begins outside the screen on the right side and moves to the left, ending outside the screen as well.</p>
<pre data-sanitized-class="language-css"><code data-sanitized-class="language-css"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token atrule"><span data-sanitized-class="token rule">@keyframes</span> marquee-right-to-left</span><span data-sanitized-class="token punctuation">{</span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token selector">from</span> <span data-sanitized-class="token punctuation">{</span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token property">transform</span><span data-sanitized-class="token punctuation">:</span> <span data-sanitized-class="token function">translateX</span><span data-sanitized-class="token punctuation">(</span>100vw<span data-sanitized-class="token punctuation">)</span><span data-sanitized-class="token punctuation">;</span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token punctuation">}</span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token selector">to</span> <span data-sanitized-class="token punctuation">{</span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token property">transform</span><span data-sanitized-class="token punctuation">:</span> <span data-sanitized-class="token function">translateX</span><span data-sanitized-class="token punctuation">(</span>-100%<span data-sanitized-class="token punctuation">)</span><span data-sanitized-class="token punctuation">;</span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token punctuation">}</span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token punctuation">}</span></span></code></pre>
<p>You may wonder why we use <code>100vw</code> as the start value and not <code>100%</code>. This is because we previously set the width of the <code>p</code> element to fit its content. If we used <code>100%</code> as a start value, the animation would not start outside of the screen but somewhere else, depending on the content length.</p>
<p><strong>Note:</strong> If you implement your fake marquee element and it is not supposed to move across the whole screen width, you must adapt the <code>100vw</code> value to your use case.</p>
<p>To start our keyframe animation, we add some animation properties to our <code>p</code> element. We refer to our <code>marquee-right-to-left</code> keyframe by setting the <code>animation-name</code>. We also specify an <code>animation-duration</code> of 20 seconds, <code>linear</code> movement and <code>infinite</code> repetitions. Depending on your desired marquee aesthetic, you can adapt these values to change the animation style according to your needs.</p>
<p>The shortened version of adding our CSS animation would be <code>animation: marquee-right-to-left 20s linear infinite;</code> instead of writing the 4 separate properties.</p>
<pre data-sanitized-class="language-css"><code data-sanitized-class="language-css"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token selector">.marquee-alternative p</span> <span data-sanitized-class="token punctuation">{</span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token property">margin</span><span data-sanitized-class="token punctuation">:</span> 0<span data-sanitized-class="token punctuation">;</span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token property">width</span><span data-sanitized-class="token punctuation">:</span> fit-content<span data-sanitized-class="token punctuation">;</span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token property">animation-name</span><span data-sanitized-class="token punctuation">:</span> marquee-right-to-left<span data-sanitized-class="token punctuation">;</span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token property">animation-duration</span><span data-sanitized-class="token punctuation">:</span> 20s<span data-sanitized-class="token punctuation">;</span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token property">animation-iteration-count</span><span data-sanitized-class="token punctuation">:</span> infinite<span data-sanitized-class="token punctuation">;</span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token property">animation-timing-function</span><span data-sanitized-class="token punctuation">:</span> linear<span data-sanitized-class="token punctuation">;</span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token punctuation">}</span></span></code></pre>
<div data-demo="Demo of our fake marquee">
  <div data-sanitized-class="advent2022 marquee-alternative">
    <p>Newsflash: JLo and Ben Affleck got married!</p>
  </div>
</div>
<p>Now our fake marquee element should work, just like the old HTML classic. <strong>But wait, we are not finished yet!</strong></p>
<h3 data-sanitized-id="dont-forget-accessibility">Don’t forget accessibility</h3>
<p>Some measures can be taken to make our fake marquee element more accessible and user-friendly.</p>
<h4>Reduce motion</h4>
<p>The <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-motion"><code>prefers-reduced-motion</code> media query</a> can be used to stop all animations for users that don't want them. As it is hard to decide when an animation is slow enough for people with disabilities, the best practice is to pause them entirely. In our case, we use the <code>prefers-reduced-motion</code> media query to only enable the animation if a user has no other preferences set.</p>
<p>We remove the <code>animation</code> property from the <code>.marquee-alternative p</code> nested class above and wrap it inside the media query.</p>
<pre data-sanitized-class="language-css"><code data-sanitized-class="language-css"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token selector">.marquee-alternative p</span> <span data-sanitized-class="token punctuation">{</span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token property">margin</span><span data-sanitized-class="token punctuation">:</span> 0<span data-sanitized-class="token punctuation">;</span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token property">width</span><span data-sanitized-class="token punctuation">:</span> fit-content<span data-sanitized-class="token punctuation">;</span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token comment">/* animation got removed here */</span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token punctuation">}</span></span><br><span data-sanitized-class="highlight-line"></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token comment">/* Only shows animation for users that have set no motion preference */</span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token atrule"><span data-sanitized-class="token rule">@media</span> <span data-sanitized-class="token punctuation">(</span><span data-sanitized-class="token property">prefers-reduced-motion</span><span data-sanitized-class="token punctuation">:</span> no-preference<span data-sanitized-class="token punctuation">)</span></span> <span data-sanitized-class="token punctuation">{</span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token comment">/* animation is added here */</span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token selector">.marquee-alternative p</span><span data-sanitized-class="token punctuation">{</span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token property">animation</span><span data-sanitized-class="token punctuation">:</span> marquee-right-to-left 20s linear infinite<span data-sanitized-class="token punctuation">;</span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token punctuation">}</span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token punctuation">}</span></span></code></pre>
<h4>Pause the animation</h4>
<p>There are two different ways to pause the <code>marquee</code> animation. We can add a pause/play <code>button</code> or stop the animation on <code>hover</code>. Adding a <code>button</code> would be a cleaner and more accessible option. However, some projects may not allow adding an extra <code>button</code>.  That is when we use the <code>hover</code> alternative with the help of a media query.</p>
<h5>Pause the animation on hover and on focus</h5>
<p>To ease the reading act and fight the issue of chasing moving text, we pause the animation when a user hovers over the marquee container (the <code>div</code>) or sets the focus on it. This is done by setting the <code>animation-play-state</code> to <code>paused</code> for the <code>p</code> element, on <code>hover</code> and <code>focus</code> of the <code>div</code>.</p>
<pre data-sanitized-class="language-css"><code data-sanitized-class="language-css"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token comment">/* Pause animation on hover and on focus */</span></span><br><span data-sanitized-class="token selector">.marquee-alternative:hover p,<br>.marquee-alternative:focus p</span><span data-sanitized-class="token punctuation">{</span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token property">animation-play-state</span><span data-sanitized-class="token punctuation">:</span> paused<span data-sanitized-class="token punctuation">;</span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token punctuation">}</span></span></code></pre>
<div data-demo="Demo of our fake marquee that pauses on hover and focus">
<div tabindex="0" data-sanitized-class="advent2022 marquee-alternative-2">
  <p>Newsflash: JLo and Ben Affleck got married!</p>
</div>
</div>
<h5>Add a pause/play button</h5>
<p>To comply with the previously named WCAG criterion 2.2.2, we add a play and pause button for the animation. Not every user has set their motion preferences to <code>reduce</code>. We still want to allow everybody to pause the animation if it is perceived as too distracting.</p>
<p><strong>Note:</strong> When you implement the pause/play button, remove the <code>animation-play-state: pause</code> from the previous step. Otherwise, it would confuse users why the text is paused although they haven't pressed the button yet.</p>
<p>As a first step, we wrap our existing <code>marquee-alternative</code> container into another <code>div</code> and assign it the class <code>marquee-container</code>. We then add a <code>button</code> element to start and stop the animation. It has the class <code>btn</code> and the <code>aria-pressed</code> state set to <code>false</code>. The <code>p</code> element gets the class <code>marquee-content</code> assigned to it. We also add the <code>animation-play-state</code> style to the <code>p</code> element to be able to change it later on with JavaScript.</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>div</span> <span data-sanitized-class="token attr-name">class</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>marquee-container<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>div</span> <span data-sanitized-class="token attr-name">class</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>marquee-alternative<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>p</span> <span data-sanitized-class="token attr-name">class</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>marquee-content<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token special-attr"><span data-sanitized-class="token attr-name">style</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span><span data-sanitized-class="token value css language-css"><span data-sanitized-class="token property">animation-play-state</span><span data-sanitized-class="token punctuation">:</span> running<span data-sanitized-class="token punctuation">;</span></span><span data-sanitized-class="token punctuation">"</span></span></span><span data-sanitized-class="token punctuation">&gt;</span></span>Newsflash: JLo and Ben Affleck got married!<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>p</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>div</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>button</span> <span data-sanitized-class="token attr-name">type</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>button<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">class</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>btn<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">aria-pressed</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>false<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>Pause<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>button</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>div</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<p>Now we add a little bit of styling to the new HTML elements. This CSS code is added in addition to the already existing styling from before.</p>
<p>The <code>.marquee-container</code> gets a <code>border</code> and <code>flex</code> position. All elements inside the container are aligned in its centre. The <code>.marquee-content</code>, which is our text, gets some styling as well.</p>
<pre data-sanitized-class="language-css"><code data-sanitized-class="language-css"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token selector">.marquee-container</span> <span data-sanitized-class="token punctuation">{</span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token property">display</span><span data-sanitized-class="token punctuation">:</span> flex<span data-sanitized-class="token punctuation">;</span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token property">align-items</span><span data-sanitized-class="token punctuation">:</span> center<span data-sanitized-class="token punctuation">;</span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token property">border</span><span data-sanitized-class="token punctuation">:</span> 3px solid #000<span data-sanitized-class="token punctuation">;</span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token punctuation">}</span></span><br><span data-sanitized-class="highlight-line"></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token selector">.marquee-content</span> <span data-sanitized-class="token punctuation">{</span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token property">margin</span><span data-sanitized-class="token punctuation">:</span> 0<span data-sanitized-class="token punctuation">;</span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token property">width</span><span data-sanitized-class="token punctuation">:</span> fit-content<span data-sanitized-class="token punctuation">;</span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token punctuation">}</span></span></code></pre>
<p>The <code>button</code> gets a basic styling by changing the <code>background-color</code>, <code>border</code>, <code>box-shadow</code>, <code>cursor</code> and <code>padding</code>. Make sure to add enough <code>padding</code> that the <code>button</code> has a minimum size of 48x48 px. This is the minimum click area a <code>button</code> should have to be accessible. <code>Hover</code> and <code>focus</code> styles are added to have a more apparent visual change when interacting with the button. We also change the visual appearance of the <code>button</code> when it gets pressed by styling it when <code>aria-pressed</code> is set to <code>true</code>.</p>
<pre data-sanitized-class="language-css"><code data-sanitized-class="language-css"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token selector">.btn</span> <span data-sanitized-class="token punctuation">{</span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token property">cursor</span><span data-sanitized-class="token punctuation">:</span> pointer<span data-sanitized-class="token punctuation">;</span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token property">background-color</span><span data-sanitized-class="token punctuation">:</span> #fff<span data-sanitized-class="token punctuation">;</span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token property">border</span><span data-sanitized-class="token punctuation">:</span> 0<span data-sanitized-class="token punctuation">;</span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token property">border-left</span><span data-sanitized-class="token punctuation">:</span> 3px solid #000<span data-sanitized-class="token punctuation">;</span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token property">padding</span><span data-sanitized-class="token punctuation">:</span> 1.1rem 1rem<span data-sanitized-class="token punctuation">;</span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token property">box-shadow</span><span data-sanitized-class="token punctuation">:</span> 0 0.5rem 0.5rem -0.125rem #0005<span data-sanitized-class="token punctuation">;</span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token punctuation">}</span></span><br><span data-sanitized-class="highlight-line"></span><br><span data-sanitized-class="token selector">.btn:hover,<br><span data-sanitized-class="highlight-line">.btn:focus-visible,</span><br>.btn[aria-pressed="true"]:hover</span> <span data-sanitized-class="token punctuation">{</span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token property">color</span><span data-sanitized-class="token punctuation">:</span> #fff<span data-sanitized-class="token punctuation">;</span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token property">background-color</span><span data-sanitized-class="token punctuation">:</span> #000<span data-sanitized-class="token punctuation">;</span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token punctuation">}</span></span><br><span data-sanitized-class="highlight-line"></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token selector">.btn[aria-pressed="true"]</span> <span data-sanitized-class="token punctuation">{</span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token property">box-shadow</span><span data-sanitized-class="token punctuation">:</span> 0 0.5rem 0.5rem -0.125rem inset #0005<span data-sanitized-class="token punctuation">;</span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token punctuation">}</span></span></code></pre>
<p>For the JavaScript part of this implementation, we first query the <code>marquee-content</code> (<code>p</code> element) and the <code>button</code> with the help of <code>document.querySelector</code> and save them into variables. This is done to make the code more readable.</p>
<pre data-sanitized-class="language-jsx"><code data-sanitized-class="language-jsx"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token keyword">let</span> marqueeText <span data-sanitized-class="token operator">=</span> document<span data-sanitized-class="token punctuation">.</span><span data-sanitized-class="token function">querySelector</span><span data-sanitized-class="token punctuation">(</span><span data-sanitized-class="token string">".marquee-content"</span><span data-sanitized-class="token punctuation">)</span><span data-sanitized-class="token punctuation">;</span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token keyword">let</span> button <span data-sanitized-class="token operator">=</span> document<span data-sanitized-class="token punctuation">.</span><span data-sanitized-class="token function">querySelector</span><span data-sanitized-class="token punctuation">(</span><span data-sanitized-class="token string">".btn"</span><span data-sanitized-class="token punctuation">)</span><span data-sanitized-class="token punctuation">;</span></span></code></pre>
<p>We then add an event listener for the <code>click</code> event of the <code>button</code>. When the <code>button</code> is clicked, we check if the animation is currently running by looking at the <code>animationPlayState</code>. If it is <code>running</code>, we stop the animation by setting the state to <code>paused</code>. We also change the <code>button.innerText</code> and set <code>ariaPressed</code> to <code>true</code>. As the <code>button</code> serves as a pause and play button, we also add the functionality of enabling the animation again after it was stopped. This is done by setting the <code>animationPlayState</code> back to <code>running</code> and changing the <code>button.innerText</code> and <code>ariaPressed</code> state again.</p>
<pre data-sanitized-class="language-jsx"><code data-sanitized-class="language-jsx"><span data-sanitized-class="highlight-line">button<span data-sanitized-class="token punctuation">.</span><span data-sanitized-class="token function">addEventListener</span><span data-sanitized-class="token punctuation">(</span><span data-sanitized-class="token string">"click"</span><span data-sanitized-class="token punctuation">,</span> <span data-sanitized-class="token punctuation">(</span><span data-sanitized-class="token punctuation">)</span> <span data-sanitized-class="token operator">=&gt;</span> <span data-sanitized-class="token punctuation">{</span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token keyword">const</span> isRunning <span data-sanitized-class="token operator">=</span> marqueeText<span data-sanitized-class="token punctuation">.</span>style<span data-sanitized-class="token punctuation">.</span>animationPlayState <span data-sanitized-class="token operator">==</span> <span data-sanitized-class="token string">"running"</span><span data-sanitized-class="token punctuation">;</span></span><br><span data-sanitized-class="highlight-line"></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token comment">// change behaviour of animation and button</span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token keyword">if</span> <span data-sanitized-class="token punctuation">(</span>isRunning<span data-sanitized-class="token punctuation">)</span> <span data-sanitized-class="token punctuation">{</span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token comment">// stop the animation</span></span><br><span data-sanitized-class="highlight-line">    marqueeText<span data-sanitized-class="token punctuation">.</span>style<span data-sanitized-class="token punctuation">.</span>animationPlayState <span data-sanitized-class="token operator">=</span> <span data-sanitized-class="token string">"paused"</span><span data-sanitized-class="token punctuation">;</span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token comment">// change button text</span></span><br><span data-sanitized-class="highlight-line">    button<span data-sanitized-class="token punctuation">.</span>innerText <span data-sanitized-class="token operator">=</span> <span data-sanitized-class="token string">"Play"</span><span data-sanitized-class="token punctuation">;</span></span><br><span data-sanitized-class="highlight-line">    button<span data-sanitized-class="token punctuation">.</span>ariaPressed <span data-sanitized-class="token operator">=</span> <span data-sanitized-class="token string">"true"</span><span data-sanitized-class="token punctuation">;</span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token punctuation">}</span> <span data-sanitized-class="token keyword">else</span> <span data-sanitized-class="token punctuation">{</span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token comment">// start the animation</span></span><br><span data-sanitized-class="highlight-line">    marqueeText<span data-sanitized-class="token punctuation">.</span>style<span data-sanitized-class="token punctuation">.</span>animationPlayState <span data-sanitized-class="token operator">=</span> <span data-sanitized-class="token string">"running"</span><span data-sanitized-class="token punctuation">;</span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token comment">// change button text</span></span><br><span data-sanitized-class="highlight-line">    button<span data-sanitized-class="token punctuation">.</span>innerText <span data-sanitized-class="token operator">=</span> <span data-sanitized-class="token string">"Pause"</span><span data-sanitized-class="token punctuation">;</span></span><br><span data-sanitized-class="highlight-line">    button<span data-sanitized-class="token punctuation">.</span>ariaPressed <span data-sanitized-class="token operator">=</span> <span data-sanitized-class="token string">"false"</span><span data-sanitized-class="token punctuation">;</span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token punctuation">}</span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token punctuation">}</span><span data-sanitized-class="token punctuation">)</span><span data-sanitized-class="token punctuation">;</span></span></code></pre>
<div data-demo="Demo of our fake marquee with a pause and play button">
<div data-sanitized-class="advent2022 marquee-container-3">
  <div data-sanitized-class="marquee-alternative-3">
    <p data-sanitized-class="marquee-content-3">Newsflash: JLo and Ben Affleck got married!</p>
  </div>
  <button type="button" aria-pressed="false" data-sanitized-class="btn-marquee">Pause</button>
</div>
</div>
<p>Your fake marquee element can now be stopped and activated again with the click of a button. This allows users to decide for themselves if they want to see the scrolling content on the screen or not.</p>
<h2 data-sanitized-id="conclusion">Conclusion</h2>
<p>Using the marquee aesthetic is a fun way of animating web content and grabbing a user's attention. But please be aware of the <code>marquee</code> element's impact on people. Even if the desired retro aesthetic is achieved without using the actual element but the presented alternative, the same named usability and accessibility concerns remain. So if you implement scrolling, animated content on your website, be conscious of its downsides and take measures to make the experience more accessible.</p>


guid: https://odysee.com/interview-a-talk-with-eva-karene:78e10580a10a08eda46352e855a8e1bb88dcfcf8
title: Interview: "A talk with Eva Karene Bartlett"
author: ;Eva K Bartlett
link: https://odysee.com/interview-a-talk-with-eva-karene:78e10580a10a08eda46352e855a8e1bb88dcfcf8
hash: ���l�PS��Τ� ^
content:
<p><img src="https://thumbnails.lbry.com/sKpw90HMnlw" width="480" alt="thumbnail" title="Interview: " a talk with eva karene bartlett></p>Interview I did yesterday. Absolutely lovely man--Alexandre Guerreiro--who interviewed me, he brought knowledge &amp; compassion to the interview.<br><br>First published here:<br>https://www.youtube.com/watch?v=1BeXKYSO5HY<br><br>His Twitter: <br>https://twitter.com/ATGuerreiro<br>...<br>https://www.youtube.com/watch?v=sKpw90HMnlw

attributes:
{"enclosures":[{"url":"https://player.odycdn.com/api/v3/streams/free/interview-a-talk-with-eva-karene/78e10580a10a08eda46352e855a8e1bb88dcfcf8/8847d5.mp4","type":"video/mp4","length":374401373}]}


guid: https://htmhell.dev/adventcalendar/2022/16/
title: 5 HTML elements, And a partridge in a despair tree
author: ;Manuel Matuzovic
link: https://htmhell.dev/adventcalendar/2022/16/
hash: ���?��?P�ئ����
attributes: {"enclosures":[]}
content:
<p>HTML is a beautiful programming language. It comes with many out-of-the-box accessibility benefits—it conveys semantic meaning to assistive technology, enabling people to consume content and complete often important journeys that they may not be able to do outside of the web. So why is all that goodness we can get for free ignored so often?</p>
<p>To expand on that point a little, why do we ignore native HTML elements that will tell people exactly what their purpose is and enable them to interact with it, and use overly complex ARIA-laden JavaScript solutions? Some of this may come down to how something is designed, while in other cases it may be misunderstanding/confusion or copied-and-pasted bad practices. In this article, we'll look at 5 common instances when semantic HTML is ignored.</p>
<h2 data-sanitized-id="lessbuttongreater"><code>&lt;button&gt;</code></h2>
<p>Let's start with a topic that people will have seen many discussions around—interactive buttons. Take a look at the <a href="https://www.htmhell.dev/">latest postings on the HTMLHell site</a>, which will no doubt feature this issue heavily!</p>
<p>A button is often used to toggle or activate some dynamic functionality for a user. That could be to reveal a menu with important pages included, submit a form, toggle expandable content, and so on.</p>
<p>HTML includes the <code>&lt;button&gt;</code> element. This tells people that it can be interacted with and can help communicate the state of a component. By default, it is focusable, has key events, and comes with some browser default styles.</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>button</span> <span data-sanitized-class="token attr-name">type</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>button<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>I'm a real button<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>button</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<p>Here we have some default browser styling making it <em>look like a button</em>, have focus behavior handled for us, and have key events mapped to it (<code>click</code>, <code>keyup</code>, <code>keydown</code>, etc) making it <em>act like a button</em>. Because <strong>it is a button!</strong></p>

<div data-demo="demo">
<button type="button" data-sanitized-class="button1">I'm a real button</button>
</div>

<p>Unfortunately, a pattern that is all too common–and used in the wrong circumstances–is to <a href="https://benmyers.dev/blog/clickable-divs/">turn a non-interactive element into a faux button</a>.</p>
<p>This will often be achieved with an ARIA role:</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>div</span> <span data-sanitized-class="token attr-name">role</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>button<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">tabindex</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>0<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>I'm not a button<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>div</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<div data-demo="demo">
<div role="button" tabindex="0" data-sanitized-class="button2">I'm not a button</div>
</div>

<p>This <code>&lt;div&gt;</code> (a non-semantic element designed for containing things) would now be announced as an interactive element by assistive technology, this is all well and good, but is it robust and accessible? No.</p>
<p>We're telling assistive technology that it's a button, but providing none of the functionality that comes with the native element.</p>
<p>As well as the role, we'd also then need to handle focus behavior manually using JavaScript and the <code>tabindex</code> attribute and also <a href="https://adrianroselli.com/2022/04/brief-note-on-buttons-enter-and-space.html">handle key events</a>. This adds unnecessary complexity and requires the user to download JavaScript just to do something that could be done with a native element.</p>
<h3 data-sanitized-id="extra-considerations">Extra considerations</h3>
<p>Whilst using a native button is a great start, there are other things to consider. Does your button have a suitable accessible name? (especially if it's an icon button). If the button has the purpose of taking a person to another page, it should be a link (<code>&lt;a&gt;</code>).</p>
<p>The following links are great resources for helping create a great button (or link).</p>
<ul>
<li><a href="https://css-tricks.com/a-complete-guide-to-links-and-buttons/">A complete guide to Links and buttons</a> on CSS-Tricks</li>
<li><a href="https://adrianroselli.com/2016/01/links-buttons-submits-and-divs-oh-hell.html">Links, Buttons, Submits, and Divs, Oh Hell</a> by Adrian Roselli</li>
</ul>
<h2 data-sanitized-id="lessselectgreater"><code>&lt;select&gt;</code></h2>
<p>A <code>&lt;select&gt;</code> is a control that provides a menu of options.</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>label</span> <span data-sanitized-class="token attr-name">for</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>select<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>Sort by<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>label</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>select</span> <span data-sanitized-class="token attr-name">id</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>select<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">name</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>select<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>option</span> <span data-sanitized-class="token attr-name">value</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>popularity<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>By popularity<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>option</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>option</span> <span data-sanitized-class="token attr-name">value</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>price-low-high<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>By lowest price<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>option</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>option</span> <span data-sanitized-class="token attr-name">value</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>price-high-low<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>By highest price<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>option</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>select</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<div data-demo="demo">
<label for="select">Sort by</label><br>
<select name="select" data-sanitized-id="select">
	<option value="popularity">By popularity</option>
	<option value="price-low-high">By lowest price</option>
	<option value="price-high-low">By highest price</option>
</select>
</div>
<p>When a person changes the option of the select, the value of it then becomes the value of the new option, nice! All browsers support this control and <a href="https://a11ysupport.io/tech/html/select_element">assistive technology support</a> is strong too. Screen readers announce the control's accessible name (our label in this example), how to open the select menu, the list of options, and then the value when selected.</p>
<p>For what is an important interaction for many products, it's surprising how many custom-built “select” controls there are in the wild. This normally comes down to a few reasons, all fairly related to each other:</p>
<ul>
<li>The design has come through and included elements other than text in the select options (checkboxes, images, multi-select functionality)</li>
<li>Select controls can be notoriously difficult to style, and the options even more so</li>
<li>Rendering inconsistencies between browsers/OS: Although the functionality remains consistent, a select and its states can look very different from one browser to another and especially with their options showing</li>
</ul>
<h3 data-sanitized-id="why-not-fake-a-select-though?">Why not <em>fake</em> a select though?</h3>
<p>It is of course possible to build something that looks and behaves like a <code>&lt;select&gt;</code> with other elements and a sprinkle of JavaScript and ARIA. It's also possible to make this into a robust and accessible solution; for example, <a href="https://24ways.org/2019/making-a-better-custom-select-element/">Julie Grundy's article</a> from 24 WAYS. This example uses semantic HTML and is careful in its usage of ARIA.</p>
<p>Whilst it may be doable, let's consider a few reasons it might still be better to suggest and use the native <code>&lt;select&gt;</code>.</p>
<h4>Future developer readability</h4>
<p>Whilst a more custom and complex approach may make sense to one developer who has followed an example/tutorial to build the component, a developer picking up bugs/changes/feature requests in the future may not have as good of an understanding of how all the elements have been set up and what their roles are supposed to be.</p>
<p>Although this could be solved with sufficient documentation, it's still extra work for somebody else to get up to speed with.</p>
<h4>Misconfiguration</h4>
<p>When using ARIA to add a role to an element to try and improve assistive technology communication, it can often require very specific roles to be included in parent/child element relationships. If misconfigured, not only will the whole component not announce correctly, but it's breaking accessibility and might cause more problems than it was used to solve!</p>
<p>The more complex and ARIA-heavy these custom components are—a custom select being a good example of one that could be with enough features—the more chance of this misconfiguration happening, especially concerning the previous point of somebody with less understanding picking up changes.</p>
<h4>Communicate with design—'shift left'</h4>
<p>Many accessibility issues can be solved during the design phase. The barriers we create are designed in, and the more we can shift the conversation and responsibility of accessibility to earlier in the product lifecycle, the better (often referred to as shifting left).</p>
<p>Constant and efficient communication between designers and developers can play a huge part in this. During sessions such as a design-developer handover, or <a href="https://www.figma.com/community/file/953682768192596304">accessibility annotation pairing</a>, it could be a great time to have a conversation about how a certain component design might lead to extra complexity, and to see if a native HTML element might be able to fit into the design.</p>
<p>Not only could this help educate a designer when it comes to semantics and accessibility considerations for future work, but it could also stop accessibility issues from getting to development or even to further down the line, when fixes/changes become much more expensive, or, even worse, end up unintentionally excluding people in production.</p>
<h3 data-sanitized-id="help-on-the-way?">Help on the way?</h3>
<p><a href="https://open-ui.org/">The Open UI project</a> is trying to make it easier for designers/developers to both use native controls for elements like <code>&lt;select&gt;</code> and to have the styling and functionality freedom that often turns people to use more complex custom solutions that can be inaccessible:</p>
<blockquote>The purpose of Open UI to the web platform is to allow web developers to style and extend built-in web UI controls, such as <code>&lt;select&gt;</code> dropdowns, checkboxes, radio buttons, and date/color pickers.
To do that, we'll need to fully specify the component parts, states, and behaviors of the built-in controls, as well as necessary accessibility requirements, and provide test suites to ensure compatibility. We'll also implement polyfills for our extensible web UI controls.
Whilst the project is still in its infancy, concerning the <code>&lt;select&gt;</code> element, there have been some developments with <code>&lt;selectmenu&gt;</code>. Whilst not ready for production yet, it can be <a href="https://open-ui.org/prototypes/selectmenu">enabled in Chromium-based browsers with a flag</a>. <code>&lt;selectmenu&gt;</code> allows greater customisation of the select control and the options that sit inside of it.</blockquote>
<p>You can read more about it in Hidde's article <a href="https://htmhell.dev/adventcalendar/2022/13/">“One day we'll have a fully customisable select”</a>.</p>
<h2 data-sanitized-id="lessnavgreater"><code>&lt;nav&gt;</code></h2>
<p>Navigation allows users to complete important journeys and find the key information they may need.</p>
<p>HTML includes the <code>&lt;nav&gt;</code> element. This is <a href="https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/roles/landmark_role">a landmark element</a> and means it will automatically communicate to assistive technology that it's an element being used for navigation links (the same as adding <code>role="navigation"</code>).</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>nav</span> <span data-sanitized-class="token attr-name">aria-label</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>Main<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>ul</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>a</span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>/about<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>About Us<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>a</span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>a</span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>/history<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>Our History<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>a</span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>a</span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>/contact<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>Contact Us<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>a</span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>ul</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>nav</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<p>This is a perfectly accessible example of some navigation. <strong>No ARIA is needed</strong>. However, navigation can often require multiple levels of nested dropdowns, and become more complex. The example can still add this and be accessible, which we will take a look at, but first let's look at a pattern often reached for when it comes to navigation with dropdowns - <code>role="menu"</code>.</p>
<p>Whilst the naming of <code>role="menu"</code> and the child roles it requires ( <code>role="menuitem"</code>) may suggest that it'd be perfect to use for site navigation, the purpose of it is very different. This pattern is more for replicating desktop application menus. <a href="https://adrianroselli.com/2017/10/dont-use-aria-menu-roles-for-site-nav.html">Adrian Roselli has a superb article</a> explaining the difference.</p>
<p>You can see an example of how this would be marked up on the <a href="https://www.w3.org/WAI/ARIA/apg/example-index/menubar/menubar-navigation.html">aria authoring practices site</a>. Whilst there are cautionary recommendations at the top of the page detailing how this is unsuitable for site navigation, the page goes on to use it for one. This is an example of how just using these resources as a copy-and-paste solution can lead to bad practices.</p>
<p>Going back to how we can use <code>&lt;nav&gt;</code> and more semantic elements to start to create site navigation with multiple levels:</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>nav</span> <span data-sanitized-class="token attr-name">aria-label</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>Main<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>ul</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>a</span> <span data-sanitized-class="token attr-name">aria-current</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>page<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>#<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>Home<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>a</span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">      <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>a</span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>#<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>About Us<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>a</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"></span><br>      <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>button</span><br><span data-sanitized-class="highlight-line">        <span data-sanitized-class="token attr-name">type</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>button<span data-sanitized-class="token punctuation">"</span></span></span><br><span data-sanitized-class="highlight-line">        <span data-sanitized-class="token attr-name">aria-expanded</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>false<span data-sanitized-class="token punctuation">"</span></span></span><br><span data-sanitized-class="highlight-line">        <span data-sanitized-class="token attr-name">aria-controls</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>about-us-submenu<span data-sanitized-class="token punctuation">"</span></span></span><br>      <span data-sanitized-class="token punctuation">&gt;</span></span><br><span data-sanitized-class="highlight-line">        <span data-sanitized-class="token comment">&lt;!-- Visual cue icon - for example a downward facing chevron --&gt;</span></span><br><span data-sanitized-class="highlight-line">        <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>svg</span> <span data-sanitized-class="token attr-name">aria-hidden</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>true<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">focusable</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>false<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">aria-hidden</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>true<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">          <span data-sanitized-class="token comment">&lt;!-- Icon SVG code --&gt;</span></span><br><span data-sanitized-class="highlight-line">        <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>svg</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">        <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>span</span> <span data-sanitized-class="token attr-name">class</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>visually-hidden<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>Toggle About Us submenu<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>span</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">      <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>button</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"></span><br><span data-sanitized-class="highlight-line">      <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>ul</span> <span data-sanitized-class="token attr-name">id</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>about-us-submenu<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">        <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>a</span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>#<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>Our history<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>a</span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">        <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>a</span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>#<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>Meet the team<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>a</span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">      <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>ul</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>a</span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>#<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>Work<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>a</span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>a</span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>#<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>Contact<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>a</span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>ul</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>nav</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<p>Here we're using nested unordered lists to mark up the second level of navigation, meaning that visually and semantically, the different levels of the menu item are related to each other, even without CSS and JavaScript loading.</p>
<p>You might be asking “but there is ARIA in there now, and you said we didn't need any?”. This is true, but we can use ARIA in the appropriate way to <strong>enhance</strong> the experience for people using assistive technology; we just shouldn’t solely rely on its <code>role</code> attribute to communicate that it's a navigation in the first place. Of course, JavaScript will also be needed to toggle some of these attributes, but, by default, without any of this our markup is semantic and accessible.</p>
<p>For a more detailed guide to building a semantic and accessible navigation, check out <a href="https://web.dev/website-navigation/">the web.dev navigation article by Manuel</a>.</p>
<h2 data-sanitized-id="lessul/olgreater"><code>&lt;ul/ol&gt;</code></h2>
<p>Lists (ordered and unordered) are very common elements used on sites. They both have semantic HTML elements:</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>ul</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span>Unordered list item<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span>Another unordered list item<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span>Yet another unordered list item<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>ul</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<div data-demo="demo">
<ul>
  <li>Unordered list item</li>
  <li>Another unordered list item</li>
  <li>Yet another unordered list item</li>
</ul>
</div>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>ol</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span>Ordered list item<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span>Another ordered list item<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span>Yet another ordered list item<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>ol</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<div data-demo="demo">
<ol>
	<li>Ordered list item</li>
	<li>Another ordered list item</li>
	<li>Yet another ordered list item</li>
</ol>
</div>
<p>They can help with things such as visually and semantically breaking down complex points, and they can give expectations of important steps to complete or consider. Communicating that a list with several items (and possibly links) exists can be important to people using assistive technology; for example, it can communicate how many items are in the list.</p>
<p>A common mistake that can be made is to just visually represent a list with a combination of other HTML elements; for example (<a href="https://htmhell.dev/30-bullet-list/">taken from HTMLHell</a>):</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>p</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  • HTML</span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>br</span> <span data-sanitized-class="token punctuation">/&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  • CSS</span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>br</span> <span data-sanitized-class="token punctuation">/&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  • JavaScript</span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>p</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<p>Whilst this may visually represent a list, it is going to give people using assistive technology a very different experience. Each 'item' has no relation to the other. As it's just one paragraph element, this would give people no indication of how many items were present and how they relate in context and the order if they needed to be read sequentially.</p>
<h3 data-sanitized-id="who-would-do-that-though?">Who would do that though?</h3>
<p>Unordered lists were amongst the <a href="https://www.webdesignmuseum.org/web-design-history/tim-berners-lee-published-a-document-called-html-tags-1991">first 18 HTML tags released</a> so why do people still ignore them over just visually representing a list? And why are they so important? Aside from poor markup choices, there could be a few other reasons for this issue occurring.</p>
<h4>CMS WYSIWYG output</h4>
<p>It may not be apparent to somebody how to add lists in a content management system WYSIWYG editor, thus causing them to just visually create the list of items (for example using the bullet point shown in the previous example).</p>
<h4>Content editor skill gaps</h4>
<p>When content editors add content in a CMS it may be that they have misunderstood that using return to add items to a newline does not create a list, but it might visually appear to look like one to them in previews, etc.</p>
<h4>Markdown/other language confusion</h4>
<p>In some content language formats, such as markdown, lists can be added by using the hyphen/asterisk to indicate a list item, and these are then translated into correct list markup. It could be that somebody has mistakenly tried this thinking it might be the case.</p>
<h4>CSS advancements</h4>
<p>Ok, so this is an HTML-focused article, but let's not forget that CSS is amazing! What we can do with it in modern web development is incredible. It also makes being able to use semantic elements easier/more appealing if it was styling reasons they were not used for in the first place.</p>
<p><a href="https://developer.mozilla.org/en-US/docs/Web/CSS/::marker">The <code>::marker</code> pseudo element</a> enables styling on the bullet point of an u <code>ul</code>, whether it just be changing the colour of it, or adding custom content to it.</p>
<p><a href="https://developer.mozilla.org/en-US/docs/Web/CSS/@counter-style">There's also the <code>@counter-style</code> rule</a>. This enables the usage of non-standard bullet types but also can convert this to a string, meaning better accessibility considerations.</p>
<p>For ordered lists <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/counter-reset">the counter reset property</a> can help with custom styling numeric counters.</p>
<h3 data-sanitized-id="slight-tangent-incoming!">Slight tangent incoming!</h3>
<p>Educating content editors on using semantic markup can be an important part of ensuring that semantic, accessible content is being added to a site. Despite designing and building an accessible experience, this work could be undone by fundamental knowledge gaps when adding content such as blog posts, case studies, etc if they are handled through a CMS. Link text, image alt text, heading structure, correct element usage, etc. can all have detrimental effects on a person's experience.</p>
<p>If the importance of using semantic and accessible elements and structure is lost on somebody, it can be useful to remind people that it can have many benefits; for example, SEO and readability. Jeremy Keith has an interesting thought on <a href="https://adactio.com/journal/18199">doing the right things for the wrong reason</a>.</p>
<p>End of tangent.</p>
<h3 data-sanitized-id='lists-and-safari-"list"-itis'>Lists and Safari "list"-itis</h3>
<p>Something to consider when using lists and testing behavior with iOS/MacOS and Safari and VoiceOver, is the removal of default styles (<code>list-style: none;</code>). With this combination of OS and browser, this style will remove the semantics using the <code>&lt;ul&gt;</code> or <code>&lt;ol&gt;</code> element provides. The reasoning behind this comes from the overuse of lists to mark components up.</p>
<p>A bug was filed for this 'issue' which prompted the following response:</p>
<blockquote>This was a purposeful change due to rampant “list”-itis by web developers. … Basically, if you remove all default visible indication of the list, there is no indication to a sighted user or screen reader user that the content is a list. If you want to override this heuristic for accessibility, you can always add an explicit ARIA role=”list”.
As suggested to get around this, you can explicitly add a role to the element:</blockquote>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>ul</span> <span data-sanitized-class="token attr-name">role</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>list<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token comment">&lt;!-- List items --&gt;</span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>ul</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<p>Although this seems verbose (it'll also get flagged when validating HTML) and is an extra <em>thing</em> to remember, it'll make the experience much better for people using VoiceOver and encountering a list.</p>
<p><em><strong>Note</strong></em>: This is not needed when the <code>ul</code> is the child of a <code>nav</code> landmark element. In this case the <a href="https://twitter.com/cookiecrook/status/1612487416346193921">semantics of the list elements are preserved</a>(disclaimer: links to a Twitter thread), even if default styling is removed. Another great reason to make sure navigation is marked up semantically and accessibly.</p>
<p>So still announce list semantics if list was custom styled.</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>nav</span> <span data-sanitized-class="token attr-name">aria-label</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>Main<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>ul</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">      <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>a</span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>/about<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>About Us<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>a</span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">      <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>a</span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>/history<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>Our History<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>a</span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">      <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>a</span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>/contact<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>Contact Us<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>a</span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>ul</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>nav</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<h2 data-sanitized-id="lessfieldsetgreater"><code>&lt;fieldset&gt;</code></h2>
<p>Forms are a critical part of many journeys on a site, but yet they are so often marked up inaccessibly or use patterns that do not take user needs into account. There are also many examples I've seen where native elements have been ignored in favor of overly complex solutions.</p>
<p>The <code>&lt;fieldset&gt;</code> and <code>&lt;legend&gt;</code> elements are a great way to break up more complex forms, and can greatly improve the flow and experience of filling a form out for many people:</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>form</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>fieldset</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>legend</span><span data-sanitized-class="token punctuation">&gt;</span></span>How would you like to hear from us?<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>legend</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token comment">&lt;!-- Checkboxes with selection options --&gt;</span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>fieldset</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>form</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<p>The <code>&lt;fieldset&gt;</code> element implicitly communicates a role of <code>group</code>—useful for grouping logically related items-and the <code>&lt;legend&gt;</code> provides the 'caption' or accessible name for it thus, communicating to assistive technology such as screen readers that the fields within are related and providing a label to announce.</p>
<p>Here's an example seen recently on a documentation site of using non-semantic elements to do this:</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>form</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>div</span> <span data-sanitized-class="token attr-name">id</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>my-radio-group<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>Picked<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>div</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>div</span> <span data-sanitized-class="token attr-name">role</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>group<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">aria-labelledby</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>my-radio-group<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>label</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">      <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>Field</span> <span data-sanitized-class="token attr-name">type</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>radio<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">name</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>picked<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">value</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>One<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token punctuation">/&gt;</span></span></span><br><span data-sanitized-class="highlight-line">      One</span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>label</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>label</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">      <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>Field</span> <span data-sanitized-class="token attr-name">type</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>radio<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">name</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>picked<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">value</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>Two<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token punctuation">/&gt;</span></span></span><br><span data-sanitized-class="highlight-line">      Two</span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>label</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>div</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>div</span><span data-sanitized-class="token punctuation">&gt;</span></span>Picked: {values.picked}<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>div</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>button</span> <span data-sanitized-class="token attr-name">type</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>submit<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>Submit<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>button</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>form</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<p>This would result in a very similar experience to the fieldset and legend pattern but is just doing more work to get there. It's using non-semantic elements and using ARIA to turn them into something that can be done natively!</p>
<p>The issue with examples like this being included on documentation sites is that it runs the risk of being copied and pasted as an example, and then becoming habits in that codebase.</p>
<p>Other benefits native elements can offer would also have to be manually handled; for example, <code>&lt;fieldset&gt;</code> can take a <code>disabled</code> attribute, which would make all child input controls disabled.</p>
<h3 data-sanitized-id="other-form-element-tips">Other form element tips</h3>
<p>OK, so these do push this article over the 5 elements specified in the title. <em>However</em>, due to the number of times these issues come up on forms, and how low-hanging, high-impact they can be to fix, let's quickly mention them.</p>
<h4>Accessible input names</h4>
<p>Don't rely solely on placeholder attributes for input controls that require people to enter text/numbers etc. These can often fail colour contrast requirements, have patchy support for assistive technology, and aren't translated if internationalisation is required.</p>
<p>One solution could be to add an <code>aria-label</code> to the control, as this would provide an accessible name; however, even better would be to include an associated visual label for the control. This has benefits for many user groups.</p>
<p>Do also try to steer clear of the 'floating label' pattern. Although it does seem to strike a great balance between the designed 'placeholder' look and having a label, it can often introduce accessibility issues of its own, such as hard-to-read text and leaving the input feeling crowded.</p>
<h4>Validation messaging</h4>
<p>Ensure that colour alone is not being relied on to convey meaning in validation messaging. It can be nice UX (user experience) to include a suitable icon along with the message, for example, an exclamation with an error. If this can't be achieved, <a href="https://design-system.service.gov.uk/components/error-message/#be-clear-and-concise">ensure messaging is well-written</a>.</p>
<p>Make sure that the messaging is suitably announced to assistive technology. This can be done via an <a href="https://tink.uk/accessible-forms-with-aria-live-regions/">ARIA live region</a>. When we think about errors associated with inputs, in particular, not having this surfaced immediately could create barriers for people relying on using a form to complete a journey/access a vital service.</p>
<p><strong>Note</strong>: Although live regions are a great idea for important or time sensitive content like form errors. Be careful overusing it, it can become very 'noisy' and disruption on a person's journey.</p>
<h2 data-sanitized-id="summary">Summary</h2>
<p>In this article, we've covered only a small amount of the <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element">HTML elements available</a>. Each case reviewed how using a native HTML element can reduce complexity when building a component and the need for having to manually handle a range of possible interactions people using different input methods need to use, which requires JavaScript.</p>
<p>When reviewing a design, consider if you might be able to use a native HTML element to achieve the functionality, or consider having a conversation with design to see if something could change to allow you to do so. Communications such as accessibility annotation sessions can be useful for this.</p>
<p>HTML can do a lot, without needing to reach for and ship large chunks of JavaScript and potentially exclude whole groups of people interacting with a component. It's robust, semantic, and accessible. Take time to learn it, and where and when to use it.</p>
<h2 data-sanitized-id="further-reading">Further reading</h2>
<p>Some useful links to help learn more about using semantic and accessible HTML. Also how to use ARIA responsibly if needed.</p>
<ul>
<li><a href="https://web.dev/learn/html/">web.dev - learn HTML</a></li>
<li><a href="https://web.dev/learn/accessibility/">web.dev - learn accessibility</a></li>
<li><a href="https://developer.mozilla.org/en-US/docs/Glossary/semantics#semantics_in_html">Why semantics matter</a>—reasoning and examples, should you need it</li>
<li><a href="https://inclusive-components.design/">Inclusive Components</a>—progressive, robust, semantic, and accessible common component patterns from Heydon Pickering</li>
<li><a href="https://www.w3.org/TR/aria-in-html/">Using ARIA</a>—including the 5 rules of ARIA</li>
<li><a href="https://www.w3.org/WAI/ARIA/apg/">ARIA authoring practices guide</a></li>
</ul>


guid: https://htmhell.dev/adventcalendar/2022/17/
title: Modern HTML as a foundation for progressive enhancement
author: ;Manuel Matuzovic
link: https://htmhell.dev/adventcalendar/2022/17/
hash: Y�leзN�^A�
attributes: {"enclosures":[]}
content:
<p>Reading HTMHell, you might be aware that progressive enhancement is a thing. To sum things up, it's a way to make sure anyone gets a viable version of your page whatever is their context — slow bandwitdh, oldish  browser, etc. — but also making the said page more resilient (e.g. to JavaScript errors).</p>
<p>Progressive enhancement starts from the ground up:</p>
<ol>
<li>content,</li>
<li>marked up with HTML,</li>
<li>styled with CSS,</li>
<li>enhanced with JavaScript</li>
<li>and improve accessibility with a bit of ARIA.</li>
</ol>
<p>Each of those steps should work as-is and enhance the lower steps without breaking them. In other words, you would need to write your markup independently from the CSS or JS you will apply later on.</p>
<p>Great.</p>
<p>That being said, it's kinda obvious that the better you know each step in the stack the more robust your page should be. JavaScript is everywhere so we may assume you know about it. ARIA is getting some shedlight for a few years now, so even without knowing ARIA we may suppose you use components libraries or something doing this just fine. CSS is constantly improving, I suppose you're following and discovering new CSS stuff every day or so.</p>
<p>But what about HTML? Is it part of your technical watch? How frequent are new HTML stuff popping out in your information sources? Not so often, I guess.</p>
<p>But hey. HTML is a living standard so specifications do change, browsers always improve support for HTML —as part of <a href="https://wpt.fyi/interop-2022">Interop 2022</a> for example— so there are new kids in town, either specified or implemented in browsers, and some of them are meant to be native controls replacing long-standing <code>&lt;div&gt;</code>-based JavaScript components.</p>
<p>What if we could improve the HTML stack for such components, making the markup step more resilient?</p>
<p><strong>Disclaimer</strong>: you need to think of HTML as a foundation, not a replacement for your existing JavaScript component. If your pattern needs ARIA, do not try to implement a low-elevel component. In other word, always try to provide the best possible user experience and don't care too much about developer experience. You may be interested in <a href="https://adrianroselli.com/2022/10/under-engineered-patterns-for-a11ytoconf.html#References">Adrian Roselli's under-engineered components blog posts serie</a>.</p>
<p>Let's go for a ride!</p>
<h2 data-sanitized-id="lessdetailsgreater-and-lesssummarygreater-as-a-aria-disclosure-pattern-foundation"><code>&lt;details&gt;</code> and <code>&lt;summary&gt;</code> as a ARIA disclosure pattern foundation</h2>
<p>Think of those "Show more" button thinggies where activating it make the content below appear. Making such component accessible currently require you to implement <a href="https://www.w3.org/WAI/ARIA/apg/patterns/disclosure/">the ARIA disclosure design pattern</a>, basically using a button with <code>aria-expanded</code> attribute to communicate state.</p>
<p><code>&lt;details&gt;</code> and <code>&lt;summary&gt;</code> are a really good fit for this. As their names are pretty obvious, this markup pattern will display a summary and hide details—but make details available when activating the summary— and the <a href="https://thepaciellogroup.github.io/AT-browser-tests/test-files/details-summary.html">browsers implementation</a> and <a href="https://caniuse.com/details">support</a> are really good.</p>
<p>This feels quite right, isn't it? So why bother with the disclosure pattern at all and not use details and summary all the way? Well, interactions are not exactly what's expected by your users and support in browser and assistive technologies is not straightforward yet— <a href="https://www.scottohara.me/blog/2022/09/12/details-summary.html">as Scott O'Hara pointed out</a>.</p>
<p>But… may we use it as our foundation for an ARIA disclosure pattern? <a href="https://codepen.io/ffoodd/pen/XWYmmGj">Let's figure it out in a dedicated CodePen</a>!</p>
<p data-height="300" data-default-tab="html,result" data-slug-hash="XWYmmGj" data-user="ffoodd" data-sanitized-class="codepen">
  <span>See the Pen <a href="https://codepen.io/ffoodd/pen/XWYmmGj">
  Enhanced &lt;details&gt; with ARIA disclosure</a> by ffoodd (<a href="https://codepen.io/ffoodd">@ffoodd</a>)
  on <a href="https://codepen.io/">CodePen</a>.</span>
</p>
<p>Not much magic here: to improve and harmonize AT support, we make it a disclosure by adding to <code>&lt;summary&gt;</code> a button role and <code>aria-expanded</code> to convey state and make sure the disclosed content is hidden with the eponymous attribute. The <code>open</code> attribute on <code>&lt;details&gt;</code> handles this natively but <a href="https://www.scottohara.me/blog/2022/09/12/details-summary.html#impact-of-removing-the-default-disclosure-triangle">we can't rely on it as long as we override the default triangle marker</a> —which we will undoubtedly do: we must fully implement the disclosure pattern to prevent inconsistent rendering in browsers and ATs.</p>
<p>Moreover, did you know Chromium-based browsers allow collapsed details content discoverability using browser search? That's something coming to HTML with <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/hidden#the_hidden_until_found_state">the <code>until-found</code> value for the <code>hidden</code> attribute</a>, but that's not supposed to be the case of disclosed content when using the ARIA pattern.</p>
<p>As you may have understood, using <code>&lt;details&gt;</code> and <code>&lt;summary&gt;</code> enhanced with the ARIA disclosure pattern makes little to no difference for most users… but whenever your JS or CSS fails, your semantic markup would take over and stay interactive—with all its current limitations in ATs.</p>
<p>Also please be careful using those elements as a foundation: they aren't a good fit <a href="https://daverupert.com/2019/12/why-details-is-not-an-accordion/">for accordions</a>, <a href="https://melsumner.github.io/details-as-a-menu">a flyout menu</a>, <a href="https://cloudfour.com/thinks/a-details-element-as-a-burger-menu-is-not-accessible/">a burger menu</a>, <a href="https://adrianroselli.com/2019/04/details-summary-are-not-insert-control-here.html">a tab set or a dialog</a>… Stay semantic!</p>
<p>What if I told you there's more progressively enhanceable HTML elements like those? Wanna have a look?</p>
<h2 data-sanitized-id="lessoutputgreater-as-a-live-region"><code>&lt;output&gt;</code> as a live region</h2>
<p>Ever needed to populate a live region to communicate content changes to screen reader users—often being <a href="https://kittygiraudel.com/2016/10/13/css-hide-and-seek/">visually hidden with CSS</a>? That's quite common now, and you find live region handling in some frameworks: <a href="https://material.angular.io/cdk/a11y/overview#liveannouncer">Angular has a <code>LiveAnnouncer</code> in its Accessibility CDK</a>, <a href="https://make.wordpress.org/accessibility/handbook/markup/wp-a11y-speak/">WordPress has it <code>wp.a11y.speak()</code> internal script</a>… <a href="https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Live_Regions">ARIA live regions rely on three specific roles: <code>status</code>, <code>log</code> and <code>alert</code></a>, each having a slightly different behaviour.</p>
<p>But did you know there's an HTML element that's a native live region, with an implicit <code>status</code> role? <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/output">Meet &lt;output&gt;</a>! Its <a href="https://thepaciellogroup.github.io/AT-browser-tests/test-files/output.html">browser implementation is complete</a> and <a href="https://caniuse.com/mdn-html_elements_output">support is excellent</a>. However some specific browsers and ATs pairing are flawed, as <a href="https://www.scottohara.me/blog/2019/07/10/the-output-element.html">Scott O'Hara (again) pointed out</a>.</p>
<p><a href="https://codepen.io/ffoodd/pen/rNvqGBB">Let's make <code>&lt;output&gt;</code> more robust by making it an ARIA live region, on CodePen</a>!</p>
<p data-height="300" data-default-tab="html,result" data-slug-hash="rNvqGBB" data-user="ffoodd" data-sanitized-class="codepen">
  <span>See the Pen <a href="https://codepen.io/ffoodd/pen/rNvqGBB">
  Enhanced &lt;output&gt; with status role</a> by ffoodd (<a href="https://codepen.io/ffoodd">@ffoodd</a>)
  on <a href="https://codepen.io/">CodePen</a>.</span>
</p>
<p>As you may remember, expliciting HTML elements roles was quite needed a few years ago for landmarks mostly to improve support in browsers and ATs —and still recommended in some accessibility guidelines like <a href="https://www.numerique.gouv.fr/publications/rgaa-accessibilite/methode-rgaa/criteres/#crit-12-6">the French RGAA</a>. We got used to write <code>&lt;main role="main"&gt;</code>, <code>&lt;header role="banner"&gt;</code> and so on. What's also good with <code>&lt;output role="status"&gt;</code> is that it allows you to style your live regions by selecting the output element: lower specificity, and some kind of soft reset too —CSS containment, maybe?</p>
<h3 data-sanitized-id="a-more-specific-live-region-toast!">A more specific live region: toast!</h3>
<p>There's also a case for visually displayed live regions: toasts! I won't go way further on the topic, because it's been explored in a wide variety of posts: <a href="https://www.scottohara.me/blog/2019/07/10/the-output-element.html">Scott O'Hara already mentionned <cite>The output element</cite></a>, a technical follow-up of his <a href="https://www.scottohara.me/blog/2019/07/08/a-toast-to-a11y-toasts.html"><cite>A toast to an accessible toast…</cite> addressing UX concerns)</a>, and <a href="https://adrianroselli.com/2020/01/defining-toast-messages.html">Adrian Roselli in <cite>Defining toast messages</cite></a>.</p>
<p><strong>Warning</strong>: if your toast or live region contains interactive elements, it should probably use a <code>dialog</code> or <code>alertdialog</code> role, and preferably not an <code>&lt;output&gt;</code> element at all. But… there might be another HTML element for that!</p>
<h2 data-sanitized-id="a-modal-lessdialoggreater">A modal <code>&lt;dialog&gt;</code></h2>
<p>I won't go that deep with <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dialog">the <code>&lt;dialog&gt;</code> element</a>, but let's explore what it does natively compared to <a href="https://www.w3.org/WAI/ARIA/apg/patterns/dialogmodal/">the ARIA dialog design pattern</a>:</p>
<ul>
<li>it has an implicit <code>dialog</code> role,</li>
<li>when opened with the <code>.showModal()</code> method:
<ul>
<li>it has an implicit <code>aria-modal="true"</code> property,</li>
<li>it's closable with the <kbd>Escape</kbd> key,</li>
</ul>
</li>
<li>it traps focus in the dialog —but allows to get out of the browser frame…</li>
<li>it restores focus to the opening element when closing the dialog,</li>
<li>it makes the document <a href="https://developer.mozilla.org/docs/Web/API/HTMLElement/inert"><code>inert</code></a> automatically.</li>
</ul>
<p>And there's more:</p>
<ul>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/CSS/::backdrop">the <code>::backdrop</code> pseudo-element</a> allows you to style your dialog overlay really easily,</li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/CSS/:modal">the <code>:modal</code> pseudo-class</a> applies when opening dialog with the <code>.showModal()</code> method,</li>
<li>if your dialog contains a form, using <code>method="dialog"</code> form attribute makes your submit button to close the dialog.</li>
</ul>
<p>Dialog element on its own isn't consistent enough in browsers and ATs (yet), <a href="https://www.scottohara.me/blog/2019/03/05/open-dialog.html">as Scott O'Harra (again) pointed out</a>, but you got the idea: what about enhancing it by applying the ARIA dialog pattern to it, and relying on its standard behaviour to save a few lines of JavaScript? That's more or less what <a href="https://web.dev/building-a-dialog-component/">Adam Argyle explored in his dialog component pattern on web.dev</a> with some nice little tricks to learn —however keep in mind <a href="https://twitter.com/aardrian/status/1586792250113232896">web.dev patterns aren't battle-tested with ATs nor against WCAG</a>. <a href="https://css-tricks.com/dialog-components-roll-your-own/">Building a dialog component is not straightforward</a>, and <a href="https://www.smashingmagazine.com/2021/07/accessible-dialog-from-scratch/">Kitty Giraudel goes in details about what's needed to make an <cite>accessible dialog from scratch</cite></a>. Since those posts, the dialog support has improved quite a lot and is even <a href="https://wpt.fyi/interop-2022">part of Interop 2022</a>, so expect it to improve again this year's last month.</p>
<p>This is probably the least obvious case, since speaking of progressive enhancement the <code>&lt;dialog&gt;</code> element might be a bad choice: it simply cannot work without JavaScript. But if your JavaScript fails for any reason, your event handlers might still work.</p>
<h2 data-sanitized-id="conclusion">Conclusion</h2>
<p>HTML is awesome. It's obviously not enough to provide a fully accessible experience to users, as <a href="https://daverupert.com/2020/02/html-the-inaccessible-parts/">Dave Rupert highlighted two years ago in <cite>HTML: the inaccessible parts<cite></cite></cite></a> — even if some of those examples are not accurate anymore, fixed in either browser or ATs.</p>
<p>But not being perfect is probably still better than being neutral, isn't it?</p>
<p>I think that's the kind of thing HTML unveils: at some point, details and summary shall be consistently implemented and exposed to ATs, making ARIA enhancements pointless. Scott's work, from advanced testing to blog posts and filing bugs, are the way forward. Fully implemented patterns in libraries like <a href="https://a11y-dialog.netlify.app/">Kitty Giraudel's a11y-dialog</a> are what alllows maturity and clarify expectations. And as usage increases, browsers and ATs will eventually consider prioritization, in Interop or <a href="https://aria-at.w3.org/">ARIA-AT</a>.</p>
<p>Let's use, test and help browsers and ATs support those newer HTML elements!</p>


guid: https://odysee.com/senator-richard-black-on-ukraine-war-on:026e005a35b1a0019bc4b494a9e42df60acc44ca
title: Senator Richard Black on Ukraine War on the Donbass, Russia's Reaction, NATO's Drive to Nuclear War
author: ;Eva K Bartlett
link: https://odysee.com/senator-richard-black-on-ukraine-war-on:026e005a35b1a0019bc4b494a9e42df60acc44ca
hash: �\}���v��V&��T
content:
<p><img src="https://thumbnails.lbry.com/ys_lI6mXA_c" width="480" alt="thumbnail" title="Senator Richard Black on Ukraine War on the Donbass, Russia's Reaction, NATO's Drive to Nuclear War"></p>“There is this element of madmen—some of the politicians, some of them military people, many of them in the US State Department, the CIA—who would be willing to do the most reckless and insane of actions to risk nuclear war or even to initiate it.” <br><br>On December 16, I spoke with Senator Richard Black about Ukraine's long war against the civilians of the Donbass, Russia's Special Military Operation in Ukraine, and the Western warmongers behind it all and their drive for endless war.<br><br>Senator Black has had an extensive military, legal and political career, serving in the US marines, and after obtaining his law degree, serving in the U.S. Army Judge Advocate General’s Corps and head of the Army’s Criminal Law Division in the Pentagon. He served eight years in the Virginia State Senate.<br><br>He is one of the few sane American voices loudly advocating for the end to Ukraine's genocide of the Donbass people, and for an end to the West's proxy war against Russia.<br><br>Follow him at:<br><br>http://www.senatorblack.com/<br>https://twitter.com/SenRichardBlack<br><br>Related Links:<br><br>*Chronology of events: the war didn't start in February 2022<br>https://www.thepostil.com/the-military-situation-in-the-ukraine/<br><br>*My Donetsk &amp; Lugansk People's Republics playlist<br>https://www.youtube.com/playlist?list=PLqtiZC-4QZC3VvabZMbM0FbOcwBoLdGBT<br><br>*My Syria writings<br>https://ingaza.wordpress.com/syria/syria-my-published-articles-from-and-on-syria-2014-2022/ <br><br>*The Referendum on Joining Russia<br>https://ingaza.wordpress.com/2022/09/29/dpr-civilians-on-why-they-wanted-a-referendum-to-join-russia/<br>https://ingaza.wordpress.com/2022/10/01/interviews-with-donetsk-residents-after-joining-russia/<br>https://ingaza.wordpress.com/2022/09/28/my-interview-from-donetsk-on-the-peoples-eagerness-to-vote-to-join-russia/<br><br>*Ukrainian war crimes I've experienced or documented<br><br>https://ingaza.wordpress.com/2022/10/24/ukrainian-army-war-crimes-include-shelling-of-ambulences-firetrucks-and-rescue-workers-in-the-donbass-republics-similar-to-israelis-and-u-s-backed-terrorists-in-syria/<br><br>14 Year Old Is One of 87 Donbass Civilians Maimed By Petal Mines Fired By Ukraine<br>https://www.youtube.com/watch?v=K-QSv-zwoSU <br><br>Carnage: Ukraine's terrorism on Donetsk September 19 killed 16 civilians, 9 in one spot<br>https://www.youtube.com/watch?v=zJpXcwMAVeI<br><br>Ukraine shelled a completely civilian area of central Donetsk, killing at least 5 civilians<br>https://www.youtube.com/watch?v=CWqeFG7DhIs<br><br>Ukrainian Terrorism of Central Donetsk September 17 Kills 4, Using Western Weapons<br>https://www.youtube.com/watch?v=kzew0mXOo2Y <br><br>More Ukrainian War Crimes: Killing &amp; Maiming Heroic Donbass Medics &amp; Emergency Workers<br>https://www.youtube.com/watch?v=BJZvxWQfSHc <br><br>Donbass Frontline Villager: "Ukraine Doesn't Consider Us Human", Wants To "Annihilate Us”<br>https://www.youtube.com/watch?v=tYLC5hsd2aA<br><br>Using American HIMARS, Ukraine Bombed Central Donetsk Building Nov 7<br>https://www.youtube.com/watch?v=0EArikOHkXc <br><br>Ukraine's Bombing of Central Donetsk August 4: 2 Ballerinas Among the 6 Murdered by Ukraine<br>https://www.youtube.com/watch?v=IQNQ_vT_j-k <br><br>Ukraine bombed just outside the hotel I was in. Was Ukraine targeting journalists?<br>https://www.youtube.com/watch?v=JqZgG7s-Sjw <br><br>Ukrainian Terrorism: Firing Munitions Containing Petal Mines On Donbass Orphanage, Another War Crime<br>https://www.youtube.com/watch?v=dCpRy1iDXcA<br><br>Ukraine turns Donetsk into a minefield using banned ‘Petal’ mines<br>https://www.youtube.com/watch?v=B6wJbPJv0kk <br><br>Civilians Fled Ukraine's Shelling of Popasnaya For Safety in Stakhanov, But Ukraine Bombs There Too<br>https://www.youtube.com/watch?v=C3H2zrrW3Dk <br><br>Ukraine Bombarded Donetsk, Including Bombing a Maternity Hospital, Then Claimed Russian Did It<br>https://www.youtube.com/watch?v=rsLWcR21iK8 <br><br>Ukrainian bombing of civilian areas of Donetsk June 13 killed 5 &amp; caused massive fires<br>https://www.youtube.com/watch?v=0tlJ8MgMCLs <br><br>Kirovsk, a City Under Ukrainian Fire<br>https://www.youtube.com/watch?v=IYpI05Rhcg4<br><br>https://ingaza.wordpress.com/2022/08/25/in-just-under-three-weeks-ukrainian-fired-prohibited-petal-mines-maim-at-least-44-civilians-kill-2-in-donetsk-region/ <br>https://ingaza.wordpress.com/2022/09/26/western-media-continues-to-ignore-how-ukraine-is-using-nato-weapons-to-kill-innocent-civilians-in-the-donbass/<br>https://ingaza.wordpress.com/2022/08/10/what-ive-seen-of-ukraines-war-crimes-against-civilians-in-the-donbass-over-the-past-few-months/ <br>https://ingaza.wordpress.com/2022/08/06/ukraine-bombed-a-donetsk-hotel-full-of-journalists-heres-what-it-felt-like-to-be-inside-at-the-time/ <br>https://ingaza.wordpress.com/2022/06/17/western-media-and-politicians-prefer-to-ignore-the-truth-about-donetsk-civilians-killed-in-ukrainian-shelling/ <br>https://ingaza.wordpress.com/2022/04/29/ukrainian-strike-on-donetsk-market-was-a-terrorist-act/ <br>https://ingaza.wordpress.com/2022/04/08/they-saw-and-heard-the-truth-then-lied-about-it-media-on-donbass-delegation-omitted-mention-of-ukraines-8-year-war-on-the-autonomous-republics/<br>...<br>https://www.youtube.com/watch?v=ys_lI6mXA_c

attributes:
{"enclosures":[{"url":"https://player.odycdn.com/api/v3/streams/free/senator-richard-black-on-ukraine-war-on/026e005a35b1a0019bc4b494a9e42df60acc44ca/7a7cf2.mp4","type":"video/mp4","length":662559195}]}


guid: https://htmhell.dev/adventcalendar/2022/18/
title: Mini-guide to add an image
author: ;Manuel Matuzovic
link: https://htmhell.dev/adventcalendar/2022/18/
hash: �5kC���Ic�-�"
attributes: {"enclosures":[]}
content:
<p>Adding an image with HTML is pretty easy, it’s just a simple tag, after all, right?</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>img</span> <span data-sanitized-class="token attr-name">src</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>path/to/image.jpg<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token punctuation">/&gt;</span></span></span></code></pre>
<p>But when you start taking into consideration topics such as performance, screen sizes, accessibility, pixel density, or user preferences, you might ask yourself at some point if plain HTML is enough for the task… And the answer is yes! HTML has many options and is powerful enough to handle this task. This article will cover what you should consider at the moment of adding an image to a site with HTML.</p>
<h2 data-sanitized-id="basic-considerations">Basic considerations</h2>
<h3 data-sanitized-id="alt-attribute"><code>alt</code> attribute</h3>
<p>Let’s start with a very important one: your image needs an alternative text. It’ll have screen reader users to identify the image content, but it’ll also help when the image doesn’t load (maybe because the image is not available, or maybe because the user has a slow network). Otherwise, they won’t know what the image is. This can be done with the <code>alt</code> attribute.</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>img</span> <span data-sanitized-class="token attr-name">src</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>path/to/image.jpg<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">alt</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>A white cat laying on a sofa<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token punctuation">/&gt;</span></span></span></code></pre>
<p>Keep in mind, sometimes an image is there for purely decorative purposes, so making it visible for screen readers might not be ideal, in those cases, you can use an empty <code>alt</code> to make screen readers ignore this image.</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>img</span> <span data-sanitized-class="token attr-name">src</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>path/to/image.jpg<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">alt</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span><span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token punctuation">/&gt;</span></span></span></code></pre>
<p>What should the alternative text contain? Usually, it should contain a brief but concise description of what’s in the image. If it’s an image with important information (like a place for an event or a full infographic), this information should also be in alternative text. W3C has created <a href="https://www.w3.org/WAI/tutorials/images/decision-tree/">an alt decision tree</a> to help you decide what information you should add.</p>
<h3 data-sanitized-id="width-and-height-attribute"><code>width</code> and <code>height</code> attribute</h3>
<p>One of the most important metrics for performance is <strong>Cumulative Layout Shift (CLS)</strong>, which measures how much a website's content shifts when it’s on screen. In other words, a low CLS means the content is pretty stable and will create no problem with user interactivity. You can check more about this concept, you can check <a href="https://web.dev/cls/">this article on web.dev about CLS</a>.</p>
<p>Image loading can create layout shift issues and one way to avoid them is by using the attributes <code>width</code> and <code>height</code> for images. It’ll tell the browser the intrinsic size of the image, and it’ll create the image’s aspect ratio when the website is loading, which will reduce the layout shift it can create. This is how it’d look in an image.</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>img</span> <span data-sanitized-class="token attr-name">src</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>path/to/image.jpg<span data-sanitized-class="token punctuation">"</span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token attr-name">alt</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>A white cat laying on a sofa<span data-sanitized-class="token punctuation">"</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token attr-name">width</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>1200<span data-sanitized-class="token punctuation">"</span></span></span><br>  <span data-sanitized-class="token attr-name">height</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>800<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token punctuation">/&gt;</span></span></code></pre>
<p>But that’s not all we can do to improve performance on our website with an <code>img</code> tag!</p>
<h3 data-sanitized-id="lazy-loading">Lazy loading</h3>
<p>You can have a lot of images on your website, and that can affect its loading time. This is where the concept of <strong>lazy loading</strong> comes in. That means the image will start to load only when it’s on the visible part of the viewport. There was a time when this was made with JavaScript but now HTML offers us a way to do it easily by using the attribute <code>loading="lazy"</code></p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>img</span> <span data-sanitized-class="token attr-name">src</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>path/to/image.jpg<span data-sanitized-class="token punctuation">"</span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token attr-name">alt</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>A white cat laying on a sofa<span data-sanitized-class="token punctuation">"</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token attr-name">width</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>1200<span data-sanitized-class="token punctuation">"</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token attr-name">height</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>800<span data-sanitized-class="token punctuation">"</span></span></span><br>  <span data-sanitized-class="token attr-name">loading</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>lazy<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token punctuation">/&gt;</span></span></code></pre>
<p>When you use <code>loading="lazy"</code> in tandem with <code>height</code> and <code>width</code> attributes, you’ll make sure the website has enough space for the image at the moment of loading, and at the same time, you’ll not load the image unless the user needs it, which is great for performance!</p>
<p>Keep in mind though, if a user has JavaScript disabled, <code>loading="lazy"</code> won’t work, so you need to keep in mind other performance considerations, but let’s put a pin on that topic for now.</p>
<p>Also, keep in mind using <code>loading="lazy"</code> in your Largest Content Painting element (we’ll talk about this metric later) will actually <strong>increase</strong> your loading time, so be careful and always test it to know if this attribute gives the intended results.</p>
<h3 data-sanitized-id="figure-and-figcaption"><code>figure</code> and <code>figcaption</code></h3>
<p>Sometimes, you need to add additional information that wouldn’t fit in the <code>alt</code>, like image credits, or an important note about it that you’d prefer everybody can access to it. You can use the tag <code>figure</code> to wrap the <code>img</code> and then add a caption with the tag <code>figcaption</code>.</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>figure</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br>  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>img</span> <span data-sanitized-class="token attr-name">src</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>path/to/image.jpg<span data-sanitized-class="token punctuation">"</span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token attr-name">alt</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>A white cat laying on a sofa<span data-sanitized-class="token punctuation">"</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token attr-name">width</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>1200<span data-sanitized-class="token punctuation">"</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token attr-name">height</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>800<span data-sanitized-class="token punctuation">"</span></span></span><br>    <span data-sanitized-class="token attr-name">loading</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>lazy<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token punctuation">/&gt;</span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>figcaption</span><span data-sanitized-class="token punctuation">&gt;</span></span>Persian cats can be recognized by their big hair, round face, and short muzzle<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>figcaption</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>figure</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<p>Keep in mind, <code>figcaption</code> needs to be a direct child of the <code>figure</code> element. Otherwise, it might not be recognized by assistive technologies. This is something Manuel highlights in his article <a href="https://www.matuzo.at/blog/2022/divs-are-bad/">divs are bad!</a>.</p>
<p>Keeping these considerations in mind helps a lot when you create an image, but that’s just the tip of the iceberg. When you start taking into consideration multiple variables like screen sizes, image formats, and user preferences. <code>img</code> tag starts to fall short in power. This is where another tag comes in to add more functionality!</p>
<h2 data-sanitized-id="picture-tag"><code>picture</code> tag</h2>
<p>This tag is a container for multiple image sources and depending on the conditions you add to them, the browser will start choosing the right file depending on multiple factors like the viewport’s size, image format, pixel density, or user preferences. It acts as a wrapper for the multiple <code>source</code> elements you’ll use to determine the best image.</p>
<p>Let’s start checking out what we can do with this element.</p>
<h3 data-sanitized-id="supporting-different-image-formats">Supporting different image formats</h3>
<p>Unlike <code>.png</code> or <code>.jpg</code> image formats, there are image formats like <code>.avif</code>, <code>.webp</code>, or <code>.apng</code> that you might want to use because they don’t have a loss in quality but have much less weight that a more supported format. However, the previously mentioned image formats have broader support. We can use the <code>source</code> tag to let us use more optimized image formats depending on the browser’s support. For this, we can use the attribute <code>type</code> in the <code>source</code> element to indicate the format you need to evaluate.</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>picture</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>source</span> <span data-sanitized-class="token attr-name">srcset</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>path/to/image.avif<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">type</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>image/avif<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token punctuation">/&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>source</span> <span data-sanitized-class="token attr-name">srcset</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>path/to/image.webp<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">type</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>image/webp<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token punctuation">/&gt;</span></span></span><br>  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>img</span> <span data-sanitized-class="token attr-name">src</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>path/to/image.jpg<span data-sanitized-class="token punctuation">"</span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token attr-name">alt</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>A white cat laying on a sofa<span data-sanitized-class="token punctuation">"</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token attr-name">width</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>1200<span data-sanitized-class="token punctuation">"</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token attr-name">height</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>800<span data-sanitized-class="token punctuation">"</span></span></span><br>    <span data-sanitized-class="token attr-name">loading</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>lazy<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token punctuation">/&gt;</span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>picture</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<p>In this case, it’ll start checking if the browser can accept the <code>.avif</code> format, if it’s not the case (like Safari before version 16), it’ll check if the <code>.webp</code> format is supported. If it’s not, it’ll show the one in the <code>img</code> element. There are multiple image formats available. If you want to learn more about it, you can check <a href="https://developer.mozilla.org/en-US/docs/Web/Media/Formats/Image_types">MDN’s documentation about this topic</a>.</p>
<p>Do you remember I mentioned <code>loading="lazy"</code> might not be enough for performance purposes? This will help us to consider the browser’s support to load the most optimal image possible, creating a very robust system to give the user the best image quality possible <strong>and</strong> use as less bandwidth as necessary. It’s the best of both worlds, and that’s possible with just HTML!</p>
<h3 data-sanitized-id="responsive-images">Responsive images</h3>
<p>You may want to show a different image or a different part of an image depending on the viewport’s size. <code>picture</code> element can help us with that with the <code>media</code> attribute, where we can use a media query to detect the viewport’s size and add a different image when needed.</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>picture</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>source</span> <span data-sanitized-class="token attr-name">srcset</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>path/to/image-mobile.jpg<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">media</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>(max-width: 600px)<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token punctuation">/&gt;</span></span></span><br>  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>img</span> <span data-sanitized-class="token attr-name">src</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>path/to/image.jpg<span data-sanitized-class="token punctuation">"</span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token attr-name">alt</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>A white cat laying on a sofa<span data-sanitized-class="token punctuation">"</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token attr-name">width</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>1200<span data-sanitized-class="token punctuation">"</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token attr-name">height</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>800<span data-sanitized-class="token punctuation">"</span></span></span><br>    <span data-sanitized-class="token attr-name">loading</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>lazy<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token punctuation">/&gt;</span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>picture</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<p>You can use any valid media query there, so for example <code>orientation: portrait</code> and <code>orientation: landscape</code> are valid options when you want to show a different image depending on if the viewport’s width is bigger (or smaller) than its width. There are many possibilities you can consider to give the best image to the user.</p>
<h3 data-sanitized-id="user-preferences">User preferences</h3>
<p>Now, this is very convenient for performance and user experience, but this also has an important use for accessibility: we can check user preferences to help people with certain disabilities.<br>
For example, some people might have problems like migraines that would prefer to use dark mode, and a very bright image could trigger a migraine attack, so having a version of your image that is better suited for dark mode would be ideal.</p>
<p>Or maybe you have a gif, and someone has disabled animations on their device. You might want to show a static image instead so their experience is not affected. How can we do that?</p>
<p>As I mentioned, you can use any valid media query, that includes media queries that check user preferences like <code>prefers-color-scheme</code> or <code>prefers-reduced-motion</code>. We can even mix them with logical operators to show the appropriate image. Let’s check out how it works with an example.</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>picture</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token comment">&lt;!-- Both dark mode preference and animations are disabled --&gt;</span></span><br>  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>source</span> <span data-sanitized-class="token attr-name">srcset</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>path/to/image-dm.jpg<span data-sanitized-class="token punctuation">"</span></span><br>    <span data-sanitized-class="token attr-name">media</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>(prefers-reduced-motion: reduce) and (prefers-color-scheme: dark)<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token punctuation">/&gt;</span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token comment">&lt;!-- Static image when animations are disabled --&gt;</span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>source</span> <span data-sanitized-class="token attr-name">srcset</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>path/to/image.jpg<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">media</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>(prefers-reduced-motion: reduce)<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token punctuation">/&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token comment">&lt;!-- Dark mode preference is checked --&gt;</span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>source</span> <span data-sanitized-class="token attr-name">srcset</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>path/to/image-dm.gif<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">media</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>(prefers-color-scheme: dark)<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token punctuation">/&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  </span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token comment">&lt;!-- None of those preferences is active --&gt;</span>        </span><br>  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>img</span> <span data-sanitized-class="token attr-name">src</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>path/to/image.gif<span data-sanitized-class="token punctuation">"</span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token attr-name">alt</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>A cat dancing<span data-sanitized-class="token punctuation">"</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token attr-name">width</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>1200<span data-sanitized-class="token punctuation">"</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token attr-name">height</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>800<span data-sanitized-class="token punctuation">"</span></span></span><br>    <span data-sanitized-class="token attr-name">loading</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>lazy<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token punctuation">/&gt;</span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>picture</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<p>It’s very important to note that order matters, it’s better to add the tags with more specific media query requirements first to be sure they will not be overwritten by the ones that will appear later. Also, keep in mind you can combine all you have seen, so there are a lot of possibilities with <code>picture</code> and <code>source</code> elements.</p>
<p>That covers mostly everything you should consider but there are a couple of points you can take into account.</p>
<h2 data-sanitized-id="additional-considerations">Additional considerations</h2>
<h3 data-sanitized-id="pixel-density-and-srcset">Pixel density and <code>srcset</code></h3>
<p>The attribute <code>srcset</code> you use in the picture element has a slightly different syntax if you want to give a better image depending on the device’s pixel density. For this, we can add a list of images separated by commas and after the image’s URL, we’ll put the type of pixel density we want to support with this image. Let’s take a look at it with an example:</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>picture</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br>  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>source</span><br>    <span data-sanitized-class="token attr-name">srcset</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>path/to/image-mobile.jpg 1x,<br><span data-sanitized-class="highlight-line">            path/to/image-mobile-2x.jpg 2x,</span><br>            path/to-image-mobile-3x.jpg 3x<span data-sanitized-class="token punctuation">"</span></span><br>    <span data-sanitized-class="token attr-name">media</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>(max-width: 600px)<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token punctuation">/&gt;</span></span><br>  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>img</span> <span data-sanitized-class="token attr-name">src</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>path/to/image.jpg<span data-sanitized-class="token punctuation">"</span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token attr-name">alt</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>A white cat laying on a sofa<span data-sanitized-class="token punctuation">"</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token attr-name">width</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>1200<span data-sanitized-class="token punctuation">"</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token attr-name">height</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>800<span data-sanitized-class="token punctuation">"</span></span></span><br>    <span data-sanitized-class="token attr-name">srcset</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>path/to/image-2x.jpg 2x,<br>            path/to/image-3x.jpg 3x<span data-sanitized-class="token punctuation">"</span></span><br>    <span data-sanitized-class="token attr-name">loading</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>lazy<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token punctuation">/&gt;</span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>picture</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<p>There is something I didn’t mention and that is the fact you can use the <code>srcset</code> attribute in the <code>img</code> element, and it works great when you want to support images depending on the device’s pixel density. Next time to want to bring better quality images for images depending on the device, you now know how to do that!</p>
<h3 data-sanitized-id="preload-image-to-improve-lcp">Preload image to improve LCP</h3>
<p>Do you remember when I mentioned CLS? There is another metric called <a href="https://web.dev/lcp/">Largest Content Paint (LCP)</a> which is a metric that measures how much it takes to load the biggest image (or text block) to render in the viewport. Commonly, this LCP is a big image. We can use other image formats to decrease the LCP’s size, but what if that’s not enough? We have the alternative of preloading the image in the <code>head</code>, so it'll make the image renders faster, and by extension, improve this metric. This is how it’d look in our <code>head</code> tag.</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>head</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>link</span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>preload<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>path/to/image.jpg<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">as</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>image<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token punctuation">/&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>head</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<p>You don’t want to abuse this technique though, because otherwise, it’ll <strong>increase</strong> the page load time. Just use it for your most important image(s) and test performance accordingly to check if it’s improving those metrics.</p>
<h3 data-sanitized-id='decoding="async"'><code>decoding="async"</code></h3>
<p>I mentioned <code>loading="lazy"</code> before but there is another HTML attribute we can use to optimize a website’s loading time. While <code>loading="lazy"</code>  decides <strong>when</strong> the image will be loaded (at the moment that it is close to the viewport), we have another attribute that defines <strong>how</strong> it’ll be loaded</p>
<p>Normally, all our site will be loaded synchronously because the browser reads HTML line by line, so if it finds a big image, the rest of the site won’t download until the image is loaded. This is where  <code>decoding="async"</code> enters to give a hint to the browser to try to download the image and at the same time downloading another part of the site.</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>img</span> <span data-sanitized-class="token attr-name">alt</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>A white cat laying on a sofa<span data-sanitized-class="token punctuation">"</span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token attr-name">width</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>1200<span data-sanitized-class="token punctuation">"</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token attr-name">height</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>800<span data-sanitized-class="token punctuation">"</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token attr-name">loading</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>lazy<span data-sanitized-class="token punctuation">"</span></span> </span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token attr-name">decoding</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>async<span data-sanitized-class="token punctuation">"</span></span></span><br><span data-sanitized-class="token punctuation">/&gt;</span></span></code></pre>
<p>Using both, <code>decoding="async"</code> and <code>loading="lazy"</code> in an image, it’ll help to reduce greatly a website’s loading time, and <code>decoding</code> is a highly supported attribute.</p>
<h2 data-sanitized-id="wrapping-up">Wrapping up</h2>
<p>Adding an image to a website is easy… But things start to complicate when you start to keep in mind performance and accessibility considerations. Luckily for us, HTML can give us the proper tools to tackle those considerations with no problem at all.</p>
<p>I chose this topic for this Advent Calendar for a reason and it’s because it made me notice how powerful, robust, and surprisingly complex HTML is. Seeing what HTML has to offer just to bring the right image to your screen with relatively low effort was fascinating and it started me to make dig deeper into what HTML can do.</p>


guid: https://htmhell.dev/adventcalendar/2022/19/
title: Do you know color-scheme?
author: ;Manuel Matuzovic
link: https://htmhell.dev/adventcalendar/2022/19/
hash: %yO !j�+�# ��
attributes: {"enclosures":[]}
content:
<p>Do you know of <code>color-scheme</code> yet? If not, I bet you still think you do. It will certainly look familiar, as <code>prefers-color-scheme</code> has been around for longer and is clearly related.</p>
<p>You're in good company if it's new to you - the <a href="https://2022.stateofcss.com/en-US/features/accessibility/#color_scheme">State of CSS 2022</a> results just came in, and 73% of respondents had never heard of it.</p>
<p>You probably use <code>prefers-color-scheme</code> a lot within your CSS media queries, to make a dark or light theme for your sites and apps based on user preference. Maybe you also add a toggle so people can choose their color scheme, irrespective of their OS settings. Beautiful. But now there's more to play with!</p>
<h3 data-sanitized-id="what-is-color-scheme-then?">What is color-scheme, then?</h3>
<p>It's a CSS property all of its own, and can save you a bunch of styling work for dark mode.</p>
<pre data-sanitized-class="language-css"><code data-sanitized-class="language-css"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token comment">/* the selector here could be :root, html or body */</span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token selector">:root</span> <span data-sanitized-class="token punctuation">{</span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token property">color-scheme</span><span data-sanitized-class="token punctuation">:</span> light dark<span data-sanitized-class="token punctuation">;</span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token punctuation">}</span></span></code></pre>
<p>Stick the above inside your stylesheet or <code>&lt;style&gt;&lt;/style&gt;</code> tags and voila, your website, without any other styling, will now respond to the user's <code>prefer-color-scheme</code> preference, as can now often be specified in their OS settings. There are default colors set in the browser for bare HTML not only in light mode, but also in dark mode. Cool, right?</p>
<figure>
<img src="https://htmhell.dev/images/advent2022/19/bare-html.png" alt="Screenshot of two bare-HTML mini-sites, one light, one dark" loading="lazy">
<figcaption>Comparison of two mock plain HTML sites, one with color-scheme set to light, one set to dark.</figcaption>
</figure>
<p>If you're like me, and tend to create little simpler sites - or if you make bigger ones with minimal styling, and you want to provide dark mode with as little extra faff as possible, you will want to explore using <code>color-scheme</code>. There's another bit of magic here - you don't even need to use it with a <code>&lt;style&gt;</code> tag, or <code>.css</code> file at all, if you don't want. You can get dark mode with HTML only.</p>
<p>Yep, just HTML. Without even touching your CSS. You can also place it inside the <code>&lt;head&gt;&lt;/head&gt;</code> as a meta tag:</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>head</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>meta</span> <span data-sanitized-class="token attr-name">name</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>color-scheme<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">content</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>light dark<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token punctuation">/&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>head</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<p>The order of modes <code>light dark</code> or <code>dark light</code> can make a difference - a user with no preference set will see the first mode. However, given that already most current OS (mobile and computer) versions ask you if you want light or dark mode, or even a mode that changes from one to the other automatically over the day, this may soon become less effective.</p>
<h3 data-sanitized-id="why-do-i-want-to-use-it?">Why do I want to use it?</h3>
<p>Many websites leave a bunch of defaults as they are - usually light mode defaults. If they just want a white background then why declare that again? You can now do the same for dark mode.</p>
<p><a href="https://dev.to/bcalou/why-you-should-always-set-a-background-color-2gb1">Some will suggest</a> that these colors <em>should</em> always be declared - but it really depends how minimal you want to be! Leave both the text and background as default, and they will both be controlled by the users themselves, via <code>color-scheme</code>.</p>
<p>You can see when other non-dark-mode sites have stuck with browser default colors, by opening up dev tools on them, and pasting that meta tag with just <code>dark</code> into their HTML. The bits that flip in color from light to dark (and where text goes from dark to light) were using the defaults.</p>
<p>Here's an example of this happening on the BBC News website, after I added a meta tag to make the <code>color-scheme</code> dark:</p>
<img src="https://htmhell.dev/images/advent2022/19/bbc-news.png" alt="BBC News Website with color-scheme: dark injected as a meta tag" loading="lazy">
<p>Here you see they kept the main background default, but must have declared the text color - as the background darkens and renders the text almost invisible. In the "Most watched" and "Most read" sections, they've left both background and text default, and so they both flip.</p>
<h3 data-sanitized-id="how-else-can-i-use-it?">How else can I use it?</h3>
<p>Of course you can use JavaScript to manipulate the content of the meta tag.</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>head</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>meta</span> <span data-sanitized-class="token attr-name">name</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>color-scheme<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">content</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>light dark<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token punctuation">/&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>head</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<pre data-sanitized-class="language-js"><code data-sanitized-class="language-js"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token keyword">function</span> <span data-sanitized-class="token function">lightMode</span><span data-sanitized-class="token punctuation">(</span><span data-sanitized-class="token punctuation">)</span> <span data-sanitized-class="token punctuation">{</span></span><br><span data-sanitized-class="highlight-line">  document</span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token punctuation">.</span><span data-sanitized-class="token function">querySelector</span><span data-sanitized-class="token punctuation">(</span><span data-sanitized-class="token string">'meta[name="color-scheme"]'</span><span data-sanitized-class="token punctuation">)</span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token punctuation">.</span><span data-sanitized-class="token function">setAttribute</span><span data-sanitized-class="token punctuation">(</span><span data-sanitized-class="token string">"content"</span><span data-sanitized-class="token punctuation">,</span> <span data-sanitized-class="token string">"light"</span><span data-sanitized-class="token punctuation">)</span><span data-sanitized-class="token punctuation">;</span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token punctuation">}</span></span><br><span data-sanitized-class="highlight-line"></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token keyword">function</span> <span data-sanitized-class="token function">darkMode</span><span data-sanitized-class="token punctuation">(</span><span data-sanitized-class="token punctuation">)</span> <span data-sanitized-class="token punctuation">{</span></span><br><span data-sanitized-class="highlight-line">  document</span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token punctuation">.</span><span data-sanitized-class="token function">querySelector</span><span data-sanitized-class="token punctuation">(</span><span data-sanitized-class="token string">'meta[name="color-scheme"]'</span><span data-sanitized-class="token punctuation">)</span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token punctuation">.</span><span data-sanitized-class="token function">setAttribute</span><span data-sanitized-class="token punctuation">(</span><span data-sanitized-class="token string">"content"</span><span data-sanitized-class="token punctuation">,</span> <span data-sanitized-class="token string">"dark"</span><span data-sanitized-class="token punctuation">)</span><span data-sanitized-class="token punctuation">;</span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token punctuation">}</span></span></code></pre>
<p>Or just keep the property within a <code>*.css</code> file as with other CSS properties. The world's your oyster.</p>
<pre data-sanitized-class="language-css"><code data-sanitized-class="language-css"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token selector">:root</span> <span data-sanitized-class="token punctuation">{</span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token property">color-scheme</span><span data-sanitized-class="token punctuation">:</span> light dark<span data-sanitized-class="token punctuation">;</span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token punctuation">}</span></span></code></pre>
<p>It's really worth experimenting. You can add the CSS to <code>:root</code>, <code>html</code>, <code>body</code>, or indeed any other element, as maybe you only want parts of your site to do the flip (you might choose to keep the header and footer the same in both modes, as an example).</p>
<h3 data-sanitized-id="system-colors">System colors</h3>
<p>When targeting elements you will also need to declare at least the <code>background-color</code>, as most elements are by default transparent. You can do this with the system colors <code>Canvas</code> for the background and <code>CanvasText</code> for the default text color, as these both follow <code>color-scheme</code>.</p>
<p>There are more system colors! See them at the W3C: <a href="https://www.w3.org/TR/css-color-4/#css-system-colors">System Colors</a>.</p>
<p>A few of them are a bit variable across browsers - notably <code>LinkText</code> in some browsers doesn't always have enough contrast with the dark background in dark mode. <code>Canvas</code> and <code>CanvasText</code> are however more reliable and very useful!</p>
<pre data-sanitized-class="language-css"><code data-sanitized-class="language-css"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token selector">section</span> <span data-sanitized-class="token punctuation">{</span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token property">background-color</span><span data-sanitized-class="token punctuation">:</span> Canvas<span data-sanitized-class="token punctuation">;</span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token property">color</span><span data-sanitized-class="token punctuation">:</span> CanvasText<span data-sanitized-class="token punctuation">;</span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token punctuation">}</span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token selector">section.light</span> <span data-sanitized-class="token punctuation">{</span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token property">color-scheme</span><span data-sanitized-class="token punctuation">:</span> light<span data-sanitized-class="token punctuation">;</span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token punctuation">}</span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token selector">section.dark</span> <span data-sanitized-class="token punctuation">{</span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token property">color-scheme</span><span data-sanitized-class="token punctuation">:</span> dark<span data-sanitized-class="token punctuation">;</span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token punctuation">}</span></span></code></pre>
<h3 data-sanitized-id="ive-already-styled-everything-for-both-modes">I've already styled everything for both modes.</h3>
<p>Really, everything?</p>
<p>Know what else is great? <code>color-scheme</code> takes the default UI elements with it. The scroll bar, the select dropdowns, radio buttons and checkboxes - they all flip with <code>color-scheme</code> too, saving you all those little niggly UI styling jobs. Maybe you have already done this for your current project, but what about your next one?</p>
<img src="https://htmhell.dev/images/advent2022/19/codepen.png" alt="A minimally-styled form in both dark and light modes" loading="lazy">
<p>Please feel free to fork and play with the <a href="https://codepen.io/sarajw/pen/xxzyOMZ">Codepen</a>.</p>
<h3 data-sanitized-id="any-other-benefits?">Any other benefits?</h3>
<p>If you're happy to forgo a mode toggle, and want to also save some CSS loading time? Put your dark mode and light mode styles into separate <code>*.css</code> files, and then use the prefers-color-scheme media queries in the <code>&lt;link&gt;</code> tags in your head to only load the relevant styles.</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>link</span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>stylesheet<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>layout.css<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token punctuation">/&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>link</span> <span data-sanitized-class="token attr-name">media</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>(prefers-color-scheme:light)<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>stylesheet<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>light.css<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token punctuation">/&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>link</span> <span data-sanitized-class="token attr-name">media</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>(prefers-color-scheme:dark)<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>stylesheet<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>dark.css<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token punctuation">/&gt;</span></span></span></code></pre>
<p>Once you start allowing scheme toggling outside of the user OS-set preference, trying to do this does of course get more complicated - I would only urge you to experiment!</p>
<p>Have fun with it! You can thank me later ;)</p>
<h3 data-sanitized-id="further-reading">Further reading:</h3>
<p>For some experimentation I did, feel free to check out <a href="https://color-scheme-light-dark.netlify.app/">https://color-scheme-light-dark.netlify.app/</a></p>
<p>Do check the dates on these! <code>color-scheme</code> is still relatively new, but it's much better supported than when a couple of these articles were written - but they remain good articles on the subject:</p>
<ul>
<li>Find out more about <code>color-scheme</code> at <a href="https://web.dev/color-scheme/">https://web.dev/color-scheme/</a> by <a href="https://toot.cafe/@tomayac">Thomas Steiner</a></li>
<li><a href="https://www.jim-nielsen.com/">Jim Nielsen</a> wrote about both <code>color-scheme</code> and system colors: <a href="https://blog.jim-nielsen.com/2021/css-system-colors/">https://blog.jim-nielsen.com/2021/css-system-colors/</a></li>
<li>More on system colors from <a href="https://front-end.social/@stefan">Stefan Judis</a>: <a href="https://www.stefanjudis.com/today-i-learned/css-defines-color-values-that-follow-system-preferences/">https://www.stefanjudis.com/today-i-learned/css-defines-color-values-that-follow-system-preferences/</a></li>
</ul>
<p>Please <a href="https://front-end.social/@sarajw">ping me a message on Mastodon</a> with any solutions you come up with that use <code>color-scheme</code> - I would love to see them!</p>


guid: https://htmhell.dev/adventcalendar/2022/20/
title: Common nesting issues in HTML
author: ;Manuel Matuzovic
link: https://htmhell.dev/adventcalendar/2022/20/
hash: �'<Xܙٿ�E|�'b
attributes: {"enclosures":[]}
content:
<p>HTML is such a lovely language. Browsers will almost always display something for you, no matter what you put in the HTML document. Heck, you could omit all tags, and it will still work.</p>
<p>That’s all nice, but as web professionals, we should aim to write valid code. But even professional web developers make mistakes. Here are some examples of common nesting issues in HTML.</p>
<h2 data-sanitized-id="anchors-and-buttons">Anchors and buttons</h2>
<p>Let’s start with anchors and buttons. It is common to see buttons inside anchors out in the web wilderness.</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>a</span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>#<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>button</span><span data-sanitized-class="token punctuation">&gt;</span></span>Button<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>button</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>a</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<p>According to the specification, the anchor element must not contain any other interactive element, so <code>&lt;button&gt;</code> elements cannot live inside the <code>&lt;a&gt;</code> element.</p>
<blockquote><strong>Permitted content</strong><br>
Transparent, except that no descendant may be interactive content or an a element, and no descendant may have a specified tabindex attribute.</blockquote>
<p>- <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#properties">the a element on MDN</a></p>
<p>If we validate the code against the <a href="https://validator.w3.org/nu/">HTML validator</a>, we can see that it's invalid.</p>
<img src="https://htmhell.dev/images/advent2022/17/validator.png" alt="Error message in the HTML validator: The element button must not appear as a descedant of the a element.">
<p>In the example below, when you click on a button, you will get two alerts, which is far from ideal.</p>
<p data-height="300" data-default-tab="html,result" data-slug-hash="NWzXeEO" data-user="CiTA" data-sanitized-class="codepen">
  <span>See the Pen <a href="https://codepen.io/CiTA/pen/NWzXeEO">
  Nesting issue: &lt;a&gt; and &lt;button&gt;</a> by Silvestar Bistrović (<a href="https://codepen.io/CiTA">@CiTA</a>)
  on <a href="https://codepen.io/">CodePen</a>.</span>
</p>

<p>You should avoid nesting interactive elements inside each other. It might affect user expectations and the functionality of your website negatively. If you need a link that looks like a button, <a href="https://www.htmhell.dev/4-link-also-button/">use the <code>a</code> element and style it like a button</a>. This also applies to links nested in buttons.</p>
<h2 data-sanitized-id="lists">Lists</h2>
<p>Let's have a look at other common HTML elements, <code>&lt;ul&gt;</code> and <code>&lt;ol&gt;</code>. Their direct children shouldn’t be any other element than <code>&lt;li&gt;</code>, <code>&lt;script&gt;</code>, or <code>&lt;template&gt;</code>.</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>ul</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span>List item 1<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>div</span><span data-sanitized-class="token punctuation">&gt;</span></span>Div item<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>div</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span>List item 2<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>span</span><span data-sanitized-class="token punctuation">&gt;</span></span>Div item<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>span</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>div</span><span data-sanitized-class="token punctuation">&gt;</span></span>Div item<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>div</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>ul</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<p>Using <code>div</code> or similar elements as direct children of lists is wrong. The final output is messed up, and users might have issues distinguishing list items from non-list items, as seen in the example below. <code>&lt;span&gt;</code> items are tough to identify, as they are rendered inline with list items.</p>
<p data-height="300" data-default-tab="html,result" data-slug-hash="XWYVovm" data-user="CiTA" data-sanitized-class="codepen">
  <span>See the Pen <a href="https://codepen.io/CiTA/pen/XWYVovm">
  Nesting issue: &lt;list&gt;</a> by Silvestar Bistrović (<a href="https://codepen.io/CiTA">@CiTA</a>)
  on <a href="https://codepen.io/">CodePen</a>.</span>
</p>
<p>Instead, only use allowed elements inside list elements.</p>
<blockquote><strong>Permitted content</strong><br>
Zero or more <code>&lt;li&gt;</code>, <code>&lt;script&gt;</code> and <code>&lt;template&gt;</code> elements.
</blockquote>
<p><a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/ul">the ul element on MDN</a></p>
<p>Note that <code>&lt;dl&gt;</code>, the description list element, accepts <code>&lt;div&gt;</code> elements.</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>dl</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>div</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>dt</span><span data-sanitized-class="token punctuation">&gt;</span></span>HTML<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>dt</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>dd</span><span data-sanitized-class="token punctuation">&gt;</span></span>HTML is a…<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>dd</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>div</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>div</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>dt</span><span data-sanitized-class="token punctuation">&gt;</span></span>CSS<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>dt</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>dd</span><span data-sanitized-class="token punctuation">&gt;</span></span>CSS is a…<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>dd</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>div</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>dl</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<h2 data-sanitized-id="same-element-type-nesting">Same element type nesting</h2>
<p>Some HTML elements mustn’t be nested in their element type. For example, the <code>&lt;main&gt;</code> element shouldn’t be nested inside another <code>&lt;main&gt;</code> element.</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>main</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  ...</span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>main</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    ...</span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>main</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>main</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<p>According to the spec, there should only be one visible <code>&lt;main&gt;</code> element. That makes sense because there are no multiple main contents in a page. We want a single main element that holds the main content.<br>
If you don’t respect this rule, nothing will be broken visually, but this could affect SEO and the accessibility of a page.</p>
<blockquote>A document mustn't have more than one <code>&lt;main&gt;</code> element that doesn't have the <code>hidden</code> attribute specified.</blockquote>
<p><a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/main">the main element on MDN</a></p>
<p>The <code>&lt;header&gt;</code> and <code>&lt;footer&gt;</code> elements also shouldn't be nested inside themselves.</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>header</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  ...</span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>header</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    ...</span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>header</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>header</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<p>The difference between these two and the <code>&lt;main&gt;</code> element is that you can have multiple <code>&lt;header&gt;</code> and <code>&lt;footer&gt;</code> elements in a document, if you’re using them inside <code>&lt;main&gt;</code>, <code>&lt;section&gt;</code>, <code>&lt;article&gt;</code>,  <code>&lt;aside&gt;</code>, or <code>&lt;nav&gt;</code> elements.</p>
<p>When used outside of the these elements, they are considered as <a href="https://htmhell.dev/tips/landmarks/">landmarks</a>. In short, landmarks are organized areas of your page which help keyboard and screen reader users understand and navigate the page more easily.</p>
<p>Many other elements, like anchors and form elements, don’t allow nesting inside themselves either. However, unlike <code>header</code>, <code>footer</code>, and <code>main</code>, nesting these elements could break their functionality and styling.</p>
<h2 data-sanitized-id="fieldset/legend">Fieldset/Legend</h2>
<p>The <code>&lt;legend&gt;</code> element is used to label its parent <code>&lt;fieldset&gt;</code>. It should be the first child of the <code>&lt;fieldset&gt;</code> element and it must not be nested inside another element.</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>fieldset</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>div</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>legend</span><span data-sanitized-class="token punctuation">&gt;</span></span>Legend<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>legend</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>div</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>input</span> <span data-sanitized-class="token attr-name">type</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>radio<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">id</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>l<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">name</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>shirt1<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>label</span> <span data-sanitized-class="token attr-name">for</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>l<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>Large<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>label</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>input</span> <span data-sanitized-class="token attr-name">type</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>radio<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">id</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>m<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">name</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>shirt1<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>label</span> <span data-sanitized-class="token attr-name">for</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>m<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>Medium<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>label</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>fieldset</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<p>The above code is wrong because since the <code>legend</code> is wrapped in a <code>div</code>, the <code>fieldset</code> has no accessible name. This may cause a group of radio buttons not being announced as a group and the <code>legend</code> might not have a sematic relation with the radio buttons. The visual appearance breaks as well. The legend isn’t positioned on the border of the fieldset, but below it.</p>
<p data-height="300" data-default-tab="html,result" data-slug-hash="PoagvKJ" data-user="CiTA" data-sanitized-class="codepen">
  <span>See the Pen <a href="https://codepen.io/CiTA/pen/PoagvKJ">
  Nesting issue: &lt;legend&gt;</a> by Silvestar Bistrović (<a href="https://codepen.io/CiTA">@CiTA</a>)
  on <a href="https://codepen.io/">CodePen</a>.</span>
</p>

<blockquote><strong>Permitted parents</strong><br>
 A <code>&lt;fieldset&gt;</code> whose first child is this <code>&lt;legend&gt;</code> element.</blockquote>
<p>- <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/legend">the legend element on MDN</a></p>
<p>Even if the <code>legend</code> is not the first child of the <code>fieldset</code>, visually it will be rendered as the first element within its parent. This can be confusing for screen reader users because the visual order doesn't match DOM order.</p>
<p data-height="300" data-default-tab="html,result" data-slug-hash="GRGdqqY" data-user="CiTA" data-sanitized-class="codepen">
  <span>See the Pen <a href="https://codepen.io/CiTA/pen/GRGdqqY">
  Nesting issue: &lt;legend&gt;</a> by Silvestar Bistrović (<a href="https://codepen.io/CiTA">@CiTA</a>)
  on <a href="https://codepen.io/">CodePen</a>.</span>
</p>
<h2 data-sanitized-id="conclusion">Conclusion</h2>
<p>Let’s face it: an invalid HTML structure will not break your site in most cases, at least visually. Some might say that’s the beauty of HTML, but others say it is a curse.<br>
Nevertheless, a weak HTML structure might make your site less usable and affect your SEO score. Not only that, assistive technologies might not announce your content correctly. And finally, your code might be rendered incorrectly if browsers decide to penalise invalid HTML in the future (less likely, though). So try to avoid HTML errors at all costs.</p>
<p>There are all sorts of tools that you could use to help you avoid common issues, from online validator tools like <a href="https://validator.w3.org/nu/">Nu HTML Validator</a> to text editor extensions like <a href="https://marketplace.visualstudio.com/items?itemName=mkaufman.HTMLHint">HTMLHint</a>. If you're unsure about nesting one tag inside another, you could always go to <a href="https://caninclude.glitch.me/">Caninclude</a> for confirmation.</p>


guid: https://htmhell.dev/adventcalendar/2022/21/
title: A Theory of Web Relativity
author: ;Manuel Matuzovic
link: https://htmhell.dev/adventcalendar/2022/21/
hash: V�YW��7ϴ�t��m�
attributes: {"enclosures":[]}
content:
<p><strong>The rel attribute has the potential to take the Internet to the next level… and yet, we usually forget about it.</strong></p>
<p>Imagine a city where people guided themselves by the landmarks and the stores, where there were no directional signs, and where streets and neighborhoods had no names. It may sound like a U2 song, but it is the current state of the web.</p>
<p>The Internet is a vast network of related pages and nodes, but the connections between the elements are void of meaning by default. They lack semantics. A link may connect pages A and B, but <em>what</em> is the relationship between the two? <em>Why</em> are they related? Wouldn’t it be great if there was a way of expressing the relationship between the Internet nodes? Then we wouldn’t have just data; we would have meaningful information. It would take the Internet to a whole new level.</p>
<p>Fortunately, it is possible. Thanks to the <code>rel</code> attribute.</p>
<h2 data-sanitized-id="the-rel-attribute">The rel attribute</h2>
<p>The <code>rel</code> attribute defines a relationship between the linked resources (one being the document it appears on). And it provides that relationship with meaning, creating a semantic network where the different pieces have a role and a purpose. This detail may go unnoticed by most browser users, but not for the browser itself, assistive technologies, and web crawlers, which can take advantage of this attribute to provide a better experience. Also, savvy web developers can use it to make friendlier sites–we’ll see some examples in the following sections.</p>
<p>The <code>rel</code> attribute is valid in elements that link the document with another resource: <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link">&lt;link&gt;</a>, <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a">&lt;a&gt;</a>/<a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/area">&lt;area&gt;</a>, and <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form">&lt;form&gt;</a>. For simplicity purposes, when talking about <code>&lt;a&gt;</code>, it will include both <code>&lt;a&gt;</code> and <code>&lt;area&gt;</code>.</p>
<p>The supported values and how the browser treats them depend on the element in which the <code>rel</code> attribute appears. This is logical because the relationship can be a <em>how</em> or a <em>what</em>, and it not always makes sense to provide the “<em>how</em>” in some links.</p>
<p>Also, some <code>rel</code>  values can be combined to generate more options and provide a more extended experience.</p>
<h2 data-sanitized-id="link-types">Link Types</h2>
<div data-sanitized-class="highlight">
<p>Author’s Note: in this article, I will refer to the values/types defined in the <a href="https://www.iana.org/assignments/link-relations/link-relations.xhtml">IANA link relationship registry</a> and the <a href="https://microformats.org/wiki/existing-rel-values">microformats wiki</a>, but the main focus will be on the <a href="https://html.spec.whatwg.org/multipage/links.html#linkTypes">values listed in the HTML Living Standard</a>.</p>
</div>
<p>I tried to group the types in categories depending on their function and the relationship they express. These are made-up categories to organize my work and they are not official in any way.</p>
<ul>
<li><a href="https://htmhell.dev/adventcalendar/2022/21/#meta-types">Meta types</a></li>
<li><a href="https://htmhell.dev/adventcalendar/2022/21/#personal-types">Personal types</a></li>
<li><a href="https://htmhell.dev/adventcalendar/2022/21/#processing-types">Processing types</a></li>
<li><a href="https://htmhell.dev/adventcalendar/2022/21/#network-types">Network types</a></li>
<li><a href="https://htmhell.dev/adventcalendar/2022/21/#sequential-types">Sequential types</a></li>
</ul>
<h2 data-sanitized-id="meta-types">Meta types</h2>
<p>“Meta links” provide information relevant to the document they appear in: meta information. Things like who’s the author? Where can we find an alternative version of the document? What is the license? Because of their nature, they can appear on <code>&lt;a&gt;</code> or <code>&lt;link&gt;</code> (although sometimes not on both) and never on a <code>&lt;form&gt;</code> tag.</p>
<h3 data-sanitized-id="alternate">alternate</h3>
<p>The “alternate” relationship usually specifies an alternative version of the document itself, but some exceptions exist. It will be the most complex of all the <code>rel</code> meta values because the meaning it provides is heavily conditioned to the context in which it is presented.</p>
<p><strong>If it appears along with the</strong> <code>**stylesheet**</code> <strong>keyword</strong>, the linked file is an alternative stylesheet. It won’t be applied to the document, but it will be ready for when we need it. For example:</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>link</span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>stylesheet<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>main-styles.css<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token punctuation">/&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>link</span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>stylesheet alternate<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>dark.css<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">title</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>dark mode<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token punctuation">/&gt;</span></span></span></code></pre>
<blockquote>When using `stylesheet` with `alternate`, the `` must have a `title` attribute with a short (and non-empty) description.</blockquote>
<p>In this case, the “dark-styles.css” file is loaded asynchronously and not applied to the document. This way, the styles will be available whenever we want to apply them, without having to wait for network or traffic.  Some browsers, like Firefox, allow switching between styles, facilitating the process for users:</p>
<p>
<img src="https://htmhell.dev/images/advent2022/22/ff_styles.png" alt="Firefox lets you pick alternative styles from the View menu" loading="lazy">
</p>
<p><strong>If it appears with a <code>type</code> attribute that has the value <code>application/rss+xml</code> or <code>application/atom+xml</code></strong>, then the <code>alternate</code> keyword creates a hyperlink referencing a syndication feed (in RSS or Atom respectively), which is useful for crawlers to find more content. In this case, it is not an exact alternative for the document, but it provides additional information about it, making it great for autodiscovery.</p>
<p>It can work both in <code>&lt;link&gt;</code> and <code>&lt;a&gt;</code>, and the meaning is the same in both:</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token doctype"><span data-sanitized-class="token punctuation">&lt;!</span><span data-sanitized-class="token doctype-tag">doctype</span> <span data-sanitized-class="token name">html</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>html</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>head</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    ...</span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>link</span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>alternate<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">type</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>application/rss+xml<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>feed.rss<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token punctuation">/&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>link</span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>alternate<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">type</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>application/atom+xml<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>atom.xml<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token punctuation">/&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    ...</span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>head</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>body</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    ...</span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>a</span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>feed.rss<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>alternate<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">type</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>application/rss+xml<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">      Subscribe to my feed and never miss a blog!</span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>a</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    ...</span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>body</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>html</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<p>This combination doesn’t impact our site’s visitors, but it provides us with control over how or what we want web crawlers to process our site. If there are multiple linked resources of this type, the first one is considered the main/default one, so the order would be important in that scenario.</p>
<p><strong>In any other case</strong>, the <code>alternate</code> keyword indicates that the linked element is an alternative version of the current document. But it doesn’t end there: the attributes that accompany the <code>rel</code> will provide additional information about the linked resource.</p>
<ul>
<li><code>media</code>: can be used to specify the target devices (mobile, print, etc.) for the alternative version.</li>
<li><code>type</code>: used to identify what format (PDF, XML, etc.) the linked alternative version is available on.</li>
<li><code>hreflang</code>: defines which language (English, Spanish, etc.) the linked resource is in.</li>
</ul>
<p>This opens a world of combinations and possibilities. Again, maybe not so much for the browser users, but definitely for bots and crawlers that need to process the information as accurately as possible.</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token doctype"><span data-sanitized-class="token punctuation">&lt;!</span><span data-sanitized-class="token doctype-tag">doctype</span> <span data-sanitized-class="token name">html</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>html</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>head</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    ...</span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token comment">&lt;!-- alternative document versions in German, Spanish, and French --&gt;</span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>link</span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>/de<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>alternate<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">hreflang</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>de<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token punctuation">/&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>link</span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>/es<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>alternate<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">hreflang</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>es<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token punctuation">/&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>link</span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>/fr<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>alternate<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">hreflang</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>fr<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token punctuation">/&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token comment">&lt;!-- alternative document version in Spanish in PDF, specific for printing --&gt;</span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>link</span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>/es/print/<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>alternate<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">hreflang</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>es<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">type</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>application/pdf<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">media</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>print<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token punctuation">/&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    ...</span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>head</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>body</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    ...</span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>p</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">      Thanks for checking out my online resume, feel free to download a</span><br><span data-sanitized-class="highlight-line">      <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>a</span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>resume.pdf<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>alternate<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">type</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>application/pdf<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">        PDF version.</span><br><span data-sanitized-class="highlight-line">      <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>a</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>p</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>p</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">      <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>a</span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>https://m.link-to-our-site.com<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>alternate<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">media</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>handheld<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">        Check out a mobile version of this site too!</span><br><span data-sanitized-class="highlight-line">      <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>a</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>p</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    ...</span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>body</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>html</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<p>Remember: the order of the attributes is not important, but for some cases, the order of appearance of the tag may define which is more <em>important</em> or the default one.</p>
<h3 data-sanitized-id="author">author</h3>
<p>This may seem like an easy one: the “author” <code>rel</code> is a hyperlink that will point to the author (it could be <code>mailto:</code> with an email). But there’s a catch, the author of what? the page? the content inside? what?</p>
<p>The answer to these questions will depend on where the author link appears: if it’s inside an <code>&lt;article&gt;</code>, then it will point to the author of the article, if it’s outside of an <code>&lt;article&gt;</code> then it applies to the document/page as a whole.</p>
<p>Let’s review it with an example:</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>article</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token comment">&lt;!-- Article content --&gt;</span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>footer</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    Written by <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>a</span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>https://janedoe.com<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>author<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>Jane Doe<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>a</span><span data-sanitized-class="token punctuation">&gt;</span></span>.</span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>footer</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>article</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token comment">&lt;!-- rest of the page --&gt;</span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>p</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  Site created by <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>a</span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>https://johndoe.com<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>author<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>John Doe<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>a</span><span data-sanitized-class="token punctuation">&gt;</span></span>.</span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>p</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<p>The first link appears inside an <code>&lt;article&gt;</code> which let us know that the link is pointing to the author of the article (Jane Doe). While the second link is outside any <code>&lt;article&gt;</code>, which tells us that is the author of the whole page (John Doe). <strong>This could be convenient in sites with syndicated content (like blogs or newspapers), to set a difference between the article’s author and the site’s owner/author</strong>.</p>
<p>Another way of specifying the page’s author is having an actual <code>&lt;link&gt;</code> tag in the page’s <code>&lt;head&gt;</code> with the <code>rel</code> “author”. Then we know for sure that it applies to the whole page and not just to a part of it:</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token doctype"><span data-sanitized-class="token punctuation">&lt;!</span><span data-sanitized-class="token doctype-tag">doctype</span> <span data-sanitized-class="token name">html</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>html</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>head</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>link</span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>author<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>https://alvaromontoro.com<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token punctuation">/&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    ...</span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>head</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  ...</span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>html</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<h3 data-sanitized-id="bookmark">bookmark</h3>
<p>This <code>rel</code> value can only appear in <code>&lt;a&gt;</code>/<code>&lt;area&gt;</code>. It identifies a permalink for the nearest ancestor <code>&lt;article&gt;</code> or section (which doesn’t necessarily have to be a <code>&lt;section&gt;</code> element). This last part can be confusing, let’s review it with an example:</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line">...</span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>body</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>h1</span><span data-sanitized-class="token punctuation">&gt;</span></span>James Bond Movies<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>h1</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>article</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>h2</span> <span data-sanitized-class="token attr-name">id</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>no-time-to-die<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>No Time To Die<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>h2</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>p</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">      The twenty-fifth movie in the James Bond series. Daniel Craig was </span><br><span data-sanitized-class="highlight-line">      James Bond in this installment.</span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>p</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>p</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">      <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>a</span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>no-time-to-die.html<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>bookmark<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>Permalink<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>a</span><span data-sanitized-class="token punctuation">&gt;</span></span>.</span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>p</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>article</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>div</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>h2</span> <span data-sanitized-class="token attr-name">id</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>goldeneye<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>Goldeneye<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>h2</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>p</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">      A movie and an amazing Nintendo 64 videogame. The iconic Pierce</span><br><span data-sanitized-class="highlight-line">      Brosnan played the role of James Bond on this movie.</span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>p</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>p</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">      <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>a</span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>goldeneye.html<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>bookmark<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>Permalink<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>a</span><span data-sanitized-class="token punctuation">&gt;</span></span>.</span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>p</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>div</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>body</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">...</span></code></pre>
<p>The first link with <code>rel= “bookmark”</code> (permalink for No Time To Die) is inside of an <code>&lt;article&gt;</code>, so it will apply to that article in particular. The second link with <code>rel= “bookmark”</code> (permalink for Goldeneye) is outside of an <code>&lt;article&gt;</code>, applying to the closest section, which will be defined by the earliest ancestor with a heading.</p>
<p>Notice how, if the bookmark link is not inside an <code>&lt;article&gt;</code>, it can be a bit tricky to identify what section it applies to. It is more important than ever to use the right markup.</p>
<h3 data-sanitized-id="canonical">canonical</h3>
<p>A canonical link specifies the preferred version of the document. This is really helpful if we cross-post content online: while a search engine indexes the pages, it will be able to identify the <em>original</em> version and not penalize the author for having duplicated content.</p>
<p>Many blogging systems (e.g., Medium, DEV, Hashnode, etc.) allow for specifying a canonical URL for the articles, and placing a <code>&lt;link&gt;</code> element with <code>rel="canonical"</code> just like this:</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token doctype"><span data-sanitized-class="token punctuation">&lt;!</span><span data-sanitized-class="token doctype-tag">doctype</span> <span data-sanitized-class="token name">html</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>html</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>head</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    ...</span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>link</span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>canonical<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>https://path-to-preferred-url-version<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token punctuation">/&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    ...</span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>head</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">...</span></code></pre>
<p>According to the HTML standard, it is only allowed on a <code>&lt;link&gt;</code> element, but the microformats definition mentions it on the <code>&lt;a&gt;</code> elements too. In my opinion, it would make sense to allow <code>rel="canonical"</code> in an <code>&lt;a&gt;</code> tag, but it could be problematic for publications. Better to stick to the HTML standard and only use canonical inside a <code>&lt;link&gt;</code> in the <code>&lt;head&gt;</code>.</p>
<h3 data-sanitized-id="help">help</h3>
<p>This keyword can be used in all the available elements: <code>&lt;link&gt;</code>, <code>&lt;a&gt;</code>, or <code>&lt;form&gt;</code>. In all of them, it identifies a resource that contains help, the difference will be the scope of that help:</p>
<ul>
<li>In a <code>&lt;link&gt;</code>, it will link to a help resource related to the document as a whole.</li>
<li>In an <code>&lt;a&gt;</code>, it will be help related to the section that contains the anchor.</li>
<li>In a <code>&lt;form&gt;</code>, it specifies that the target contains information about the form and its contents.</li>
</ul>
<p>In the following example, the help link applies to the section that contains the label and input:</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line">...</span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>form</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  ...</span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>div</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>label</span> <span data-sanitized-class="token attr-name">for</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>phone<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>Phone number<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>label</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>input</span> <span data-sanitized-class="token attr-name">id</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>phone<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">name</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>phone<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token punctuation">/&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>a</span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>phone-help.html<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>help<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>(Help)<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>a</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>div</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  ...</span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>form</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">...</span></code></pre>
<p><strong>Browsers and assistive technologies can use this link to provide a more standard computer behavior.</strong> For example: historically, pressing F1 opens the help functionality; So they could open the linked resource if the special key is pressed while on the section to which the help link applies.<br>
Also, in some cases, browsers may style the cursor differently if a link has the <code>rel="help"</code>. (And if they don’t, it may be a nice feature to add by developers.)</p>
<h3 data-sanitized-id="icon">icon</h3>
<p>This <code>rel</code> value can only be used within a <code>&lt;link&gt;</code>, usually in the <code>&lt;head&gt;</code>, and it should link to an image. That image will then be displayed for representing the page in the user interface.</p>
<p>The <code>rel="icon"</code> can be combined with other attributes such as <code>type</code>, <code>media</code>, or <code>sizes</code> which will help the browser pick the most adequate icon for the user.</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>link</span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>icon<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>fav.ico<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token punctuation">/&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>link</span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>icon<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>favicon.png<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">type</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>image/png<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token punctuation">/&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>link</span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>icon<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>small.ico<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">sizes</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>16x16 32x32 48x48<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token punctuation">/&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>link</span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>icon<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>large.ico<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">sizes</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>128x128 512x512 1024x1024<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token punctuation">/&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>link</span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>icon<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>iphone.png<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">sizes</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>57x57<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">type</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>image/png<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token punctuation">/&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>link</span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>icon<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>bw.ico<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">media</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>screen and (max-color:2)<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token punctuation">/&gt;</span></span></span></code></pre>
<p>You might have found a <code>rel</code> value of <code>shortcut icon</code> (in that order) instead of just <code>icon</code>, that was the old way of writing it and browsers still support it for historical reasons, but there’s no reason to do that anymore.</p>
<p>Another thing that we find in the wild is a <code>rel</code> value of <code>apple-touch-icon</code>. This is a specific value for Safari, only supported on Apple devices. Feel free to use it if you want to provide specific icons for them, but remember that it is not a standard value.</p>
<h3 data-sanitized-id="license">license</h3>
<p>The <code>license</code> value can be used in all the supported tags (<code>&lt;link&gt;</code>, <code>&lt;a&gt;</code>, and <code>&lt;form&gt;</code>) to create a hyperlink to the copyright license terms under which the main content is provided. Notice the term “main content” instead of “current document” that is used throughout the article. This is because the license applies to the content itself, and the page/template may have a different copyright or license.</p>
<p>The specification does not specify how to differentiate the main content from the rest of the content. The link with <code>rel="license"</code> must be presented in a way that makes it clear to the user what content it applies to.</p>
<p>The following example simulates a website with images/videos and the license hyperlink for one of the images:</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line">...</span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>figure</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>img</span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>image.jpg<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">alt</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>Image for this demo<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token punctuation">/&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>figcaption</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    An demo image for the article. License:</span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>a</span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>https://creativecommons.org/licenses/by/4.0/<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>license<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">      CC BY 4.0</span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>a</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>figcaption</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>figure</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">...</span></code></pre>
<p>The value <code>copyright</code> was accepted in the past as a synonym of <code>license</code>, and browsers still support it, but we should go with the standard <code>license</code>.</p>
<h3 data-sanitized-id="manifest">manifest</h3>
<p>The <code>manifest</code> relationship can only happen in a <code>&lt;link&gt;</code>. It indicates that the linked resource is a manifest file with metadata related to the current document.</p>
<p>The manifest may contain information about the entry file to install the web application, the icons to use, the app’s name, theme colors… In this article, we won’t dig into how to use the manifest as our focus is exclusively on the <code>rel</code> attribute used to link it.</p>
<p>Here’s how you can link your manifest from the <code>&lt;head&gt;</code>:</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token doctype"><span data-sanitized-class="token punctuation">&lt;!</span><span data-sanitized-class="token doctype-tag">doctype</span> <span data-sanitized-class="token name">html</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>html</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>head</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    ...</span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>link</span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>manifest<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>/manifest.json<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token punctuation">/&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    ...</span></code></pre>
<p>s<br>
Two important things to remember about this <code>rel</code> value:</p>
<ol>
<li>Browsers will use the first <code>&lt;link&gt;</code> with <code>rel="manifest"</code> in the tree order, ignoring any other that may appear.</li>
<li>Browsers will execute the manifest when they consider it necessary, never assume that the entry point script will be executed.</li>
</ol>
<h3 data-sanitized-id="pingback">pingback</h3>
<p>A pingback is a method for authors to get notifications when their content is linked. With <code>pingback</code>, we can provide the address of the pingback server that handles the pingbacks to the current document:</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>link</span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>pingback<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>https://alvaromontoro.com/pingback<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token punctuation">/&gt;</span></span></span></code></pre>
<p>This can be useful, for example, to process the notification and add a note on the page (like WordPress does). It can also be helpful for SEO.</p>
<p>The <code>pingback</code> value can only be used in the <code>&lt;link&gt;</code> element.</p>
<h3 data-sanitized-id="search">search</h3>
<p>The <code>search</code> keyword indicates that the linked resource provides a way of searching the document and its related resources. It redirects to a search page.</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>p</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  Read more about this topic by <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>a</span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>/search<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>search<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>searching this</span><br><span data-sanitized-class="highlight-line">  site<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>a</span><span data-sanitized-class="token punctuation">&gt;</span></span> or <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>a</span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>https://google.com/search?q=rel+attribute<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>search<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  checking on Google<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>a</span><span data-sanitized-class="token punctuation">&gt;</span></span>.</span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>p</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<p>Notice how it doesn’t have to be an internal search functionality. In the example above, one of the search links points to Google.</p>
<p>Some browsers allow adding plugins to their interfaces to provide custom searching features. If we have an OpenSearch plugin, we can link it using <code>type="application/opensearchdescription+xml"</code> alongside the <code>search</code> value to add the plugin easily to the browser.</p>
<h3 data-sanitized-id="tag">tag</h3>
<p>The linked resource contains information about a tag or keyword related to the current document. It can be a description, a list of other elements from the same category, etc. This <code>rel</code> value is only valid on <code>a</code> and <code>area</code> elements.</p>
<p>A practical use of the <code>tag</code> value could be seen on blogs or other sites where content can be categorized. <a href="https://stackoverflow.com/">StackOverflow</a> is a great place to see links with <code>rel="tag"</code> working live. Or we could have something like this on our blog:</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line">...</span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>article</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>h1</span><span data-sanitized-class="token punctuation">&gt;</span></span>The Definitive Guide of Colors in CSS<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>h1</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  ...</span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>footer</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>h2</span><span data-sanitized-class="token punctuation">&gt;</span></span>Tags<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>h2</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>ul</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">      <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>a</span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>/tags?t=css<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>tag<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>CSS<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>a</span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">      <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>a</span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>/tags?t=htm<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>tag<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>HTML<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>a</span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">      <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>a</span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>/tags?t=webdev<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>tag<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>Web Development<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>a</span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>ul</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>footer</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>article</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">...</span></code></pre>
<p>The <code>rel="tag"</code> links apply to the whole page independently of where they appear within it. Even if they are located inside an article, they are not exclusive to the article itself.</p>
<p>
<img src="https://htmhell.dev/images/advent2022/22/tag.png" alt="Screenshot of StackOveflow’s use of rel=tag" loading="lazy" width="740" height="137">
</p>
<h2 data-sanitized-id="personal-types">Personal Types</h2>
<p>They indicate a relationship between the author of the document/article and the linked resource (which should be an online profile). The HTML standard only has one of this type (“author”), but the XHTML Friends Network (XFN) defines many more:</p>
<ul>
<li><code>author</code>: see description in the meta types.</li>
<li><code>crush</code>: the linked page represents a person you have a crush on.</li>
<li><code>date</code>: the hyperlink is to a page about someone you are dating.</li>
<li><code>friend</code>: the link identifies a friend.</li>
<li><code>me</code>: <strong>this value became really popular with the rise of Mastodon</strong>. It is used to link to a page that represents the same person as the current document.</li>
<li><code>muse</code>: a link that identifies a person who inspires the person.</li>
</ul>
<p>As you may imagine, there are <a href="https://gmpg.org/xfn/11">many more values that could be used</a>. Quite often, just using the English word for the personal relationship will work as a valid <code>rel</code>: colleague, child, acquaintance, neighbor, parent… all good.</p>
<p>Here are some of these personal <code>rel</code> values in action:</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>h1</span><span data-sanitized-class="token punctuation">&gt;</span></span>Welcome!<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>h1</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>p</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  My name is <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>a</span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>profile.html<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>me<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>Ross Geller<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>a</span><span data-sanitized-class="token punctuation">&gt;</span></span>, thanks for </span><br><span data-sanitized-class="highlight-line">  visiting my personal website!</span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>p</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>p</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  I live in NYC with my buddies <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>a</span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>j-man.html<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>friend<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>Joey<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>a</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  and <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>a</span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>king-of-bad-thanksgivings.html<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>friend<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>Chandler<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>a</span><span data-sanitized-class="token punctuation">&gt;</span></span>. </span><br><span data-sanitized-class="highlight-line">  In the same building block as famous cook (and my younger sister)</span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>a</span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>monica.html<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>sibling<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>Monica Geller<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>a</span><span data-sanitized-class="token punctuation">&gt;</span></span>.</span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>p</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>p</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  Monica lives with <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>a</span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>rachel.html<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>crush date<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>Rachel<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>a</span><span data-sanitized-class="token punctuation">&gt;</span></span> and </span><br><span data-sanitized-class="highlight-line">  renown musician <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>a</span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>regina-phalange<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>muse friend<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>Phoebe<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>a</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  (author of the smash hit "Smelly Cat").</span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>p</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<p>One last point about this personal type: only the “author” value is supported in a <code>&lt;link&gt;</code> tag, all the others are only allowed on <code>&lt;a&gt;</code>.</p>
<h2 data-sanitized-id="processing-types">Processing Types</h2>
<p>These types don’t indicate what the linked resource is or how it is related to the current document, instead, <strong>they tell the browser how the link should be treated or processed</strong>, creating a connection that may not be completely semantic but making it special.</p>
<p>All of these values are <strong>only accepted in the <code>&lt;link&gt;</code> element</strong>, they will normally appear in the <code>&lt;head&gt;</code>, and will mainly impact performance.</p>
<h3 data-sanitized-id="dns-prefetch">dns-prefetch</h3>
<p>The <code>dns-prefetch</code> keyword indicates that the browser should preemptively perform DNS resolution for the specified domain. Basically, we are telling the browser that we will likely need some resources from the linked domain, so it will be beneficial and good for the user experience if it started resolving the address and getting ready to ask for files.</p>
<p>Using this type of <code>rel</code> reduces the latency when requesting an online resource and improves the overall performance, giving the impression that the content loaded faster (because some of the load work was done before it was actually needed.)</p>
<p>For example, if we are using Google Fonts, and we know that our page will at some point need the font, we can prefetch the CDN where Google hosts the fonts:</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>link</span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>dns-prefetch<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>https://fonts.googleapis.com<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<p>If you have used Google Fonts before, you might have noticed that it doesn’t use <code>rel="dns-prefetch"</code> but <code>rel="preconnect"</code> (we will analyze it soon). This is because <code>dns-prefetch</code> only performs DNS resolution, while <code>preconnect</code> does DNS resolution and also establishes a connection to the server, making the process <em>faster</em>.</p>
<p>Which raises a fair question: why even use <code>dns-prefetch</code> if <code>preconnect</code> does more? Because network connections are “expensive”. If we need sources from many third-party domains, preconnecting to all of them may impact performance negatively. Instead, it would be better to preconnect only to the more “urgent” ones and do a <code>dns-prefetch</code> for the rest. There’s no risk in using both together (even for the same domains!) and if for some reason the browser doesn’t support them, it won’t impact our site at all (apart from having to load a couple more lines of code.)</p>
<h3 data-sanitized-id="modulepreload">modulepreload</h3>
<p>JavaScript code is getting bigger and bigger, and it is becoming more important to split the code and organize it into simpler modules that can be run when needed. NodeJS and some frameworks have their own methods for module usage, and some browsers provide native module functionality too. This is where the <code>modulepreload</code> value is important.</p>
<p>We can use <code>rel="modulepreload"</code> to preload a module script and place it in the appropriate module map without evaluating it (that will happen when it is required). This optimizes the module load, making the process more efficient.</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token doctype"><span data-sanitized-class="token punctuation">&lt;!</span><span data-sanitized-class="token doctype-tag">doctype</span> <span data-sanitized-class="token name">html</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>html</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>head</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    ...</span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>link</span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>modulepreload<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>app.mjs<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token punctuation">/&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>link</span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>modulepreload<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>record-player.mjs<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token punctuation">/&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>link</span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>modulepreload<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>trade.mjs<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token punctuation">/&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>link</span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>modulepreload<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>payment.mjs<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token punctuation">/&gt;</span></span></span><br><span data-sanitized-class="highlight-line"></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>script</span> <span data-sanitized-class="token attr-name">type</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>module<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">src</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>app.mjs<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span><span data-sanitized-class="token script"></span><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>script</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    ...</span></code></pre>
<p>In the example above, we are preloading several scripts. The main module is executed (<code>app.mjs</code>), and the others will be available whenever they are needed (<code>record-player.mjs</code>, <code>trade.mjs</code>, <code>payment.mjs</code>).</p>
<p><code>modulepreload</code> is basically a specialized version of the <code>preload</code> keyword (see below), as it applies specifically to one type of resource: script modules.</p>
<h3 data-sanitized-id="preconnect">preconnect</h3>
<p>As mentioned in the <code>dns-prefetch</code> section, with the <code>preconnect</code> keyword, we indicate to the browser that a resource from the linked domain will most likely be needed, and initiate a connection to its origin before the resource has even been found by the browser.</p>
<p>By doing so, we are increasing the network performance, because we are establishing a connection that will be ready when it’s needed, reducing the latency, and improving the user experience.</p>
<p>A practical example of <code>preconnect</code> can be found on Google Fonts: you may have noticed the code to embed fonts includes a couple of extra lines:</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>link</span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>preconnect<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>https://fonts.googleapis.com<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>link</span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>preconnect<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>https://fonts.gstatic.com<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">crossorigin</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>link</span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>https://fonts.googleapis.com/css2?family=Roboto&amp;display=swap<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>stylesheet<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<p>The first two <code>&lt;link&gt;</code> use <code>preconnect</code> while the third <code>&lt;link&gt;</code> imports a stylesheet which will bring the font. Those first two lines initiate a connection for loading content from the Google CDNs, so the browser is ready to download the files.</p>
<h3 data-sanitized-id="prefetch">prefetch</h3>
<p>With <code>prefetch</code>, we identify a resource that may be used by the subsequent pages, telling the browser that it should fetch that resource to deliver a faster response when the navigation to those pages actually happens. The browser will proceed to load the content into the cache for later use.<br>
Prefetching some files for later use–an image, some script, and a song:</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>link</span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>prefetch<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">as</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>image<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>super-important-image.jpg<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token punctuation">/&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>link</span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>prefetch<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">as</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>script<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>code.js<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token punctuation">/&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>link</span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>prefetch<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">as</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>audio<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>https://somecdn.com/music.mp3<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">crossorigin</span> <span data-sanitized-class="token punctuation">/&gt;</span></span></span></code></pre>
<p>The <code>as</code> attribute is optional, but highly recommended (see <code>preload</code> section for more details.)</p>
<p>Use <code>prefetch</code> carefully. It is a little bit of a “gamble”: we are fetching content that we presume the user will need soon, but if the user doesn’t navigate the way we expect it, we might have used bandwidth unnecessarily.</p>
<h3 data-sanitized-id="preload">preload</h3>
<p>With <code>preload</code>, we ask the browser to fetch some resources and process them as specified with the <code>as</code> attribute, because those files are important and we will need them on the current document.<br>
In this example we will preload an image, a script file, and an audio file:</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>link</span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>preload<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">as</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>image<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>super-important-image.jpg<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token punctuation">/&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>link</span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>preload<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">as</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>script<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>code.js<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token punctuation">/&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>link</span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>preload<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">as</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>audio<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>https://somecdn.com/music.mp3<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">crossorigin</span> <span data-sanitized-class="token punctuation">/&gt;</span></span></span></code></pre>
<p>Notice the <code>as</code> attribute because it is not trivial. It tells the browser what type of resource is being linked so it can process it adequately. Without it, the browser may end up fetching the content twice (the same thing with the <code>crossorigin</code> attribute.)</p>
<p>So, how are <code>preload</code> and <code>prefetch</code> different? While they seem to do the same, there’s a key difference: <code>prefetch</code> <strong>is used for “lower priority” resources that will be needed at a later time,</strong>  and <code>preload</code> <strong>is for “higher priority” content that will be needed sooner</strong> (as on the same page, but that may have not been discovered by the browser yet.)</p>
<p>I will end this section by giving a piece of advice: <strong>do not preload everything</strong>. Quoting The Incredible’s supervillain Syndrome: “<em>When everyone is super, no one will be</em>.” If we preload every file that we will need, then there won’t be a real gain (and it may even be counterproductive). Be selective with the content to preload, and consider using <code>prefetch</code> or <code>preconnect</code>.</p>
<h3 data-sanitized-id="prerender">prerender</h3>
<p><code>prerender</code> works similarly to <code>prefetch</code> but at a larger scale. The linked resource may be a page, and it is not only prefetched but also processed (including its content) and rendered, caching the result until it’s needed.</p>
<p>Imagine that you created a multi-page form. You may want to prerender the next step because the user should logically navigate to it:</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>link</span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>prerender<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>form-step-2.html<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token punctuation">/&gt;</span></span></span></code></pre>
<p>As with <code>prefetch</code>, <code>prerender</code> could be a bit of a “gamble” (even more this time): if the user doesn’t navigate the site the way we expect or if they leave the site completely, we will have fetched and processed content unnecessarily.</p>
<h3 data-sanitized-id="stylesheet">stylesheet</h3>
<p>Surprised to see this value as part of the processing types? I considered adding it to the meta types, but it fits here better.</p>
<p>The <code>stylesheet</code> indicates that the linked resource contains styles for the page, so it provides a little semantics; but it does much more: browsers know that stylesheets are a key part of the page’s presentation and, unless the <code>alternate</code> keyword shows up too, it also knows that it needs to process the styling file and apply it to the page. The <code>stylesheet</code> keyword is telling the browser how to treat the linked file.</p>
<p>Its basic use is simple: only in <code>&lt;link&gt;</code>, the <code>rel="stylesheet"</code>, and an <code>href</code> pointing to the stylesheet file. We can also use other attributes (<code>media</code>) to change the default behavior and when the styles will be applied:</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token comment">&lt;!-- this file will be automatically downloaded and applied --&gt;</span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>link</span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>stylesheet<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>my-super-cool-styles.css<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token punctuation">/&gt;</span></span></span><br><span data-sanitized-class="highlight-line"></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token comment">&lt;!-- this one is downloaded but not applied --&gt;</span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>link</span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>stylesheet alternate<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>prototype.css<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">title</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>prototype<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token punctuation">/&gt;</span></span></span><br><span data-sanitized-class="highlight-line"></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token comment">&lt;!-- this one is downloaded but only applied when printing --&gt;</span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>link</span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>stylesheet<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>printer.css<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">media</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>print<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token punctuation">/&gt;</span></span></span></code></pre>
<h2 data-sanitized-id="network-types">Network Types</h2>
<p>The “network types” specify the type of connection that the document and the linked resource have as well as the information that will be shared between them.</p>
<p>They don’t create a link, they annotate it, making it easier for crawlers and spiders to index the content appropriately. As they will have more information about the nature of the connection.</p>
<h3 data-sanitized-id="external">external</h3>
<p>A resource is external if it is not part of the current site. We can easily identify them by adding a <code>rel="external"</code> to it, which is allowed on <code>&lt;a&gt;</code>/<code>&lt;area&gt;</code> or the target in a <code>&lt;form&gt;</code>, but never on a <code>&lt;link&gt;</code>.</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token comment">&lt;!-- on a personal blog --&gt;</span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>a</span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>https://en.wikipedia.org/wiki/Cat<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>external<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>Read about cats<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>a</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<p>This doesn’t give much information to the browser (it is transparent for it), but it can be convenient for developers to use CSS attribute selectors and style these links differently:</p>
<pre data-sanitized-class="language-css"><code data-sanitized-class="language-css"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token comment">/* add a small icon behind each external link */</span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token selector">a[rel="external"]::after</span> <span data-sanitized-class="token punctuation">{</span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token property">content</span><span data-sanitized-class="token punctuation">:</span> <span data-sanitized-class="token url"><span data-sanitized-class="token function">url</span><span data-sanitized-class="token punctuation">(</span>external-icon.svg<span data-sanitized-class="token punctuation">)</span></span><span data-sanitized-class="token punctuation">;</span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token property">margin-left</span><span data-sanitized-class="token punctuation">:</span> 0.5rem<span data-sanitized-class="token punctuation">;</span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token property">vertical-align</span><span data-sanitized-class="token punctuation">:</span> middle<span data-sanitized-class="token punctuation">;</span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token punctuation">}</span></span></code></pre>
<h3 data-sanitized-id="nofollow">nofollow</h3>
<p>A <code>nofollow</code> rel value on a link tells the crawlers to “ignore” the linked resource because it is not endorsed by the current document’s owner, or that it was included because of a commercial relationship.</p>
<p>It is an important value for Search Engine Optimization (SEO): if your page links to low-quality content, your site’s credibility (and its ranking in the search engines) may suffer. Using <code>nofollow</code> won’t penalize your site:</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>a</span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>https://totallynotmischivieoussite.com<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>nofollow<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  This is a link created by an user</span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>a</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<p>Using <code>rel="nofollow"</code> in user-generated content and links is a must. You never know what they are going to share, and you don’t want to end up on the losing side of a spamming scheme.</p>
<h3 data-sanitized-id="noopener">noopener</h3>
<p>A link may have access to the previous page by using <code>window.opener</code> depending on how it was opened (e.g. if it has <code>target="_blank"</code>). This is a potential security problem and it could lead to other issues like phishing attempts.</p>
<p>To avoid these situations, we can use <code>noopener</code> value in <code>rel</code> to open the new document without granting it access to the document that opened it:</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line">...</span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>div</span> <span data-sanitized-class="token attr-name">class</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>comment<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  Check my <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>a</span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>noopener<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>https://no-good-phishy-site.tk<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>site<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>a</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>div</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">...</span></code></pre>
<p>As with <code>nofollow</code>, the main target for this value will be user-generated content that we don’t want to provide with extra information.</p>
<h3 data-sanitized-id="noreferrer">noreferrer</h3>
<p><code>noreferrer</code> is really close to <code>noopener</code>. In fact, it does the same thing as <code>noopener</code> (it doesn’t grant access to the document) plus it tells the browser to omit the <code>Referer</code> header when opening the link. This way, the linked resource cannot access the referrer’s information (e.g., its address).</p>
<p>This provides an extra layer of anonymity and security. The linked resource will not see a referrer, looking like the request came from direct traffic to their site instead of from the originating link.</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line">...</span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>div</span> <span data-sanitized-class="token attr-name">class</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>comment<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  Check my <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>a</span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>noreferrer<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>https://no-good-phishy-site.tk<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>site<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>a</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>div</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">...</span></code></pre>
<p><code>noreferrer</code> and <code>nofollow</code> are often used together, to ensure that one is applied in case the other one is not supported by the browser.</p>
<h3 data-sanitized-id="opener">opener</h3>
<p>This is effectively the opposite of <code>noopener</code>. It doesn’t add that extra layer of protection when following the link by allowing it to access the opener.</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>a</span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>./help-page.html<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>opener<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>You have access<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>a</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<h2 data-sanitized-id="sequential-types">Sequential Types</h2>
<p>These values indicate that the current document is part of a series or sequence and specifies the relationship of the linked resource with it. They have a big impact on user experience, accessibility, and SEO.</p>
<p>The HTML Living Standard only has two values related to sequences: “next” and “prev”, but there are some interesting ones defined in previous versions of the standard that are listed by IANA and microdata too:</p>
<ul>
<li><code>next</code>: indicates that the linked resource is the next in a series.</li>
<li><code>prev</code>: refers to the linked document as the previous in a series.</li>
<li><code>previous</code>: this value is a synonym of “prev”. It isn’t valid anymore, so we should avoid it, but <a href="https://html.spec.whatwg.org/multipage/links.html#link-type-prev">browsers may still treat it as a “prev” for historical reasons</a>.</li>
<li><code>first</code>: identifies the linked document as the first in a series.</li>
<li><code>last</code>: indicates that the linked resource is the last in a series.</li>
<li><code>contents</code>: the linked document is a table of contents. Some agents may use the synonym <code>toc</code> too.</li>
<li><code>archives</code>: links to a collection of records or materials of historical interest for the document.</li>
<li><code>up</code>: refers to the parent/upper category of the current document. Not necessarily in a sequence, but it shows some hierarchy.</li>
</ul>
<p>Here’s a practical example of how it could be used to create pagination:</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>nav</span> <span data-sanitized-class="token attr-name">aria-label</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>course index<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>ul</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">      <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>a</span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>toc.html<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>contents<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>Table of Contents<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>a</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">      <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>a</span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>lesson-1.html<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>first<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>Lesson 1<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>a</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">      <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>a</span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>lesson-2.html<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>Lesson 2<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>a</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">      <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>a</span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>lesson-3.html<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>up<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>Lesson 3<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>a</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">      <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>a</span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>lesson-3.1.html<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>prev<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>Lesson 3.1<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>a</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">      <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>a</span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>lesson-3.2.html<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">aria-current</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>page<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>Lesson 3.2<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>a</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">      <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>a</span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>lesson-3.3.html<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>next<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>Lesson 3.3<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>a</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">      <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>a</span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>lesson-4.html<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>Lesson 4<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>a</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">      <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>a</span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>lesson-5.html<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>Lesson 5<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>a</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">      <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>a</span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>lesson-6.html<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>last<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>Lesson 6<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>a</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">      <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>a</span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>glossary.html<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>glossary<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>Glossary<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>a</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">    <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>li</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>ul</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>nav</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<p>In this example, we have a navigation with eleven links to the table of contents, each of the six lessons (plus three “sub lessons”), and a glossary page. Many of those links have been extended using the <code>rel</code> attribute and provide helpful information to the browser and assistive technologies.</p>
<p><strong>One perk of using “next” and “prev” with a <code>&lt;link&gt;</code> is that the browser may preload the linked documents</strong> to reduce the perceived load time, assuming that the user will most likely move forward/backward within the series.</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>link</span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>next<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>https://link-to-next-in-series<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token punctuation">/&gt;</span></span></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>link</span> <span data-sanitized-class="token attr-name">rel</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>prev<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">href</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>https://link-to-previous-in-series<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token punctuation">/&gt;</span></span></span></code></pre>
<p>In the past, Google used the “next” and “prev” links to index the pages accordingly, but <a href="https://twitter.com/JohnMu/status/1108717486424363009">that is no longer the case</a>. This doesn’t mean you should stop using those values: they are still helpful for accessibility, and other search engines may index based on them. Google is dominant but not the only one.</p>
<h1>Conclusion</h1>
<p>As you may have noticed by this really long article, the <code>rel</code> attribute is anything but trivial. It plays an important role in providing meaning to the links, taking the Internet to the next level semantically, and boosting your site’s performance through the roof.</p>
<p>If you made it here (did I already mention that this article is really long?), take a few more minutes to check other resources with more details and better explanations (Addy Osmani’s article is simply amazing.)</p>
<p>Thanks for reading!</p>
<h1>Bibliography</h1>
<ul>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a"><code>&lt;a&gt;</code>: The Anchor element</a>, on MDN Web Docs.</li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/area"><code>&lt;area&gt;</code>: The Image Map Area element</a>, on MDN Web Docs.</li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form"><code>&lt;form&gt;</code>: The Form element</a>, on MDN Web Docs.</li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link"><code>&lt;link&gt;</code>: The External Resource Link element</a>, on MDN Web Docs.</li>
<li><a href="https://microformats.org/wiki/existing-rel-values">Existing rel values</a>, on the microformats wiki.</li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/rel">HTML Attribute: rel</a>, on MDN Web Docs.</li>
<li><a href="https://www.iana.org/assignments/link-relations/link-relations.xhtml">Link Relations</a>, on the Internet Assigned Numbers Authority (IANA).</li>
<li><a href="https://html.spec.whatwg.org/multipage/links.html">Links</a>, on the HTML Living Standard.</li>
<li><a href="https://www.hixie.ch/specs/pingback/pingback">Pingback 1.0</a>, by Ian Hickson.</li>
<li><a href="https://medium.com/reloading/preload-prefetch-and-priorities-in-chrome-776165961bbf">Preload, Prefetch And Priorities in Chrome</a>, by Addy Osmani on Medium.</li>
<li><a href="https://nitropack.io/blog/post/resource-hints-performance-optimization">Preload, Preconnect, Prefetch: Improve Your Site’s Performance with Resource Hints</a>, by Niko Kaleev on Nitropack.</li>
<li><a href="https://www.w3.org/TR/resource-hints/">Resource Hints (Working Draft)</a>, by Ilya Grigorik on the W3C.</li>
<li><a href="https://gmpg.org/xfn/11">XFN 1.1 relationships meta data profile</a>, on the GMPG.</li>
</ul>


