# entry

title: Escaping Calypso's Island Ep.2: Trapped in the Cave (The Curse of Game Theory)
author: ;Rising Tide Foundation
hash: �EB;4��ד~h� ��
guid:
https://odysee.com/escaping-calypso%27s-island-ep.2-trapped:b469f7c71842299e12a2683c9815bd276ac1ca48

content:
<p><img src="https://thumbnails.lbry.com/gv97LL4LUNw" width="480" alt="thumbnail" title="Escaping Calypso's Island Ep.2: Trapped in the Cave (The Curse of Game Theory)"></p>Is the world a zero sum game or an open system shaped by creativity and cooperation? What truly defines humanity's supposed "limits to growth" and what is a "limited resource"? Is overpopulation a true crisis or is it a myth?<br><br>In this second episode in the ongoing series 'Escaping Calypso's Island', Cynthia Chung explores these questions, and examines the fallacies underlying the popular notion that human civilization can only grow at the expense of nature.<br><br>To watch Episode One (The Song of the Sirens), click here:<br>https://youtu.be/eH9qaTawttE<br><br>Support the Rising Tide Foundation's work by any of the following ways:<br><br>1) Sponsor these videos by making a donation on Paypal, Patreon or Wordpress<br>https://risingtidefoundation.net/support-the-work/<br><br>2) Subscribe to Matt and Cynthia's Substacks at<br>matthewehret.substack.com<br>cynthiachung.substack.com<br><br>3) Buy some books!<br>https://canadianpatriot.org/untold-history-of-canada-books/<br>...<br>https://www.youtube.com/watch?v=gv97LL4LUNw

link:
https://odysee.com/escaping-calypso%27s-island-ep.2-trapped:b469f7c71842299e12a2683c9815bd276ac1ca48

attributes:
{"enclosures":[{"url":"https://player.odycdn.com/api/v3/streams/free/escaping-calypso's-island-ep.2-trapped/b469f7c71842299e12a2683c9815bd276ac1ca48/b460ee.mp4","type":"video/mp4","length":475859783}]}


guid: https://htmhell.dev/adventcalendar/2023/16/
title: Swallowing camels
author: ;Manuel Matuzovic
link: https://htmhell.dev/adventcalendar/2023/16/
hash: e�m�ԟ��+���B�g
attributes: {"enclosures":[]}
content:
by Ida Franceen<br><blockquote>I don't like how the screen reader pronounces these numbers and I've been experimenting with different kinds of markup to get it to read better, like injecting spans to force it to make proper pauses…</blockquote>
<p>Reflecting on my tendency to obsess over small, but maybe not so important details has led me to write this article. I want to share my experiences and the lessons learned from past projects where I may have lost sight of what is actually important.</p>
<h2 data-sanitized-id="the-biggest-problem">The biggest problem</h2>
<p>When I'm actively trying to improve the accessibility of a website it's easy to start with the first issue I come across. Maybe the color contrast of the icons in the footer is not good enough, making it hard for people to see them. Let's fix this!<br>
But contrast might not be the biggest and most critical issue. To identify the biggest problem we need to pinpoint the core functionality. Are there any issues there? If yes, I need to fix them first. But what is the core functionality?</p>
<p>Well, if I'm selling things then the core functionality is probably people being able to buy things. However, if I'm focused on getting a screen reader to read prices in a preferred way, and my checkout is broken due to missing form labels, it's a problem. This situation makes it hard for some people to enter their addresses and in the end unable to make a purchase. In this case, I'm definitely focusing on the wrong thing. In other words, I'm <a href="https://dictionary.cambridge.org/dictionary/english/strain-at-a-gnat-and-swallow-a-camel">straining mosquitoes from my drink while swallowing camels</a>.</p>
<h2 data-sanitized-id="100percent-accessible">100% accessible</h2>
<p>I've always wanted to make the websites I'm working on perfect. But there is no such thing. Especially when it comes to accessibility. Websites are either more accessible or less accessible. They are never 100% accessible because we live in an evolving world where there will always be new barriers. This means that while striving for 100% accessibility is a good thing, it will remain an ongoing process of improvement rather than a fixed endpoint.</p>
<p>If my core functionality has big issues then my website is less accessible. Trying to fix it all and I will probably end up just fixing a few of the not-so-important things. If I want to move fast towards being more accessible I need to focus on fixing the core issues. There needs to be priorities.</p>
<h2 data-sanitized-id="its-not-about-me">It's not about me</h2>
<p>As a developer, it's straightforward to have a so-called “definition-of-done” where things work properly when I test it on my computer. I know there are other devices and other ways of using the web but I constantly need to remind myself of this. It is really easy to get caught up in details like how a screen reader pronounces things. But it's probably not the most important thing for me to care about.</p>
<p>Yes, of course really bad pronunciation may be an indicator that something is missing. Maybe a proper language attribute? Or maybe my screen reader is not set up properly?</p>
<p>The point is that I need to move away from my priorities and what I find annoying or interesting and <strong>consider what might be the biggest obstacle for other people</strong>.</p>
<h2 data-sanitized-id="take-a-step-back">Take a step back</h2>
<p>So, if I find myself arguing whether an extra div makes it too tricky for people to apply custom CSS it's time to take a pause. Or if I'm spending too much time thinking about whether a description list might be better off as an unordered list then I should take a step back. I need to check the core functionality and make sure that I didn't just swallow another camel.</p>


guid: https://htmhell.dev/adventcalendar/2023/17/
title: Revisiting Fundamentals - Semantic lists for Improved Accessibility
author: ;Manuel Matuzovic
link: https://htmhell.dev/adventcalendar/2023/17/
hash: kֈR#��G�ɑ�#
attributes: {"enclosures":[]}
content:
by Winnie Bosibori<br><p>Lists are one of the fundamental semantic HTML configurations that, when implemented appropriately can enhance accessibility.</p>
<h2 data-sanitized-id="html-lists-refresher">HTML Lists Refresher</h2>
<p>Whenever I visit any website, I have formed the habit of checking for any accessibility issues and delving deeper into the HTML code structure. One apparent thing is that a large number of sites are characterized by non-semantic code structures that result in inaccessible sites.<br>
One common culprit that I constantly come across is poorly marked-up list structures. From having list elements made with the paragraph elements to having headings, div, or span elements as direct children of <code>&lt;ul&gt;</code>, <code>&lt;ol&gt;</code>, or <code>&lt;dl&gt;</code> elements.</p>
<p>As developers or designers, we may sometimes overlook and deem lists as insignificant HTML constructs. However, Without lists, it will be difficult for people to follow content or information on a site. This is because they facilitate grouping related pieces of information, so they are associated with each other and make it easy to read and understand. In addition, people who use assistive technologies such as screen readers may be able to easily interact with a page using <a href="https://dequeuniversity.com/screenreaders/survival-guide">keyboard shortcuts</a>.</p>
<p>In this article, we are going to not only point out some of the bad practices that result from non-semantic lists but also provide best practices for creating accessible and inclusive lists. This article focuses exclusively on unordered and ordered lists.</p>
<h2 data-sanitized-id="unordered-list">Unordered List</h2>
<p>An unordered list is used to represent data or content whose order or hierarchy is not important. The items are commonly displayed in bullet form. A use case scenario for implementing an unordered list includes grouping related hyperlinks or a to-do list. Below is a code sample that demonstrates how to create an unordered list.</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>h2</span><span data-sanitized-class="token punctuation">&gt;</span></span> Shopping List <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> Apples <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> Pears <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> Oranges <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>
<h2 data-sanitized-id="ordered-lists">Ordered Lists</h2>
<p>The ordered list is used to represent data or content whose order or hierarchy is important. The items are indexed and commonly displayed as a numbered list, in alphabet letters, or in Roman numerals. Some of the use case scenarios for implementing an ordered list include but are not limited to a food recipe guide, a list of instructions for an online registration process, or multiple-choice tests. Below is a code sample demonstrating an ordered list.</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>h2</span><span data-sanitized-class="token punctuation">&gt;</span></span> Online Conference Registration Process <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>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>Go to the conference's official website and find the registration section.<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>Select the appropriate registration category.<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>Complete the online form with personal and professional details, and choose sessions if available.<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>Make a secure payment to confirm your registration.<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>Check emails for any conference updates and preparations.<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>
<h2 data-sanitized-id="semantic-html-lists-and-accessibility">Semantic HTML lists and Accessibility</h2>
<p>Semantic HTML entails the use of HTML tags to convey the meaning of a site’s content. Regarding lists, this refers to the use of lists for structuring or grouping related content, organizing information by importance, and conveying a particular order for processes or procedures.</p>
<p>For sighted users, identifying items organized as lists, including the type of list and the total number of items, is usually straightforward. This is due to their reliance on visual formatting cues like markers and indentation. However, for people using screen readers, the experience differs significantly. Screen readers, when encountering poorly marked-up lists, may fail to announce content as list items or specify the number of items present. Instead, they announce information based on the content's code structure. For example, if paragraph tags are utilized instead of list tags, the screen reader will present the content as paragraphs. This can hinder users' understanding and expectations, as they remain unaware of the actual number of items on the perceived 'list'.</p>
<figure data-sanitized-class="u-mb">
<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">  • Apples</span><br><span data-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">  • Pears</span><br><span data-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">  • Oranges</span><br><span data-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>
<figcaption>Bad practice: <a href="https://htmhell.dev/30-bullet-list/">A paragraph disguised as a list</a></figcaption>
</figure>
<p>The use of semantic lists is crucial for people relying on screen readers. They are notified they are interacting with a list, the index of the current item (in the case of ordered lists), the number of items, and the end of a list (NVDA will announce "out of list"). For instance, in the unordered list example, the NVDA screen reader on Windows will announce the following: "List with 3 items: Bullet Oranges, Bullet Pears, and Bullet Oranges". With this announcement, the users are communicated with semantic information (a list), the number of items (3), and the prepended bullet point markers to indicate an unordered list.<br>
Having such information upfront provides people using screen readers with an understanding of what to expect from the content. This is particularly beneficial in situations where establishing appropriate expectations is key to preparing them to interact with the content, enabling them to decide whether or not to go through the list.</p>
<p>Screen readers also provide several navigation techniques that ensure people are navigating seamlessly on a webpage. This is especially important for a web page that features several lists or a large list item. They include: jumping from one list to another, jumping from one list item to another, and in some screen readers getting out of the list. These navigation techniques are aligned with the keyboard to provide shortcut keys for accessing any list content present on a webpage. This <a href="https://dequeuniversity.com/screenreaders/">resource</a> provides keyboard shortcuts to how other screen-readers interact with lists. The table below provides a summary of the navigation techniques and keyboard shortcuts for navigating lists with NVDA (NonVisual Desktop Access, version 2023.2) screen reader.</p>
<table>
<thead>
<tr>
<th>List navigation technique</th>
<th>Keyboard shortcut</th>
</tr>
</thead>
<tbody>
<tr>
<td>Jump to next list</td>
<td>L</td>
</tr>
<tr>
<td>Jump to the previous list</td>
<td>Shift + L</td>
</tr>
<tr>
<td>Jump to next list item</td>
<td>I</td>
</tr>
<tr>
<td>Jump to the previous list item</td>
<td>Shift + I</td>
</tr>
<tr>
<td>To exit a list</td>
<td>, (comma)</td>
</tr>
</tbody>
</table>
<p>Semantic lists hugely contribute to content readability. This is especially important for people with <a href="https://www.w3.org/TR/coga-usable/#objective-2-help-users-find-what-they-need-0">cognitive and learning disabilities</a>. Large blocks of content can be difficult to read and understand. List facilitates breaking content into comprehensible chunks making it easier to read and understand the structure of the content. This is in addition to highlighting important points that might otherwise be lost when presented in a paragraph. For instance, the use of an ordered list for a food recipe demonstrates that the process has several sequential steps for its preparation.</p>
<p>In summary, lists provide the following benefits for accessibility:</p>
<ul>
 <li>Improved readability</li>
 <li>Highlight important points</li>
 <li>Provide the total number of items in a list </li>
 <li>May announce the current index of an item (in the case of ordered lists)</li>
 <li>Provide shortcuts to navigate between lists</li>
 <li>Provide shortcuts to navigate between list items</li>
</ul>
<h2 data-sanitized-id="common-mistakes-and-how-to-avoid-them">Common Mistakes and how to avoid them:</h2>
<p>Here are some common mistakes associated with the implementation of semantic HTML lists.</p>
<h3 data-sanitized-id="using-the-wrong-list-type">Using the Wrong List Type</h3>
<p>This entails implementing unordered lists when the order is important and vice versa. The key emphasis is if the order of your content or items is not relevant, implement an unordered list <code>&lt;ul&gt;</code> otherwise implement an ordered list <code>&lt;ol&gt;</code>. Below is a code sample demonstrating the relevance of using an ordered list.</p>
<p>Do not:</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>h2</span><span data-sanitized-class="token punctuation">&gt;</span></span> Cake Recipe <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>Preheat your oven to 350°F (175°C).<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>Grease and flour two 9-inch round cake pans.<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>In a medium bowl, sift together the flour, baking powder, baking soda, and salt.<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>
<p>Do:</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>h2</span><span data-sanitized-class="token punctuation">&gt;</span></span> Cake Recipe <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>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>Preheat your oven to 350°F (175°C).<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>Grease and flour two 9-inch round cake pan.<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>In a medium bowl, sift together the flour, baking powder, baking soda, and salt.<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>
<p>While both unordered and ordered lists present information sequentially, their implications differ significantly, especially in languages like English which are read from left to right and top to bottom. An unordered list, despite lacking explicit indexing, still suggests a sequence. In contrast, an ordered list emphasizes a specific, often chronological, sequence. By indexing the list items, people are directed to follow the information in a particular order, which is crucial for understanding instructions or processes, as illustrated in the example of the ordered list code. This difference matters in various contexts such as instructional or procedural information, where the order of steps can affect how well they are understood and done.</p>
<h3 data-sanitized-id="using-lists-for-non-list-content">Using Lists for Non-List Content</h3>
<p>HTML lists can sometimes be misused by authors who wish to achieve a particular visual effect on a webpage. This can involve manipulating the typical structure and presentation of lists for reasons unrelated to their intended purpose. One common example is wrapping entire paragraphs of text within <code>&lt;li&gt;</code> tags when the content is not itemized or part of a sequence. This could make the text harder to read and understand for everyone including people relying on screen readers, as it suggests a list structure where there isn't one. Instead, authors should use tags semantically, to reflect the type of content they are communicating. In this case, a paragraph <code>&lt;p&gt;&lt;/p&gt;</code> constructs are appropriate.</p>
<h3 data-sanitized-id="creating-fake-lists">Creating ‘fake’ lists.</h3>
<p>This involves implementing items in a way that they are visually recognized as lists. Often, some authors use divs, spans, or paragraphs, decorating them with hyphens, emojis, images, or numbers to simulate list formatting. While this approach might seem adequate for sighted users due to the presence of markers, it falls short for people who rely on screen readers. This is because screen readers announce the content based on its code structure, not on how the lists appear visually.</p>
<p>Don't:</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>h2</span><span data-sanitized-class="token punctuation">&gt;</span></span> To-do List <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>div</span><span data-sanitized-class="token punctuation">&gt;</span></span>*Clean<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>-Exercise <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>⭐Meal Prep <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>Do:</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>h2</span><span data-sanitized-class="token punctuation">&gt;</span></span> To-do List <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>Clean<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>Exercise<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>Meal Prep<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>
<p>In the first code sample, a screen reader will only announce the text content of the divs. People relying on screen readers will not know that this is a list or how many items are present. However, in the second example, the screen reader will announce the items as a list and provide the context of the number of items, which is three.</p>
<h3 data-sanitized-id="implementing-invalid-list-structure">Implementing invalid list structure.</h3>
<p>Implementing invalid list structures is another common issue on the web. Using <code>divs</code>, <code>p</code>, and <code>spans</code> as direct children-ordered lists <code>&lt;ol&gt;</code> or unordered lists <code>&lt;ul&gt;</code> is not valid. According to the Web Hypertext Application Technology Working Group (WHATWG), it disallows other elements as direct children on <code>&lt;ul&gt;</code> or <code>&lt;ol&gt;</code> constructs as outlined in their <a href="https://html.spec.whatwg.org/#concept-element-content-model">HTML specifications</a>. This ensures that content is structured and presented consistently and accessible across various platforms such as web browsers and assistive technologies like screen readers, making it usable for everyone.</p>
<p>Don't:</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>h2</span><span data-sanitized-class="token punctuation">&gt;</span></span> My Favorite Fruits <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> Orange<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> Apple<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> Banana <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>
<p>Do:</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>h2</span><span data-sanitized-class="token punctuation">&gt;</span></span> My Favorite Fruits <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>Orange<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> Apple<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> Banana <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>
<p>Screen readers interpret and announce lists based on the code's structure. Consider the two above code samples with NVDA (screen reader). In the first code sample, a non-list child element is included within a list. This results in a confusing output. Although the screen reader recognizes three items in the list, it fails to correctly identify 'apple' as a separate item. Instead, it announces 'apple' as plain text, seemingly part of the 'Orange' item, leading to an output like 'Bullet Orange apple'. In addition, this creates confusion because the screen reader announces the presence of three items, but effectively only two are clearly announced. In the second code sample, the list is structured correctly with valid items. The screen reader accurately announces the number of items, along with each item's context, providing clarity and understanding of the list items.</p>
<h2 data-sanitized-id="conclusion">Conclusion</h2>
<p>Lists, when implemented semantically, are great. They facilitate the visual conveyance of relationships between items, ensuring that information is easier to consume and understand. Assistive technologies such as screen readers can also present information accurately. Let's aim to implement semantic HTML lists so that we can continue creating meaningful structures and content for everyone.</p>
<p>Thank you for reading!</p>
<h2 data-sanitized-id="resources-for-further-reading">Resources for Further Reading</h2>
<ul>
<li><a href="https://benmyers.dev/blog/on-the-dl/">On the <code>&lt;dl&gt;</code></a> by Ben Myers</li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/ul">The Unordered List element</a> by MDN (Mozilla Developer Network)</li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/ol">The Ordered List element</a> by MDN</li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dl">The Description List element</a></li>
<li><a href="https://www.scottohara.me/blog/2018/05/26/aria-lists.html">ARIA Lists: Jump to Native ul and ol announcements</a></li>
</ul>


guid: https://htmhell.dev/adventcalendar/2023/18/
title: The road to HTMHell is paved with semantics
author: ;Manuel Matuzovic
link: https://htmhell.dev/adventcalendar/2023/18/
hash: �� ��Cש(� ϱ��b
attributes: {"enclosures":[]}
content:
by Vadim Makeev<br><p>HTML semantics is a nice idea, but does it really make a difference? There’s a huge gap between HTML spec’s good intentions and what browsers and screen readers are willing to implement. Writing semantic markup only because <a href="https://youtu.be/EIBRdBVkDHQ">the good spec is a spec, and it is good, and it’s a spec</a> is not the worst approach you can take, but it might lead you to HTMHell.</p>
<h2 data-sanitized-id="simple-days">Simple days</h2>
<p>Like most people involved in the front-end, I started my journey into Web development from HTML. It was simple enough, close to a natural language, and easy to use: you type some tags, save a text file, and reload the browser to see the result. And it would almost never fail if I made a mistake!</p>
<p>Back then, I considered HTML a simple set of visual building blocks. It was too late for purely visual <code>&lt;font&gt;</code> elements (the CSS has replaced them), but the general idea stayed pretty much the same: if you wrap your text into <code>&lt;h1&gt;</code>, it becomes big and bold, if you have two <code>&lt;td&gt;</code> cells in a row, that’s your two-column layout. Easy! I learned tags to be able to achieve certain styles and behaviors. Remember <code>&lt;marquee&gt;</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>marquee</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">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>7<span data-sanitized-class="token punctuation">"</span></span></span><br><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>marquee</span><span data-sanitized-class="token punctuation">&gt;</span></span></code></pre>

<p>
  <button type="button">
    Stop Marquee
  </button>
  <button type="button">
    Start Marquee
  </button>
</p>

<p>That was just the beginning: soon, I needed calendars, popups, icons, etc. It turned out I had to code them myself! And so I did, mainly using divs, spans, and some CSS. Back in the mid-2000s, there weren’t any particular “logical” tags or functional widgets, only the ones you’d find on a typical text editor panel.</p>
<p>But at some point, a trend called “<a href="https://www.webstandards.org/">web standards</a>” emerged: it suggested to stop using HTML as a set of visual blocks and start thinking about the meaning of the content and wrapping it into appropriate tags: <code>&lt;table&gt;</code> only for tabular data, not layout; <code>&lt;blockquote&gt;</code> only for quotes, not indentation, etc. The people bringing the web standards gospel were convincing enough, so I joined the movement.</p>
<h2 data-sanitized-id="semantics">Semantics</h2>
<p>Following the trend, we started studying the HTML 4 spec to learn the proper meaning of all those tags we’ve already known and many new ones we’ve never heard about. Suddenly, we’ve discovered semantics in HTML, not just visual building blocks.</p>
<ul>
<li><code>&lt;b&gt;</code> and <code>&lt;i&gt;</code> weren’t cool anymore: the proper stress and emphasis could only be achieved with <code>&lt;strong&gt;</code> and <code>&lt;em&gt;</code>.</li>
<li><code>&lt;ul&gt;</code> and <code>&lt;ol&gt;</code> weren’t only for bulleted/numbered lists in content anymore, but for all kinds of UI lists: menus, cards, icons.</li>
<li><code>&lt;dl&gt;</code>, <code>&lt;dt&gt;</code>, <code>&lt;dd&gt;</code> were accidentally discovered in the spec and extensively used for all kinds of lists with titles.</li>
<li><code>&lt;table&gt;</code> was banned from layout usage mainly because it wasn’t meant for that by the spec, but later, we also discovered rendering performance reasons.</li>
</ul>
<p>Why? Because we started paying attention to the spec, and it was semantically correct to do so. Every decision we make would have to be checked to determine whether it’s semantic enough. And how would we do that? By reading the spec like it’s a holy book that gives you answers in challenging moments of your life. On top of that, there was the <a href="https://validator.w3.org/">HTML Validator</a>’s seal of approval.</p>
<p><img src="https://htmhell.dev/adventcalendar/2023/18/images/valid.svg" alt="W3C HTML 4.01 badge with a checkmark."></p>
<p>But then came the <a href="https://en.wikipedia.org/wiki/Cambrian_explosion">Cambrian explosion</a> that changed everything: HTML 5.</p>
<h2 data-sanitized-id="a-new-hope">A new hope</h2>
<p>Just after the failed promise of <a href="https://en.wikipedia.org/wiki/XHTML">XHTML</a>, HTML 5 brought us new hope. Many new elements were added based on existing naming conventions to pave the cow paths. The new spec has challenged browsers for years ahead, from supporting the new parsing algorithm to default styles and accessibility mappings.</p>
<p>For the Web standards believers of the old spec, the new one was just a promised land:</p>
<ul>
<li><a href="https://developer.mozilla.org/en-US/blog/aria-accessibility-html-landmark-roles/">Landmarks</a> to mark logical parts like headers, footers, asides, navigations, sections, and articles.</li>
<li>Variety of new form elements other than the text ones: <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/date">dates</a>, <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/email">emails</a>, <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/number">numbers</a>, <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/range">ranges</a>, and <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/color">colors</a>.</li>
<li>Media and interactive elements for <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/video">video</a>, <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/audio">audio</a>, and <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/picture">graphics</a>.</li>
</ul>
<p>There was even a logo for semantics in the <a href="https://www.w3.org/html/logo/">HTML 5’s design</a>!</p>
<p><img src="https://htmhell.dev/adventcalendar/2023/18/images/semantics.svg" alt="Semantics logo with three horizontal angled lines pointing up."></p>
<p>Apart from extending the list of functional building blocks, the spec added several semantic elements that didn’t even come with any styling, just meaning. But not only that! Some old, purely visual elements were lucky enough not to be deprecated but redefined. For example, <code>&lt;b&gt;</code> and <code>&lt;i&gt;</code> became cool again, though no one could explain the use cases, apart from rather vague taxonomy and emphasis ones and… naming ships. You think I’m kidding? <a href="https://html.spec.whatwg.org/multipage/text-level-semantics.html#the-i-element">Check the spec!</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>i</span><span data-sanitized-class="token punctuation">&gt;</span></span>Boaty McBoatface<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>i</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<p>Don’t get me wrong, I think HTML 5 significantly advanced the Web, but it has also detached us from reality even further. Especially the idea of an outline algorithm and multiple nested <code>&lt;h1&gt;</code> elements that would change the level based on nesting. It was never implemented by any browser but existed in the spec for a long, long time <a href="https://github.com/whatwg/html/pull/7829">until finally removed in 2022</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>section</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>Please<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>section</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>Don’t use<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>section</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>This code!<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>section</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>section</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>section</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<p>⚠️ Please don’t use the code above. It’s wrong and harmful.</p>
<p>Personally, I’ve wasted too many hours arguing about the difference between <code>&lt;article&gt;</code> and <code>&lt;section&gt;</code> for purely theoretical reasons instead of focusing on good user experience.</p>
<h2 data-sanitized-id="drunk-on-semantics">Drunk on semantics</h2>
<p>Although the spec would provide examples, it primarily focused on marking up content, not UI. Even examples themselves were often purely theoretical with a kind of usage that would be semantically correct, not always practically useful. There’s <a href="https://www.w3.org/wiki/HTML/W3C-WHATWG-Differences">another whole story</a> about the difference between the W3C and WHATWG spec versions, but the W3C’s examples were usually better.</p>
<p>I’ve seen a lot of weird stuff and did it myself, too. People would often look at the HTML spec as a dictionary, looking up a word in the list of elements for an idea they had in mind. Try to read the following examples through the eyes of a beginner, giving a shallow look at the spec. They totally make sense!</p>
<ul>
<li><code>&lt;menu&gt;</code> for wrapping the navigation menus.</li>
<li><code>&lt;article&gt;</code> for the content of an article.</li>
<li><code>&lt;input type="number"&gt;</code> for a phone number.</li>
<li><code>&lt;button&gt;</code> for everything that looks like a button.</li>
</ul>
<p>I haven’t seen the <code>&lt;slot&gt;</code> element used on a casino website to mark up a slot machine, but maybe only because I’m not into gambling. But the rest of the examples are real.</p>
<p>At the same time, a lot of people would read the spec carefully and use <code>&lt;footer&gt;</code>, <code>&lt;header&gt;</code>, <code>&lt;main&gt;</code>, and other semantic elements properly. But the reason for that won’t be any different: they would also aim for semantically correct markup only because the spec says so. And if it does, the smartest of us would think it should be good for users, search engines, etc. Right?</p>
<p>It turned out that the spec could be wrong, and <strong>semantically correct markup wouldn’t guarantee good practical results</strong>.</p>
<p>I don’t blame people who gave up on following the spec altogether and became cynical enough to use <code>&lt;i&gt;</code> for icons instead of naming damn ships. Fortunately, I didn’t go this way. I found another reason to keep caring about markup: user experience and accessibility.</p>
<h2 data-sanitized-id="good-intentions">Good intentions</h2>
<p>Unlike many other languages, HTML is a user-facing one. It means that <strong>our decisions directly affect users</strong>.</p>
<p>Fortunately, it doesn’t matter how we format our markup, but our selection of elements matters a lot. So when I hear “this markup is semantic,” it often means that it’s correct according to the spec but not exactly good for actual users. Even though both can be true at the same time, the focus is in the wrong place.</p>
<p>It seems to me that we decided to trust the spec’s recommendations at some point without checking whether they were true. I firmly believe that the spec authors’ intentions are always good, and I know many smart people working on the HTML spec. But when it comes to implementation in browsers or screen readers, these intentions don’t always survive the reality.</p>
<p>There are usually three main obstacles:</p>
<ol>
<li>Product priorities: you probably know that already, but accessibility isn’t always a number one priority for various reasons, including complexity and the lack of people who know the area.</li>
<li>Different points of view: for the same reason, automated testing won’t save you from accessibility issues, different user agents might have other points of view on certain platform features.</li>
<li>Actual user experience: browsers call themselves “user agents” for a reason. When a specific platform feature or how developers use it hurts the users, browsers tend to intervene.</li>
</ol>
<p>For example, the following list won’t be exposed as a list to VoiceOver in Safari only because you decided to disable default bullets and implement custom ones via CSS pseudo-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 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">list-style</span><span data-sanitized-class="token punctuation">:</span> none</span><span data-sanitized-class="token punctuation">"</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>li</span><span data-sanitized-class="token punctuation">&gt;</span></span>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>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>
<p>You can force the usual behavior by adding <code>role="list"</code> to every list you style, but how convenient is that? Not at all for you as a developer. But Safari has probably had some reasons, most likely to improve their users’ experience by ignoring all semantically correct lists we started using so much outside of content.</p>
<p>As for the screen readers, Steve Faulkner’s “<a href="https://www.tpgi.com/screen-readers-support-for-text-level-html-semantics/">Screen Readers support for text level HTML semantics</a>” article might open your eyes to the actual value of those tags we’re so passionately arguing about.</p>
<blockquote>No browsers expose <code>&lt;strong&gt;</code> or <code>&lt;em&gt;</code> element role semantics in the accessibility tree.</blockquote>
<p>Again, you can force some semantics via ARIA roles, but should you? That’s an open question. The answer depends on the value you’re trying to bring your users.</p>
<p>Does it mean we should immediately stop using semantic elements if they don’t bear any value for the users? I don’t think so. But I stopped using a <em>semantics argument</em> when talking about good markup. Just like tabs and spaces, semicolons, or quotes, semantics sometimes is a stylistic preference.</p>
<p>There’s also a future-proofing argument that suggests using semantic markup with the hope that someday, browsers will start supporting all those elements they choose to ignore now. I wouldn’t rely on it too much and prefer to focus on what’s important right now.</p>
<p>I used to be among those people who’d judge the quality of a website based on the number of divs it’s built of. We’d say, “Nah, too many divs, it’s not semantic.” Now I know that <strong>what’s inside of those divs matters the most</strong>. Enough landmarks, headings, links, and buttons would make it good, even if the divs/semantic elements ratio is 1000 to 10. We are <em>divelopers,</em> <a href="https://twitter.com/chriscoyier/status/1050456501414838272">as Chris Coyier once said</a>. Don’t be ashamed of this, wear this name with pride.</p>
<h2 data-sanitized-id="training-wheels">Training wheels</h2>
<p>Following spec’s recommendations with semantic markup is still a good start, especially when you treat it as not just the list of available elements. I mostly agree with this idea often expressed by accessibility experts:</p>
<blockquote>If you write semantic markup, it will be mostly accessible.</blockquote>
<p>But to me, it sounds like a simple answer to a complex question. The HTML spec might be a good set of training wheels, but at some point, you’ll have to take them off. Not everything can be solved by semantic markup, for example, you’ll need to learn ARIA to create any modern interactive UI. There’s just not enought semantic elements for everything!</p>
<p>There are many simple answers waiting for you in the spec or articles praising semantics as the only thing you need. There are even more compromises made in modern frameworks in the name of better developer experience. And they aren’t all wrong! But if you keep your focus on the user experience, on the actual quality of the user interface, you’ll be able to make the right decisions.</p>
<p>And you know what? It doesn’t matter if you agree with me on the value of semantics. I’m sure you’ll be fine. After all, you’ve just read a big rant on HTML in the HTMHell advent calendar.</p>


guid: https://htmhell.dev/adventcalendar/2023/19/
title: Boosting testing efficiency: how semantic HTML transforms End-to-End testing
author: ;Manuel Matuzovic
link: https://htmhell.dev/adventcalendar/2023/19/
hash: .B�1��P��������6
attributes: {"enclosures":[]}
content:
by Stefania Mellai<br><p>Semantic and accessible HTML serves as a powerful tool, enhancing not only human interaction but also the efficiency of software systems. For instance, when users fill out forms with clear labels and accessible input fields, this reduces errors and ensures sending accurate data to the backend and databases. You may also have heard about how a well structured web page is fundamental for search engine optimization (SEO).<br>
Creating crafts that are accessible and easy to use for everybody should be the top concern of every developer. The good thing is that prioritizing this aspect can also have a positive side effect: it enables seamless interactions between your website and other software components.<br>
Let's explore in particular how to improve your testing processes and save valuable time.</p>

 
 
<h2 data-sanitized-id="the-connection-between-semantic-html-accessibility-and-testing">The Connection Between Semantic HTML, Accessibility, and Testing</h2>
<p>This topic was beautifully explored by Rita Castro, in her talk <a href="https://portal.gitnation.org/contents/a11y-and-tdd-a-perfect-match">a11y and TDD: A Perfect Match</a>. While Rita mainly focuses on unit tests, it's worth mentioning how these principles can be applied to end-to-end testing as well, and for the same reasons.</p>
<h2 data-sanitized-id="the-end-to-end-testing-dilemma">The End-to-End Testing Dilemma</h2>
<p>End-to-end testing, goes beyond checking individual parts of a website. It tries to act like a real user in a real web browser, testing the whole webpage as it would appear to someone using it for real.</p>
<p>Let's imagine we are writing a unit test for a list item component, that produces the following HTML:</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>li</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">  A description for this item</span><br><span data-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>Pick this item<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>li</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<p>And the unit test can target the button like this:</p>
<pre data-sanitized-class="language-js"><code data-sanitized-class="language-js"><span data-sanitized-class="highlight-line">screen<span data-sanitized-class="token punctuation">.</span><span data-sanitized-class="token function">getByRole</span><span data-sanitized-class="token punctuation">(</span><span data-sanitized-class="token string">'button'</span><span data-sanitized-class="token punctuation">)</span></span></code></pre>
<p>This approach is great for testing the component in isolation, which is what "unit" means. It simplifies testing by not worrying about other possible buttons on the page and by ignoring context.</p>
<p>However, unit tests can't fully replicate real-life scenarios. For instance, they can't ensure that clicking the button saves some data for the current user and navigates to another page.</p>
<p>Now, consider our list item used in a full web page, with a topbar that contains buttons and other sections beyond the list container. The list in the page wasn't built with semantics and accessibility in mind, so it looks like this (taken from real production web application 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>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>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>root<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 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>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 comment">&lt;!-- topbar --&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>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>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>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>h1</span><span data-sanitized-class="token punctuation">&gt;</span></span>Page Title<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>h3</span><span data-sanitized-class="token punctuation">&gt;</span></span>Page subtitle<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>h3</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>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>div</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;!-- a form for filtering the list --&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>hr</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>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>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>p</span><span data-sanitized-class="token punctuation">&gt;</span></span>A description for this item<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>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>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 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> Pick this 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>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><br><span data-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>div</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;!-- second item --&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 comment">&lt;!-- ... --&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>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>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>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>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>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></code></pre>


<p>Most end-to-end testing tools can record your actions as you interact with a webpage and then use those actions for automation. They save selectors to automatically identify the items you interact with.<br>
We want to test the click of the button in the first element in the list. I have to confess I simplified a bit the HTML in the example, and the real selector produced by the tool looks like this:</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line">//*[@id="root"]/div/div/div/div/div/div/div[3]/div/div/div[2]/div[1]/div[2]/button</span></code></pre>
<p>Whenever you tweak your HTML, even adding or removing only one of the div wrappers, your test suite can easily get messed up in this situation. End-to-end tests aren't something you update every day because they are slow and need lots of resources. So, figuring out why a test failed can be time-consuming and take you away from more important tasks.</p>
<p>Testing tools are getting more and more better at identifing targets, but the algorithms are not bulletproof and can't react to page structure changes with 100% reliability. That's why it is important that targets can be recognized without ambiguity. One of the techniques more common to obtain this clarity is adding unique <code>id</code>s, <code>test-id</code>s or other selectors to the HTML elements, but it's not a best practice, for a bunch of reasons:</p>
<ul>
<li><strong>Separation of Concerns</strong>: Mixing testing concerns with your application's business logic violates the principle of separation of concerns. You are coupling two distinct and indipendent objects and a person working in one of the sides may be totally unaware that something is used and necessary on the other side. This person can also be the same person that didn't work on one of the parts for some time and lose the context in the meanwhile.</li>
<li><strong>Maintainability</strong>: Test IDs may need to change or evolve as your application grows and changes. When you embed these IDs directly in your code, you may need to make widespread changes throughout your codebase whenever test requirements change. This can be time-consuming and error-prone.</li>
<li><strong>Code Clutter</strong>: Embedding test-related identifiers in your source code can clutter the codebase and make it less readable for developers.</li>
<li><strong>Accessibility</strong>: Adding test IDs actively misses the opportunity to incorporate accessibility testing for free. If my test suite explicitly looks for a button, it also ensures that the target keeps being an accessible button, and it's not refactored to unsemantic div later.</li>
</ul>




<h2 data-sanitized-id="the-power-of-semantic-html-in-testing">The Power of Semantic HTML in Testing</h2>
<p>Now, envision a different scenario where your list is built with clean, semantic HTML. We don't use the automatic targeting algorithm and we add a manual selector for the first item in the list like this:</p>
<pre data-sanitized-class="language-html"><code data-sanitized-class="language-html"><span data-sanitized-class="highlight-line">//*li[1]/button</span></code></pre>


<p>Regardless of any HTML changes you make to the sourrounding structure around the list item, your test remains rock-solid. To recap:</p>
<ul>
<li>Relying on automatic targeting algorithm may result in flakyness and, in best case scenario, you need to regenerate the target. If your tests require adjustements every time you change the underlying structure of your markup, they may not authentically simulate a user journey but instead are too closely tied to implementation details.</li>
<li>Using arbitrary <code>ids</code> or other unique selectors is a bad practice.</li>
<li>Having semantic HTML enables easy manual targeting that is more resilient against changes. It should also help detecting actions that may break the accessibility of your UI.</li>
</ul>




<h2 data-sanitized-id="why-it-matters">Why It Matters</h2>
<p>So, why should you care about semantic HTML and accessibility in testing?</p>


<ul>
<li><strong>Developer and QA Bliss</strong>: Life becomes easier for developers and QA engineers. Writing tests becomes a breeze when you can work with straightforward, semantic code.</li>
<li><strong>Mimicking Real Users</strong>: Your tests better mimic real user behavior. Real users don't look for divs and spans in your web application; they look for headings, buttons, links, and familiar interface elements with clear labels.</li>
</ul>


<ul>
<li><strong>Reliability and Time Savings</strong>: Your tests become more reliable and won't break with every deployment for arbitrary reasons. Say goodbye to countless hours spent tweaking tests and hello to more productive work.</li>
</ul>


<p>In conclusion, embracing semantic HTML and accessibility in your development process isn't just about adhering to best practices; it's a game-changer for testing. It streamlines your testing efforts, makes your tests more realistic, and ensures they stand the test of time—saving you precious hours and frustration. So, don't underestimate the power of clean code; it could be your testing superhero in disguise.</p>


guid: https://htmhell.dev/adventcalendar/2023/20/
title: Design pattern for custom tooltips
author: ;Manuel Matuzovic
link: https://htmhell.dev/adventcalendar/2023/20/
hash: �%D5�T��^��B%��
attributes: {"enclosures":[]}
content:
by Jan Hellbusch<br><p>Should we use tooltips to convey information? Hints and descriptions are often included on web pages through tooltips – but not everyone has access to them.</p>
<p>A tooltip is a short text that usually appears as a popup when a user hovers a mouse pointer over an element. Tooltips can be attached to any HTML element using the title attribute. There are only a few exceptions when a tooltip created with a title attribute will not be displayed (e.g., a title attribute on an iframe element).</p> 
<p>In this article, we’ll first take a look at the title attribute in HTML and point out to a few accessibility issues. Then we’ll make a few general suggestions about how to use tooltips. In the third part, we’ll build two accessible custom tooltips with HTML and ARIA, then look at two different CSS solutions and finally add an event handler in accordance with accessibility guidelines. Both tooltips can be previewed:</p>
<ul>
<li>In <a href="https://codepen.io/matuzo/debug/mdvGMpb">example 1</a>, you’ll find a nested tooltip with a basic design using the z-index property.</li>
<li>In <a href="https://cdpn.io/pen/debug/RwvYZxX">example 2</a>, you’ll find a tooltip using the new anchor positioning technique.</li>
</ul>
<h2>Accessibility issues for the title attribute</h2>
<p>The title attribute is not particularly accessible. As Steve Faulkner puts it:</p>
<figure data-sanitized-class="u-mb">
<blockquote><p>If you want to hide content from mobile and tablet users as well as assistive tech users and keyboard-only users, use the title attribute.</p></blockquote>
<figcaption><cite><a href="https://www.tpgi.com/using-the-html-title-attribute-updated/">https://www.tpgi.com/using-the-html-title-attribute-updated</a></cite></figcaption>
</figure>
<p>Assistive technologies include screen readers and screen magnifiers. In terms of accessibility, title attributes lack support for the following user groups:</p>
<ul>
<li>Keyboard users. <p>Because keyboard users are only able to focus active elements such as links or forms, browsers can only reveal tooltips for focusable elements. Even then, browsers do not display the content of title attributes on keyboard focus (there were some exceptions for forms on Internet Explorer some time ago).</p></li>  
<li>Screen reader users. <p>For active elements, browsers will process the content of a title attribute as an “accessible description” when an active element such as a link is focused with the tab key. Usually, the accessible description is suffixed to the link name. That can be helpful in certain situations, but screen reader users won’t necessarily navigate by tab key, because non-focusable content will be skipped. A title attribute can nevertheless be discovered on links, forms and other active elements in a screen reader.</p></li>
<li>Screen magnification users. <p>Using a screen magnifier can make tooltips impossible to read. Tooltips included with a title attribute will only be displayed when the mouse pointer is hovering over the triggering element. Using screen magnification, the enlarged portion of the viewport that is actually visible can reduced significantly. In this situation, users will have to move the pointer to pan the tooltip to read the full text. However, as soon as the pointer hovers over the tooltip, browsers will hide the tooltip.</p></li>
</ul>
<p>Also take a look at the HTML Standard. HTML discourages the use of the title attribute:</p> 
<figure data-sanitized-class="u-mb">
<blockquote><p>Relying on the title attribute is currently discouraged as many user agents do not expose the attribute in an accessible manner as required by this specification (e.g., requiring a pointing device such as a mouse to cause a tooltip to appear, which excludes keyboard-only users and touch-only users, such as anyone with a modern phone or tablet).</p></blockquote>
<figcaption><cite><a href="https://html.spec.whatwg.org/multipage/dom.html#the-title-attribute">https://html.spec.whatwg.org/multipage/dom.html#the-title-attribute</a></cite></figcaption>
</figure>
<div data-sanitized-class="highlight u-mb">
<p><strong>Best practice</strong>: do not use the title attribute to create a tooltip.</p>
</div>
<h2>Reconsidering using tooltips?</h2>
<p>If you are still considering using tooltips on your web pages, be restrictive when using them. There are plenty of guidelines on the web about when to use tooltips and when not, for example:</p>
 <ol>
<li>Do not include crucial information in a tooltip. Information required to finish a task must always be accessible to all users.</li>
<li>Do not include repetitive or obvious text in a tooltip. At best, those kinds of tooltips are distracting.</li>
<li>Keep tooltips short. Tooltips can be a reminder or a brief rewording to a short label.</li> 
<li>Tooltips should not cover other relevant content. For example, the tooltip should not cover the label in a form field.</li>
</ol>
<p>Most importantly, tooltips should only provide descriptive and non-essential text, giving slightly more detailed text for active elements such as links and form controls. Ultimately, they provide expendable text which is already on the web page.</p>
<p>The following code shows a form field with an additional text to be shown as a tooltip:</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">	<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>foo<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>Full name<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">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>text<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">autocomplete</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>name<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>foo<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>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>tooltip<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">hidden</span><span data-sanitized-class="token punctuation">&gt;</span></span>Enter your first name followed by your surname<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>p</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<p>The hidden text is intended to be displayed when the form field is focused. The hidden text is the first step in creating a custom, accessible tooltip as an alternative to the title attribute. The CSS properties to disclose and hide the tooltip will be discussed in Step 2 below.</p> 
<div data-sanitized-class="highlight u-mb">
<p><strong>Best practice</strong>: provide only expendable information in a tooltip.</p>
</div>
<h2>Tooltip accessibility</h2>
<p>Make sure your tooltips are accessible. That will include keyboard users and users of assistive technology. An accessible tooltip will have to fulfil the following requirements:</p>
<ol>
<li>Use correct semantics (HTML and ARIA).</li>
<li>Make sure the tooltip can be displayed by keyboard.</li>
<li>Ensure all users can lightly dismiss the tooltip.</li>
</ol>
<p>Note that there is more to accessible custom tooltips than just these three aspects. For example, tooltips must also satisfy contrast requirements or adapt to text resizing.</p>
<h3>Step 1: HTML and ARIA</h3>
<p>If you’re starting from scratch, it is always best to begin with HTML. A tooltip for a link can be set up as follows:</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">	<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://www.example.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">		link text</span><br><span data-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>tooltip<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">hidden</span><span data-sanitized-class="token punctuation">&gt;</span></span>helpful, but non-essential tooltip<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>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 tooltip does not have to be nested within the active element. What you need to consider in HTML is:</p>
<ul>
<li>Assistive technology must be able to determine the correct reading sequence. The tooltip must immediately follow the triggering component or its label.</li>
<li>You will need to position the tooltip. Nesting the tooltip within the link simplifies CSS positioning.</li>
</ul>
<p>Note: Users should never be able to focus something within a tooltip. If, for whatever reason, the popup requires focus, then you should be using a dialog element with the <code>showModal()</code> or <code>show()</code> methods. Alternatively, you might need a popovertarget attribute for the triggering element.</p>
<div data-sanitized-class="highlight u-mb">
<p><strong>Best practice</strong>:</p> 
<ul>
<li>When building a custom tooltip, first make sure the HTML makes sense in a screen reader.</li>
<li>Ensure the triggering element can be focused by keyboard.</li>
</ul>
</div>
<p>In our code example, the relationship between link and tooltip seems obvious, but the conveyed relationship must also be determinable by assistive technology. The places to check possible requirements are the <a href="https://www.w3.org/WAI/ARIA/apg/patterns/tooltip/">ARIA Authoring Practices Guide (APG)</a> or the <a href="https://www.w3.org/TR/wai-aria-1.2/#tooltip">ARIA specification</a>, if the APG does not provide guidance for whatever you are coding. For tooltips, the APG suggests the following:
</p><ol>
<li>The element that serves as the tooltip container has a tooltip role.</li>
<li>The element that triggers the tooltip references the tooltip element with aria-describedby. To this end, the element with the tooltip requires an ID.</li>
</ol>
<p>Basically, with the <code>aria-describedby</code> attribute we are telling the link what its tooltip is and turning the tooltip into an accessible description for the link. Accessible descriptions for links are exposed to assistive technology users when the link is focused by tab key.</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">	<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://www.example.com<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">aria-describedby</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></span><br><span data-sanitized-class="highlight-line">		link text </span><br><span data-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">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>me<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>tooltip<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">hidden</span><span data-sanitized-class="token punctuation">&gt;</span></span>helpful, but non-essential tooltip<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>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>How useful the tooltip role is when implementing custom tooltips is unclear. Currently, it makes no difference in assistive technology whether the tooltip has <code>role="tooltip"</code> or not. The relationship between link and tooltip is conveyed solely by the <code>aria-describedby</code> attribute. The role has purposely been omitted. You’ll find more on this subject on <a href="https://github.com/w3c/aria/issues/979">GitHub</a>.</p> 
<div data-sanitized-class="highlight u-mb">
<p><strong>Best practice</strong>: use ARIA only when it is useful to assistive technology.</p>
</div>
<p>Explicitly referencing a tooltip from its triggering element is even more important for form controls. Tooltips will not be nested within a component. To better position the tooltip, you might add a span element with a class as in the following snippet:</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">	<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>foo<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>Full name<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>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>tooltipWidget<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>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>text<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">autocomplete</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>name<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>foo<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">aria-describedby</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>bar<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>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>bar<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>tooltip<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">hidden</span><span data-sanitized-class="token punctuation">&gt;</span></span>Enter your first name followed by your surname<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>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></span></code></pre>
<h3>Step 2: Displaying and hiding the tooltip</h3>
<p>For a tooltip to be accessible, displaying a tooltip must not only be possible for mouse users, but also for keyboard and touchscreen users. There are generally two approaches for displaying a tooltip with a keyboard:</p>
<ol>
<li>Automatically displaying the tooltip when the triggering element receives focus.</li>
<li>Providing a keyboard shortcut to open the tooltip for the focused element.</li>
</ol>
<p>The first approach makes tooltips easily discoverable for keyboard users, but if a webpage includes many tooltips, the continuous displaying of expendable information can become distracting. The advantage of the second approach to open the tooltip is that users can display the tooltip only on request. But the second approach also comes with some disadvantages:</p>
<ul>
<li>It is impossible to tell whether the tooltip will show supplemental (helpful) or expendable information. Hitting keyboard shortcuts to display (and hide) tooltips seems to be an unnecessary burden.</li>
<li>There is no standardized keystroke for displaying a tooltip. If you choose this technique, you should use a keystroke common to different platforms for invoking interaction such as space key using JavaScript.</li> 
<li>Components with tooltips will require a visual affordance to indicate the presence of a tooltip. <p>Note: the visual affordance is for sighted users only and should not be accessible to screen readers. Screen readers access the tooltip through the <code>aria-describedby</code> attribute.</p></li>
</ul>
<p>We will take the first approach. This seems closer to the expected behavior for a tooltip.</p>
<p>There are two specific accessibility aspects to consider for your CSS:</p>
<ol>
<li>If tooltips appear on hover or keyboard focus, they must remain visible until hover or focus is removed by the user. Some users will have difficulty reading or even perceiving the displayed content, if the tooltip is hidden after a short time.</li> 
<li>Especially users who use a screen magnifier with high magnification can only view small portions of the screen. In order to get an overview of the content, users must be able to pan the viewport, with the magnified portion following the mouse pointer. The tooltip must be displayed as long as the pointer is hovering on the triggering element as well as on the tooltip. See the second condition for success criterion 1.4.13 in the <a href="https://www.w3.org/WAI/WCAG22/Understanding/content-on-hover-or-focus">Web Content Accessibility Guidelines (WCAG) 2.2</a>. <p>Note: the magnification levels vary greatly and 20x, 30x or even higher magnification is quite possible. The higher the magnification level, the smaller the screen portion.</p></li>
</ol>
<p>Basic CSS for displaying and hiding a tooltip is fairly straightforward using a nested tooltip. The following CSS declarations create custom tooltips for the link and the input field for <a href="https://codepen.io/matuzo/debug/mdvGMpb">example 1</a>. You can use the position property to place the tooltip next to the triggering element:</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">a:has(.tooltip), .tooltipWidget:has(.tooltip)</span> <span data-sanitized-class="token punctuation">{</span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token property">position</span><span data-sanitized-class="token punctuation">:</span> relative<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">.tooltipWidget:focus-within .tooltip, <br><span data-sanitized-class="highlight-line">.tooltipWidget:hover .tooltip,</span><br><span data-sanitized-class="highlight-line">.tooltipWidget .tooltip:hover,</span><br><span data-sanitized-class="highlight-line">a:focus .tooltip, </span><br><span data-sanitized-class="highlight-line">a:hover .tooltip, </span><br>a .tooltip:hover</span> <span data-sanitized-class="token punctuation">{</span><br><span data-sanitized-class="highlight-line">	<span data-sanitized-class="token property">display</span><span data-sanitized-class="token punctuation">:</span>block<span data-sanitized-class="token punctuation">;</span></span><br><span data-sanitized-class="highlight-line">	<span data-sanitized-class="token property">position</span><span data-sanitized-class="token punctuation">:</span> absolute<span data-sanitized-class="token punctuation">;</span></span><br><span data-sanitized-class="highlight-line">	<span data-sanitized-class="token property">left</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">top</span><span data-sanitized-class="token punctuation">:</span>1em<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>0.5em 0.75em<span data-sanitized-class="token punctuation">;</span> </span><br><span data-sanitized-class="highlight-line">	<span data-sanitized-class="token property">background</span><span data-sanitized-class="token punctuation">:</span>#334E58<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> white<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>solid #334E58 2px<span data-sanitized-class="token punctuation">;</span> <span data-sanitized-class="token comment">/* for contrast mode */</span></span><br><span data-sanitized-class="highlight-line">	<span data-sanitized-class="token property">width</span><span data-sanitized-class="token punctuation">:</span>10em<span data-sanitized-class="token punctuation">;</span></span><br><span data-sanitized-class="highlight-line">	<span data-sanitized-class="token property">z-index</span><span data-sanitized-class="token punctuation">:</span>1<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><a href="https://codepen.io/matuzo/pen/mdvGMpb">See example 1 on CodePen</a></p>
<div data-sanitized-class="highlight u-mb">
<p><strong>Best practice</strong>: make sure to extend the hover state to the tooltip to allow users to move the pointer over the tooltip without the tooltip disappearing.</p>
</div> 
<p>There is a lot more to consider when displaying tooltips, for example:</p>
<ul>
<li>Where should the tooltip be shown – above, below or to one side of the triggering element?</li>
<li>What is to be done if the tooltip is cut off by the viewport?</li> 
<li>Can we display tooltips using CSS or do we need JavaScript?</li>
<li>Do you need some kind of package to create your custom tooltips?</li>
</ul>
<p>As this article deals with the accessibility of tooltips, we won’t go down a rabbit hole to provide answers to these questions. The bottom line is that as soon as you need a flexible presentation of tooltips (e.g., displaying tooltips below the triggering element, unless the triggering element is at the bottom of the viewport, in which case the tooltip should be displayed above the triggering element), you are dependent on JavaScript. You may need to exchange classes for repositioning or redimensioning your tooltip, depending on viewport size and other factors. Your code can get quite complicated. See some assessments on: <a href="https://developer.chrome.com/blog/tether-elements-to-each-other-with-css-anchor-positioning/">Tether elements to each other with CSS anchor positioning</a>.</p> 
<p>But fortunately, there is something new in CSS that will help solve these issues.</p>
<p>The new CSS feature is <a href="https://www.w3.org/TR/css-anchor-position-1/">anchor positioning</a>. Currently, it will work in Chrome Canary with experimental mode switched on, but it will take some time before it is found in mainstream browsers.</p>
<p>Anchor positioning promises flexible positioning of your tooltips based on CSS and your guidance. First of all, you are not dependent on nesting your tooltips to easily position them. You can rearrange your HTML, but remember that you still need to consider the reading order. The input field from example 1 could be adapted to the following (<a href="https://cdpn.io/pen/debug/RwvYZxX">example 2</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 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>form-element<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>foo<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>Full name<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 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">	<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>text<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">autocomplete</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>name<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>foo<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">aria-describedby</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>bar<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></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>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>bar<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>tooltip<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token attr-name">hidden</span><span data-sanitized-class="token punctuation">&gt;</span></span></span><br><span data-sanitized-class="highlight-line">	Enter your first name followed by your surname</span><br><span data-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></span></code></pre>
<p>With anchor positioning, the example could be adapted to display the tooltip to the right or below the anchor (triggering element), depending on where the anchor is in the viewport:</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">@supports</span> <span data-sanitized-class="token punctuation">(</span><span data-sanitized-class="token property">anchor-name</span><span data-sanitized-class="token punctuation">:</span> --anchor-foo<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 selector">*</span> <span data-sanitized-class="token punctuation">{</span></span><br><span data-sanitized-class="highlight-line">		<span data-sanitized-class="token property">box-sizing</span><span data-sanitized-class="token punctuation">:</span> border-box<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">input</span> <span data-sanitized-class="token punctuation">{</span></span><br><span data-sanitized-class="highlight-line">		<span data-sanitized-class="token property">position</span><span data-sanitized-class="token punctuation">:</span> relative<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> 200px<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> 1px solid #334e58<span data-sanitized-class="token punctuation">;</span></span><br><span data-sanitized-class="highlight-line">		<span data-sanitized-class="token property">anchor-name</span><span data-sanitized-class="token punctuation">:</span> --anchor-foo<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">input:hover,<br>	input:focus</span> <span data-sanitized-class="token punctuation">{</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 #334e58<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> 0.5rem 0.75rem<span data-sanitized-class="token punctuation">;</span></span><br><span data-sanitized-class="highlight-line">		<span data-sanitized-class="token property">outline</span><span data-sanitized-class="token punctuation">:</span> none<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">.form-element</span> <span data-sanitized-class="token punctuation">{</span></span><br><span data-sanitized-class="highlight-line">		<span data-sanitized-class="token property">position</span><span data-sanitized-class="token punctuation">:</span> relative<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">.form-element:hover ~ .tooltip,<br><span data-sanitized-class="highlight-line">	.form-element ~ .tooltip:hover,</span><br>	.form-element:focus-within ~ .tooltip</span> <span data-sanitized-class="token punctuation">{</span><br><span data-sanitized-class="highlight-line">		<span data-sanitized-class="token property">display</span><span data-sanitized-class="token punctuation">:</span> block<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">.tooltip</span> <span data-sanitized-class="token punctuation">{</span></span><br><span data-sanitized-class="highlight-line">		<span data-sanitized-class="token property">margin-right</span><span data-sanitized-class="token punctuation">:</span> 20px<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> white<span data-sanitized-class="token punctuation">;</span></span><br><span data-sanitized-class="highlight-line">		<span data-sanitized-class="token property">background</span><span data-sanitized-class="token punctuation">:</span> #334e58<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 #334e58<span data-sanitized-class="token punctuation">;</span> <span data-sanitized-class="token comment">/* for contrast mode */</span></span><br><span data-sanitized-class="highlight-line">		<span data-sanitized-class="token property">position</span><span data-sanitized-class="token punctuation">:</span> absolute<span data-sanitized-class="token punctuation">;</span></span><br><span data-sanitized-class="highlight-line">		<span data-sanitized-class="token property">min-width</span><span data-sanitized-class="token punctuation">:</span> <span data-sanitized-class="token function">anchor-size</span><span data-sanitized-class="token punctuation">(</span></span><br><span data-sanitized-class="highlight-line">			--anchor-foo width</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 comment">/* Reposition a little bit earlier */</span></span><br><span data-sanitized-class="highlight-line">		<span data-sanitized-class="token property">anchor-default</span><span data-sanitized-class="token punctuation">:</span> --anchor-foo<span data-sanitized-class="token punctuation">;</span></span><br><span data-sanitized-class="highlight-line">		<span data-sanitized-class="token property">position-fallback</span><span data-sanitized-class="token punctuation">:</span> --left-to-bottom<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 atrule"><span data-sanitized-class="token rule">@position-fallback</span> --left-to-bottom</span> <span data-sanitized-class="token punctuation">{</span></span><br><span data-sanitized-class="highlight-line">		<span data-sanitized-class="token atrule"><span data-sanitized-class="token rule">@try</span></span> <span data-sanitized-class="token punctuation">{</span></span><br><span data-sanitized-class="highlight-line">			<span data-sanitized-class="token property">bottom</span><span data-sanitized-class="token punctuation">:</span> <span data-sanitized-class="token function">anchor</span><span data-sanitized-class="token punctuation">(</span>bottom<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 property">left</span><span data-sanitized-class="token punctuation">:</span> <span data-sanitized-class="token function">calc</span><span data-sanitized-class="token punctuation">(</span><span data-sanitized-class="token function">anchor</span><span data-sanitized-class="token punctuation">(</span>right<span data-sanitized-class="token punctuation">)</span> + 0.5rem<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 atrule"><span data-sanitized-class="token rule">@try</span></span> <span data-sanitized-class="token punctuation">{</span></span><br><span data-sanitized-class="highlight-line">			<span data-sanitized-class="token property">top</span><span data-sanitized-class="token punctuation">:</span> <span data-sanitized-class="token function">calc</span><span data-sanitized-class="token punctuation">(</span><span data-sanitized-class="token function">anchor</span><span data-sanitized-class="token punctuation">(</span>bottom<span data-sanitized-class="token punctuation">)</span> + 0.5rem<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 property">left</span><span data-sanitized-class="token punctuation">:</span> <span data-sanitized-class="token function">anchor</span><span data-sanitized-class="token punctuation">(</span>left<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 property">width</span><span data-sanitized-class="token punctuation">:</span> <span data-sanitized-class="token function">anchor-size</span><span data-sanitized-class="token punctuation">(</span>--anchor-foo width<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><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token punctuation">}</span></span><br><span data-sanitized-class="highlight-line"></span></code></pre>
<p><a href="https://codepen.io/matuzo/pen/RwvYZxX">See example 2 on CodePen</a></p>
<p>There are numerous further properties provided in anchor positioning. You can find an introduction by Sebastian Weber on: <a href="https://blog.logrocket.com/use-css-anchor-positioning/">How to use CSS anchor positioning</a>.</p>
 <h3>Step 3: Tooltip dismiss</h3>
<p>Light dismiss is a term used in the HTML Standard. Light dismiss means that clicking outside of a popover of any sort will close the popover. For keyboard users, light dismiss is equivalent to pressing the Escape key.</p> 
<p>Above, we mentioned the second condition in success criterion 1.4.13 in WCAG 2.2. The success criterion has a total of three conditions. When applied to tooltips, the first condition must also be met for the tooltip to be considered accessible:</p>
<figure>
<blockquote><p>A mechanism is available to dismiss the additional content without moving pointer hover or keyboard focus, unless the additional content communicates an input error.</p></blockquote>
</figure>
<p>Keyboard users also using some form of magnification need a way to clear their viewport from unwanted tooltips. Because of the magnification, tooltips and corresponding triggers can fill a major part of the viewport. They must be able to hide the tooltips by keyboard, for example by pressing the Escape key. Simply moving focus forwards and backwards won’t help.</p>
<p>To prevent interference through tooltips, there are two possible techniques:</p>
<ol>
<li>The tooltip is positioned so that it does not cover any other content.</li>
<li>You provide a mechanism to dismiss the tooltip by keyboard.</li> 
</ol>
<p>Even if a tooltip does not obscure any other content, it is desirable for the second technique to be applied. In other words, the tooltip must stay visible as long as hover or focus is on the triggering element and the user has not explicitly dismissed it.  Only error messages may be non-dismissible (e.g., when remedial action is necessary).</p>
<p>For keyboard users, pressing the Escape key while focus is on the triggering element should hide the tooltip again. We can go back to both of the examples and add the following two event handlers to do that:</p>
<pre data-sanitized-class="language-js"><code data-sanitized-class="language-js"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token keyword">let</span> tooltips <span data-sanitized-class="token operator">=</span> document<span data-sanitized-class="token punctuation">.</span><span data-sanitized-class="token function">querySelectorAll</span><span data-sanitized-class="token punctuation">(</span><span data-sanitized-class="token string">"[aria-describedby]"</span><span data-sanitized-class="token punctuation">)</span><span data-sanitized-class="token punctuation">;</span></span><br><span data-sanitized-class="highlight-line">tooltips<span data-sanitized-class="token punctuation">.</span><span data-sanitized-class="token function">forEach</span><span data-sanitized-class="token punctuation">(</span><span data-sanitized-class="token punctuation">(</span><span data-sanitized-class="token parameter">tooltip</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">	tooltip<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">"keydown"</span><span data-sanitized-class="token punctuation">,</span> <span data-sanitized-class="token keyword">function</span> <span data-sanitized-class="token punctuation">(</span><span data-sanitized-class="token parameter">event</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">if</span> <span data-sanitized-class="token punctuation">(</span>event<span data-sanitized-class="token punctuation">.</span>key <span data-sanitized-class="token operator">==</span> <span data-sanitized-class="token string">"Escape"</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 data-sanitized-class="token punctuation">.</span><span data-sanitized-class="token function">getElementById</span><span data-sanitized-class="token punctuation">(</span></span><br><span data-sanitized-class="highlight-line">				tooltip<span data-sanitized-class="token punctuation">.</span><span data-sanitized-class="token function">getAttribute</span><span data-sanitized-class="token punctuation">(</span><span data-sanitized-class="token string">"aria-describedby"</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 punctuation">.</span>style<span data-sanitized-class="token punctuation">.</span>display <span data-sanitized-class="token operator">=</span> <span data-sanitized-class="token string">"none"</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><br><span data-sanitized-class="highlight-line"></span><br><span data-sanitized-class="highlight-line">	tooltip<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">"blur"</span><span data-sanitized-class="token punctuation">,</span> <span data-sanitized-class="token keyword">function</span> <span data-sanitized-class="token punctuation">(</span><span data-sanitized-class="token parameter">event</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">getElementById</span><span data-sanitized-class="token punctuation">(</span>tooltip<span data-sanitized-class="token punctuation">.</span><span data-sanitized-class="token function">getAttribute</span><span data-sanitized-class="token punctuation">(</span><span data-sanitized-class="token string">"aria-describedby"</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 data-sanitized-class="token function">removeAttribute</span><span data-sanitized-class="token punctuation">(</span><span data-sanitized-class="token string">"style"</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 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 data-sanitized-class="token punctuation">)</span><span data-sanitized-class="token punctuation">;</span></span></code></pre>
<div data-sanitized-class="highlight u-mb">
<p><strong>Note:</strong> by hiding the tooltip directly in the DOM, the style property remains persistent, meaning the tooltip will not be displayed a second time. To prevent that from happening, the style property is removed when the triggering element is not focused anymore.</p> 
</div>
<div data-sanitized-class="highlight u-mb">
<p><strong>Best practice</strong>: ensure a custom tooltip can be dismissed by keyboard.</p>
</div>
<h2>Acknowledgements and links</h2>
<p>Thanks to <a href="https://www.textformer.de/">Nicolai Schwarz</a> and <a href="https://word-nerd.eu/">Tessa Hellbusch</a> for their support.</p> 
<p>Links referenced in the article:</p>
<ul>
<li>Using the HTML title attribute – updated March 2020 (Steve Faulkner) <br><a href="https://www.tpgi.com/using-the-html-title-attribute-updated/">https://www.tpgi.com/using-the-html-title-attribute-updated/</a></li>
<li>HTML Standard, 3.2.6.1 The title attribute (WHATWG) <br><a href="https://html.spec.whatwg.org/multipage/dom.html#the-title-attribute">https://html.spec.whatwg.org/multipage/dom.html#the-title-attribute</a></li>
<li>ARIA Authoring Practices Guide (W3C) <br><a href="https://www.w3.org/WAI/ARIA/apg/">https://www.w3.org/WAI/ARIA/apg/</a></li>
<li>Accessible Rich Internet Applications (WAI-ARIA) 1.2 (W3C) <br><a href="https://www.w3.org/TR/wai-aria-1.2/">https://www.w3.org/TR/wai-aria-1.2/</a></li>
<li>Clarify the use of role=tooltip <br><a href="https://github.com/w3c/aria/issues/979">https://github.com/w3c/aria/issues/979</a></li>
<li>Understanding Success Criterion 1.4.13: Content on Hover or Focus (W3C) <br><a href="https://www.w3.org/WAI/WCAG22/Understanding/content-on-hover-or-focus">https://www.w3.org/WAI/WCAG22/Understanding/content-on-hover-or-focus</a></li>
<li>Tether elements to each other with CSS anchor positioning (Jhey Tompkins) <br><a href="https://developer.chrome.com/blog/tether-elements-to-each-other-with-css-anchor-positioning/">https://developer.chrome.com/blog/tether-elements-to-each-other-with-css-anchor-positioning/</a></li>
<li>CSS Anchor Positioning (W3C) <br><a href="https://www.w3.org/TR/css-anchor-position-1/">https://www.w3.org/TR/css-anchor-position-1/</a></li>
<li>How to use CSS anchor positioning (Sebastian Weber) <br><a href="https://blog.logrocket.com/use-css-anchor-positioning/">https://blog.logrocket.com/use-css-anchor-positioning/</a></li>
</ul>


guid: https://htmhell.dev/adventcalendar/2023/21/
title: The Implied Web
author: ;Manuel Matuzovic
link: https://htmhell.dev/adventcalendar/2023/21/
hash: e55eH���}�f&v�K�
attributes: {"enclosures":[]}
content:
by Halvor William Sanden<br><p>People don’t need call-to-action buttons. Interface elements made to get attention and <em>herd</em> people towards clicks increase cognitive effort because they obscure themselves and reduce interfaces to clickable surfaces.</p>
<p>The implied web is based on the idea that people read interfaces through the glasses of their needs combined with previous web platform experiences. Driven by tasks, they are open to clues about solutions and need clear communication to comprehend and actively move through the interface. In short, people must recognise elements so they can act accordingly.</p>
<p>To better understand how to work with the implied web, we will look at <em>signifier mishmash</em>, intent through HTML and the dynamics of roles.</p>
<h2 data-sanitized-id="the-impossible-element">The impossible element</h2>
<p>Interface elements tasked with explicitly communicating clickability make things more complicated because clicking is neither a defining nor a driving factor in the interface; it’s just the mundane way things work.</p>
<p>We make such click-focused elements by taking visual affordance indicators from elements we perceive as communicating clickability, usually the link and the button, and we mash them together. Affordance indicators are aspects of an element that communicate what kind of element they are. They can also indicate state and even hint at actions available to the user in the capacity of what they are. When we make a combined clickable style, maybe as part of a design system, we tend to reapply it to any relevant element. At the same time, we end up removing those elements’ native affordances.</p>
<p>The problem is that there are no affordance indicators or signifiers unique to the click, and HTML has no click element. In other words, it’s impossible to communicate clickability as a standalone concept, and with good reason, telling people to click is a sign of inferior communication.</p>
<h3 data-sanitized-id="action-isnt-functionality">Action isn’t functionality</h3>
<p>What signifies clickability for a link is not the same as for a button or a select. Signifiers belong primarily to elements; they are clues to the functionality of the element, not the action the user can take. The link’s functionality, for instance, is to point to somewhere, not to be clicked. If we apply its underline and pointer cursor to other elements, we communicate that those are also links or share some functionality instead of being the “click here” we wanted to convey.</p>
<p>Elements that don’t share default affordances, conventions and functions end up being too similar. It becomes difficult, if not impossible, to tell them apart.</p>
<h3 data-sanitized-id="countering-attention">Countering attention</h3>
<p>When we approach elements as communicators of action, we also start adding weight to them based on how much attention we think they should get. Elements we want people to click, or think they would like to click, are made to draw attention to themselves. This comes at the cost of the surrounding elements. It can disrupt the order and make it harder to follow the flow of the interface.</p>
<p>As a countermeasure, we attempt to create a scale of clickability and a system of attention instead of an information hierarchy. We invent our own flavour of interface disconnected from HTML, web platform conventions and actual content or data. We end up with elements that don’t come across as anything in particular; we have effectively diverged communication into visuals and code.</p>
<h3 data-sanitized-id="no-click-here">No click here</h3>
<p>We cannot work with the action and attention approaches in code. We must work with the meaning and state of elements and roles.</p>
<p>Even though there are ways to steal focus with code, there isn’t a “click me!” HTML element, and no attribute can create an attention hierarchy. What people can do is cycle through element types in various means of interaction, like keyboard navigation or screen readers. Still, attention can only be in one place at a time.</p>
<p>Also, action isn’t one thing. A click is not a click because an element is not an element; they have different functionality. For instance, a link can be alt-clicked, a label click activates its input, and a text input activates itself and enables the actual input functionality.</p>
<h2 data-sanitized-id="meaning-through-html">Meaning through HTML</h2>
<p>Programming web interfaces is communication work. It’s not the code’s job to give life to a visual; it’s the visual’s job to reflect the meaning already there.</p>
<p>While HTML doesn’t have a visual side, we can safely talk about an element’s base visual properties as defined by conventions that make them reasonably similar across browsers’ default CSS. They may have different styles, but most of the same affordance indicators are present, such as borders, underlines, hover changes and colours. We shouldn’t disregard an element’s conventions or break them without consideration because there is a direct link between the intentional use of the HTML element and its visuals.</p>
<p>Much of HTML’s meaning comes through roles, and disregarding them means working without the meaning that the web platform provides. In other words, we should work from the HTML elements, their conventions and default styles to bring the affordance indicators into the process. Then, we can consciously override them when necessary.</p>
<p>When the reason behind an HTML element lies in the users’ needs, and not a sketch, we go from writing valid code to writing correct code.</p>
<h3 data-sanitized-id="roles">Roles</h3>
<p>Central to picking the correct HTML element is its role; that’s where a lot of meaning comes from.</p>
<p>Many HTML elements have implicit roles, and we don’t have to do anything but use the elements. Some roles can also change depending on non-ARIA attributes and ancestor element types. The mapping is done through <a href="https://www.w3.org/TR/html-aam/">HTML Accessibility API Mappings</a> (HTML-AAM). A role can be relevant for any means of consumption or interaction, even though the wide range of assistive tech perhaps comes to mind first.</p>
<p>Elements that have no implicit role are generic. That doesn’t mean we can use the elements anywhere; all HTML has designated usage areas. But some don’t need a role, and others cannot have one because the usage wouldn’t work well with things like assistive tech. For instance, <code>div</code>, <code>span</code> and <code>i</code> all have the generic role but different use cases and default visual properties. It would also be fairly annoying to have every <code>div</code> and <code>span</code> announced.</p>
<p>We cannot set the generic role, but we can set the role to <em>presentation</em> or <em>none</em>. In contrast to generic, the two are not exposed in accessibility APIs or accessibility trees.</p>
<p>We can also use the role attribute to communicate meaning HTML doesn’t have by default, though the role would no longer be implicit. Reasons to do this can be because the element is versatile, and it would be impractical to have a default role, or because we need to give an element a role different from its default. We should not explicitly set the same role already implied by the element.</p>
<h3 data-sanitized-id="examples-of-implicit-and-indirect-roles">Examples of implicit and indirect roles</h3>
<p>The following examples are a few selected elements that demonstrate roles and how some can be affected by surrounding or related code.</p>
<ol>
<li><code>header</code> has the role of banner, and <code>footer</code> has the role of contentinfo. When we place them inside <code>article</code>, <code>aside</code>, <code>main</code>, <code>nav</code> or <code>section</code>, or elements that have set the role to article, complementary, main, navigation or region, their role becomes generic.</li>
</ol>
<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;!-- header and footer with banner and contentinfo roles --&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>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>header</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>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>main</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>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>footer</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>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>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 comment">&lt;!-- header and footer with the generic role --&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>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>header</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>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>footer</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>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></code></pre>
<ol start="2">
<li><code>section</code> has a generic role. When we give it an accessible name, typically using the aria-label attribute, it gets the role of region. Beware that over-use of named sections can cause clutter, but there can be other reasons to write code with these elements than exposing their roles.</li>
</ol>
<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;!-- section with the generic role --&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>section</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>section</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;!-- section with the region role --&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>section</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>changelog<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>section</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<ol start="3">
<li><code>img</code> with an empty alt attribute has the role of presentation. <code>img</code> with text inside the alt attribute has the role of img. <code>img</code> without the alt attribute should be avoided, it has the role of img but it will not have an accessible name.</li>
</ol>
<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;!-- img with the presentation role --&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">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 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>/<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;!-- img with the img role --&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">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>horse with beard<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>/<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;!-- img with the img role but without an accessible name – avoid! --&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">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>/<span data-sanitized-class="token punctuation">"</span></span> <span data-sanitized-class="token punctuation">/&gt;</span></span></span></code></pre>
<ol start="4">
<li><code>select</code> has the role of combobox, but if we give it the multiple attribute or a size attribute greater than one, the role changes to listbox</li>
</ol>
<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;!-- select with the combobox role --&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>select</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>select</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;!-- select with the listbox role --&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>select</span> <span data-sanitized-class="token attr-name">multiple</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>select</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">size</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>3<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>select</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">multiple</span> <span data-sanitized-class="token attr-name">size</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>2<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>select</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<ol start="5">
<li><code>strong</code> and <code>em</code> have the roles of strong and emphasis. Strong is for important, serious or urgent, while emphasis is for just that. Both are misused to a level where their code semantics are no longer useful to screen readers and they are practically just a way to achieve bold and italic like the <code>i</code> and <code>b</code> elements. There can be other software that differentiates between them, so they are still relevant. Markdown and WYSIWYG editors are commonly not in that group and output only <code>strong</code> and <code>em</code> by default, further contributing to the misuse. And we can’t really blame WYSIWYG editors, seeing as they are more WYSIWYGIYCS – <em>what you see is what you get if you can see</em>. The biggest contributor to misuse is probably the microscopic typographic difference. Leaving bold and strong for another article, we typically set things like titles in italic, while emphasis is used potentially to affect the meaning of an entire sentence.</li>
</ol>
<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;!-- The author implies that something other than the movie is a better Elvis resource. --&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>i</span><span data-sanitized-class="token punctuation">&gt;</span></span>Elvis<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>i</span><span data-sanitized-class="token punctuation">&gt;</span></span> is the best <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>em</span><span data-sanitized-class="token punctuation">&gt;</span></span>movie<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>em</span><span data-sanitized-class="token punctuation">&gt;</span></span> about Elvis.</span><br><span data-sanitized-class="highlight-line"></span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token comment">&lt;!-- The author implies that other Elvis movies have other leading qualities, such as length or truth. --&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>i</span><span data-sanitized-class="token punctuation">&gt;</span></span>Elvis<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>i</span><span data-sanitized-class="token punctuation">&gt;</span></span> is the <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>em</span><span data-sanitized-class="token punctuation">&gt;</span></span>best<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>em</span><span data-sanitized-class="token punctuation">&gt;</span></span> movie about Elvis.</span></code></pre>
<ol start="6">
<li>
<p><code>small</code>, <code>u</code>, <code>i</code>, <code>b</code>, <code>q</code>, <code>pre</code> are some of the elements with generic role, just like <code>span</code>. We should still use them as intended and not interchangeably, as they mostly have different default styling and layout behaviours.</p>
</li>
<li>
<p><code>menu</code> has the role of list. It does not have the role of menu or toolbar. It’s identical to <code>ul</code>; there is no inherent reason to use <code>menu</code> except if we want to separate the two in code. If we want to indicate navigation, chances are we already have a <code>nav</code> element with an aria-label. Additionally, the <code>menu</code> element can only have list items inside while <code>nav</code> element can hold complete lists and other elements like headings. The possible mixup with WAI-ARIA’s menu role is reason enough not to use the <code>menu</code> element. The menu <em>role</em> is less about navigation and more about choices and actions like we find in toolbars.</p>
</li>
<li>
<p>Many specific input types, such as color, date, file and password have no implicit ARIA role. Inputs should have labels and attributes indicating the type and don’t need an additional role to convey meaning.</p>
</li>
<li>
<p><code>label</code> has no role and cannot be given an aria-label attribute since it is already a label for another element and cannot be anything else.</p>
</li>
<li>
<p>Setting aria-label or aria-labelledby is not allowed on several elements such as <code>a</code> without the href attribute, <code>div</code>, <code>p</code>, <code>abbr</code>, <code>address</code>, <code>body</code>, <code>caption</code> and <code>code</code>. Elements that cannot have aria-label or aria-labelledby can be given those if they change role, granted that they can change role. Even though the language might not allow something, it doesn’t mean browsers ignore it. Still, using labels on the mentioned elements could be a sign that another more specific element should be used instead or that something like a heading is missing.</p>
</li>
</ol>
<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;!-- not allowed --&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 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>news<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>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>a</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>crows<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>Crows<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 comment">&lt;!-- allowed --&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 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>article<span data-sanitized-class="token punctuation">"</span></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>news<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>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>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>crows.png<span data-sanitized-class="token punctuation">"</span></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>crows<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>Crow picture<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="implied-platform">Implied platform</h2>
<p>While a button might be the desired destination of a page, clicking it doesn’t complete anyone’s task as long as the rest of the form is blank. People’s tasks lie at the single input asking for an email address, the form with a well of input types or a table heavy with data; that’s what we must communicate, the path and the information enabling people to walk it, not only the destination.</p>
<p>The implied web is not about avoiding being explicit; it’s about leaning on the platform to tell browsers how it should work for people. Conventions and external consistency enable them to move across different services and domains more easily, and how we make our services should regard that.</p>
<p>Knowing about roles means knowing a central communication capability of the web. We can use it to help people read and comprehend the interface. We can use it to avoid rehashed elements, and we can use it to work with code, visuals and function simultaneously. It’s the direction in which the web moves, <em>again</em>.</p>
<h2 data-sanitized-id="sources-and-resources">Sources and resources</h2>
<p><a href="https://html.spec.whatwg.org/multipage/">The HTML spec</a><br>
<a href="https://www.w3.org/TR/html-aria/">ARIA in HTML W3C recommendation</a><br>
<a href="https://www.tpgi.com/screen-readers-support-for-text-level-html-semantics/">Screen Readers support for text level HTML semantics by Steve Faulkner</a></p>


guid: https://htmhell.dev/adventcalendar/2023/22/
title: ARIA Live Regions
author: ;Manuel Matuzovic
link: https://htmhell.dev/adventcalendar/2023/22/
hash: �$ {`���Fe�����=
attributes: {"enclosures":[]}
content:
by Andrea de Souza<br><p><a href="https://www.w3.org/TR/wai-aria/">ARIA</a> stands for Accessible Rich Internet Applications. It is a set of roles and attributes that makes web page elements accessible to users who require assistive technology, like screen readers, when native HTML alone is not enough. One of these sets of roles and attributes is aimed at defining live regions.</p>
<p>Live regions are areas that, when dynamically updated, trigger screen readers to announce their new content. They are commonly used for notifications that do not receive focus when the new content is added to the page. For example: form errors, loading spinners, search results that appear on dynamic search, and toasts.</p>
<p>Here is a practical example. On an e-commerce website, the notification “product added to cart” displays momentarily whenever the “add to cart” button is pressed. The new content is added to the page, but doesn't receive focus. While sighted users would be able to see it, screen-reader users would not know that somewhere on the page an updated happened. Adding a live region to the parent element that displays this type of notification allows it to be announced by screen readers.</p>
<h2 data-sanitized-id="creating-live-regions">Creating Live Regions</h2>
<p>There are two ways widely used to implement a live region in an HTML element: adding the <code>aria-live</code> attribute or adding a role that has an implicit live region.</p>
<p>A third option for specific scenarios is to use the native HTML <code>&lt;output&gt;</code> element, which has the implicit <code>role="status"</code> property. However, there are accessibility issues associated with it, as described in detail by <a href="https://www.scottohara.me/blog/2019/07/10/the-output-element.html">Scott O’Hara</a>.</p>
<h3 data-sanitized-id="aria-live-attribute"><code>aria-live</code> Attribute</h3>
<p>The <code>aria-live</code> attribute on an HTML element creates the behaviour of a live region by defining a "politeness setting", which indicates when dynamic updates should be announced to users of assistive technology. This attribute needs to be declared using one of three possible values:</p>
<ul>
<li><code>off</code>: This is the default value. No changes will be announced, unless if the user is focused on the region where the update happens.</li>
<li><code>polite</code>: The screen reader will announce the changes when it has a chance. For example, when the user is idle or once the task being performed at the moment of the notification ends. This option should be used for low priority updates that don’t require immediate attention from the user.</li>
<li><code>assertive</code>: The screen reader will interrupt whatever it is reading to announce the content update. This option should only be used for time-sensitive, critical information.</li>
</ul>
<p>Going back to the e-commerce website example, the “product added to cart” message may have an <code>aria-live="polite"</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>div</span> <span data-sanitized-class="token attr-name">aria-live</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>polite<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>Product added to cart.<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>
<p>However, if the user is on a news website and there's a weather alert or an emergency broadcast, then this notification has a high degree of priority and should have an <code>aria-live="assertive"</code>.</p>
<p>Please note that those are generic examples. The <code>aria-live</code> attribute value will depend on different factors. A good way to determine the politeness setting required is to ask directly the users that will be the recipients of the message. One important aspect to keep in mind is that the <code>assertive</code> level is disruptive for screen-reader users and should only be used when absolutely required.</p>
<p>There are other ARIA attributes that, in theory, should provide greater control of how ARIA live regions should behave. But, in practice, they have only partial support and/or their behaviour varies between different screen reader/browser combinations.</p>
<ul>
<li><code>aria-busy</code>: When set to <code>true</code>, it indicates that the element is not yet ready to be announced because it’s still being modified. It also means that screen readers <em>MAY</em> want to wait before announcing the changes (<a href="https://www.w3.org/TR/wai-aria-1.2/#aria-busy">W3C</a>). The partial support for this attribute happens when it's set to <code>true</code>, according to <a href="https://a11ysupport.io/tech/aria/aria-busy_attribute">a11ysupport.io</a>. The default value is <code>false</code>. An example that may apply this attribute is to set <code>area-busy="true"</code> while a page is still loading and change it to <code>false</code> once all elements are loaded.</li>
<li><code>aria-relevant</code>: Specifies the updates that are relevant to be announced, which can be either: the addition of new nodes (<code>aria-relevant="additions"</code>); text content, text alternative, or node removal (<code>aria-relevant="removals"</code>); or the addition of text content or text alternative (<code>aria-relevant="text"</code>). The shorthand <code>all</code> includes the three values. Multiple space-separated values can also be used. For example, <code>additions text</code>, which is the default value. Please note that the values <code>removals</code> and <code>all</code> should be used carefully, since only in specific scenarios it's relevant to announce the removal of content. One example would be when a user leaves a chat room. According to <a href="https://www.w3.org/TR/wai-aria-1.2/#aria-relevant">W3C</a>, <code>aria-relevant</code> is an optional attribute and represents a <em>suggestion</em> to assitive technologies. The partial support for this attribute is documented by <a href="https://a11ysupport.io/tech/aria/aria-relevant_attribute">a11ysupport.io</a>.</li>
<li><code>aria-atomic</code>: Specifies if the whole live region should be announced (<code>aria-atomic="true"</code>) or only the content that has changed (<code>aria-atomic="false"</code>) based on the value of <code>aria-relevant</code>. For example, with default value <code>false</code> and the default <code>aria-relevant="additions text"</code>, only the updated nodes and the addition of text content or text alternative will be announced. When set to <code>true</code>, the entire live region will be announced. In this case, screen readers <em>MAY</em> choose to combine multiple changes and present the whole region at once (<a href="https://www.w3.org/TR/wai-aria-1.2/#aria-atomic">WAI ARIA - aria-atomic</a>). Depending on the application, this attribute may be important, but make sure to test the behaviour with different browser/screen reader combinations. Test results for this attribute can be found at <a href="https://a11ysupport.io/tech/aria/aria-atomic_attribute">a11ysupport.io</a> and at <a href="https://pauljadam.com/demos/aria-atomic-relevant.html">Paul J. Adam's website</a>.</li>
</ul>
<h3 data-sanitized-id="live-region-roles">Live Region Roles</h3>
<p><a href="https://www.w3.org/TR/wai-aria-1.2/#live_region_roles">The ARIA specification</a> lists five live region roles, according to the type of notification that they announce:</p>
<ul>
<li><code>alert</code>: Time-sensitive notifications that require immediate attention, like form errors.</li>
<li><code>status</code>: Notifications that are not as important as an <code>alert</code>, nor time-sensitive.</li>
<li><code>log</code>: The order in which the notifications are added have meaning, as in a log, and old information may disappear.</li>
<li><code>marquee</code>: The information is non-essential, changes often, and the order is not meaningful.</li>
<li><code>timer</code>: The notification is the amount of elapsed time from a starting point or the remaining time until an end point of a numerical counter.</li>
</ul>
<p>Each live region role has an implicit <code>aria-live</code> attribute:</p>
<ul>
<li><code>role="alert"</code> has <code>aria-live="assertive"</code></li>
<li><code>role="status"</code> has <code>aria-live="polite"</code></li>
<li><code>role="log"</code> has <code>aria-live="polite"</code></li>
<li><code>role="marquee"</code> has <code>aria-live="off"</code></li>
<li><code>role="timer"</code> has <code>aria-live="off"</code></li>
</ul>
<p><a href="https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Live_Regions#roles_with_implicit_live_region_attributes">MDN</a> recommends adding a redundant <code>aria-live</code> attribute to the alert, status, and log roles to maximize compatibility.</p>
<p data-sanitized-class="highlight">Please keep in mind that <code>role="status"</code> and <code>role="alert"</code> are the only two live region roles that have good browser/screen reader support.</p>
<h3 data-sanitized-id="aria-live-attribute-vs-live-region-role"><code>aria-live</code> Attribute vs Live Region Role</h3>
<p>So, what is the difference between using <code>aria-live</code> and a live region role? <code>aria-live</code> is an attribute that creates the behaviour of a live region by defining the “politeness” level of how the notification should be announced. A live region role not only creates the behaviour of a live region, but also provides semantic meaning to screen readers. It has an implicit <code>aria-live</code> property.</p>
<p>For example, an element with <code>role="alert"</code> has an implicit <code>aria-live="assertive"</code> property and should inform the screen reader that the notification in that area is really an alert. While the <code>aria-live="assertive"</code> attribute by itself will inform the screen reader that it should interrupt whatever it is reading to announce that notification.</p>
<p>Another difference is that live region roles allow to define an accessible name, which may be important when having more than one live region in the same page. 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>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>status<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>[id-of-an-element]<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>div</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<p>While the definition with <code>aria-live</code> wouldn't allow the addition of an accessible name:</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">aria-live</span><span data-sanitized-class="token attr-value"><span data-sanitized-class="token punctuation attr-equals">=</span><span data-sanitized-class="token punctuation">"</span>polite<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>div</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<p>One last difference specific to live regions defined with <code>role="alert"</code> or <code>role="status"</code> is the implicit <code>aria-atomic="true"</code> property.</p>
<h2 data-sanitized-id='"robust"-live-regions'>“Robust” live regions</h2>
<p>Unfortunately, live regions don’t behave consistently in all browser/screen reader combinations, even if all roles and attributes are added according to the specification. However, there are a few recommendations that can be followed to make the implementation as robust as possible:</p>
<h3 data-sanitized-id="first-insert-the-live-region">First: Insert the live region</h3>
<p>The element that contains the aria-live attribute or live region role should be in the DOM, empty, before the update happens. Ideally, on page load or as close as possible to it. This is important because live regions need to be in the <a href="https://developer.mozilla.org/en-US/docs/Glossary/Accessibility_tree">accessibility tree</a> in order to be announced. The accessibility tree is a subset of the DOM tree. It provides information from the DOM in a way that can be understood by screen readers and other assistive technologies.</p>
<p>For example, the <code>div</code> below can be part of the initial HTML markup and, later on, used for a dynamic notification:</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>status<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>div</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<p>Having an element with a live region declared, as the example above, will not trigger any announcement by screen readers. It's only when an update in the content inside the live region happens that the it will trigger screen readers to announce the new content.</p>
<p>If the element with the live region role is dynamically injected in the DOM at the same time as the notification happens, it may not be correctly announced. For example, if an element with a live region is in the HTML, but has the CSS property <code>display: none</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>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>status<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">display</span><span data-sanitized-class="token punctuation">:</span>none<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><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>Using the CSS properties <code>display: none</code> or <code>visibility: hidden</code> hides the content from users, but also removes it from the accessibility tree. And if the live region is not in the accessibility tree, then it cannot be tracked by screen readers. Although these properties can be dynamically changed with JavaScript to <code>display: block</code> or <code>visibility: visible</code>, it should not be done at the same time as the content update.</p>
<h3 data-sanitized-id="second-add-dynamic-content">Second: Add dynamic content</h3>
<p>The dynamic content should be added to descendants of the element that has the <code>aria-live</code> attribute or live role region. Adding to the previous example, the dynamic content can be added as:</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>status<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>Product added to cart.<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>
<h2 data-sanitized-id="when-not-to-use-a-live-region">When not to use a live region</h2>
<p>Although a live region may seem like the ideal solution to announce a dynamic content update, it is not always the best approach. Here are a few examples when not to use it:</p>
<ul>
<li>If there is an option to replace the live region with static instructions, then do it. It will probably be a better experience for screen-reader users to read additional content than to be interrupted with a notification. For example, a <code>&lt;select&gt;</code> element updates another area of the page according to the option value. Instead of using a live region for the area that will be updated, it's possible to have static text saying that the content will be updated according to the option selected.</li>
<li>Focus change and live regions firing at the same time are prone to conflicts. If there is a focus change to the element being updated, then a live region is not needed. Going back to the "add to cart" example, instead of having the "product added to cart" message, we can have a "cart flyout" (modal dialog) opening on the side of the screen. Focus may go the modal close button, an interactive element. In this example, there's no need for a live region, but the user should be informed of the new context.</li>
<li>Don’t use live regions to announce state changes that can be communicated through an ARIA state. For example, if using an accordion, use the attribute <code>aria-expanded</code> to indicate if it’s opened or closed. If using a toggle button, use <code>aria-pressed</code>.</li>
<li>Don’t use live regions for visual UIs that change constantly. <a href="https://www.youtube.com/live/W5YAaLLBKhQ?si=SxKUbgEKmGxItV8D">Sarah Higley</a> suggests to provide a separate interface in some scenarios. This will keep the live region concise by announcing only relevant information. A practical example would be a search box in which the results update every time the user types a character. Wrapping the element in an ARIA live region would be too verbose because every single change would be announced.</li>
</ul>
<h2 data-sanitized-id="tips-to-improve-the-user-experience">Tips to improve the user experience</h2>
<p>There are a few tips that can improve the user experience:</p>
<ul>
<li>
<p>Live region notifications should be concise. Remember that screen-reader users have no control over it. And since the notification is only announced once, there’s no possibility to go back and review it, according to <a href="https://www.youtube.com/live/W5YAaLLBKhQ?si=SxKUbgEKmGxItV8D">Sarah Higley - The Many Lives of a Notification</a>.</p>
</li>
<li>
<p>Notifications should be easy to understand. Screen readers will read everything as plain text. Even if the text has headings, bold content, or any interative content (links or buttons, for example), everything will be read as one block of text. Try reading out loud your notifications and ask yourself if they make sense.</p>
</li>
<li>
<p>Don’t use special characters (anything other than letters and numbers). For example, always use "and" instead of ampersand (&amp;). Use correct grammar. For punctuation, use only commas and periods.</p>
</li>
<li>
<p>If the live region contains a notification specific for screen-reader users that does not appear visually, it is recommended to remove it shortly after it shows up. This is important to avoid screen readers announcing old updates that are not relevant anymore. According to <a href="https://www.youtube.com/live/W5YAaLLBKhQ?si=SxKUbgEKmGxItV8D">Sarah Higley</a>, a notification doesn’t need to stay long in the DOM. Even half a second is enough because the screen reader is watching the live regions for updates, so it will announce any new content, even if it’s removed right after. Please note that this recommendation does not apply to notifications that communicate user-facing state and status that other ARIA cannot. It is only for content that can become obsolete.</p>
</li>
<li>
<p>Don’t add too many live regions to the same page. It may cause conflicts if more than one fires at the same time. For example, a "polite" notification may not be announced if an "assertive" notification also happens around the same time. According to <a href="https://www.w3.org/TR/wai-aria-1.2/#aria-live">W3C</a>, the politeness level is an ordering mechanism and "user agents or assistive technologies <em>MAY</em> choose to clear queued changes when an assertive change occurs".</p>
</li>
</ul>
<p>Keep in mind that if a live region can be avoided, take that route. If possible and if it makes sense for your application, move focus and don’t add a live region. However, focus should only move if it’s because of a user action. Also, depending on the scenario, adding clear instructions may be enough, instead of using a live region.</p>
<h2 data-sanitized-id="taking-control">Taking Control</h2>
<p>Screen readers allow users to control how they navigate a web page. For example, they can go first through all the headings of a page before deciding to read a full section. They can also go back and read a specific content again.</p>
<p>But when an element has a live region, the control is taken away from the screen-reader user. They will be forced to hear the notification, either in a <em>polite</em> or <em>assertive</em> way, and that announcement only happens once.</p>
<p>Therefore, developers should use caution when implementing live regions. They can negatively impact a screen-reader user experience if poorly implemented or if there are too many of them, providing non-stop notifications.</p>
<p>If the element requires a live region, then make sure to test the implementation with screen readers to ensure that it works as intended.</p>
<h2 data-sanitized-id="testing">Testing</h2>
<p>It is crucial to test live regions with different browser/screen reader combinations. And, whenever possible, get your page tested by a real screen-reader user.</p>
<p>If you need help to get started with screen readers, Sara Soueidan has an article with detailed instructions on <a href="https://www.sarasoueidan.com/blog/testing-environment-setup/">setting up a screen reader testing environment on your computer</a>. The article also suggests the following <a href="https://www.sarasoueidan.com/blog/testing-environment-setup/#which-browser-and-screen-reader-pairings-should-you-test-on?">pairings</a> for testing based on usage and compatibility:</p>
<ul>
<li>JAWS on Chrome</li>
<li>NVDA on Firefox</li>
<li>Narrator on Edge</li>
<li>VoiceOver on Safari for macOS,</li>
</ul>
<p>You will probably notice that the same implementation will not behave the same way across the board. This is because support for live regions vary between how browsers and screen readers are paired together. Since this can result in a poor experience for some users, it's essential to test thoroughly to uncover potential issues and fix them.</p>
<h2 data-sanitized-id="wrapping-up">Wrapping up</h2>
<p>Live regions provide a solution for announcing dynamically added content that would otherwise be missed by screen readers, but their behaviour is not consitent across different browser/screen reader combinations. If adding a live region to your page, follow the specification to implement it in the most robust way possible. Don’t add too many live regions to the same page and only make them <code>assertive</code> if it’s absolutely necessary. Remember to test your live regions thoroughly and re-test often to confirm that they still work as intended. Even better, have your page tested by a real screen-reader user.</p>
<h2 data-sanitized-id="useful-links-and-references">Useful links and references</h2>
<ul>
<li><a href="https://developer.mozilla.org/en-US/docs/Glossary/Accessibility_tree">MDN Accessibility tree</a></li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Live_Regions">MDN aria-live regions</a></li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles#4._live_region_roles">MDN Live region roles</a></li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/output">MDN <output>: The Output element</output></a></li>
<li><a href="https://www.youtube.com/live/W5YAaLLBKhQ?si=SxKUbgEKmGxItV8D">Sarah Higley - The Many Lives of a Notification</a></li>
<li><a href="https://www.scottohara.me/blog/2022/02/05/are-we-live.html">Scott O’Hara - Are we live?</a></li>
<li><a href="https://www.scottohara.me/blog/2019/07/10/the-output-element.html">Scott O’Hara - output: HTML's native live region element</a></li>
<li><a href="https://www.sarasoueidan.com/blog/testing-environment-setup/">Sara Soueidan - Setting up a screen reader testing environment on your computer</a></li>
<li><a href="https://adrianroselli.com/2023/04/exposing-field-errors.html">Adrian Roselli - Exposing Field Errors</a></li>
<li><a href="https://www.w3.org/TR/wai-aria/#attrs_liveregions">W3C - Live Region Attributes</a></li>
<li><a href="https://www.w3.org/TR/wai-aria/#live_region_roles">W3C - Live Region Roles</a></li>
<li><a href="https://webaim.org/projects/screenreadersurvey9/">Screen-reader User Survey #9 Results</a></li>
<li><a href="https://assistivlabs.com/articles/screen-reader-browser-pairing-stats">Which Screen Readers and Browsers are best for Accessibility Testing?</a></li>
<li><a href="https://business.scope.org.uk/article/accessibility-screen-readers-special-characters-and-unicode-symbols#:~:text=accessible%20for%20everyone.-,Use%20correct%20grammar%20and%20punctuation,text%20much%20easier%20to%20read.">How special characters and symbols affect screen reader accessibility</a></li>
</ul>


guid: https://htmhell.dev/adventcalendar/2023/23/
title: The devil is in the details: a look into a disclosure widget markup
author: ;Manuel Matuzovic
link: https://htmhell.dev/adventcalendar/2023/23/
hash: XK3��lG�uL�+)�[�
attributes: {"enclosures":[]}
content:
by Cristian Diaz<br><p><a href="https://www.w3.org/WAI/ARIA/apg/patterns/disclosure/">Disclosure widgets</a> are one of the most common component patterns you can find on the web. It consists of a button that can hide or show information when you click it. It's also one of the straightforward components to make from a technical standpoint.</p>
<p>Just a quick note: this article will focus on the most basic form of it to show or hide content. A navigation menu can be considered as a disclosure widget but it has other features that won’t be the main focus of this article.</p>
<p>This component pattern has two approaches: the first one is creating a <code>&lt;button&gt;</code> element with the attribute <a href="https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-expanded">aria-expanded</a> that will toggle between <code>true</code> and <code>false</code> when you want the content to be shown or hidden. Additionally, you want to create a relationship between those two elements with <a href="https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-controls">aria-controls</a> to indicate the button controls the presence of this element, 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 tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>button</span> <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 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>accordion<span data-sanitized-class="token punctuation">"</span></span><span data-sanitized-class="token punctuation">&gt;</span></span>What are cephalopods?<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 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>accordion<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>A cephalopod is any member of the molluscan class <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>i</span><span data-sanitized-class="token punctuation">&gt;</span></span>Cephalopoda<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>i</span><span data-sanitized-class="token punctuation">&gt;</span></span> such as a squid, octopus, cuttlefish, or nautilus.<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>
<p>This approach requires JavaScript to modify the <code>aria-expanded</code> attribute. However, we can pair it with a pure CSS’ <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Next-sibling_combinator">n</a><a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Next-sibling_combinator">ext-sibling combinator</a> to control showing and hiding the disclosure’s content.</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">button[aria-expanded="false"] + div</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> none</span><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token punctuation">}</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">const</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">"button"</span><span data-sanitized-class="token punctuation">)</span></span><br><span data-sanitized-class="highlight-line"></span><br><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 parameter">element</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> isExpanded <span data-sanitized-class="token operator">=</span> element<span data-sanitized-class="token punctuation">.</span>target<span data-sanitized-class="token punctuation">.</span><span data-sanitized-class="token function">getAttribute</span><span data-sanitized-class="token punctuation">(</span><span data-sanitized-class="token string">"aria-expanded"</span><span data-sanitized-class="token punctuation">)</span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token keyword">if</span> <span data-sanitized-class="token punctuation">(</span>isExpanded <span data-sanitized-class="token operator">===</span> <span data-sanitized-class="token string">"true"</span><span data-sanitized-class="token punctuation">)</span> <span data-sanitized-class="token punctuation">{</span></span><br><span data-sanitized-class="highlight-line">    element<span data-sanitized-class="token punctuation">.</span>target<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">"aria-expanded"</span><span data-sanitized-class="token punctuation">,</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 data-sanitized-class="token keyword">else</span> <span data-sanitized-class="token punctuation">{</span></span><br><span data-sanitized-class="highlight-line">    element<span data-sanitized-class="token punctuation">.</span>target<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">"aria-expanded"</span><span data-sanitized-class="token punctuation">,</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><br><span data-sanitized-class="highlight-line"><span data-sanitized-class="token punctuation">}</span><span data-sanitized-class="token punctuation">)</span></span></code></pre>
<p>Creating a disclosure widget that requires JavaScript also means you should work on a progressively enhanced version of it in case JavaScript doesn't load. There are multiple approaches to this, a very common one is using heading instead of buttons, and when JavaScript loads, replacing the header with a button:</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>h3</span><span data-sanitized-class="token punctuation">&gt;</span></span>What are cephalopods<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>h3</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>p</span><span data-sanitized-class="token punctuation">&gt;</span></span>A cephalopod is any member of the molluscan class <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>i</span><span data-sanitized-class="token punctuation">&gt;</span></span>Cephalopoda<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>i</span><span data-sanitized-class="token punctuation">&gt;</span></span> such as a squid, octopus, cuttlefish, or nautilus.<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>
<p>All of this sounds like quite some work for a relatively simple component pattern, it'd be cool if we had a native option to make a disclosure widget... Oh, wait, we have one! This is where our second approach enters, and that's using the <code>&lt;details&gt;</code> and <code>&lt;summary&gt;</code> elements. Let's come back to our initial markup and let's modify it with this approach.</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>details</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>summary</span><span data-sanitized-class="token punctuation">&gt;</span></span>What are cephalopods?<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>summary</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>A cephalopod is any member of the molluscan class <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>i</span><span data-sanitized-class="token punctuation">&gt;</span></span>Cephalopoda<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>i</span><span data-sanitized-class="token punctuation">&gt;</span></span> such as a squid, octopus, cuttlefish, or nautilus.<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>details</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<p>And that's it! This disclosure widget works, and it's accessible, so I guess the answer would be using this one instead of using the first approach, right? Well, as usual, the reality is more nuanced than that. As much as I'd prefer to use native options for component patterns, the answer to that question is a definitive “It depends”.</p>
<p>When picking a disclosure widget markup, the author needs to balance the strengths and limitations of each approach, and consider what content it will contain. This article will talk about those nuances you should keep in mind about choosing one markup approach or another, mostly focusing on screen reader accessibility because both of them meet the requirements of keyboard navigation with no problem at all.</p>
<h2 data-sanitized-id="experience-across-different-browsers">Experience across different browsers</h2>
<p>The first factor to keep in mind is consistency. When you use a progressively enhanced button approach, you know that it'll be the same for screen readers. Both markup approaches will read them as a button and will read the <code>aria-expanded</code> attribute similarly. But with <code>&lt;details&gt;</code> and <code>&lt;summary&gt;</code> things change quite a bit when you start taking into consideration different screen readers and browsers.</p>
<p>When you use <code>&lt;details&gt;</code> and <code>&lt;summary&gt;</code>, NVDA and JAWS both narrate it as a button in Chrome, and they'll mention if the element is collapsed or expanded. But when you use the same markup in Firefox, they narrate the marker (that is, the visual indicator is being used to indicate the element is collapsed or expanded) as well. My previous example will be read as “Filled right pointing small triangle, what are cephalopods, button, collapsed”. And when we start talking about mobile, the experiences vary a lot.</p>
<p>This is not bad per se, but in some browsers, mentioning the marker can feel a bit like noise, but buttons on the other hand offer a cleaner more consistent experience.</p>
<p>The key point in this section is that you should ask yourself this question: am I okay with letting the screen reader experience be different between different screen readers and browsers? If <strong>you're all right with this</strong>, use <code>&lt;details&gt;</code> and <code>&lt;summary&gt;</code>, but if <strong>you'd prefer a more consistent experience all around</strong>, use a progressively enhanced <code>&lt;button&gt;</code>.</p>
<h2 data-sanitized-id="wait-i-can-modify-this-default-marker-right?">Wait, I can modify this default marker, right?</h2>
<p>By default <code>&lt;details&gt;</code> and <code>&lt;summary</code>  have this triangle arrow that will change when it is expanded or collapsed. Maybe you have a design that has a different indicator, can you modify that? The answer is yes, but there is a <em>huge</em> caveat here:</p>
<p>As Manuel mentions in his article <a href="https://www.matuzo.at/blog/2023/details-summary">details/summary inconsistencies</a>, you can modify the default arrow by using those CSS rules:</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">summary</span> <span data-sanitized-class="token punctuation">{</span></span><br><span data-sanitized-class="highlight-line">  <span data-sanitized-class="token property">list-style</span><span data-sanitized-class="token punctuation">:</span> none<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>This will hide the arrow in all browsers except Safari, so you’ll need an additional CSS rule:</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">summary::-webkit-details-marker</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> none<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>This deletes the indicator in all browsers, but this brings a big problem: as Manuel's tests in the same article show, some combination of screen readers and browsers will use the arrow indicator as part of the accessible name, and if you remove them, it'll stop indicating its state once the user press the <code>&lt;summary&gt;</code> element.</p>
<p>This behavior is particularly notorious with VoiceOver and Firefox because when you remove the marker, it'll indicate nothing when the user expands the content.</p>
<p>For this reason, my suggestion here is that if the design <strong>has a different indicator for the expanded/collapsed states than the default option,</strong> you should use a progressively enhanced <code>&lt;button&gt;</code> approach. On the other hand, if <strong>you are ok with the default marker</strong>, you can stick with <code>&lt;details&gt;</code> and <code>&lt;summary&gt;</code>.</p>
<h2 data-sanitized-id="browsers-in-page-search">Browser's in-page search</h2>
<p>Those previous points are making look <code>&lt;details&gt;</code> and <code>&lt;summary&gt;</code> as an unreliable option, but there is something that those elements add to the table that a progressively enhanced button option can't.</p>
<p>As Manuel mentions in his article <a href="https://www.matuzo.at/blog/2023/details-find-in-page">the details element and in-page search</a>, Chromium-based browser in-page search option can look for content even <strong>when the <code>&lt;summary&gt;</code> element is collapsed</strong>. This is an important factor to keep in mind because this improves usability for someone who uses the in-page search.</p>
<p>As a side note, do you remember when I said I would not focus on disclosure widget variants like a navigation menu? Well, between the different ways a screen reader displays this component and now taking into consideration the in-page search option, makes <code>&lt;details&gt;</code> and <code>&lt;summary&gt;</code> <strong>unsuitable for a navigation menu</strong>.</p>
<p>So, the key point of this section: if you think <strong>letting the user find a keyword using the browser in-page search is important</strong>, stick with <code>&lt;details&gt;</code> and <code>&lt;summary&gt;</code>, otherwise, use a progressively enhanced button.</p>
<h2 data-sanitized-id="do-i-need-to-always-hide-the-content?">Do I need to always hide the content?</h2>
<p>The main selling point of <code>&lt;details&gt;</code> and <code>&lt;summary&gt;</code> is that they'll hide the disclosure widget’s content always, even where there is no JavaScript involved. This is something really important in some scenarios.</p>
<p>The first example that comes into my mind is a <a href="https://www.sistersincrime.org/page/contentwarnings">content warning</a> if it's visible, can cause legitimately bad experiences or trigger a PTSD (Post traumatic stress disorder) episode for a person.</p>
<p>You <em>could</em> use a progressively enhanced button, but if JavaScript doesn't load, there is a risk, and depending on the context, it can be <strong>critical</strong> to hide this content even in those scenarios. Kitty Giraudel created a content warning component using only <code>&lt;details&gt;</code> and <code>&lt;summary&gt;</code> in her article, <a href="https://kittygiraudel.com/2022/09/04/a-content-warning-component/">A content warning component</a>.</p>
<p>My key point here is that you need to consider <strong>how critical is to hide the content as an initial state,</strong> no matter what. If it's necessary, consider using <code>&lt;details&gt;</code> and <code>&lt;summary&gt;</code>, otherwise, using a progressive enhanced button is a good option.</p>
<h2 data-sanitized-id="use-of-headings">Use of headings</h2>
<p>There is quite an interesting thing you can do with a disclosure widget made with the progressively enhanced <code>&lt;button&gt;</code>, and that's adding headings on them. This makes it easier for screen reader users to navigate to this part of the content. The process changes a bit depending on what approach you want to use. For this approach, the markup would look 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 tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>h3</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">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 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>accordion<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">    What are cephalopods?</span><br><span data-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 data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>h3</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>accordion<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>A cephalopod is any member of the molluscan class <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>i</span><span data-sanitized-class="token punctuation">&gt;</span></span>Cephalopoda<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>i</span><span data-sanitized-class="token punctuation">&gt;</span></span> such as a squid, octopus, cuttlefish, or nautilus.<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>
<p>There is a catch though: the <code>&lt;button&gt;</code> is now inside the heading, so it’ll be undetected by the next-sibling combinator. There are two options: we can use to solve this issue:</p>
<p><strong>Modifying our script:</strong> We can make a slight modification in our script and making the adjacent container have the <code>hidden</code> attribute .Then, we toggle it when the <code>&lt;button&gt;</code> has the proper <code>aria-expanded</code> value, like this:</p>
<pre data-sanitized-class="language-js"><code data-sanitized-class="language-js"><span data-sanitized-class="highlight-line"><span data-sanitized-class="token keyword">const</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">"button"</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">const</span> accordionElement <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">"[data-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><br><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 parameter">element</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> isExpanded <span data-sanitized-class="token operator">=</span> element<span data-sanitized-class="token punctuation">.</span>target<span data-sanitized-class="token punctuation">.</span><span data-sanitized-class="token function">getAttribute</span><span data-sanitized-class="token punctuation">(</span><span data-sanitized-class="token string">"aria-expanded"</span><span data-sanitized-class="token punctuation">)</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 keyword">if</span> <span data-sanitized-class="token punctuation">(</span>isExpanded <span data-sanitized-class="token operator">===</span> <span data-sanitized-class="token string">"true"</span><span data-sanitized-class="token punctuation">)</span> <span data-sanitized-class="token punctuation">{</span></span><br><span data-sanitized-class="highlight-line">    accordionElement<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">"hidden"</span><span data-sanitized-class="token punctuation">,</span> <span data-sanitized-class="token string">""</span><span data-sanitized-class="token punctuation">)</span><span data-sanitized-class="token punctuation">;</span></span><br><span data-sanitized-class="highlight-line">    element<span data-sanitized-class="token punctuation">.</span>target<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">"aria-expanded"</span><span data-sanitized-class="token punctuation">,</span> <span data-sanitized-class="token string">"false"</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 data-sanitized-class="token keyword">else</span> <span data-sanitized-class="token punctuation">{</span></span><br><span data-sanitized-class="highlight-line">    accordionElement<span data-sanitized-class="token punctuation">.</span><span data-sanitized-class="token function">removeAttribute</span><span data-sanitized-class="token punctuation">(</span><span data-sanitized-class="token string">"hidden"</span><span data-sanitized-class="token punctuation">)</span><span data-sanitized-class="token punctuation">;</span></span><br><span data-sanitized-class="highlight-line">    element<span data-sanitized-class="token punctuation">.</span>target<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">"aria-expanded"</span><span data-sanitized-class="token punctuation">,</span> <span data-sanitized-class="token string">"true"</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 data-sanitized-class="token punctuation">}</span><span data-sanitized-class="token punctuation">)</span><span data-sanitized-class="token punctuation">;</span></span></code></pre>
<p><code>:has()</code>: The other option is using the (relatively) new CSS <code>:has()</code> selector like this:</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">h3:has([aria-expanded="false"]) + div</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> none<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 problem with <code>:has()</code> <a href="https://caniuse.com/css-has">is its browser support</a>. At the moment of writing this article, Firefox just shipped it in the latest version (121), so browser support may make use of this selector not robust enough to be reliable (for now!).</p>
<p>Can you do that with <code>&lt;details&gt;</code> and <code>&lt;summary&gt;</code>? Yes, do I recommend it to do it? No, it has some inconsistent and even buggy behaviors when you use a screen reader to activate them.</p>
<p>Let's start with checking how it is “possible”, first, we add our heading inside <code>&lt;summary&gt;</code> 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 tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>details</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>summary</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>h3</span><span data-sanitized-class="token punctuation">&gt;</span></span>What are cephalopods?<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>h3</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>summary</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>A cephalopod is any member of the molluscan class <span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;</span>i</span><span data-sanitized-class="token punctuation">&gt;</span></span>Cephalopoda<span data-sanitized-class="token tag"><span data-sanitized-class="token tag"><span data-sanitized-class="token punctuation">&lt;/</span>i</span><span data-sanitized-class="token punctuation">&gt;</span></span> such as a squid, octopus, cuttlefish, or nautilus.<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>details</span><span data-sanitized-class="token punctuation">&gt;</span></span></span></code></pre>
<p>Keep in mind you need to add the <code>&lt;summary&gt;</code> element as the direct child of <code>&lt;details&gt;</code>, otherwise, it’ll not be recognized as our disclosure’s trigger. Now, There is one detail, this is how it'd look:</p>
<figure data-sanitized-class="u-mb">
<details>
  <summary><h3>What are cephalopods?</h3></summary>
  <p>A cephalopod is any member of the molluscan class <i>Cephalopoda</i> such as a squid, octopus, cuttlefish, or nautilus.</p>
</details>
<figcaption>The title “What are cephalopods?” is just below the arrow marker when it should be at its side</figcaption>
</figure>
<p>Then, we'd need to use CSS to put the heading at the same level, but if you do it with, for example, <code>display: flex</code>, it'll not show the marker, and as we saw before, this will affect screen reader experience for some combinations of screen reader and browser. My approach here was making the heading inline, and that worked well, like this:</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">summary h3</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> inline<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>Why I don't recommend doing that with <code>&lt;details&gt;</code> and <code>&lt;summary&gt;</code>? With both approaches, you can use screen reader shortcuts to navigate directly to a heading, but there is a caveat here:</p>
<p>With the <code>&lt;button&gt;</code> approach there will be no problem: the button is inside the heading and if the screen reader's <a href="https://support.freedomscientific.com/teachers/lessons/4.2.3_VirtualPCCursor.htm">virtual cursor</a> is over the heading, you can control the button by pressing the <code>Enter</code> or <code>Space</code> keys. This is useful when you use screen reader’s shortcuts to navigate to a heading (like using the H key).</p>
<p>There catch here comes with <code>&lt;details&gt;</code> and <code>&lt;summary&gt;</code> because it has way less consistent results. To prove that, I decided to test each disclosure with heading markup next to each other. You can take a look at the example I used right here:</p>
<p data-height="300" data-default-tab="html,result" data-slug-hash="wvRNJye" data-user="ItsCrisDiaz" data-sanitized-class="codepen">
  <span>See the Pen <a href="https://codepen.io/ItsCrisDiaz/pen/wvRNJye">
  Untitled</a> by Cristian Diaz (<a href="https://codepen.io/ItsCrisDiaz">@ItsCrisDiaz</a>)
  on <a href="https://codepen.io/">CodePen</a>.</span>
</p>

<p><a href="https://codepen.io/ItsCrisDiaz/pen/wvRNJye">CodePen</a></p>
<p>This test used the next combinations of screen readers and browser:</p>
<ul>
<li>NVDA and JAWS with both Chrome and Firefox.</li>
<li>Narrator with Edge</li>
<li>VoiceOver with Safari, Chrome and Firefox</li>
</ul>
<p>And those are the results:</p>
<ul>
<li>NVDA works perfectly with both browsers, you can navigate using the key shortcuts and you can activate them with <code>Enter</code> or <code>Space</code>.</li>
<li>With JAWS you <em>can’t</em> navigate to a heading inside the <code>&lt;summary&gt;</code> element, making this feature not advisable.</li>
<li>Narrator with Edge is surprisingly buggy, it read both headings at the same time as if they were just one, and it didn’t let me to activate any of them. However, once I removed the <code>&lt;details&gt;</code> element it worked normally, so it’s safe to say adding a heading inside <code>&lt;summary&gt;</code> is not advisable.</li>
<li>With VoiceOver, you can navigate to a heading using the key shortcuts, <em>however</em>, you can’t activate the <code>&lt;summary&gt;</code> element that way. You can activate it navigating with the <code>Tab</code> key but for some reason, if VoiceOver visual cursor is on the heading itself, it can’t be activated. This can create confusion for screen reader users because they found a heading, but they will not find extra content below it because it's a disclosure widget.</li>
</ul>
<p>So, key point of this section: if you think <strong>adding heading navigation to your disclosure widget improves the user experience for screen reader users</strong>, you'd be better using a <code>&lt;button&gt;</code> element, otherwise, use <code>&lt;details&gt;</code> and <code>&lt;summary&gt;</code>.</p>
<h2 data-sanitized-id="wrapping-up">Wrapping up</h2>
<p>Having a native way to make a disclosure widget is great! But as usual, things are not that easy because browsers' implementation tend to vary in details that you need to take into consideration. It's not the first HTML element that has inconsistencies among browser (As an example, just look at Manuel's article <a href="https://www.matuzo.at/blog/2023/focus-dialog">O dialog focus, where art thou?</a> to check how browsers implement keyboard focus with the <code>&lt;dialog&gt;</code> element) and it certainly won't be the last.</p>
<p>In my mind, there is no doubt that browser’s implementation of <code>&lt;details&gt;</code>  and <code>&lt;summary&gt;</code>will be more consistent in the future and this article might end up being a thing of the past. But for now, there are important considerations you need to keep in mind before deciding to use one markup approach or another.</p>


guid: https://htmhell.dev/adventcalendar/2023/24/
title: Never underestimate HTML
author: ;Manuel Matuzovic
link: https://htmhell.dev/adventcalendar/2023/24/
hash: ��y���0���#�I
attributes: {"enclosures":[]}
content:
by Lara Aigmüller<br><p>“HTML is easy.”, “Frontend development is easier than backend development.”, “Updating the UI should be a simple task once the backend is ready.”—these and other similar statements reached my ears time and again during my career as a web developer.</p>
<p>Very often, these made me sad. 🥲</p>
<p>The reason is that I spend most of my working hours writing frontend code including HTML, CSS, and JavaScript (JS) (actually, TypeScript most of the time). When somebody tells me, that my job is “easy”, I feel like my skills are nothing special and another developer could replace me anytime…</p>
<p>What follows now is an article about thoughts that came to my mind in the last couple of years when working together with different people from different teams with different backgrounds in HTML and frontend technologies in general. This is an article about the many “whys” in my head and possible answers…</p>
<h2 data-sanitized-id="why-do-people-think-html-is-easy?">Why do people think HTML is easy?</h2>
<p>What is meant by “easy” anyway? Whether something is easy or not is usually in the eye of the beholder. When I know a technology or programming language well, it’s easier for me than somebody new to the field and inexperienced.</p>
<p>Some people tend to make assumptions about the complexity of frontend development and in my experience those people are the ones not working with frontend technologies and especially HTML on a daily basis. Here are a few reasons I can think of why this happens:</p>
<ul>
<li>The HTML syntax is not that hard to learn. Put together some angle brackets, tag names and key-value pairs (a.k.a. attributes) and you’re good to go!</li>
<li>The HTML syntax is machine and <em>human</em> readable, which was one of the ideas behind XML-like languages.</li>
<li>Once you’ve written a couple of lines of code in a <code>.html</code> file, no compilation or build steps are required to see the result of your work immediately when you open the same file in a browser.</li>
<li>HTML has a low barrier of entry. In some WYSIWYG editors there is an option to switch to the “code” view, and you can fiddle around with the HTML version of your text, no matter if you know what you’re doing or not. (You have a preview available, what could possibly go wrong?)</li>
<li>Browsers are great and forgive a <em>lot</em> of mistakes (J. David Eisenberg described this in a pretty old <a href="https://alistapart.com/article/forgiving/">article about “forgiving” browsers</a>, that contains some thoughts that are still valid today.). When you open a syntactically broken HTML page the chances are high that the browser still renders <em>something</em>. You forgot to close a tag? No problem. You added an unknown tag or attribute? The browser just ignores it. Compared to a programming language where the whole app crashes because of a missing semicolon, yes, this feels “easy”.</li>
</ul>
<p>Let’s go one step further and think about why people tend to compare web technologies or contrast frontend with backend development.</p>
<h2 data-sanitized-id="why-do-people-think-frontend-development-is-easy?">Why do people think frontend development is easy?</h2>
<p>Programming the backend of a website or application is the hard part, creating the frontend an easy one. Right? Sometimes, it feels to me that this is the common opinion among many developers.</p>
<p>And again, I’m looking for the answers to the “why” and came up with the following thoughts:</p>
<p>Users and project stakeholders are often not confronted with the business logic and backend code at all, but only with the user interface (UI). Adding thoughts about where to put which button or piece of information and how the UI should work in general is easier because it’s just more tangible than complex database queries or nested for-loops and if-statements. The backend is a black box that does its magic and spits out data for the frontend. The frontend developer “just” needs to display this data, add colors, and build a layout (using CSS) and the work is done.</p>
<p>Luckily, there are many frontend component libraries that can be used. Put together some (predefined) views, fill the data in there, and you don’t even need to think about colors and layouts anymore – isn’t that great? So, with this amount of help, almost anyone can build great frontends without too much HTML/CSS knowledge!</p>
<p><code>&lt;/sarcasm&gt;</code></p>
<h3 data-sanitized-id='frontend-built-by-"non-frontend"-developers'>Frontend built by “non-frontend” developers</h3>
<p>I made the experience that people who thought programming the frontend was the easy part of web development (and would never call themselves “frontend developer” but rather “full-stack developer”) made the biggest mistakes in their frontend code (even with help of frameworks and libraries).</p>
<p>Heydon addressed this topic in <a href="https://medium.com/@Heydon/reluctant-gatekeeping-the-problem-with-full-stack-e9ad836570f6">“Reluctant Gatekeeping: The Problem With Full Stack”</a> where he wrote:</p>
<blockquote>[...] if you put someone in charge of all of these things and more [...] it’s highly likely they are going to be much weaker in some areas than others. [...] In my experience, men especially earn kudos for their knowledge of JavaScript or Python, but little from CSS skills. CSS, which makes things look ‘pretty’, is considered feminine.</blockquote>
<p>Some of the mistakes mentioned above were actual syntax errors, others were problems with semantics, performance, accessibility, etc. In prototype presentations or during testing, often they aren’t noticed because the browser forgives them (see above), performance is usually good on the developer’s machine, no accessibility tests are being made… The result is: it works, the browser displays what’s expected, everything seems to work fine and can be shipped to production.</p>
<h2 data-sanitized-id="why-is-broken-html-code-a-problem?">Why is broken HTML code a problem?</h2>
<p>Once the code is deployed to production, the first problems might come up. Users who were not part of the development process interact with the product for the first time and run into issues, some of which may be caused by broken HTML code, impairing the user experience.</p>
<h3 data-sanitized-id="bad-user-experience">Bad user experience</h3>
<p>Let’s have a look at problems based on bad HTML code the end-user might stumble upon:</p>
<ul>
<li>frustrating forms (here’s an <a href="https://www.scale.at/blog/forms-ux-problems-solutions">article of mine about bad user experience when using forms on the web</a> with some examples)</li>
<li>performance problems (here’s a talk on YouTube by Harry Roberts about what can go wrong in your HTML document’s “head” – <a href="https://www.youtube.com/watch?v=MHyAOZ45vnU">Get your “head” straight</a>)</li>
<li>wrong usage of headlines (<code>h1</code>-<code>h6</code>) or missing text alternatives for non-text content, which is bad for people using a screen reader</li>
<li>wrong/no usage of interactive elements (“A div is not a button!”) or a confusing tab order of elements, which is bad for people using the keyboard for interaction</li>
<li>basically everything you can find on <a href="https://www.htmhell.dev/">htmhell.dev</a></li>
<li>broken HTML code which leads to broken JavaScript and thus broken functionality</li>
</ul>
<h3 data-sanitized-id="bad-developer-experience">Bad developer experience</h3>
<p>Not only the users of your sites and applications might have a hard time using your product when the HTML/frontend code isn’t correct, also your fellow developers could have their “facepalm moments”, because…</p>
<ul>
<li>…when HTML code is badly structured, it’s harder to write good CSS code for it. To put it differently: HTML code often has to be adjusted once CSS comes into play. When you have experience in writing both languages, the chances are high that your HTML <em>and</em> your CSS code turn out great and maintainable.</li>
<li>…when HTML code of your project’s UI components isn’t flexible, you might not be able to reuse them or scale the project at all without required refactoring when a new feature is requested.</li>
<li>…when developers are not working <em>with</em> the platform but try to reinvent the wheel and not taking browsers’ capabilities into account (like using JavaScript to navigate from one page to another instead of just using a link), bugs might be more likely and fixing them without breaking another part of the application gets harder.</li>
</ul>
<h2 data-sanitized-id="why-should-we-care?">Why should we care?</h2>
<p>As mentioned above, browsers are great and forgive a lot of mistakes; websites might work for many people, even if they are not accessible or performant or even if parts of them break. Maintaining these websites might also be done by good-hearted/ill-fated developers who don’t mind working on a smelly codebase.</p>
<p>But I’m sure we can do better. 💪</p>
<p>The goal should be that websites (and web applications) work for most, no, for <em>all</em> people browsing the web and we as developers should build products respecting the needs of all our (potential) users. Writing scalable and maintainable code leads not only to accessible, fast, and usable websites but also to happy developers.</p>
<h2 data-sanitized-id="its-not-only-about-writing-html">It’s not only about writing HTML</h2>
<p>I’ve met people who started learning web development by diving head-first into the newest frameworks and then built a simple website using Angular without learning the basics first. The problem: without basic HTML (or CSS or JS) knowledge, the most popular framework doesn’t help you succeed; on the contrary. You’re using a sledgehammer to crack a nut. No matter which tools you use, the code that gets shipped to the browser is HTML, CSS, and JavaScript and knowing how these languages work is required to build great applications—no matter which newfangled technology you’re throwing at your problems.</p>
<p>Writing HTML in itself isn’t that hard, no.</p>
<p>But: building user interfaces by elegantly composing this language’s features with CSS, creating pleasant designs and user experiences worth remembering requires experience and skills that should not be underestimated. Neither should HTML; it’s one of the languages—if not the most important one of them all—that shape the web.</p>
<p>Related thoughts about the value of (expertise in) web frontend development were shared by</p>
<ul>
<li>Christian Heilmann, who <a href="https://www.linkedin.com/pulse/ongoing-defence-frontend-full-time-job-christian-heilmann-/">defended frontend development as a full-time job</a></li>
<li>Jeremy Keith, who is worried that we might have <a href="https://adactio.com/journal/20442">“reached a state where the more complex over-engineered approach is viewed as the default”</a></li>
<li>Andy Bell, who describes that <a href="https://andy-bell.co.uk/front-end-is-so-much-more-than-building-designs/">front-end is so much more than building designs</a></li>
</ul>
<p>Let’s stop comparing web technologies and their values. Let’s not discuss what’s easier/harder to do or more/less important. Let’s work in teams, listen to and learn from people with expertise, no matter whether they shine in writing HTML, CSS, TypeScript, PHP, Python, {add-your-favorite-language-here}… let’s make the web a great place together and value people who work on the front of the frontend more!</p>
<hr>
<p>P.S.: Thanks to <a href="https://mastodon.social/@felixh10r">Felix</a> for always proofreading my articles and expanding my English vocabulary. Thanks to Manuel for maintaining HTMHell and creating this inspiring advent calendar.</p>


guid: https://odysee.com/episode-2-the-curse-of-game-theory:038c90006fd276cd1af386f546fa3dedfd671a37
title: Episode 2: The Curse of Game Theory (Escaping Calypso's Island Trailer)
author: ;Rising Tide Foundation
link: https://odysee.com/episode-2-the-curse-of-game-theory:038c90006fd276cd1af386f546fa3dedfd671a37
hash: M�.�!u�Q��O ��
content:
<p><img src="https://thumbnails.lbry.com/-WLh7tK9PnU" width="480" alt="thumbnail" title="Episode 2: The Curse of Game Theory (Escaping Calypso's Island Trailer)"></p>Watch the full film here: https://www.youtube.com/watch?v=gv97LL4LUNw<br><br>and watch part one here: https://www.youtube.com/watch?v=eH9qaTawttE<br><br>Support the project by making a donation here<br>https://risingtidefoundation.net/support-the-work/<br>...<br>https://www.youtube.com/watch?v=-WLh7tK9PnU

attributes:
{"enclosures":[{"url":"https://player.odycdn.com/api/v3/streams/free/episode-2-the-curse-of-game-theory/038c90006fd276cd1af386f546fa3dedfd671a37/2ed3c5.mp4","type":"video/mp4","length":43715829}]}


guid: http://isystem-tf.com/?p=3624
title: Middle Eastern tensions: is the oil price about to explode?
author: ;Alex Krainer
link: https://isystem-tf.com/2024/01/15/middle-eastern-tensions-is-the-oil-price-about-to-explode/
hash: *> �>~S��0�ׄv*)
content:
<p>On the morning of 12 January 2024, the <strong>United</strong> <strong>States</strong> and Britain, with support from Australia, Bahrain, Canada, and the Netherlands, launched a series of cruise missile and airstrikes against some 60 Houthi (Ansar Allah) targets across <strong>Yemen</strong> in an attempt to check their attacks on ships in the Red Sea. In spite of claiming self-defence, the “freedom and democracy” enforcement squad conducted the attacks unilaterally, without a UN Security Council resolution. In doing so, they’ve exacerbated the risks of an escalation to a wider regional war with unpredictable consequences. </p>



<p></p>



<figure data-sanitized-class="wp-block-image size-large"><img width="784" height="496" data-attachment-id="3630" data-permalink="https://isystem-tf.com/2024/01/15/middle-eastern-tensions-is-the-oil-price-about-to-explode/image-2-15/" data-orig-file="https://isystem-tf.com/wp-content/uploads/2024/01/image-2.png" data-orig-size="784,496" data-comments-opened="1" data-image-meta='{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"0"}' data-image-title="image-2" data-image-description="" data-image-caption="" data-medium-file="https://isystem-tf.com/wp-content/uploads/2024/01/image-2.png?w=300" data-large-file="https://isystem-tf.com/wp-content/uploads/2024/01/image-2.png?w=784" src="https://isystem-tf.com/wp-content/uploads/2024/01/image-2.png?w=784" alt="" data-sanitized-class="wp-image-3630"></figure>



<p></p>



<p>An escalation could have a severe impact on oil prices, deepening the energy crisis in the West. In fact, this was one of the concerns of many observers and the producer with Sputnik News reached out to me to comment on this. However, <a href="https://sputnikglobe.com/20240112/how-will-yemen-attacks-affect-global-oil-market-1116134665.html" target="_blank" rel="noreferrer noopener">my response</a> wasn’t exactly a standard fare commentary, but it does reflect my nearly 30 years’ experience in commodities markets.</p>



<h2 data-sanitized-class="wp-block-heading">First, ignore the hype</h2>



<p>To be sure, the geopolitical events in West Asia <em>could</em> push oil prices higher, but we should not assume that they necessarily will. There could be a spike upward in the short term, but whether the upward pressure on prices will be sustained is an open question. This will depend on the way the situation evolves. If tensions escalate, we’ll almost certainly see oil prices increase sharply. </p>



<p>In these situations, market analysts and the commentariat tend to generate a blizzard of extraordinary predictions and hype, but we should be cautious with any sensational interpretations of what’s to come.</p>



<p>For example,on Saturday, 14 September 2019 a missile attack on Saudi Arabia caused substantial damage to Aramco’s Abqaiq oil production facilities. The following Monday, Brent crude oil experienced the largest-ever one-day price jump, reaching $70.32 during the day and closing at $67.78 – $8.42/bbl above previous Friday’s closing price ($59.25/bbl). </p>



<p>This event is marked as <strong>(A)</strong> in the chart below. Fearing further escalations, many market participants expected that the price would rapidly move toward $100/bbl but this did not happen. Instead, the price quickly dropped back below $60/bbl and continued to fluctuate between the high $50s and low $60s for the rest of the year:</p>



<p></p>



<figure data-sanitized-class="wp-block-image"><a href="https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd7b83dbc-0035-4f83-95fe-4c91c58cafd1_1640x666.png" target="_blank" rel="noreferrer noopener"><img src="https://substackcdn.com/image/fetch/w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd7b83dbc-0035-4f83-95fe-4c91c58cafd1_1640x666.png" alt=""></a></figure>



<p></p>



<p>In 2020, entirely different circumstances evolved with the pronouncement of the Covid 19 pandemic, which had a different impact on oil prices altogether:</p>



<p></p>



<figure data-sanitized-class="wp-block-image"><a href="https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e5636fa-3e1a-4eba-a172-92399914db3b_1582x488.png" target="_blank" rel="noreferrer noopener"><img src="https://substackcdn.com/image/fetch/w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e5636fa-3e1a-4eba-a172-92399914db3b_1582x488.png" alt=""></a></figure>



<p></p>



<p>Seen in this perspective, the September 2019 attack on Aramco facilities appears only as a blip on the historical price chart. For traders who got taken up by the day’s hype, anticipating a rapid ascent toward $100/bbl probably left them with crippling losses. </p>



<h2 data-sanitized-class="wp-block-heading">Prediction is difficult</h2>



<p>As <strong>Niels Bohr</strong>, the nobel laureate in physics and father of the atomic model said, “Prediction is very difficult, especially if it’s about the future.” Bohr had it exactly correct. In addition to geopolitics and the supply and demand economics, oil prices are determined by a very complex confluence of factors that are almost impossible to account for.</p>



<p>During most of the last 20+ years, the most important single factor influencing oil prices has been the US dollar which has had a very strong inverse correlation to oil prices:</p>



<p></p>



<figure data-sanitized-class="wp-block-image"><a href="https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fade2b847-181d-4e2a-8147-bf9cb701b2e1_833x381.png" target="_blank" rel="noreferrer noopener"><img src="https://substackcdn.com/image/fetch/w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fade2b847-181d-4e2a-8147-bf9cb701b2e1_833x381.png" alt=""></a></figure>



<p></p>



<p>We can see that this correlation has broken down after 2021 (marked “?” in the chart), but it nevertheless tells us an important story: that of all factors impacting oil prices, the US dollar has been by far the most important one. This implies that factors like US economic performance, employment, inflation, Federal Reserve policy, and interest rates play a much greater role in determining the price of oil than do the discernible supply/demand economics and even geopolitics. </p>



<h2 data-sanitized-class="wp-block-heading">How to navigate the roller-coaster?</h2>



<p>The next question is, how should market participants – investors, traders and hedgers – navigate the roller-coaster, since making predictions is out of the question? My own strong conviction is that the only way to navigate through uncertainty is through systematic trend following. The chart below illustrates how a set of I-System Trend Following strategies have performed during the 2019/2020 period:</p>



<figure data-sanitized-class="wp-block-image size-large"><img loading="lazy" width="712" height="397" data-attachment-id="1972" data-permalink="https://isystem-tf.com/image-13/" data-orig-file="https://isystem-tf.com/wp-content/uploads/2022/03/image-13.png" data-orig-size="762,425" data-comments-opened="1" data-image-meta='{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"0"}' data-image-title="image-13" data-image-description="" data-image-caption="" data-medium-file="https://isystem-tf.com/wp-content/uploads/2022/03/image-13.png?w=300" data-large-file="https://isystem-tf.com/wp-content/uploads/2022/03/image-13.png?w=762" src="https://isystem-tf.com/wp-content/uploads/2022/03/image-13.png?w=712" alt="" data-sanitized-class="wp-image-1972"></figure>



<p>I-System strategies are based entirely on the analysis of price fluctuations and are blind to factors like supply/demand fundamentals or geopolitics. As such, they can’t anticipate nor react to unpredictable events like the Abqaiq attack. But what is far more relevant to oil traders are the large-scale price events (LSPEs), which represent by far the greatest risk (and conversely the greatest opportunity) for oil-related businesses. </p>



<p>While we can’t predict the timing or the magnitude of LSPEs, we do know that they invariably unfold as trends, spanning weeks, months and even years. It follows that tracking the markets with a set of high quality trend following strategies will likely prove the most effective and most sustainable way to navigate them profitably, confidently and with peace of mind.</p>

tags:
#Commodity price #Geopolitics #Hedging #Trend following #Energy #Investing #oil #Oil price #oil-prices #price risk #Trading

attributes:
{"thumbnail":{"url":"https://isystem-tf.com/wp-content/uploads/2024/01/babelmandeb.png"},"enclosures":[{"url":"https://isystem-tf.com/wp-content/uploads/2024/01/babelmandeb.png","title":"BabElMandeb","medium":"image"},{"url":"https://0.gravatar.com/avatar/3cf56351ad2361f720df6adf94285322fc831b589472a80e77d0f256d827358f?s=96&amp;d=identicon&amp;r=G","title":"nakedhedgie","medium":"image"},{"url":"https://isystem-tf.com/wp-content/uploads/2024/01/image-2.png?w=784","medium":"image"},{"url":"https://substackcdn.com/image/fetch/w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd7b83dbc-0035-4f83-95fe-4c91c58cafd1_1640x666.png","medium":"image"},{"url":"https://substackcdn.com/image/fetch/w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7e5636fa-3e1a-4eba-a172-92399914db3b_1582x488.png","medium":"image"},{"url":"https://substackcdn.com/image/fetch/w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fade2b847-181d-4e2a-8147-bf9cb701b2e1_833x381.png","medium":"image"},{"url":"https://isystem-tf.com/wp-content/uploads/2022/03/image-13.png?w=712","medium":"image"}]}


title: The Truth About Plato (Reading Session 01)
author: ;Rising Tide Foundation
hash: �v��^V�A�+I.~;1
guid:
https://odysee.com/the-truth-about-plato-%28reading-session:b7fba7f3ed7ee06ab2b21de0ea0ea43b71d54f25

content:
<p><img src="https://thumbnails.lbry.com/ntPOFy2smkc" width="480" alt="thumbnail" title="The Truth About Plato (Reading Session 01)"></p>Since we last worked through a four week reading of How Jesus and his Followers Saved Civilization followed by a 3 week reading of Philo of Alexandria’s On Creation, The Rising Tide Foundation study group now maps out the geopolitical terrain of ancient Athens in the centuries prior to the births of Jesus of Nazareth and his contemporary Philo of Alexandria. What better way to conduct this exercise than to plunge into the two part mega-essay The Truth About Plato written by Charles Tate and published in two editions of the Campaigner Magazine in 1980.<br><br>Click here to download the full PDF of the Truth About Plato by Charles Tate (published in a 1980 edition of the Campaigner) part 1: https://canadianpatriot.org/wp-content/uploads/2024/01/8102-Truth-about-Plato.pdf<br><br> and click here for part 2: https://canadianpatriot.org/wp-content/uploads/2024/01/8104-Socialism-and-fascism.pdf<br><br>Matt and Cynthia's books:<br>https://canadianpatriot.org/untold-history-of-canada-books/<br><br>Support the Rising Tide Foundation in the following ways:<br><br>1) Make a donation <br>https://risingtidefoundation.net/support-the-work/<br>2) Subscribe to Matt and Cynthia's Substack<br>matthewehret.substack.com<br>cynthiachung.substack.com<br>3) Buy some books!<br>https://canadianpatriot.org/untold-history-of-canada-books/<br><br>and follow us on www.risingtidefoundation.net and t.me/risingtidefoundation<br>...<br>https://www.youtube.com/watch?v=ntPOFy2smkc

link:
https://odysee.com/the-truth-about-plato-%28reading-session:b7fba7f3ed7ee06ab2b21de0ea0ea43b71d54f25

attributes:
{"enclosures":[{"url":"https://player.odycdn.com/api/v3/streams/free/the-truth-about-plato-(reading-session/b7fba7f3ed7ee06ab2b21de0ea0ea43b71d54f25/7f8870.mp4","type":"video/mp4","length":529628894}]}


guid: yt:video:olicbQ8-zAw
title: Effortless Text Animation in After Effects with Smart Animator
author: ;ukramedia
link: https://www.youtube.com/watch?v=olicbQ8-zAw
hash: O-�`����]�� �B
attributes:
{"enclosures":[{"url":"https://www.youtube.com/v/olicbQ8-zAw?version=3","title":"Effortless Text Animation in After Effects with Smart Animator","description":"Unleash the potential of text animation effortlessly with Smart Animator in Adobe After Effects! This powerful tool simplifies the animation process, empowering you to create personalized animations with just a few clicks. Manipulate various parameters to breathe life into your text in breathtaking ways. Elevate your animation skills with Smart Animator, making text animation in After Effects smarter and simpler than ever!\n\n🔗 Smart Tools Links\nSmart Tools Bundle (25 Tools for $75): https://ukramedia.com/product/smart-tools-bundle/\nSmart Animator: https://ukramedia.com/product/smart-animator/\n\n🌐 Let's Connect\nFacebook: https://www.facebook.com/ukramedia\nSergei's Facebook Page: https://www.facebook.com/sergeiprokhn...\nTwitter: https://twitter.com/ukramedia\nTikTok: https://www.tiktok.com/@ukramedia\nInstagram: https://www.instagram.com/ukramedia/\nPinterest: https://www.pinterest.com/ukramedia/\nLinkedin: https://www.linkedin.com/company/ukra...\nYouTube: https://www.youtube.com/c/ukramedia\nUkramedia Online Community: https://www.ukramedia.com/community\n\n\n🔖 #AeScripts #AfterEffects #AdobeAfterEffects","type":"application/x-shockwave-flash","height":390,"width":640,"thumbnails":["https://i4.ytimg.com/vi/olicbQ8-zAw/hqdefault.jpg"]}]}


guid: http://isystem-tf.com/?p=3656
title: Markets move in trends: the Cocoa edition
author: ;Alex Krainer
link: https://isystem-tf.com/2024/01/24/markets-move-in-trend-the-cocoa-edition/
hash: �A��M�I7���?*��/
content:
<p>The core twin hypotheses behind I-System Trend Following and this newsletter are that, </p>



<ul data-sanitized-class="wp-block-list">
<li><a href="https://isystem-tf.com/2021/07/11/market-trends-far-and-away-the-most-powerful-drivers-of-investment-performance/" target="_blank" rel="noreferrer noopener">Market trends are far and away the most potent drivers of investment performance</a>, and that </li>



<li><a href="https://isystem-tf.com/2020/05/26/trend-following-is-the-only-valid-answer-to-the-problem-of-uncertainty/" target="_blank" rel="noreferrer noopener">Systematic trend following is the most reliable way to capture value from trends</a>.</li>
</ul>



<p>But as I mentioned before, getting the best long-term results out of systematic trend following also requires iron discipline and a great deal of patience, because while markets do move in trends, we’ve no way to predict when trends might emerge, how long they could last nor how high (or low) they will push the price. The latest example illustrating all this is the Cocoa market, one of the few markets that have trended during the last 12 months. Last Friday, 14 March 2024, they closed at $8,018/MT. The average I-System strategy generated over $3,300/MT ($30,304 per contract). The chart below illustrates the evolution of our gains from this last LSPE. The chart below tells the story:</p>



<p></p>



<figure data-sanitized-class="wp-block-image size-large"><img width="1024" height="883" data-attachment-id="3943" data-permalink="https://isystem-tf.com/2024/01/24/markets-move-in-trend-the-cocoa-edition/image-1-17/" data-orig-file="https://isystem-tf.com/wp-content/uploads/2024/04/image-1.png" data-orig-size="1198,1034" data-comments-opened="1" data-image-meta='{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"0"}' data-image-title="image-1" data-image-description="" data-image-caption="" data-medium-file="https://isystem-tf.com/wp-content/uploads/2024/04/image-1.png?w=300" data-large-file="https://isystem-tf.com/wp-content/uploads/2024/04/image-1.png?w=1024" src="https://isystem-tf.com/wp-content/uploads/2024/04/image-1.png?w=1024" alt="" data-sanitized-class="wp-image-3943"></figure>



<p></p>



<p>Top chart shows the price of CSCE Cocoa (USD/metric ton) overlaid with the I-System <a href="https://isystem-tf.com/wp-content/uploads/2023/03/isystem_descriptionofatypicalstrategy.pdf">trend confidence function</a>, fluctuating between -100 (<em>certainty</em> that we are in a downtrend) and 100 (<em>certainty </em>that we’re in an uptrend). The middle chart shows the total net exposure of the 12 trading strategies we use to track Cocoa futures, fluctuating between <em>fully short</em> (-12) and <em>fully long</em> (+12). Every change in value along that chart is the result of a <em>buy</em> or <em>sell</em> signal generated by the I-System. Bottom chart shows the results in USD per metric ton of Cocoa: the performance of each of the 12 strategies and their average performance.</p>



<p>If we look at the start point and end point, the trading looks like a success: in just over 4 years, the strategies generated a profit of just over $3,300 per metric ton on average, or $30,304 per contract traded. However, this windfall only started to accrue from mid-2022. If there is one thing that the above chart should make clear is that it had a real cost in terms of risk, discipline and patience. Trading Cocoa hasn’t been great fun during the first 2+ years, in the above chart, and at one point we had about $600 loss per metric ton, or $6,000 per contract. That may seem tolerable, but the fact this loss had been accumulating for more than 2 years makes it challenging from the psychological point of view.</p>



<p>The performance progression shown above is by no means universal, but it is typical and illustrates the importance of cultivating patience and adhering to discipline in trading. We can have patience if we believe that markets move in trends and that a trend will ultimately emerge and redeem all the small losses we must incur to catch a LSPE. Discipline obliges us to continue taking risk in spite of the long sequence of unsuccessful trades and the drawdowns they generate. </p>



<p>Discipline also requires that our risk taking remains conservative enough that we can withstand a long period of drawdowns and retain enough “dry powder” to be able to profit from conditions when they turn favorable. Finally, having faith is easier if we can rely on high-conviction trading strategies. This is not an easy feat. As <strong>Baruch Spinoza</strong> pointed out, “all things excellent are as difficult as they are rare.”</p>



<h2 data-sanitized-class="wp-block-heading">The versatility of trend following</h2>



<p>The great advantage of systematic trend following is that once we’ve mastered the art, we can use it in any market, allowing us to take advantage of the only free lunch available in investment speculation: diversification. Trend following is the same game whether we’re trading Gold, Oil, Soybeans, FX pairs, Treasury bonds or Cocoa. I literally don’t know anything at all about the supply and demand fundamentals of the Cocoa market. In spite of that I can trade Cocoa futures with the same confidence as any other market and I have done so for many years. Again, in addition to quality strategies, the key is discipline and perseverance.</p>



<p>Incidentally, the above graph also tells us something important about risk management. For illustration, at the price of $2,500/MT each contract is worth $25,000. However, when trading futures, we don’t need to pay the full price for the contract, but only the maintenance margin which tends to range between 2% and 10% of the value of the underlying contract. This is how some traders get themselves in trouble and it is also the reason why many investors mistakenly believe that trading futures is very risky. It is very risky, but only if you use too much leverage. </p>



<p>Suppose that the maintenance margin for a contract worth $25,000 is ‘only’ $2,500. If you had $10,000 in your risk budget you might be tempted to buy 4 contracts (4 * 2,500). But the historical performance in the above example tells us that, regardless of how much leverage we <em>can</em> have (because the margin requirement is low), we should reserve a $10,000 risk budget for each contract of Cocoa we plan to trade (more if we only trade 1 contract, less if we trade multiple contracts). </p>



<p>This is one of the valid methods of establishing your position limits. The major part of trading discipline is to never exceed your position limits. Instead, you maintain your risk profile and continue to position risk for those windfalls which arrive when they arrive – there’s no predicting them. Until then, the job is to maintain sufficient dry powder to be able to take advantage of them <em>when</em> they happen.</p>



<h2 data-sanitized-class="wp-block-heading">Get the signals with I-System TrendCompass</h2>



<p>In addition to Cocoa, we track more than 200 financial and commodity markets, generating daily trend following signals. To learn more, check out the <a href="https://isystem-tf.com/trendcompass/" target="_blank" rel="noreferrer noopener"><strong>TrendCompass page</strong></a> and if interested, please feel free to request a one months free trial. There’s no strings attached nor hoops to jump through to cancel.</p>

tags:
#Commodity price #CTA #Hedging #I-System TrendCompass #Quantitative strategies #Trend following #TrendCompass #Cocoa #CTAs #I-System

attributes:
{"enclosures":[{"url":"https://0.gravatar.com/avatar/3cf56351ad2361f720df6adf94285322fc831b589472a80e77d0f256d827358f?s=96&amp;d=identicon&amp;r=G","title":"nakedhedgie","medium":"image"},{"url":"https://isystem-tf.com/wp-content/uploads/2024/04/image-1.png?w=1024","medium":"image"}]}


guid: yt:video:vzRmXlp8Jbw
title: Sliding Text Reveal in After Effects with Smart Tools
author: ;ukramedia
link: https://www.youtube.com/watch?v=vzRmXlp8Jbw
hash: iJ��B�íǕl 7�
attributes:
{"enclosures":[{"url":"https://www.youtube.com/v/vzRmXlp8Jbw?version=3","title":"Sliding Text Reveal in After Effects with Smart Tools","description":"Discover how to effortlessly craft a Sliding Text Animation in Adobe After Effects in this tutorial! I'll guide you step-by-step using my tools: Smart Animator and Smart Mask. Perfect for enhancing your text animation skills!\n\n🔗 Smart Tools Links\nSmart Tools Bundle (25 Tools for $75): https://ukramedia.com/product/smart-tools-bundle/\nSmart Animator: https://ukramedia.com/product/smart-animator/\nSmart Mask: https://ukramedia.com/product/smartmask/\n\n🌐 Let's Connect\nFacebook: https://www.facebook.com/ukramedia\nSergei's Facebook Page: https://www.facebook.com/sergeiprokhn...\nTwitter: https://twitter.com/ukramedia\nTikTok: https://www.tiktok.com/@ukramedia\nInstagram: https://www.instagram.com/ukramedia/\nPinterest: https://www.pinterest.com/ukramedia/\nLinkedin: https://www.linkedin.com/company/ukra...\nYouTube: https://www.youtube.com/c/ukramedia\nUkramedia Online Community: https://www.ukramedia.com/community\n\n🔖 #AeScripts #AfterEffects #AdobeAfterEffects","type":"application/x-shockwave-flash","height":390,"width":640,"thumbnails":["https://i3.ytimg.com/vi/vzRmXlp8Jbw/hqdefault.jpg"]}]}


guid: https://scottjehl.com/posts/composition/
title: HTML Web Components on the Server Are Great
author: ;Scott Jehl
link: https://scottjehl.com/posts/composition/
hash: X�_A�>8��� ��1a�
attributes: {"enclosures":[]}
content:
<p>I'll start this post by echoing what many others have been saying: Web Components are having a moment lately! After a decade dominated by fragile, complicated, and slow Single-Page Application delivery patterns, it's refreshing to see folks stepping back to look for simple, resilient, standards-based alternatives... and discovering Web Components. Meanwhile, there's an understandable "what took so long?" sentiment coming from many folks who have been happily using web components for a long time.</p>
<p>That's even more true of "HTML Web Components," a new term describing a judicious use of a subset of Web Components' feature set, since that subset has been supported across browsers for many years. Better late than never though! The increased interest in this pattern is great for all of us.</p>
<p>In this post, I want to talk about some tools that enable HTML Web Component patterns to work on the server-side, making it easier to use them at scale in sites and apps of all kinds.</p>
<h2>First, What's an HTML Web Component?</h2>
<p>Much like the term "Responsive Web Design," "HTML Web Components" refer to a pattern that use several web standards in a certain way to achieve a particular outcome. It's not my term (<a href="https://adactio.com/journal/20618">it's Jeremy's</a>), but here's how I'd attempt to describe them.</p>
<p>They are custom elements that</p>
<ol>
<li>are not empty, and instead contain functional HTML from the start,</li>
<li>receive some amount of progressive enhancement using the Web Components JavaScript lifecycle, and</li>
<li>do not rely on that JavaScript to run for their basic content or functionality.</li>
</ol>
<p>Perhaps a little code might help illustrate.</p>
<p>The following HTML Web Component uses a custom element called <code>my-header</code> to wrap a website's masthead markup, followed by a JavaScript module that enhances that custom element's interactivity:</p>
<pre><code data-sanitized-class="language-html">&lt;my-header&gt;
  &lt;header&gt;
    &lt;img src="logo.svg" alt="ACME Hammers"&gt;
    &lt;nav&gt;
      &lt;a href="/"&gt;Home&lt;/a&gt;
      &lt;a href="/contact"&gt;Contact&lt;/a&gt;
    &lt;/nav&gt;
  &lt;/header&gt;
&lt;/my-header&gt;

&lt;script type="module"&gt;
class MyHeader extends HTMLElement {
  constructor() {
    super();
  }
  connectedCallback() {
    console.log("my-header element added to page. Here we can turn that nav element into a burger menu");
  }
}
customElements.define("my-header", MyHeader);
&lt;/script&gt;
</code></pre>
<p>I've paraphrased the <em>enhancement</em> part in a <code>console.log</code> above to save space, but the HTML content and JS scaffolding's all there. Most importantly, the HTML contains markup that will be usable regardless of whether the script successfully runs or not. If the script does run though, the browser will automatically recognize every <code>my-header</code> it finds as an element with inherent custom behaviors attached, just like the other HTML elements you use. For examples of ready-to-use HTML Web Components, I'd recommend browsing that section of Zach Leatherman's <a href="https://www.zachleat.com/web/a-taxonomy-of-web-component-types/#html-web-components">Taxonomy of Web Components</a> post.</p>
<h2>Composability Assumptions &amp; Hurdles</h2>
<p>Once you have an HTML Web Component like this,  you may want to place it in many pages on a site. Ideally, you might want to do that by putting that HTML into its own file so that you can include that file into pages while maintaining it in one place. Unfortunately, HTML alone doesn't really have an "include" feature like that though, so you might reach for a server-side tool like PHP's <code>&lt;?php include('my-header.php'); ?&gt;</code>, or a static site generator like <a href="https://www.11ty.dev/">Eleventy's</a> <code>{% include "my-header" %}</code> to do the job.</p>
<p>To be sure, those are both fine options!</p>
<p>However, there are now several tools designed to perform tasks like this using ordinary HTML syntax instead. These tools focus heavily on composability, using custom elements as a server-side templating abstraction. And most importantly, they perform "Server Side Rendering" of HTML Web Components, allowing you to compose complex, dynamic pages from components that are delivered to the browser as meaningful, resilient HTML.</p>
<p>For example, using these tools, we could include a <code>my-header</code> element into a page simply by referencing its tag, like this:</p>
<pre><code data-sanitized-class="language-html">&lt;!DOCTYPE html&gt;
&lt;html&gt;
  &lt;head&gt;...&lt;/head&gt;
  &lt;body&gt;
    &lt;my-header&gt;&lt;/my-header&gt;
    ...more page content here
  &lt;/body&gt;
&lt;/html&gt;
</code></pre>
<p>That alone would cause the <code>my-header</code> to expand in place with the full HTML defined in its file, before it is sent to the browser.</p>
<p>This is pretty neat stuff, I think! Let's talk about tools that make this happen and what else they can do.</p>
<h2>Enter Custom Element SSR Tools!</h2>
<p>To my knowledge, the first tool designed for this task was <a href="https://enhance.dev/">Enhance</a>, built by the folks at Begin, and soon after that came Zach Leatherman's <a href="https://github.com/11ty/webc">WebC</a>. Nowdays, several frameworks and libraries make use of this kind of pattern, so there's a lot to choose from depending on your development stack.</p>
<p>As I've written recently, I've been consulting with the Enhance team and I'm most familiar with their framework, so I'll be using Enhance in this post's examples. That said, I'd encourage you to check out all the various flavors of tools that work with HTML Web Components to see which ones suit your needs.</p>
<h2>Custom Element Composability in Enhance</h2>
<p>Custom elements are a great abstraction for server-side templating. Let's look at some examples.</p>
<p>Say you have a page called <code>about.html</code> in the directory where the Enhance web server is running. The body of that file could look something like this:</p>
<pre><code data-sanitized-class="language-html">&lt;my-header&gt;&lt;/my-header&gt;
&lt;my-content&gt;&lt;/my-content&gt;
&lt;my-footer&gt;&lt;/my-footer&gt;
</code></pre>
<p>This example references a few "elements" in Enhance parlance, which are literally files that live in the <code>/elements/</code> directory. First, let's look at what the <code>elements/my-header.mjs</code> file might look like.</p>
<pre><code data-sanitized-class="language-js">export default function MyHeader ({ html }) {
  return html`
    &lt;my-header&gt;
      &lt;header&gt;
        &lt;img src="logo.svg" alt="ACME Hammers"&gt;
        &lt;nav&gt;
          &lt;a href="/"&gt;Home&lt;/a&gt;
          &lt;a href="/contact"&gt;Contact&lt;/a&gt;
        &lt;/nav&gt;
      &lt;/header&gt;
    &lt;/my-header&gt;`
}
</code></pre>
<p>At a high level, <code>my-header.mjs</code> is a JavaScript module file, and what it does is export a function that returns a string of HTML. That string is the HTML for our <code>my-header</code> component, to be specific (note that I've removed the client-side script portion in the first example for brevity). Set up like this, as far as Enhance is concerned, it's a reusable HTML Web Component, and in about.html, that full HTML response above will replace the <code>&lt;my-header&gt;&lt;/my-header&gt;</code> element just like an old server-side include.</p>
<p>So that's a simple include, but it gets better.</p>
<h2>Elements in Elements in Elements</h2>
<p>Enhance doesn't stop at level 1 when it comes to including and expanding HTML elements. From here, you can do a lot more to compose views. For example, you can reference elements <em>inside</em> other elements, and they too will be expanded on the server-side for delivery. In Enhance, there's no limit to this depth of inclusion.</p>
<p>Perhaps you'd want to move the <code>nav</code> element above into its own custom element to include inside <code>my-header</code>. That's as easy as creating a <code>my-nav.mjs</code> element and replacing <code>&lt;nav&gt;</code> with <code>&lt;my-nav&gt;&lt;/my-nav&gt;</code> in the header file. And just so it's clear, just like standard custom elements these element names don't have any rules around the word "my" or anything like that. You might go with <code>global-nav</code> for example, or <code>site-navigation-list</code> and that's just as well.</p>
<h2>Composing with Slots</h2>
<p>Enhance takes custom elements much further than includes, of course. If you're familiar with web components, perhaps you've heard of the <code>slot</code> element. I won't cover it here more than saying that its a way to offer up a space inside a custom element that you can pass variable content into. Enhance supports the slots concept on the server side, enabling powerful nesting and composability.</p>
<p>Let's make use of a slot for the <code>my-content</code> element. Here's our <code>about.html</code> page again:</p>
<pre><code data-sanitized-class="language-html">&lt;my-header&gt;&lt;/my-header&gt;
&lt;my-content&gt;
  &lt;h1&gt;About!&lt;/h1&gt;
&lt;/my-content&gt;
&lt;my-footer&gt;&lt;/my-footer&gt;
</code></pre>
<p>Do you see how we've made <code>my-content</code> into a sort of HTML Web Content of its own here? Now let's set up <code>/elements/my-content.mjs</code> to accept that <code>h1</code> into a slot:</p>
<pre><code data-sanitized-class="language-js">export default function MyContent ({ html }) {
  return html`
    &lt;my-content&gt;
      &lt;main&gt;
        &lt;slot&gt;&lt;/slot&gt;
      &lt;/main&gt;
    &lt;/my-content&gt;`
}
</code></pre>
<p>The HTML output that the browser receives from Enhance will look like this:</p>
<pre><code data-sanitized-class="language-html">&lt;my-content&gt;
  &lt;main&gt;
    &lt;h1&gt;About!&lt;/h1&gt;
  &lt;/main&gt;
&lt;/my-content&gt;
</code></pre>
<p>Ready to go! Of course, instead of just an <code>h1</code> we could alternatively pass <em>custom elements</em> into the slot as well, and it all will be expanded for delivery just the same.</p>
<h2>Taking things Dynamic</h2>
<p>So far, these examples have been moving static HTML around, but given that Enhance elements live in server-side JavaScript modules, they can be as dynamic as you'd like. In Enhance, an element function merely needs to return a string of HTML, but you can compile that string from whatever you'd like.</p>
<p>Maybe the HTML string will incorporate response data from an API, or from the local application or session state. Maybe it needs to listen to attribute values passed into it from the parent tag. And additionally, perhaps you'll want to write some JavaScript logic to massage the output along the way.</p>
<p>All of these things are straight-forward within an enhance element. You can even return the response of a templating language, say, Mustache or something like that, if you happen to prefer its syntax. You just need to return a string of HTML.</p>
<p>As a simple example, let's finish our about page by using one dynamic variable inside the <code>my-footer.mjs</code> element to drive its copyright date:</p>
<pre><code data-sanitized-class="language-js">export default function MyFooter ({ html }) {
  const year = new Date().getFullYear()
  return html`
    &lt;my-footer&gt;
      &lt;footer&gt;
        &lt;p&gt;Copyright ${ year } Scott Jehl&lt;/p&gt;
      &lt;/footer&gt;
    &lt;/my-footer&gt;`
}
</code></pre>
<p>...which would neatly arrive in the browser as:</p>
<pre><code data-sanitized-class="language-html">&lt;my-footer&gt;
  &lt;footer&gt;
    &lt;p&gt;Copyright 2024 Scott Jehl&lt;/p&gt;
  &lt;/footer&gt;
&lt;/my-footer&gt;
</code></pre>
<p>No JavaScript required! (In the browser, that is.)</p>
<h2>Wrapping Up</h2>
<p>In this post, I've scratched the surface of how you can use a tool like Enhance to compose server-side templates using custom elements. To my eye, this represents a super-clean abstraction for constructing sites and applications. Additionally, for any elements that need further enhancement and interactivity on the client-side, the custom element output is a perfect foundation for extension using the client-side web component lifecycle (and Enhance offers helpers for that part too if you want them).</p>
<h2>Thanks!</h2>
<p>Thank you for reading. I hope you appreciate this pattern as much as I do and I'd encourage you to check out the <a href="https://enhance.dev/">Enhance site and docs</a> from here!</p>
<p>Feel free to reach out on <a href="https://mstdn.social/@scottjehl">Mastodon</a> or via the <a href="https://scottjehl.com/#contact">contact form</a> if you have ideas or questions.</p>


guid: https://odysee.com/1979-a-polarized-persia-%28rtf-lecture:141e4ce4977ad5876d8e6e7ce8d57aa6247f1880
title: 1979: A Polarized Persia (RTF lecture with Gordon McCormick)
author: ;Rising Tide Foundation
link: https://odysee.com/1979-a-polarized-persia-%28rtf-lecture:141e4ce4977ad5876d8e6e7ce8d57aa6247f1880
hash: ���% �* ��`�7b
content:
<p><img src="https://thumbnails.lbry.com/SbOTENDrpbs" width="480" alt="thumbnail" title="1979: A Polarized Persia (RTF lecture with Gordon McCormick)"></p>On Sunday (January 28) the Rising Tide Foundation hosted a live lecture with Gordon McCormick (co-host of Breaking History on Badlands and geopolitical analyst extraordinaire) who delivered a historic outline of the hand of Anglo-American intelligence in the Middle East with a focus on Iran and the 1979 revolution.<br><br>Some additional chapters from Guanzi for those interested in reading more:<br>Public Download link to full book:<br>https://ebin.pub/guanzi-political-economic-and-philosophical-essays-from-early-china-volume-two-2-0691048169-9780691048161.html<br><br>On Maintaining Restraint (pg 214)<br><br>Discourse on Economic Matters (pg 368)<br><br> Kingship Based on the Sea (pg 372)<br><br>The State's Store of Grain (pg 376)<br><br>Qing Zhong Economic Policies A - F (pg 446-509)<br><br>Ready to start your journey to learn Mandarin? I highly recommend this book, by far the best introduction to the characters, slow paced with no speaking required, absolutely anyone can complete it:<br><br>https://www.amazon.ca/Fundamentals-Chinese-Characters-John-Jing-hua/dp/0300109458<br><br>Support the Rising Tide Foundation in the following ways:<br><br>1) Make a donation <br>https://risingtidefoundation.net/support-the-work/<br>2) Subscribe to Matt and Cynthia's Substack<br>matthewehret.substack.com<br>cynthiachung.substack.com<br>3) Buy some books!<br>https://canadianpatriot.org/untold-history-of-canada-books/<br><br>and follow us on www.risingtidefoundation.net and t.me/risingtidefoundation<br>...<br>https://www.youtube.com/watch?v=SbOTENDrpbs

attributes:
{"enclosures":[{"url":"https://player.odycdn.com/api/v3/streams/free/1979-a-polarized-persia-(rtf-lecture/141e4ce4977ad5876d8e6e7ce8d57aa6247f1880/83830b.mp4","type":"video/mp4","length":422587125}]}


guid: https://scottjehl.com/posts/begin-design/
title: New Work: Begin.com's New Site &amp; Brand Extensions
author: ;Scott Jehl
link: https://scottjehl.com/posts/begin-design/
hash: i��x�ЫN�4��z�
attributes: {"enclosures":[]}
content:
<div><img alt="an array of devices displaying the Begin website" src="https://scottjehl.com/assets/work/begin.com_all.jpg"></div>
<p>When I began consulting with the <a href="https://begin.com/">Begin</a> team in late 2023, they had a "good problem" on their hands. Several years prior, the team took a calculated risk, anticipating that our industry would soon grow weary–and wary–of the fragile, complicated, and slow web delivery methods they'd been using for so long. They foresaw a shift towards resilient, simpler, and performant standards-driven patterns and developed a suite of top-notch full-stack developer tools centered around concepts such as <a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_components">Web Components</a> (a W3C web standard) and <a href="https://fwa.dev/">Functional Web Apps</a> (a serverless architecture geared towards deterministic, scalable deployment). As 2024 approached, the web industry had awakened to the advantages of these patterns. Now, the Begin team merely needed to broaden awareness of their tools and communicate just how well they meet the moment we're in.</p>
<p>I worked with the Begin team to create a new website and design language that would showcase their premium <a href="https://begin.com/deploy">Begin Deploy</a> product alongside their open source products like <a href="https://enhance.dev/">Enhance</a>, <a href="https://arc.codes/docs/en/get-started/quickstart">Architect</a>, and <a href="https://aws-lite.org/">aws-lite</a>. The site needed to explain how the tools relate to one another, how powerful they are on their own, and of course how to use them. The team aimed to strike a balance of retaining the charm and familiarity of existing brands–particularly their playful, developer-focused <a href="https://enhance.dev/">Enhance framework</a> and its adorable mascot, <em>Axol</em>–while presenting their overall suite in a visual language that matched the professional grade of the tools.</p>
<p><video loop="" muted="" playsinline="" width="921" height="333" controls="controls" preload="none">
<source src="https://scottjehl.com/assets/work/begin_buildwebapps.mp4" type="video/mp4">
</video></p>
<p>Begin's tools are carefully built to enable fast and resilient sites, which is something I care a great deal about, so it was great fun to lead with a big, bold, and animated headline on the homepage emphasizing those aims: <strong>"Build Resilient, Fast, Radically Simple, Light, Maintainable, Accessible Web Apps."</strong></p>
<p><img src="https://scottjehl.com/assets/work/begin.com_branding.png" alt="&quot;a series of logos displaying Begin's brand logo extension&quot;"></p>
<p>The full scope of the work, <strong>which you can <a href="https://scottjehl.com/work/">browse in my work section</a></strong> involved extending their existing brand with new product logos, helping plan a hierarchy for their site, designing global user interfaces and landing pages, tweaking CSS animation keyframes, and front-end HTML and CSS development. A special shoutout goes to Cole Peters and Kristofer Joseph at Begin for all of the tight collaboration and work that brought this new design to life.</p>
<h2>Check it out!</h2>
<p>The new Begin site launched this week and I want to congratulate <a href="https://begin.com/about">the team</a> on their new online home!</p>
<ul>
<li>See their new site at <a href="https://begin.com/">Begin</a></li>
<li>Browse the work <a href="https://scottjehl.com/work/">in my portfolio</a></li>
</ul>
<p><strong>Oh! And lastly, but not least..ly, do not sleep on <a href="https://begin.com/wat">their 404 page</a>!</strong></p>


guid: https://odysee.com/guanzi-introduction-to-3000-years-of:0eafb90e8bbb28a308d8b8d77b0856597d731e27
title: Guanzi- Introduction to 3000 Years of Chinese Economic Thought
author: ;Rising Tide Foundation
link: https://odysee.com/guanzi-introduction-to-3000-years-of:0eafb90e8bbb28a308d8b8d77b0856597d731e27
hash: �/r.�lnK�]��I
content:
<p><img src="https://thumbnails.lbry.com/6AAESZHz6Ic" width="480" alt="thumbnail" title="Guanzi- Introduction to 3000 Years of Chinese Economic Thought"></p>Guanzi is a nearly 3000 year old Chinese treatise that defines economics as “the study of making the country rich” which is still quoted by China’s leaders to this day. Join us for an afternoon we we transcend the lens of western-only understanding, read from original texts, and see what economics has always meant from a traditionally Chinese point of view”<br><br>Support the Rising Tide Foundation in the following ways:<br><br>1) Make a donation <br>https://risingtidefoundation.net/support-the-work/<br>2) Subscribe to Matt and Cynthia's Substack<br>matthewehret.substack.com<br>cynthiachung.substack.com<br>3) Buy some books!<br>https://canadianpatriot.org/untold-history-of-canada-books/<br><br>and follow us on www.risingtidefoundation.net and t.me/risingtidefoundation<br>...<br>https://www.youtube.com/watch?v=6AAESZHz6Ic

attributes:
{"enclosures":[{"url":"https://player.odycdn.com/api/v3/streams/free/guanzi-introduction-to-3000-years-of/0eafb90e8bbb28a308d8b8d77b0856597d731e27/e3486c.mp4","type":"video/mp4","length":288844658}]}


hash: ~�����:���q>�E6
attributes: {"enclosures":[]}
guid:
/fr/sencaplus/opinion/resoudre-la-crise-du-logement-la-collaboration-des-gouvernements-et-des-parties-prenantes-est-essentielle-senatrice-bellemare/

title:
Résoudre la crise du logement – la collaboration des gouvernements et des parties prenantes est essentielle : sénatrice Bellemare

link:
https://sencanada.ca//fr/sencaplus/opinion/resoudre-la-crise-du-logement-la-collaboration-des-gouvernements-et-des-parties-prenantes-est-essentielle-senatrice-bellemare/


title: Connu comme « la voix des victimes d’actes criminels », le sénateur Boisvenu prend sa retraite
hash: �\"#=E���iHޣ9
attributes: {"enclosures":[]}
guid:
/fr/sencaplus/personnalites/connu-comme-la-voix-des-victimes-dactes-criminels-le-senateur-boisvenu-prend-sa-retraite/

link:
https://sencanada.ca//fr/sencaplus/personnalites/connu-comme-la-voix-des-victimes-dactes-criminels-le-senateur-boisvenu-prend-sa-retraite/


hash: T��{B�0��̔α<�
attributes: {"enclosures":[]}
guid:
/fr/sencaplus/opinion/le-canada-sattaque-au-probleme-des-etudiants-etrangers-avec-des-solutions-simplistes-qui-ne-marcheront-pas-senatrice-omidvar/

title:
Le Canada s’attaque au problème des étudiants étrangers avec des solutions simplistes qui ne marcheront pas : sénatrice Omidvar

link:
https://sencanada.ca//fr/sencaplus/opinion/le-canada-sattaque-au-probleme-des-etudiants-etrangers-avec-des-solutions-simplistes-qui-ne-marcheront-pas-senatrice-omidvar/


guid: yt:video:52nezFXv2AQ
title: How To Create &amp; Automate a Gauge Graphic &amp; Giveaway Announcement
author: ;ukramedia
link: https://www.youtube.com/watch?v=52nezFXv2AQ
hash: � (ٱ��]�@K����
attributes:
{"enclosures":[{"url":"https://www.youtube.com/v/52nezFXv2AQ?version=3","title":"How To Create &amp; Automate a Gauge Graphic &amp; Giveaway Announcement","description":"In this tutorial, Brandon shows you how to create an automated gauge meter with expressions. This graphic is perfect for any sort of indicator meter for risk, difficulty, progress, value, or for a speedometer. We’ll cover the split expression, linear function, if/then statement, hexToRgb &amp; more.\n\nWin free Ukramedia tools &amp; learn more from Brandon: https://youtu.be/K48XJiMjZho?si=PEmQSPwVNPkUvuzh\n\nProject Files:\n► https://www.pixel-planet-studios.com/downloads\n\n00:00 Introduction\n00:34 Set Up First Segment\n04:39 Offset Segments with Split Expression\n08:03 Arrow Rotates with Linear Function\n09:57 Arrow Picks Up Color (If/Then Statement)\n14:36 Use Color Picker With Expressions (hexToRgb)\n15:49 Increase Activated Segment’s Stroke Width\n19:11 Use Essential Graphics in After Effects\n22:17 Win Free Ukramedia Tools\n\n#adobeaftereffects #motiongraphics #aftereffects","type":"application/x-shockwave-flash","height":390,"width":640,"thumbnails":["https://i2.ytimg.com/vi/52nezFXv2AQ/hqdefault.jpg"]}]}


guid: /fr/sencaplus/opinion/remedier-a-la-crise-du-logement-au-canada-senatrice-wallin/
title: Remédier à la crise du logement au Canada : sénatrice Wallin
hash: [%IK��n��:�hN�t
attributes: {"enclosures":[]}
link:
https://sencanada.ca//fr/sencaplus/opinion/remedier-a-la-crise-du-logement-au-canada-senatrice-wallin/


hash: ���h�aٿC��ɜ�
attributes: {"enclosures":[]}
guid:
/fr/sencaplus/opinion/les-retards-dans-loctroi-de-permis-nuisent-a-la-construction-de-nouveaux-logements-au-canada-senateur-loffreda/

title:
Les retards dans l’octroi de permis nuisent à la construction de nouveaux logements au Canada : sénateur Loffreda

link:
https://sencanada.ca//fr/sencaplus/opinion/les-retards-dans-loctroi-de-permis-nuisent-a-la-construction-de-nouveaux-logements-au-canada-senateur-loffreda/


guid: http://isystem-tf.com/?p=3543
title: Investing: how not to lose
author: ;Alex Krainer
link: https://isystem-tf.com/2024/02/24/investing-how-not-to-lose/
hash: mJ��e�K�Lj�#
tags: #Uncategorized
content:
<h3 data-sanitized-class="wp-block-heading">We’re in a new game, requiring new thinking, versatility and resilience.</h3>



<p><a href="https://substack.com/profile/21365744-alex-krainer" target="_blank" rel="noreferrer noopener"></a></p>



<p>Navigating the markets has become increasingly difficult and rife with risk. We should recognize however, that even in the best of times, investors have a strong tendency to underperform market benchmarks. Over a 20-year period from 1988 through 2007, the S&amp;P 500 returned 11.81% annually. During the same interval, the average investor lagged far behind with only 4.48% (<strong>N. Scott Pritchard,</strong> <a href="https://capdir.com/wp-content/uploads/2018/09/The_Tyranny_of_Choice_in_JPBAutumn2008.pdf">Journal of Pension Benefits, 2008)</a>.</p>



<p>That’s a staggering underperformance. In his commentary to <strong>Benjamin Graham</strong>’s “Intelligent Investor,” <strong>Jason Zweig</strong> suggested that investors achieve such poor results “<em>simply by buying high and selling low</em>.” One blogger illustrated it succinctly enough:</p>



<figure data-sanitized-class="wp-block-image"><a href="https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fafe309b3-fc6c-4e26-ab17-55580e6f1195_687x309.png" target="_blank" rel="noreferrer noopener"><img src="https://substackcdn.com/image/fetch/w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fafe309b3-fc6c-4e26-ab17-55580e6f1195_687x309.png" alt=""></a></figure>



<h2 data-sanitized-class="wp-block-heading">Pros do the same</h2>



<p>Professional investors – the types that probably manage your pension plans – are equally susceptible to this pitfall. In his 2010 report “<a href="https://hbr.org/2011/02/untangling-skill-and-luck">Untangling Skill and Luck</a>,” Legg Mason’s <strong>Michael Mauboussin</strong> cited a study by finance professors <strong>Amit Goyal</strong> and <strong>Simil Wahal</strong>, who studied how well 3,400 plan sponsors (retirement plans, endowments, foundations) performed at hiring and firing investment managers over a 10-year period.</p>



<p>They found that pension plan sponsors hired investment managers <em>after </em>they had generated superior returns, only to see post-hiring returns revert to zero. They fired the managers for a variety of reasons (poor performance topped the list), only to see the managers they fired deliver statistically significant excess returns. That’s exactly the same error that the above image illustrates. The key reason for this is that they tend to make their investment decisions when the assets/funds do well and pull the money out when they fall behind.</p>



<h2 data-sanitized-class="wp-block-heading">It’s about the strategy, not the stats</h2>



<p>At peak performance, an asset will looks attractive and its performance statistics may appear stellar. But even a temporary decline in performance will make those statistics look much less attractive. When we consider investment funds or pension plans, statistics can’t convey the most relevant attributes of an investment: its quality. Is it based on a valid strategy? Is the investment process credible, well thought-out, and robust? Is the risk management properly calibrated? As Mauboussin concluded:</p>



<p>“<em>in evaluating an analyst or portfolio manager, it is much less important to see how she has done recently than it is to assess the process by which she did her job… And make no mistake about it: the reason to emphasize process is that a good process provides the best chance for agreeable long-term outcomes</em>.”</p>



<p>Inevitably, investing comes with periodic rough patches. In such conditions, the “keep calm and carry on,” could be the best approach, so long as the strategy remains valid. But what strategies make sense for the uncertain times that lie ahead?</p>



<h2 data-sanitized-class="wp-block-heading">Which strategies for the future?</h2>



<p>The last 30+ years were defined by globalization, monetary inflation (credit expansion), commodity price suppression and a continued decline in interest rates, as the following chart illustrates:</p>



<figure data-sanitized-class="wp-block-image"><a href="https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F845657c8-9447-4368-a3ac-97c366c47d74_745x275.png" target="_blank" rel="noreferrer noopener"><img src="https://substackcdn.com/image/fetch/w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F845657c8-9447-4368-a3ac-97c366c47d74_745x275.png" alt=""></a></figure>



<p>This trend shaped the conditions that constituted our <em>normal. </em>Most of what we think we know about the economy, capital markets, valuation metrics and risk, we learned in that normal. But those conditions are now gradually dissipating and different trends will shape the next normal. The three key trends we should prepare for include:</p>



<ol data-sanitized-class="wp-block-list">
<li>A continued rise in interest rates</li>



<li>Stagflation</li>



<li>A commodity super-cycle that could span the coming two decades or so.</li>
</ol>



<figure data-sanitized-class="wp-block-image size-large"><img width="1024" height="1020" data-attachment-id="3545" data-permalink="https://isystem-tf.com/2024/02/24/investing-how-not-to-lose/commoditysupercycle/" data-orig-file="https://isystem-tf.com/wp-content/uploads/2023/12/commoditysupercycle.png" data-orig-size="1200,1196" data-comments-opened="1" data-image-meta='{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"0"}' data-image-title="CommoditySupercycle" data-image-description="" data-image-caption="" data-medium-file="https://isystem-tf.com/wp-content/uploads/2023/12/commoditysupercycle.png?w=300" data-large-file="https://isystem-tf.com/wp-content/uploads/2023/12/commoditysupercycle.png?w=1024" src="https://isystem-tf.com/wp-content/uploads/2023/12/commoditysupercycle.png?w=1024" alt="" data-sanitized-class="wp-image-3545"></figure>



<p>Furthermore, the unfolding geopolitical changes could overturn the the centuries-old primacy of the West in global trade, which will drive economic changes in ways that would be impossible to predict. The future is indeed shrouded in uncertainty, so how should investors prepare to navigate the coming changes?</p>



<h2 data-sanitized-class="wp-block-heading">The good news: markets move in trends</h2>



<p>Some 2,500 years ago <strong>Sun Tzu</strong> wrote in “The Art of War,” that there are three avenues of opportunity: events, <strong>trends</strong> and conditions. As we saw in the above chart, the 30-year decline in interest rates did in fact unfold as a trend. Future changes will almost certainly unfold in trends, and therein lie the good news.</p>



<figure data-sanitized-class="wp-block-image"><a href="https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb85c58ba-0701-4101-ab59-a202bd92fc22_1990x840.png" target="_blank" rel="noreferrer noopener"><img src="https://substackcdn.com/image/fetch/w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb85c58ba-0701-4101-ab59-a202bd92fc22_1990x840.png" alt=""></a></figure>



<p>With more than a century’s worth of empirical evidence, trends have proven to be far and away <strong>the most powerful drivers of investment performance, </strong>and trend following strategies have proven effective in capturing investment profits from trends. I have summarized these twin hypotheses in two earlier articles you can find at the following links:</p>



<ul data-sanitized-class="wp-block-list">
<li><strong>Why <a href="https://isystem-tf.com/2021/07/11/market-trends-far-and-away-the-most-powerful-drivers-of-investment-performance/">trends are the most powerful drivers of investment performance</a></strong></li>



<li>Why <strong><a href="https://isystem-tf.com/2020/05/26/trend-following-is-the-only-valid-answer-to-the-problem-of-uncertainty/">trend following is the only valid answer to the problem of uncertainty</a></strong></li>
</ul>



<h2 data-sanitized-class="wp-block-heading">Crossing the mindset barrier</h2>



<p>Trend following has enabled many investors to outperform market benchmarks for more than 50 years. Yet, in spite of its undeniable success, most investors either don’t know enough about it, or continue to regard the strategy as an oddity, not entirely fit for the ranks of serious market professionals – you know, the same folks that habitually underperform. But the reason for this rejection of trend following has nothing to do with performance. It is largely cultural.</p>



<p>Namely, most of today’s market experts were educated in the Cartesian tradition which validates rigorous scientific method as a way to acquire knowledge. Value is placed on understanding linear cause-and-effect relationships that allow us to make predictions about stuff. This mindset has an obvious appeal in investment speculation: we expect to profit from market events by understanding and predicting how the conditions we can observe would cause those events. That same mindset also gives us the comforting sense of competence and control.</p>



<p>Trend following is a cultural misfit in this intellectual tradition. To begin with, it is based on a field of study called <em>technical analysis</em> where knowledge accrues through judgment heuristics and experience rather than empirical science. Trend following also blurs the relationship between intellectual work and its expected results. The linear thinking investor judges a transaction according to an explicit understanding of how and why that transaction should generate a profit.</p>



<p>By contrast, a trend follower simply implements a strategy, a set of predefined rules, accepting that any given transaction may produce a loss. He expects profits, not from any particular transaction, but from the process that spans long sequence of trades extending indefinitely into the future.</p>



<p>Thus, while the conventional approaches to investing stem from an understanding of a particular situation, trend following is based on the <em>belief</em> that a certain strategy will deliver positive results over time, regardless of the economic situation, industry, market, or geography. Incidentally, this is another great advantage of trend following: its versatility.</p>



<h2 data-sanitized-class="wp-block-heading">Versatility and resilience</h2>



<p>Namely, if you learn how to read price charts and formulate effective trend following strategies, you’ll be able to greatly enhance your universe of opportunities and participate profitably in many markets you might not know much about, like metals, energy, agricultural commodities or foreign currencies.</p>



<p>In the evolving new normal, a rigid adherence to the old thinking and <em>business as usual</em> approach to investing could prove dangerous. Adopting new approaches, including trend following, will provide investors with a degree of resilience that could make the difference between success and failure.</p>



<h2 data-sanitized-class="wp-block-heading">Trend following “bible” is free</h2>



<p>For those who are inclined to expand their horizons, in 2021 I published a book titled “<strong><a href="https://isystem-tf.com/wp-content/uploads/2021/11/alexkrainerstrendfollowingbible_pdf.pdf">Alex Krainer’s Trend Following Bible</a></strong>,” which one reader described as, “no doubt one of the best books on financial markets and trading I have ever read!” The book is available as a free download at the link above. It is not free because it’s rubbish, but because Amazon cancelled me entirely (and appropriated more than 3 years’ worth of earned royalties).</p>



<figure data-sanitized-class="wp-block-image"><a href="https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F443b7ba7-d5ad-4a12-92a8-a7f2625b5d12_1528x1113.png" target="_blank" rel="noreferrer noopener"><img src="https://substackcdn.com/image/fetch/w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F443b7ba7-d5ad-4a12-92a8-a7f2625b5d12_1528x1113.png" alt=""></a></figure>



<p>Further resources are available on my website, <a href="https://isystem-tf.com/">I-System Trend Following</a>. Active traders can subscribe to our daily <a href="https://isystem-tf.com/trendcompass/">TrendCompass reports</a> which provide daily trend following signals on more than 200 global financial and commodities markets including all major equity indices, treasury bonds futures, commodities and some 100 FX pairs.</p>



<p></p>



<p><strong><a href="http://linkedin.com/in/alex-sasha-krainer-0b74ab1a">Alex Krainer</a> – <a href="https://twitter.com/NakedHedgie">@NakedHedgie</a></strong> is the creator of <strong><a href="https://isystem-tf.com/">I-System Trend Following</a></strong> and publisher of daily <strong><a href="https://isystem-tf.com/trendcompass/">TrendCompass</a></strong> investor reports which cover over 200 financial and commodities markets. One-month test drive is always free of charge, <strong>no jumping through hoops to cancel</strong>. To start your trial subscription, drop us an email at <a href="mailto:TrendCompass@ISystem-TF.com">TrendCompass@ISystem-TF.com</a></p>



<p>For<strong> <a href="https://isystem-tf.com/solutions/u-s-investors/">US investors</a></strong>, we propose a trend-driven inflation/recession resilient portfolio covering a basket of 30+ financial and commodities markets. For more information, you can drop me a comment or an email to <a href="mailto:xela.reniark@gmail.com">xela.reniark@gmail.com</a></p>



<figure data-sanitized-class="wp-block-image"><a href="https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F778c45ae-896d-4151-bc31-313bc594a250_2553x1497.png" target="_blank" rel="noreferrer noopener"><img src="https://substackcdn.com/image/fetch/w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F778c45ae-896d-4151-bc31-313bc594a250_2553x1497.png" alt="" title=""></a></figure>

attributes:
{"enclosures":[{"url":"https://0.gravatar.com/avatar/3cf56351ad2361f720df6adf94285322fc831b589472a80e77d0f256d827358f?s=96&amp;d=identicon&amp;r=G","title":"nakedhedgie","medium":"image"},{"url":"https://substackcdn.com/image/fetch/w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fafe309b3-fc6c-4e26-ab17-55580e6f1195_687x309.png","medium":"image"},{"url":"https://substackcdn.com/image/fetch/w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F845657c8-9447-4368-a3ac-97c366c47d74_745x275.png","medium":"image"},{"url":"https://isystem-tf.com/wp-content/uploads/2023/12/commoditysupercycle.png?w=1024","medium":"image"},{"url":"https://substackcdn.com/image/fetch/w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb85c58ba-0701-4101-ab59-a202bd92fc22_1990x840.png","medium":"image"},{"url":"https://substackcdn.com/image/fetch/w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F443b7ba7-d5ad-4a12-92a8-a7f2625b5d12_1528x1113.png","medium":"image"},{"url":"https://substackcdn.com/image/fetch/w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F778c45ae-896d-4151-bc31-313bc594a250_2553x1497.png","medium":"image"}]}


guid: yt:video:EOWq6JLs50Y
title: AI Revolution: From Renders to Music, It's Here!
author: ;ukramedia
link: https://www.youtube.com/watch?v=EOWq6JLs50Y
hash: ,rb� ������
attributes:
{"enclosures":[{"url":"https://www.youtube.com/v/EOWq6JLs50Y?version=3","title":"AI Revolution: From Renders to Music, It's Here!","description":"I'm on a mission to keep myself in the loop with all the latest happenings, so I decided to start a weekly video where I chat about the stuff I'm learning. Check out my first attempt!\n\n00:00 Merk Unveils Airen 4D\n      LINK: https://www.youtube.com/watch?v=q64ATr8mfzU\n00:33 OpenAI's Sora\n      LINK: https://openai.com/sora\n01:06 Apple Introduces Keyframer\n      LINK: https://arxiv.org/pdf/2402.06071.pdf\n01:23 Apple's Multimodal Image Editing\n      LINK: https://arxiv.org/pdf/2309.17102.pdf\n01:39 Google's MusicFX\n      LINK: https://aitestkitchen.withgoogle.com/tools/music-fx\n01:59 Meet Croq\n      LINK: https://groq.com/\n02:27 Shoutout to Luke Thompson\n      LINK: https://cutmy.link/lukethompson\n02:42 Dive into &quot;Scrum&quot;\n      LINK: https://amzn.to/49J6nyR\n02:52 Codeium\n      LINK: https://codeium.com/\n03:19 Epipheo's Free Animation Training\n      LINK: https://www.youtube.com/@epipheo\n03:38 Adobe MAX 2024\n      LINK: https://www.adobe.com/max.html\n03:47 Project Avalanche\n      LINK: https://youtu.be/nF4Xf7t0Hgg?si=pKdzf71RbPLF-GIg\n04:17 Thank You for Smart Animator Love!\n      LINK: https://ukramedia.com/product/smart-animator/","type":"application/x-shockwave-flash","height":390,"width":640,"thumbnails":["https://i2.ytimg.com/vi/EOWq6JLs50Y/hqdefault.jpg"]}]}


guid: /fr/sencaplus/opinion/leffort-emotionnel-du-mois-de-lhistoire-des-noirs-senatrice-clement/
title: L’effort émotionnel du Mois de l’histoire des Noirs : sénatrice Clement
hash: ���t�-��L���1@
attributes: {"enclosures":[]}
link:
https://sencanada.ca//fr/sencaplus/opinion/leffort-emotionnel-du-mois-de-lhistoire-des-noirs-senatrice-clement/


guid: yt:video:fSk1KHYr81k
title: How I Create Tools for After Effects
author: ;ukramedia
link: https://www.youtube.com/watch?v=fSk1KHYr81k
hash: ��'�5T��k�\7[;�
attributes:
{"enclosures":[{"url":"https://www.youtube.com/v/fSk1KHYr81k?version=3","title":"How I Create Tools for After Effects","description":"My After Effects Tools: https://ukramedia.com/product/smart-tools-bundle/\nScript UI: https://scriptui.joonas.me/\nPseudo Effect Maker: http://aescripts.com/pseudo-effect-maker/?aff=45\nNotion: https://affiliate.notion.so/ukramedia\nEraser: https://app.eraser.io/","type":"application/x-shockwave-flash","height":390,"width":640,"thumbnails":["https://i3.ytimg.com/vi/fSk1KHYr81k/hqdefault.jpg"]}]}


guid: yt:video:mCLZeQnNFOg
title: Coding Just Got Easier with Codeium!
author: ;ukramedia
link: https://www.youtube.com/watch?v=mCLZeQnNFOg
hash: �VP�7�j �qC��
attributes:
{"enclosures":[{"url":"https://www.youtube.com/v/mCLZeQnNFOg?version=3","title":"Coding Just Got Easier with Codeium!","description":"Learn more about Codeium at https://codeium.com/","type":"application/x-shockwave-flash","height":390,"width":640,"thumbnails":["https://i2.ytimg.com/vi/mCLZeQnNFOg/hqdefault.jpg"]}]}


guid: https://odysee.com/the-replacement-of-continental-physics:886a2a4e55ef135c69c52e95eacbc97761089bbb
title: The Replacement of Continental Physics in 19th Century Science
author: ;Rising Tide Foundation
link: https://odysee.com/the-replacement-of-continental-physics:886a2a4e55ef135c69c52e95eacbc97761089bbb
hash: mS�Gn�ݮ/� ���
content:
<p><img src="https://thumbnails.lbry.com/HAsQWdl4j8I" width="480" alt="thumbnail" title="The Replacement of Continental Physics in 19th Century Science"></p>Follow Dr. John Plaice's work on<br>https://johnplaice.substack.com/<br><br>Support the Rising Tide Foundation in the following ways:<br><br>1) Make a donation <br>https://risingtidefoundation.net/support-the-work/<br>2) Subscribe to Matt and Cynthia's Substack<br>matthewehret.substack.com<br>cynthiachung.substack.com<br>3) Buy some books!<br>https://canadianpatriot.org/untold-history-of-canada-books/<br><br>and follow us on www.risingtidefoundation.net and t.me/risingtidefoundation<br>...<br>https://www.youtube.com/watch?v=HAsQWdl4j8I

attributes:
{"enclosures":[{"url":"https://player.odycdn.com/api/v3/streams/free/the-replacement-of-continental-physics/886a2a4e55ef135c69c52e95eacbc97761089bbb/599d57.mp4","type":"video/mp4","length":566384552}]}


guid: yt:video:LlbM0f17CkE
title: Automatic Text Color Adjustment in After Effects
author: ;ukramedia
link: https://www.youtube.com/watch?v=LlbM0f17CkE
hash: �+�shJ�E�a�w 2
attributes:
{"enclosures":[{"url":"https://www.youtube.com/v/LlbM0f17CkE?version=3","title":"Automatic Text Color Adjustment in After Effects","description":"DESCRIPTION:\nTired of manually adjusting text color for Motion Graphics Templates (MoGrts)? This After Effects expressions tutorial is your game-changer!\n\nLearn how to create dynamic text that automatically adjusts its color based on the background. Simply pick your desired background color, and the text will intelligently switch between black and white for optimal contrast.\n\nHere's what you'll learn:\n- The power of expressions in After Effects\n- Building an expression to adjust text color based on brightness\n- Fine-tuning the expression for perfect results\n\nThis tutorial is perfect for:\n- Motion Designers (especially MoGrt creators)\n- Anyone who wants to create dynamic and responsive text animations\n\nMake your MoGrts truly versatile with this easy-to-follow tutorial!\n\nADOBE STOCK:\nhttps://stock.adobe.com/contributor/207251555/UKRAMEDIA.COM\n\nBRIGHTNESS FORMULA:\nMath.sqrt(0.299 * inputColor[0]**2 + 0.587 * inputColor[1]**2 + 0.114 * inputColor[2]**2)\n\n#mogrt #aftereffects #motiongraphics","type":"application/x-shockwave-flash","height":390,"width":640,"thumbnails":["https://i1.ytimg.com/vi/LlbM0f17CkE/hqdefault.jpg"]}]}


guid: https://odysee.com/connecting-the-dots-with-matt-ehret-2:b941941106b59f862636467d923bd61ccba86f0f
title: Connecting the Dots with Matt Ehret and Guest: Cynthia Chung
author: ;Rising Tide Foundation
link: https://odysee.com/connecting-the-dots-with-matt-ehret-2:b941941106b59f862636467d923bd61ccba86f0f
hash: E�ON��������b�
content:
<p><img src="https://thumbnails.lbry.com/-H-uZ13Tl9U" width="480" alt="thumbnail" title="Connecting the Dots with Matt Ehret and Guest: Cynthia Chung"></p>On today's show, Cynthia Chung Joins Matt to discuss her work on Operation Gladio, Operation Condor, and the anglo-American control of international neo-fascist programs after WW2 with a focus on Latin America<br><br>March 2, 2024<br><br>GUEST OVERVIEW: Cynthia Chung is the Editor-in-Chief and co-founder of the Rising Tide Foundation, a non-profit organization dedicated to the enhancement of cross-cultural understanding and dialogue between east and west. She is also a contributing author to the book series “The Clash of the Two Americas.” Cynthia writes for her own blog on Substack and has lectured on topics such as Schiller's aesthetics, Shakespeare's tragedies, Roman history, and the Florentine Renaissance, among others.<br><br>**********************************************<br>You can find more about Cynthia’s work at:<br>https://risingtidefoundation.net/<br>https://cynthiachung.substack.com/<br>**********************************************<br>Read Cynthia's series on Operation Condor and Operation Phoenix here:<br>https://cynthiachung.substack.com/p/the-enemy-within-a-story-of-the-take<br><br>https://cynthiachung.substack.com/p/how-panama-became-the-skynet-for<br><br>Matt and Cynthia's books:<br>https://canadianpatriot.org/untold-history-of-canada-books/<br><br>Watch The Hidden Hand Behind UFOs episode 1 here:<br>https://canadianpatriot.org/2023/11/01/the-hidden-hand-behind-ufos-episode-1-lifting-the-esoteric-veil/<br><br>Watch The Hidden Hand Behind UFOs episode 2 here:<br>https://canadianpatriot.org/2024/02/27/episode-2-of-the-hidden-hand-behind-ufos-has-been-unleashed-h-g-wells-war-of-the-worlds-and-the-dawn-of-a-new-age/<br>...<br>https://www.youtube.com/watch?v=-H-uZ13Tl9U

attributes:
{"enclosures":[{"url":"https://player.odycdn.com/api/v3/streams/free/connecting-the-dots-with-matt-ehret-2/b941941106b59f862636467d923bd61ccba86f0f/95798c.mp4","type":"video/mp4","length":217622679}]}


guid: https://odysee.com/connecting-the-dots-with-matt-ehret-and:fb321dcfaea0d0be6031c1443c71aa41c929ae59
title: Connecting the Dots with Matt Ehret and Cynthia Chung: On Escaping Calypso's Island
author: ;Rising Tide Foundation
link: https://odysee.com/connecting-the-dots-with-matt-ehret-and:fb321dcfaea0d0be6031c1443c71aa41c929ae59
hash: 1 㗣m6�ʷ�u�
content:
<p><img src="https://thumbnails.lbry.com/bObqI_o3wHs" width="480" alt="thumbnail" title="Connecting the Dots with Matt Ehret and Cynthia Chung: On Escaping Calypso's Island"></p>Cynthia Chung discusses her documentary series 'Escaping Calypso's Island' with Matt Ehret on TNT's Connecting the Dots<br><br>Watch episodes 1 and 2 of Escaping Calypso's Island here:<br>https://risingtidefoundation.net/2024/03/02/escaping-calypsos-island-a-journey-out-of-our-green-delusion/<br><br>Support the Rising Tide Foundation in the following ways:<br><br>1) Make a donation <br>https://risingtidefoundation.net/support-the-work/<br>2) Subscribe to Matt and Cynthia's Substack<br>matthewehret.substack.com<br>cynthiachung.substack.com<br>3) Buy some books!<br>https://canadianpatriot.org/untold-history-of-canada-books/<br><br>and follow us on www.risingtidefoundation.net and t.me/risingtidefoundation<br>...<br>https://www.youtube.com/watch?v=bObqI_o3wHs

attributes:
{"enclosures":[{"url":"https://player.odycdn.com/api/v3/streams/free/connecting-the-dots-with-matt-ehret-and/fb321dcfaea0d0be6031c1443c71aa41c929ae59/da355f.mp4","type":"video/mp4","length":496196181}]}


title: Les sculpteurs ravivent des visages fantomatiques du passé de l’édifice du Centre
hash: �x����\�#�Ӏ Yw
attributes: {"enclosures":[]}
guid:
/fr/sencaplus/comment-pourquoi/les-sculpteurs-ravivent-des-visages-fantomatiques-du-passe-de-ledifice-du-centre/

link:
https://sencanada.ca//fr/sencaplus/comment-pourquoi/les-sculpteurs-ravivent-des-visages-fantomatiques-du-passe-de-ledifice-du-centre/


title: Simulation du Sénat 2024 : Un nombre record d’étudiants à la barre de la Chambre rouge
hash: �|�,���EH�v
attributes: {"enclosures":[]}
guid:
/fr/sencaplus/nouvelles/simulation-du-senat-2024-un-nombre-record-detudiants-a-la-barre-de-la-chambre-rouge/

link:
https://sencanada.ca//fr/sencaplus/nouvelles/simulation-du-senat-2024-un-nombre-record-detudiants-a-la-barre-de-la-chambre-rouge/


guid: https://odysee.com/eva:2487059fb7b64329039bb0e0cb5f7c44cb0afa3a
title: Gutsy Women: Eva Bartlett
author: ;Eva K Bartlett
link: https://odysee.com/eva:2487059fb7b64329039bb0e0cb5f7c44cb0afa3a
hash: ���Ϭ��m�n��HQ��
content:
<p><img src="https://thumbs.odycdn.com/5dcaae7ef8723ff0475d31a40e85a920.webp" width="480" alt="thumbnail" title="Gutsy Women: Eva Bartlett"></p>"In a conversation with Eva Bartlett, Brian Gerrish (UK Column) learns what takes a young woman from Canada to travel to explore the world.<br>Bartlett (2007) paid for herself to go to the West Bank and the Gaza Strip (2008-2013) to understand what was really happening. <br><br>Eva paid a price for her courage on the front lines: she suffered physical harm from Israeli soldiers &amp; from illegal Jewish colonists; she endured arrest, shackling and custody by the Israeli police; and she experienced the trauma of being in the firing line when Israeli troops targeted live rounds against unarmed Palestinian protestors—a frequent occurrence. <br><br>Eva visited Syria (2014-2021, 15 times), rather than relying on the reports of others while observing from a distance. Western media reports on the Syrian war were heavily distorted to meet what she clearly regards as a US-UK-NATO official line.<br><br>In more recent years, Eva went to see and experience the reality of life in both the Crimea and in the Donbass.<br><br>It was in the Donetsk environs that Eva was to understand the horrors of the Ukrainian shelling and rocket attacks that the Russian civilian population has endured for nearly a decade. She spoke with local families, she witnessed the destruction, and she filmed and reported the reality of the dead bodies and parts of bodies of those killed in recent attacks.<br><br>Placing herself at risk on the front line of conflict zones, Eva Bartlett has then had to defend herself against vile and dangerous social media and related attacks. Abuse ranges from accusations of cowardice by armchair social media warriors to her being placed on Myrotvorets (‘Peacemaker’), the supposedly non-official Ukrainian death list <br><br>Canadian state-aligned media  (CBC), clearly intent on undermining her Donbas reporting in whatever manner they could, smeared her, drawing from the kill list entry... <br><br><br>Related:<br><br>https://ingaza.wordpress.com/about-me/<br><br>https://opt2007.wordpress.com/category/my-entries-from-occupied-palestine-apr-dec-2007/<br><br>https://opt2007.wordpress.com/2007/08/13/reflections-on-accountability/<br><br>https://opt2007.wordpress.com/2007/10/17/illegal-colonists-assault-palestinian-farmers/<br><br>https://opt2007.wordpress.com/2007/09/05/arrested-for-protesting-illegal-roadblock/<br><br>Israeli Military Shoot Gaza Farmer<br>https://youtu.be/zSECq3kxT4I?si=nkVj9UD-EFD3hqin&amp;t=88<br><br>https://ingaza.wordpress.com/2014/01/01/observations-from-occupied-palestine-in-gaza/<br><br>My Gaza playlist:  https://odysee.com/$/playlist/ce33a0a4910ada76a21dffe25319f136eb6e96f6<br><br>https://ingaza.wordpress.com/syria/syria-my-published-articles-from-and-on-syria-2014-2022/<br><br>https://ingaza.wordpress.com/2015/10/13/deconstructing-the-nato-narrative-on-syria/<br><br>https://ingaza.wordpress.com/2019/10/10/return-to-russia-crimeans-tell-the-real-story-of-the-2014-referendum-and-their-lives-since/ <br><br>https://ingaza.wordpress.com/the-donbass-my-articles-videos-interviews-from-on-the-donetsk-lugansk-peoples-republics-2019-present/<br><br>https://ingaza.wordpress.com/2022/08/10/what-ive-seen-of-ukraines-war-crimes-against-civilians-in-the-donbass-over-the-years/<br><br>https://ingaza.wordpress.com/2021/06/12/im-on-a-hit-list-kiev-allows-to-silence-dissent-journalism-thats-all-you-need-to-know-about-ukrainian-democracy/<br><br>https://ingaza.wordpress.com/2022/07/17/government-funded-cbc-smears-me-interview-with-maverick-media-cbc-fake-news-hit-piece-targets-journalists-eva-bartlett/

attributes:
{"enclosures":[{"url":"https://player.odycdn.com/api/v3/streams/free/eva/2487059fb7b64329039bb0e0cb5f7c44cb0afa3a/9abc4f.mp4","type":"video/mp4","length":2414689631}]}


guid: /fr/salle-de-nouvelles/ollo-un-comite-du-senat-etudiera-les-effets-du-plafond-des-permis-detudes/
title: Un comité du Sénat étudiera les effets du plafond des permis d’études
hash: N�n�(�0��e����
attributes: {"enclosures":[]}
link:
https://sencanada.ca//fr/salle-de-nouvelles/ollo-un-comite-du-senat-etudiera-les-effets-du-plafond-des-permis-detudes/


guid: https://scottjehl.com/posts/wordleish/
title: How would you build Wordle with just HTML &amp; CSS?
author: ;Scott Jehl
link: https://scottjehl.com/posts/wordleish/
hash: Q��c,��7DDB*C
attributes: {"enclosures":[]}
content:
<p>I’ve been thinking about the questions folks are typically asked in front-end interviews these days, and how well those questions assess a candidate's depth of understanding of web standard technologies, and not just their ability to employ JavaScript algorithms and third-party frameworks. It made me think about the sort of questions I would like to hear or ask in an interview myself.</p>
<p>I think this sort of question would be a useful one:</p>
<blockquote>
<p>"How would you attempt to build <a href="https://www.nytimes.com/games/wordle/index.html"><em>Wordle</em></a> (<em>...or some other complex app</em>) if you could only use HTML and CSS? Which features of that app would make more sense to build with JavaScript than with other technologies? And, can you imagine a change or addition to the HTML or CSS standard that could make any of those features more straight-forward to build?"</p>
</blockquote>
<p>Now, to be clear, this is meant to be a contrived exercise. I don't actually think a game app like Wordle <em>should</em> be built without using any JavaScript, <em>(though I do think the app could be better if it functioned at all without it!)</em>. In reality, I feel there are many user experience enhancements to an app like Wordle that <em>only</em> JavaScript is capable of providing.</p>
<p>Still, I like this question as an exercise. Discussing any approaches to this challenge will reveal the candidate's broad knowledge of web standards–including new and emerging HTML and CSS features–and as a huge benefit, it would help select for the type of folks who are best suited to lead us out of the JavaScript over-reliance problems that are <a href="https://infrequently.org/2024/01/performance-inequality-gap-2024/">holding back the web today</a>.</p>
<p>Interview questions aside though, I also thought this would be a fun little experiment to explore myself! So I took a few hours yesterday to do just that, and in the rest of this post I'll cover how I approached it.</p>
<h2>A Quick Attempt</h2>
<p><strong>Here's a CodePen link with the demo and code for my first attempt:</strong></p>
<p><a href="https://codepen.io/scottjehl/details/LYvQxqa">Wordle, just HTML &amp; CSS</a></p>
<p>By the way, if you aren't here to play games (or you want to save some time), you can find the answer to the puzzle in this little disclosure:</p>
<details><summary>Reveal Answer</summary>PROUD</details>
<p>The approach I took for this example leans hard on HTML form validation for the game logic. I'm using a text <code>input</code> for each letter of the word, with <code>pattern</code> attributes describing the correct letter. The browser can natively use a pattern attribute to determine whether the input's value is "valid," which in the case of this contrived example can mean that a letter is correct.</p>
<p>To give an example, if the correct word was "TIGER" then the first letter's <code>input</code> could have a pattern attribute like this: <code>pattern="[tT]"</code> which would match lowercase and uppercase T. Additionally, the inputs have a <code>maxlength</code> attribute to limit their content length to 1 character.</p>
<p>HTML:</p>
<pre><code>&lt;input type="text" id="input1" name="input1" maxlength="1" pattern="[tT]"&gt;
</code></pre>
<p>Through these two attributes alone, we can already write a CSS selector to visually display whether a typed letter is correct or not, using a gray or green background similar to Wordle itself, like this:</p>
<pre><code>input[type="text"]:invalid {
    background-color: lightgray;
}
input[type="text"]:valid {
    background-color: lightgreen;
}
</code></pre>
<p>Neat! But there are some problems.</p>
<h3>Delaying Validation</h3>
<p>As written above, the validation styles will show immediately as you are writing the letters, rather than after you type the entire word, which makes it too easy to change your answer as you see whether each letter is correct or not. That's not how Wordle works!</p>
<p>Instead, we want the validation to kick in <em>only</em> after a word is entered and complete. You could try to do this in a number of ways. I decided to use the <code>:not()</code> and <code>:has()</code> CSS selectors to qualify the validation styles to only apply when the user is done entering a whole word. The game board grid uses an HTML <code>table</code> element and each "word" row sits in a <code>tr</code> element. The following styles will apply to <code>tr</code> elements that do not contain focused or empty inputs, meaning every input has a character in it and the user is no longer typing in any of the inputs.</p>
<p>To gauge whether the inputs are empty, I added a <code>placeholder</code> attribute to the HTML <code>input</code>, which conveniently pairs with the <code>:placeholder-shown</code> selector that matches empty inputs. Here's the HTML and CSS:</p>
<p>HTML:</p>
<pre><code>&lt;input type="text" id="input1" name="input1" maxlength="1" pattern="[tT]" placeholder=" "&gt;
</code></pre>
<p>CSS:</p>
<pre><code>/* invalidate only non-focused populated row */
tr:not(:has(input:placeholder-shown, input:focus)) input[type="text"]:invalid {
    background-color: lightgray;
}
/* validate only non-focused populated row */
tr:not(:has(input:placeholder-shown, input:focus)) input[type="text"]:valid {
    background-color: lightgreen;
}
</code></pre>
<p>Nice. Now the form validation happens after a complete guess for each row. <em>Small note: iOS Safari seems to only allow this selector to work with placeholder attributes that have at least some sort of string, so I added a blank space to its value, but there's probably a better character that I could use (maybe "A"?).</em></p>
<h3>Disabling Future and Completed Rows</h3>
<p>Another thing I wanted to do to match the game's behavior is to only allow interaction with the inputs in the active row. Admittedly, I didn't fully pull this one off for restricting keyboard focus, but I was at least able to disable touch and click-focus on those inputs by using a similar selector to the prior ones, and disabling pointer events.</p>
<pre><code>/* disallow next row until row is populated */
tr:has(input:placeholder-shown) ~ tr input,
/* disallow revisiting populated row */
tr:not(:has(input:placeholder-shown, input:focus)) input {
    pointer-events: none;
}
</code></pre>
<p>Good enough, moving on.</p>
<h3>Announcing a Win</h3>
<p>When the correct word is typed, it would be nice to hide the rows after the correct guess and display a message that the game is over. To do this, I used a rule similar to the ones above, with some additional generated content to announce the win.</p>
<pre><code>tr:not(:has(input:placeholder-shown, input:invalid, input:focus)) ~ tr {
    display: none;
}
table tr:not(:has(input:placeholder-shown, input:invalid, input:focus)):after {
  content: "You Win!";
  /* ...some additional less critical styles here */
}
</code></pre>
<p><strong>Improvement to test:</strong> This winning announcement should be accessible, and I'm not sure that CSS generated content will be announced in assistive tech, even if I use an aria-live region. Perhaps it'd be better to toggle the CSS display of a status message that follows the table, or have a status column on the right with messages that can be revealed as needed. I'm thinking on this.</p>
<h3>So What About Tan?</h3>
<p>Now, admittedly, so far the game only offers the gray and green states of Wordle, which represent letters that are either not in the word at all (gray), or are entirely correct and in the right place (green). Unlike the real Wordle, it's missing the "tan" state that tells you a letter is in the word, yet in the wrong place. This means that the game is playable, but it's pretty hard!</p>
<p>Unfortunately, HTML validation only offers a binary answer, and what we really want here is a sort of in-between state that's valid but not super-valid.</p>
<h4>Validating for Tan</h4>
<p>So pattern validation only allows us to match for one type of pattern, but that pattern could refer to the whole word if we wanted to use it for the tan state instead of the green state. For example, the following pattern would match every letter in TIGER, both lowercase and uppercase: <code>pattern="[tTiIgGeErR]"</code>.</p>
<p>Once again, our familiar CSS could target that valid pattern to color an input tan if it contains a letter that is in the word at all:</p>
<pre><code>/* validate only non-focused populated row */
tr:not(:has(input:placeholder-shown, input:focus)) input[type="text"]:valid {
  background-color: tan;
}
</code></pre>
<p>So now our problem is tan works, but green doesn't. We need a little help showing the green state for letters that are not ONLY in the word, but in the right place as well.</p>
<h3>Extending with JavaScript</h3>
<p>Okay. Let's add some JavaScript to get 3 states instead of 2.</p>
<p>The following 10 lines add an <code>input</code> event handler (which fires whenever the user changes the input's value) to all of the inputs in the page. It will grab a regular expression pattern in that input's custom <code>data-correct-pattern</code> attribute and add a <code>data-incorrect</code> attribute to the input when the pattern doesn't match the input's current value:</p>
<pre><code>document.querySelectorAll("input").forEach(inpt =&gt; {
  inpt.addEventListener("input", function(e) {
    const correct = this.value.match(new RegExp(this.getAttribute("data-correct-pattern")));
    if (correct) {
      this.removeAttribute("data-incorrect");
    } else {
      this.setAttribute("data-incorrect", true);
    }
  });
});
</code></pre>
<p>With that attribute toggle, I can write some CSS to add the green state! Here are my 3 states, the third of which using that new data-incorrect attribute:</p>
<pre><code>/* invalidate only non-focused populated row */
tr:not(:has(input:placeholder-shown, input:focus)) input[type="text"]:invalid {
  background-color: lightgray;
}
/* validate only non-focused populated row */
tr:not(:has(input:placeholder-shown, input:focus)) input[type="text"]:valid {
  background-color: tan;
}
/* validate only non-focused populated row */
tr:not(:has(input:placeholder-shown, input:focus)) input[type="text"]:not([data-incorrect]) {
  background-color: lightgreen;
}
</code></pre>
<p><strong>You can view the demo of this version here:</strong></p>
<p><a href="https://codepen.io/scottjehl/details/JjVpNEb">Wordle, almost just HTML &amp; CSS</a></p>
<h2>Caveats and Implementation Ideas</h2>
<p>Needless to say, these examples don't do everything that the real Wordle does, so I won't attempt to itemize the differences here. Perhaps the most important difference to note is that there's no validation of real words, so you can enter any old letters you please.</p>
<p>I also want to explore how to make the state of the app persistently make sense to assistive technology, which might mean having an additional table column with cells containing the result of each validation (toggling the display of various possible messages so that they are accessible. Maybe that'll be a followup post (and if you're interested, <a href="https://blog.mayank.co/how-i-built-an-accessible-version-of-wordle">here's a more practical article about improving actual-Wordle's accessibility</a>).</p>
<p>Also, um, the puzzle is always the same answer? True! The real Wordle has a different word every day. A fuller implementation of an approach like this would need some dynamic handling on the server side to deliver different HTML patterns for the word of the day.</p>
<p>Having said all of that, I find it pretty awesome that HTML and CSS alone can get us so far today, and it's totally possible that there are different HTML patterns that could pull off all 3 colors without JS already, as well (perhaps if we built a large QUERTY keyboard out of radio inputs...)</p>
<h2>What if :valid was a function?</h2>
<p>Okay, as for the the last part of my original question. What could be added to HTML or CSS to make that last example possible without JavaScript? One thing comes to mind for me: an ability to validate multiple patterns on one input.</p>
<p>For example, let's revisit that <code>pattern</code> attribute value. The existing <code>pattern="[tTiIgGeErR]"</code> will match for all of the letters in the word Tiger, uppercase or lowercase. From that, you get a simple yes or no match for whether the letter is in the word at all, again like this:</p>
<pre><code>input[type="text"]:valid {
  background-color: tan;
}
</code></pre>
<p>That gives us the tan color, but again we still have the green pattern to worry about. What if that <code>:valid</code> pseudo-class allowed for arguments, though? If it did, then I could pass a string to it, like <code>:valid("[gG]")</code> to specifically match for a g or G. Even better, maybe the value could accept the standard CSS <code>attr()</code> function too, which would allow the HTML to define additional patterns for the CSS to validate. In my second demo, I used a <code>data-correct-pattern</code> attribute to define that second pattern.</p>
<p>Here's how the markup and CSS might look for that dreamed-up feature, which could allow the second demo to work without JS:</p>
<p>HTML:</p>
<pre><code>&lt;input type="text" id="input1" name="input1" maxlength="1" pattern="[tTiIgGeErR]" data-correct-pattern="[tT]" placeholder=" "&gt;
</code></pre>
<p>CSS:</p>
<pre><code>/* invalidate only non-focused populated row */
tr:not(:has(input:placeholder-shown, input:focus)) input[type="text"]:invalid {
  background-color: lightgray;
}
/* validate only non-focused populated row */
tr:not(:has(input:placeholder-shown, input:focus)) input[type="text"]:valid {
  background-color: tan;
}
/* validate only non-focused populated row */
tr:not(:has(input:placeholder-shown, input:focus)) input[type="text"]:valid(attr(data-correct-pattern)) {
  background-color: lightgreen;
}
</code></pre>
<p>JavaScript:</p>
<pre><code>...none needed.
</code></pre>
<p>Maybe I'll file an issue in the CSS standard asking for <code>:valid(attr(...))</code>! :)</p>
<h2>Thanks!</h2>
<p>I hope you enjoyed this post. Please feel free to reach out with ideas or questions or improvements on <a href="https://mstdn.social/@scottjehl">Mastodon</a>. Thanks for reading!</p>


author: ;Eva K Bartlett
hash: �.E���Q����k 5
guid:
https://odysee.com/Hypocrisy-and-culpability-of-Western-politicians_MSM-on-Ukraine-and-Gaza:9ce3f2163abc4f41b0627e46b0fad487d71f33b2

title:
Interviewed on The David Kurten Show: “Hypocrisy and culpability of Western politicians/MSM on Ukraine and Gaza”

content:
<p><img src="https://thumbs.odycdn.com/1157824159d9088753f5ab7b258e1fd6.webp" width="480" alt="thumbnail" title="Interviewed on The David Kurten Show: “Hypocrisy and culpability of Western politicians/MSM on Ukraine and Gaza”"></p>First published:  https://www.youtube.com/watch?v=37a4haHEw7I   &amp;   https://tntradio.live/shows/the-david-kurten-show/<br><br>My Related Links here:<br><br>https://ingaza.wordpress.com/2024/04/05/interviewed-on-the-david-kurten-show-hypocrisy-and-culpability-of-western-politicians-msm-on-ukraine-and-gaza/

link:
https://odysee.com/Hypocrisy-and-culpability-of-Western-politicians_MSM-on-Ukraine-and-Gaza:9ce3f2163abc4f41b0627e46b0fad487d71f33b2

attributes:
{"enclosures":[{"url":"https://player.odycdn.com/api/v3/streams/free/Hypocrisy-and-culpability-of-Western-politicians_MSM-on-Ukraine-and-Gaza/9ce3f2163abc4f41b0627e46b0fad487d71f33b2/1b6cae.mp4","type":"video/mp4","length":94033967}]}


title: Soutenir la prospérité et la réussite des entrepreneurs noirs : sénatrice Gerba
hash: g䂽�g?��Y�=H3
attributes: {"enclosures":[]}
guid:
/fr/sencaplus/opinion/soutenir-la-prosperite-et-la-reussite-des-entrepreneurs-noirs-senatrice-gerba/

link:
https://sencanada.ca//fr/sencaplus/opinion/soutenir-la-prosperite-et-la-reussite-des-entrepreneurs-noirs-senatrice-gerba/


title: « L’importance de redonner » : le sénateur Mockler fait ses adieux à la Chambre rouge
hash: +���3�V�0�XH��
attributes: {"enclosures":[]}
guid:
/fr/sencaplus/personnalites/limportance-de-redonner-le-senateur-mockler-fait-ses-adieux-a-la-chambre-rouge/

link:
https://sencanada.ca//fr/sencaplus/personnalites/limportance-de-redonner-le-senateur-mockler-fait-ses-adieux-a-la-chambre-rouge/


title: La Série du siècle de 1972 alimente toujours ma fierté pour la feuille d’érable : sénateur Loffreda
hash: ���U�fj�� iSu�
attributes: {"enclosures":[]}
guid:
/fr/sencaplus/opinion/la-serie-du-siecle-de-1972-alimente-toujours-ma-fierte-pour-la-feuille-derable-senateur-loffreda/

link:
https://sencanada.ca//fr/sencaplus/opinion/la-serie-du-siecle-de-1972-alimente-toujours-ma-fierte-pour-la-feuille-derable-senateur-loffreda/


title: Les banques canadiennes investissent dans les catastrophes climatiques : sénatrice Galvez
hash: �D���\<��r },�
attributes: {"enclosures":[]}
guid:
/fr/sencaplus/opinion/les-banques-canadiennes-investissent-dans-les-catastrophes-climatiques-senatrice-galvez/

link:
https://sencanada.ca//fr/sencaplus/opinion/les-banques-canadiennes-investissent-dans-les-catastrophes-climatiques-senatrice-galvez/


hash: �W�^YE2(: �O��
attributes: {"enclosures":[]}
guid:
/fr/sencaplus/opinion/la-resistance-aux-antimicrobiens-est-une-menace-mondiale-et-le-canada-est-mal-prepare-senateure-seidman/

title:
La résistance aux antimicrobiens est une menace mondiale – et le Canada est mal préparé : sénateure Seidman

link:
https://sencanada.ca//fr/sencaplus/opinion/la-resistance-aux-antimicrobiens-est-une-menace-mondiale-et-le-canada-est-mal-prepare-senateure-seidman/


guid: /fr/salle-de-nouvelles/appel-de-candidatures-11e-poete-officiel-ou-officielle-du-parlement/
title: Appel de candidatures : 11e poète officiel ou officielle du Parlement
hash: �: 8.��S㛶+�
attributes: {"enclosures":[]}
link:
https://sencanada.ca//fr/salle-de-nouvelles/appel-de-candidatures-11e-poete-officiel-ou-officielle-du-parlement/


guid: https://odysee.com/the-lost-confucian-philosopher-gu:59aaeb86308356bde0b736f39adbb50465f7ff24
title: The Lost Confucian Philosopher Gu Hongming and the Chinese Religion of Good Citizenship [part 2]
author: ;Rising Tide Foundation
link: https://odysee.com/the-lost-confucian-philosopher-gu:59aaeb86308356bde0b736f39adbb50465f7ff24
hash: &A��^��.� K0��
content:
<p><img src="https://thumbnails.lbry.com/_TnjUNiyM8k" width="480" alt="thumbnail" title="The Lost Confucian Philosopher Gu Hongming and the Chinese Religion of Good Citizenship [part 2]"></p>The Rising Tide Foundation reading group continues studying the introductory text to confucian philosopher and educational reformer Gu Hongming (download the essay here: https://risingtidefoundation.net/wp-content/uploads/2024/03/Gu_Hongming_and_Chinese_Religion_of_Good.docx<br><br>Support the Rising Tide Foundation in the following ways:<br><br>1) Make a donation <br>https://risingtidefoundation.net/support-the-work/<br>2) Subscribe to Matt and Cynthia's Substack<br>matthewehret.substack.com<br>cynthiachung.substack.com<br>3) Buy some books!<br>https://canadianpatriot.org/untold-history-of-canada-books/<br><br>and follow us on www.risingtidefoundation.net and t.me/risingtidefoundation<br>...<br>https://www.youtube.com/watch?v=_TnjUNiyM8k

attributes:
{"enclosures":[{"url":"https://player.odycdn.com/api/v3/streams/free/the-lost-confucian-philosopher-gu/59aaeb86308356bde0b736f39adbb50465f7ff24/1483fb.mp4","type":"video/mp4","length":436718842}]}


guid: https://odysee.com/the-lost-confucian-philosopher-gu-2:bd7750b4f6dd6dc3e0141d2e4e6f063cacb7f883
title: The Lost Confucian Philosopher Gu Hongming and the Chinese Religion of Good Citizenship [part 3]
author: ;Rising Tide Foundation
link: https://odysee.com/the-lost-confucian-philosopher-gu-2:bd7750b4f6dd6dc3e0141d2e4e6f063cacb7f883
hash: ��<�$����g
content:
<p><img src="https://thumbnails.lbry.com/dbbIUn65ReY" width="480" alt="thumbnail" title="The Lost Confucian Philosopher Gu Hongming and the Chinese Religion of Good Citizenship [part 3]"></p>The Rising Tide Foundation reading group continues studying the introductory text to confucian philosopher and educational reformer Gu Hongming (download the essay here: https://risingtidefoundation.net/wp-content/uploads/2024/03/Gu_Hongming_and_Chinese_Religion_of_Good.docx<br><br>Support the Rising Tide Foundation in the following ways:<br><br>1) Make a donation <br>https://risingtidefoundation.net/support-the-work/<br>2) Subscribe to Matt and Cynthia's Substack<br>matthewehret.substack.com<br>cynthiachung.substack.com<br>3) Buy some books!<br>https://canadianpatriot.org/untold-history-of-canada-books/<br><br>and follow us on www.risingtidefoundation.net and t.me/risingtidefoundation<br>...<br>https://www.youtube.com/watch?v=dbbIUn65ReY

attributes:
{"enclosures":[{"url":"https://player.odycdn.com/api/v3/streams/free/the-lost-confucian-philosopher-gu-2/bd7750b4f6dd6dc3e0141d2e4e6f063cacb7f883/d29818.mp4","type":"video/mp4","length":384458533}]}


guid: https://odysee.com/the-importance-of-embracing-historical:3bf77aca930e39de1c1b44116d9e017349ce3d8a
title: The Importance of Embracing Historical Truth (A Dialogue with Fehmi Krasniqi)
author: ;Rising Tide Foundation
link: https://odysee.com/the-importance-of-embracing-historical:3bf77aca930e39de1c1b44116d9e017349ce3d8a
hash: ����)� ���[)�9�
content:
<p><img src="https://thumbnails.lbry.com/t2L9WQG9WjE" width="480" alt="thumbnail" title="The Importance of Embracing Historical Truth (A Dialogue with Fehmi Krasniqi)"></p>In this presentation, film maker, researcher and philosopher Fehmi Krasniqi provides a concise demonstration of the origins of the metric system using water droplets- a lost discovery known to the ancient Egyptians and demonstrated in his film K19: The Great Pyramid. The importance of embracing the truth of the vast contributions to human civilization and the growth of ancient Egyptian science by black Africans is discussed at length as well as the existential importance of choosing the more difficult of the two paths ahead of humanity going into a very precarious future. Additionally, Fehmi's new documentary "The 10th Hieroglyph: Mother" is also discussed at the end of the presentation.<br><br>To Watch part one of this two part presentation, click here: https://www.youtube.com/watch?v=9B4LmigzNek<br><br>Watch the trailer for Fehmi's new film "The 10th Hieroglyph: The Mother" (en francais) here: https://youtu.be/hANujYTe1v0?si=eJjcxoaMgBsDL6uM<br><br>Watch K19: The Great Pyramid here: https://www.youtube.com/watch?v=KMAtkjy_YK4<br><br>Support Fehmi's work here:<br>https://www.gofundme.com/f/book-great-pyramid-k-2019<br><br>Support the Rising Tide Foundation in the following ways:<br><br>1) Make a donation <br>https://risingtidefoundation.net/support-the-work/<br>2) Subscribe to Matt and Cynthia's Substack<br>matthewehret.substack.com<br>cynthiachung.substack.com<br>3) Buy some books!<br>https://canadianpatriot.org/untold-history-of-canada-books/<br><br>and follow us on www.risingtidefoundation.net and t.me/risingtidefoundation<br>...<br>https://www.youtube.com/watch?v=t2L9WQG9WjE

attributes:
{"enclosures":[{"url":"https://player.odycdn.com/api/v3/streams/free/the-importance-of-embracing-historical/3bf77aca930e39de1c1b44116d9e017349ce3d8a/3bc521.mp4","type":"video/mp4","length":194249982}]}


title: Education, Economics and the Mind with Cynthia Chung
author: ;Rising Tide Foundation
hash: ����H��|ED�q�A
guid:
https://odysee.com/education%2C-economics-and-the-mind-with:58ebddcb321b44404a3a1af3a16ccd1bc92d72dd

content:
<p><img src="https://thumbnails.lbry.com/ChLyUhpIZBA" width="480" alt="thumbnail" title="Education, Economics and the Mind with Cynthia Chung"></p>In this excerpt, Cynthia Chung speaks with Vince and Brandi (hosts of the Campus Earth Curriculum on the Grass Roots Warrior Network) to discuss her work on history, philosophy, cultural warfare and solutions.<br><br>Watch the full 2 hr interview here: https://rumble.com/v3xje9d-campus-earth-curriculum-28-education-economics-and-the-mind-with-cynthia-ch.html<br><br>Follow the Alternative Education Alliance here<br>alternativeeducationalalliance.org<br><br>Support the Rising Tide Foundation in the following ways:<br><br>1) Make a donation <br>https://risingtidefoundation.net/support-the-work/<br>2) Subscribe to Matt and Cynthia's Substack<br>matthewehret.substack.com<br>cynthiachung.substack.com<br>3) Buy some books!<br>https://canadianpatriot.org/untold-history-of-canada-books/<br><br>and follow us on www.risingtidefoundation.net and t.me/risingtidefoundation<br>...<br>https://www.youtube.com/watch?v=ChLyUhpIZBA

link:
https://odysee.com/education%2C-economics-and-the-mind-with:58ebddcb321b44404a3a1af3a16ccd1bc92d72dd

attributes:
{"enclosures":[{"url":"https://player.odycdn.com/api/v3/streams/free/education,-economics-and-the-mind-with/58ebddcb321b44404a3a1af3a16ccd1bc92d72dd/3e5483.mp4","type":"video/mp4","length":154995884}]}


title: Escaping Calypso's Island Ep.03: Energy Wars
author: ;Rising Tide Foundation
hash: �J�:���k������
guid:
https://odysee.com/escaping-calypso%27s-island-ep.03-energy:c9e6f2cd05b99a0f8a051fbcef374a641891953e

content:
<p><img src="https://thumbnails.lbry.com/-pX1Hf3U2tM" width="480" alt="thumbnail" title="Escaping Calypso's Island Ep.03: Energy Wars"></p>Watch ep. 1 here: https://www.youtube.com/watch?v=eH9qaTawttE<br><br>Watch ep. 2 here: https://www.youtube.com/watch?v=gv97LL4LUNw<br><br>Support the Rising Tide Foundation's work by any of the following ways:<br><br>1) Sponsor these videos by making a donation on Paypal, Patreon or Wordpress<br>https://risingtidefoundation.net/support-the-work/<br><br>2) Subscribe to Matt and Cynthia's Substacks at<br>matthewehret.substack.com<br>cynthiachung.substack.com<br><br>3) Buy some books!<br>https://canadianpatriot.org/untold-history-of-canada-books/<br>...<br>https://www.youtube.com/watch?v=-pX1Hf3U2tM

link:
https://odysee.com/escaping-calypso%27s-island-ep.03-energy:c9e6f2cd05b99a0f8a051fbcef374a641891953e

attributes:
{"enclosures":[{"url":"https://player.odycdn.com/api/v3/streams/free/escaping-calypso's-island-ep.03-energy/c9e6f2cd05b99a0f8a051fbcef374a641891953e/333438.mp4","type":"video/mp4","length":864232557}]}


title: Les sénateurs nous font part de leurs réflexions sur le Mois du patrimoine asiatique 2024
hash: ���|%a;� KD{=�
attributes: {"enclosures":[]}
guid:
/fr/sencaplus/nouvelles/les-senateurs-nous-font-part-de-leurs-reflexions-sur-le-mois-du-patrimoine-asiatique-2024/

link:
https://sencanada.ca//fr/sencaplus/nouvelles/les-senateurs-nous-font-part-de-leurs-reflexions-sur-le-mois-du-patrimoine-asiatique-2024/


title: Une stratégie nationale pour la jeunesse aiderait les enfants à s’épanouir : sénatrice Moodie
hash: g��b����A(��/
attributes: {"enclosures":[]}
guid:
/fr/sencaplus/opinion/une-strategie-nationale-pour-la-jeunesse-aiderait-les-enfants-a-sepanouir-senatrice-moodie/

link:
https://sencanada.ca//fr/sencaplus/opinion/une-strategie-nationale-pour-la-jeunesse-aiderait-les-enfants-a-sepanouir-senatrice-moodie/


guid: https://scottjehl.com/posts/web-components-demystified/
title: Announcing Web Components Demystified, an Online Course
author: ;Scott Jehl
link: https://scottjehl.com/posts/web-components-demystified/
hash: �dηHw-�~����/
attributes: {"enclosures":[]}
content:
<p><strong>I have some exciting news!</strong> I just launched <a href="https://www.kickstarter.com/projects/scott-jehl/web-components-demystified">a crowdfunding campaign</a> for a new online course I plan to produce. It's called <strong>Web Components Demystified</strong>, and it aims to explore web components holistically, covering not only the details of the collective standards behind web components, but also how they're being used across the web today and what's ahead as well. <strong>The time for learning web components is now</strong> and I intend to help teams get up to speed with all they can do.</p>
<iframe width="800" height="450" src="https://www.kickstarter.com/projects/scott-jehl/web-components-demystified/widget/video.html" frameborder="0" scrolling="no" allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" sandbox="allow-scripts allow-same-origin"> </iframe>
<p>You can find out more about the project, and secure access to the course materials over one Kickstarter, where you'll find various reward tiers for individual and discounted team access, all at an early bird rate.</p>
<p><a href="https://www.kickstarter.com/projects/scott-jehl/web-components-demystified" data-sanitized-class="wcd-ksbutton">Help this project succeed on <img src="https://scottjehl.com/assets/wcd-kickstarter.png" alt="Web Components Demystified on Kickstarter"></a></p>
<p>I've set up a <a href="https://scottjehl.com/learn/webcomponentsdemystified/">project site</a> as well.</p>
<h2>Back the Project Now and Save!</h2>
<p>The campaign will run through June 8, and it needs to meet its goal in order to be funded at all. Of course, my hope is to exceed its goal so that I can consider ways to increase the scope and quality of the course, and perhaps offer in-person and online team training for the material in the fall.</p>
<p>Regardless of whether it has already met its goal, <strong>it's advantageous to back the project now</strong> as you'll save with early bird pricing that will increase after the campaign finishes. Thank you so much for your support. Here's hoping <a href="https://www.kickstarter.com/projects/scott-jehl/web-components-demystified">the campaign</a> succeeds!</p>


hash: ��ż�>�Y+ ��yq
attributes: {"enclosures":[]}
guid:
/fr/sencaplus/opinion/le-gouvernement-federal-doit-preter-loreille-quand-les-premieres-nations-se-disent-favorables-a-lexploitation-des-ressources-senateur-wells/

title:
Le gouvernement fédéral doit prêter l’oreille quand les Premières Nations se disent favorables à l’exploitation des ressources : sénateur Wells

link:
https://sencanada.ca//fr/sencaplus/opinion/le-gouvernement-federal-doit-preter-loreille-quand-les-premieres-nations-se-disent-favorables-a-lexploitation-des-ressources-senateur-wells/


guid: yt:video:GAaCiFS-Wkw
title: Senate Explained: What is Time Allocation?
author: ;Senate of Canada | Sénat du Canada
link: https://www.youtube.com/watch?v=GAaCiFS-Wkw
hash: Ns�KS�[�8XS{�
attributes:
{"enclosures":[{"url":"https://www.youtube.com/v/GAaCiFS-Wkw?version=3","title":"Senate Explained: What is Time Allocation?","description":"Like the Senate of Canada on Facebook http://ow.ly/dSjS307h4in\r\nFollow the Senate of Canada on X (Twitter) http://ow.ly/JRDm307h4lF\r\nFollow the Senate of Canada on Instagram http://ow.ly/UDUy307h4oG\r\nVisit the Senate’s website https://sencanada.ca/","type":"application/x-shockwave-flash","height":390,"width":640,"thumbnails":["https://i4.ytimg.com/vi/GAaCiFS-Wkw/hqdefault.jpg"]}]}


guid: yt:video:G4zEwOXRkyA
title: Senate Explained: The Speaker of the Senate
author: ;Senate of Canada | Sénat du Canada
link: https://www.youtube.com/watch?v=G4zEwOXRkyA
hash: �C�`E[��&�4.u��J
attributes:
{"enclosures":[{"url":"https://www.youtube.com/v/G4zEwOXRkyA?version=3","title":"Senate Explained: The Speaker of the Senate","description":"Like the Senate of Canada on Facebook http://ow.ly/dSjS307h4in\r\nFollow the Senate of Canada on Twitter http://ow.ly/JRDm307h4lF\r\nFollow the Senate of Canada on Instagram http://ow.ly/UDUy307h4oG\r\nVisit the Senate’s website https://sencanada.ca/","type":"application/x-shockwave-flash","height":390,"width":640,"thumbnails":["https://i4.ytimg.com/vi/G4zEwOXRkyA/hqdefault.jpg"]}]}


guid: https://scottjehl.com/posts/speculation-rules/
title: Just Speculating: You May Not Need a SPA framework
author: ;Scott Jehl
link: https://scottjehl.com/posts/speculation-rules/
hash: u�*�T��:vΌ����
attributes: {"enclosures":[]}
content:
<p>If you follow Web Performance topics closely, perhaps you've heard about <a href="https://wicg.github.io/nav-speculation/speculation-rules.html">Speculation Rules</a>, a new browser API that aims to improve page-to-page navigation speed for multi-page websites (<em>aka normal websites</em>). While not yet a W3C standard, Speculation Rules are already fully supported in the stable version of Chromium-based browsers. That means you can use them today to improve the time it takes users to navigate from particular pages to another, and it'll work for folks who use Chrome, Edge, and others while not impacting the experience in browsers that don't yet support it.</p>
<p>As a fan of technologies that aim to help reduce our reliance on JavaScript for critical front-end infrastructure, I'm excited for the potential that Speculation Rules offers. Page-to-page navigation speed is often touted as a key reason that teams decide to build sites using Single-Page-App JavaScript frameworks, but in order to reap the benefits those frameworks provide, <a href="https://www.zachleat.com/web/single-page-applications/">there's often an upfront performance cost</a>.</p>
<p>I would uh, speculate that Speculation Rules used in combination with <a href="https://developer.chrome.com/docs/web-platform/view-transitions">Cross-Document View Transitions</a> will offer a preferable and elegant approach to mimicking all of that with JavaScript. It may be a minute before we can rely on these things across browsers, but they happen to be built in ways that are harmless to opt-into already, which is great.</p>
<h2>How SR works, in brief</h2>
<p>The way Speculation Rules work is similar in some ways to existing standards like resource hints (you know, <code>rel=preload</code>, <code>prerender</code>, <code>preconnect</code>, etc), though the format is more robust and expressive, and formatted as JSON. The rules can be delivered via a <code>script</code> element with a type of <code>speculationrules</code>, like this example from MDN:</p>
<pre><code>&lt;script type="speculationrules"&gt;
  {
    "prerender": [
      {
        "where": {
          "and": [
            { "href_matches": "/*" },
            { "not": { "href_matches": "/logout" } },
            { "not": { "selector_matches": ".no-prerender" } }
          ]
        }
      }
    ],
    "prefetch": [
      {
        "urls": ["next.html", "next2.html"],
        "requires": ["anonymous-client-ip-when-cross-origin"],
        "referrer_policy": "no-referrer"
      }
    ]
  }
&lt;/script&gt;
</code></pre>
<p>Or perhaps preferably, via an HTTP header that references a JSON file containing something like the example above, like this:</p>
<pre><code>Speculation-Rules: "/rules/prefetch.json"
</code></pre>
<h2>Find Out More!</h2>
<p>I hope to see more experimentation and broader browser support for Speculation Rules in the near future. For more on the topic, I'd recommend checking out <a href="https://developer.mozilla.org/en-US/docs/Web/API/Speculation_Rules_API">MDN's great documentation of the Speculation Rules API</a>.</p>
<p>And also, don't miss Barry Pollard's talk, <em>From fast loading to instant loading</em>, from Google I/O, which I'll embed here below:</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/bSua9vMdrNM?si=PYxU66J33tGNCsA5" title="YouTube video player" frameborder="0" allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" sandbox="allow-scripts allow-same-origin"></iframe>


title: TRAILER: Calypso's Island Energy Wars (1 min)
author: ;Rising Tide Foundation
hash: �g��h�t2e��ҍ
guid:
https://odysee.com/trailer-calypso%27s-island-energy-wars-%281:751c598d1d8facc628f9c22b757aa34474788596

content:
<p><img src="https://thumbnails.lbry.com/J7-7NxjVy0A" width="480" alt="thumbnail" title="TRAILER: Calypso's Island Energy Wars (1 min)"></p>Watch the full episode here<br>https://youtu.be/-pX1Hf3U2tM<br><br>And watch episode 1 here <br>https://youtu.be/eH9qaTawttE<br><br>and episode 2 here<br>https://youtu.be/gv97LL4LUNw<br><br>Support the Rising Tide Foundation's work by any of the following ways:<br><br>1) Sponsor these videos by making a donation on Paypal, Patreon or Wordpress<br>https://risingtidefoundation.net/support-the-work/<br><br>2) Subscribe to Matt and Cynthia's Substacks at<br>matthewehret.substack.com<br>cynthiachung.substack.com<br><br>3) Buy some books!<br>https://canadianpatriot.org/untold-history-of-canada-books/<br>...<br>https://www.youtube.com/watch?v=J7-7NxjVy0A

link:
https://odysee.com/trailer-calypso%27s-island-energy-wars-%281:751c598d1d8facc628f9c22b757aa34474788596

attributes:
{"enclosures":[{"url":"https://player.odycdn.com/api/v3/streams/free/trailer-calypso's-island-energy-wars-(1/751c598d1d8facc628f9c22b757aa34474788596/f37ad4.mp4","type":"video/mp4","length":12867431}]}


hash: ��F6MG��z.8�8$�
attributes: {"enclosures":[]}
guid:
/fr/sencaplus/opinion/alors-que-dautres-pays-bonifient-leur-offre-de-services-le-canada-augmente-son-nombre-de-fonctionnaires-senateur-colin-deacon/

title:
Alors que d’autres pays bonifient leur offre de services, le Canada augmente son nombre de fonctionnaires : sénateur Colin Deacon

link:
https://sencanada.ca//fr/sencaplus/opinion/alors-que-dautres-pays-bonifient-leur-offre-de-services-le-canada-augmente-son-nombre-de-fonctionnaires-senateur-colin-deacon/


hash: ����_y��3+7��
attributes: {"enclosures":[]}
guid:
/fr/salle-de-nouvelles/soci-le-systeme-des-travailleurs-migrants-echoue-a-legard-des-travailleurs-et-des-employeurs-comite-senatorial/

title:
Le système des travailleurs migrants échoue à l’égard des travailleurs et des employeurs : comité sénatorial

link:
https://sencanada.ca//fr/salle-de-nouvelles/soci-le-systeme-des-travailleurs-migrants-echoue-a-legard-des-travailleurs-et-des-employeurs-comite-senatorial/


hash: xFD��� ���{տ%Z�
attributes: {"enclosures":[]}
guid:
/fr/salle-de-nouvelles/pofo-le-gouvernement-doit-conclure-des-accords-pour-ouvrir-de-nouveaux-marches-pour-les-produits-du-phoque-canadiens-rapport-du-senat/

title:
Le gouvernement doit conclure des accords pour ouvrir de nouveaux marchés pour les produits du phoque canadiens :  Rapport du Sénat

link:
https://sencanada.ca//fr/salle-de-nouvelles/pofo-le-gouvernement-doit-conclure-des-accords-pour-ouvrir-de-nouveaux-marches-pour-les-produits-du-phoque-canadiens-rapport-du-senat/


title: The Edward Teller Plan for the Strategic Defense of the Earth with Chuck Stevens
author: ;Rising Tide Foundation
hash: �v�7cաz����dZ_t
guid:
https://odysee.com/the-edward-teller-plan-for-the-strategic:41b8ffed471bc5326abfc9e6f033deb1442ccf59

content:
<p><img src="https://thumbnails.lbry.com/l4a0rwyH2Gw" width="480" alt="thumbnail" title="The Edward Teller Plan for the Strategic Defense of the Earth with Chuck Stevens"></p>As the world careens towards a dangerous precipice of thermonuclear war, the need for creative problems solving has never been higher.<br><br>On Sunday May 12, 2024, the Rising Tide Foundation hosted Chuck Stevens (co-founder of the Fusion Energy Foundation and International Labor Committees) who introduced the hidden history of the Strategic Defense Initiative, the rise of pulsed electron beam weapons, the efforts to break free from the Cold War formulas of Mutual Assured Destruction, Lyndon LaRouche’s Fusion Energy Foundation, and the modern world’s last chance to revive a strategic doctrine to convert next generation fusion-driven technology towards a real defensive strategy.<br><br>Support the Rising Tide Foundation in the following ways:<br><br>1) Make a donation <br>https://risingtidefoundation.net/support-the-work/<br>2) Subscribe to Matt and Cynthia's Substack<br>matthewehret.substack.com<br>cynthiachung.substack.com<br>3) Buy some books!<br>https://canadianpatriot.org/untold-history-of-canada-books/<br><br>and follow us on www.risingtidefoundation.net and t.me/risingtidefoundation<br>...<br>https://www.youtube.com/watch?v=l4a0rwyH2Gw

link:
https://odysee.com/the-edward-teller-plan-for-the-strategic:41b8ffed471bc5326abfc9e6f033deb1442ccf59

attributes:
{"enclosures":[{"url":"https://player.odycdn.com/api/v3/streams/free/the-edward-teller-plan-for-the-strategic/41b8ffed471bc5326abfc9e6f033deb1442ccf59/82373d.mp4","type":"video/mp4","length":435264484}]}


guid: https://odysee.com/christelle:dfe50f4e70cf15172fcb52dc8f9a98fd17d818ef
title: French Journalist Christelle Néant on Ukraine's Decade of War on Donbass Civilians
author: ;Eva K Bartlett
link: https://odysee.com/christelle:dfe50f4e70cf15172fcb52dc8f9a98fd17d818ef
hash: �FOY&݅�?b�p�p
content:
<p><img src="https://thumbs.odycdn.com/d9ea32403a906b4e794b4212e7962f25.webp" width="480" alt="thumbnail" title="French Journalist Christelle Néant on Ukraine's Decade of War on Donbass Civilians"></p>Christelle arrived in Donetsk in 2016 to report on what had already been two bloody years of Ukraine warring on its former population in the Donetsk and Lugansk Peoples Republics. <br><br>She reported from extremely dangerous frontline positions, documenting the Ukrainian shelling and violations of Minsk accords, also giving a human face to the civilians being terrorized by Kiev's forces. <br><br>When the Special Military Operation began in February 2022, Christelle had already seen towns destroyed--and people she knew and had come to love killed--by Ukraine's bombings.  She reported from Mariupol--the city Western corporate media lied about from afar--taking testimonies from civilians who spoke of being prevented from leaving by Ukrainian forces, fired on by Ukrainian forces. <br><br>Néant saw time and again how Ukraine used civilian populations as human shields in cities and towns throughout the Donbass, Russian forces liberating them with painstaking care.<br><br>Her words are incredibly powerful, providing and overview of nearly the entirety of Ukraine's (NATO's) bloody war on the Donbass and on Russia.<br><br>Follow her work at:<br><br>https://t.me/internationalreporters  <br><br>https://www.ir-press.ru/<br><br><br>My related links at this post: <br>https://ingaza.wordpress.com/2024/05/28/french-journalist-christelle-neant-on-ukraines-decade-of-war-on-donbass-civilians/<br>

attributes:
{"enclosures":[{"url":"https://player.odycdn.com/api/v3/streams/free/christelle/dfe50f4e70cf15172fcb52dc8f9a98fd17d818ef/3fe50d.mp4","type":"video/mp4","length":1872182700}]}


guid: https://scottjehl.com/posts/rwd-video/
title: Responsive Video Works Now. These Features Could Make It Work Better.
author: ;Scott Jehl
link: https://scottjehl.com/posts/rwd-video/
hash: m�K]��_�3?
attributes: {"enclosures":[]}
content:
<p>Recently in the <a href="https://webperformance.slack.com/">Web Performance Slack group</a>, there was some discussion around Responsive Video and what else it is lacking, <a href="https://scottjehl.com/posts/using-responsive-video/">now that it works at a baseline level</a>.</p>
<p>I thought I'd write a quick post that lists a few features that are on my wishlist and include relevant links to WhatWG issues where you might lend your feedback!</p>
<ul>
<li><strong>Responsive Poster Images:</strong> Now that we can offer multiple sources for a video, having one poster image source per video is a major shortcoming. For the simplest resolution switching use cases, it would be best for performance to have ways to deliver different image sizes depending on a device's needs, so something like <code>srcset</code> and <code>sizes</code> comes to mind as a potential option, or even just allowing a poster attribute on <code>source</code> elements in addition to the <code>video</code> element. That said, while the majority of responsive image usage today may be for delivering different video resolutions, the media attribute allows us to target much more, such as pixel density, or landscape and portrait formats to serve users based on <s>which decade they were born</s> the orientation of a device's viewport. With all of the possible needs we may have, simply <strong>allowing a child <code>picture</code> element to act as a video element's poster might be ideal</strong>. Here's an issue where that is proposed: <a href="https://github.com/whatwg/html/issues/10378">HTML Video: Allow a child Picture Element to Control the Video Poster Image</a></li>
<li><strong>Post-Pageload Responsiveness</strong> One thing that surprises folks about responsive video is that it's only responsive when the video first loads, unlike the picture element's behavior which reevaluates sources when media changes (on resize for example!). Not only is this unexpected, but it could be problematic when certain video sources are expected to be delivered at different viewport sizes and they aren't (again, the orientation aspect ratio example comes to mind). <a href="https://scottjehl.com/posts/even-responsiver-video/">I recently blogged about a web component that instructs the browser to be more responsive with video</a>, reevaluating media when it changes, and time code syncing so a video can resume playing where it was when a source swaps. I used that component as a proof of concept to attach to this issue: <a href="https://github.com/whatwg/html/issues/10377">Specify That Responsive Video Elements Re-Evaluate Sources on Media Change, Like Picture </a></li>
<li><strong>Lazy Behavior for Autoplay, Poster, and more:</strong> It would be great if the video element had lazy loading. I think it would be even greater if the now-familiar <code>loading="lazy"</code> worked on video elements and controlled a few relevant properties. For example, if <code>loading="lazy"</code> was combined with <code>autoplay</code>, maybe the autoplay feature could only apply when the video enters the viewport? Additionally, with that attribute in place, it'd be great if the poster image loaded lazily too, (admittedly, a child <code>picture</code> element could handle that part too). Also, it'd be nice if <code>loading="lazy"</code> caused a video to delay its preloading behavior, waiting to load video data until the video is actually going to be used. Here's an issue for that: <a href="https://github.com/whatwg/html/issues/10376">Video loading=lazy attribute support</a></li>
<li><strong>Srcset and Sizes for Video:</strong> The <code>video</code> element and its <code>source</code> elements only support the <code>src</code> attribute, unlike <code>img</code> and the <code>picture</code> element's <code>source</code> elements which support <code>srcset</code> and <code>sizes</code>. Support for srcset and sizes attributes would allow developers to deliver video based on conditions the browser knows best. It would offer a resolution based delivery for cases where art direction is less important. <a href="https://github.com/whatwg/html/issues/10379">HTML Video and its Source Elements Should Support SRCSET and SIZES</a></li>
</ul>
<p>I'd love to see some community feedback on any or all of these. Thanks for reading!</p>


guid: https://odysee.com/dmitry-int:b402ece4714348f25d3e6a357d82f5fe497c3757
author: ;Eva K Bartlett
link: https://odysee.com/dmitry-int:b402ece4714348f25d3e6a357d82f5fe497c3757
hash: ����ŗ��7ޛ�=D
title:
Donbass War Correspondent &amp; Journalist, Dmitry Astrakhan, on 10 Years of Ukraine's Brutal Terrorism &amp; Slaughter of Donbass Civilians

content:
<p><img src="https://thumbs.odycdn.com/4206080c7ef70cd3cefabe1a95e5e15e.webp" width="480" alt="thumbnail" title="Donbass War Correspondent &amp; Journalist, Dmitry Astrakhan, on 10 Years of Ukraine's Brutal Terrorism &amp; Slaughter of Donbass Civilians"></p>In Donetsk's Kievsky district on May 27, I interviewed Dmitry Astrakhan, a war correspondent and journalist who has covered Ukraine's brutal war on the civilians of the Donbass since its inception one decade ago.<br><br>He details Ukraine's war crimes, attacking Donbass civilians since 2014, along with the complicity of the OSCE in enabling these atrocities. He covered the liberation of  Mariupol, and countless other Donbass regions, and saw Ukrainian forces using civilians as human shields, a well-established fact by now, keeping civilians on one or two floors, and putting Ukrainian forces above them who then fired on Russian forces. <br><br>“You could see white flags on one level, and machine gun firing from another.”<br><br>He took testimonies regarding Ukrainian snipers shooting at civilians, Ukrainian forces exploding buildings knowing there were civilians inside, in Artyomovsk (Bakhmut).<br><br>Dmitry spoke of too many Ukrainian war crimes to detail here. Instead, listen to the first-hand experiences of this courageous Donbass journalist. <br><br>Follow Dmitry at:<br><br>https://t.me/astrahandm<br>https://iz.ru/author/dmitrii-astrakhan-0 <br><br><br>My related links:<br>https://ingaza.wordpress.com/2024/06/01/donbass-war-correspondent-journalist-dmitry-astrakhan-on-10-years-of-ukraines-brutal-terrorism-slaughter-of-donbass-civilians/

attributes:
{"enclosures":[{"url":"https://player.odycdn.com/api/v3/streams/free/dmitry-int/b402ece4714348f25d3e6a357d82f5fe497c3757/4dc561.mp4","type":"video/mp4","length":2033650777}]}


guid: /fr/salle-de-nouvelles/agfo-la-sante-des-sols-canadiens-en-peril-rapport-du-senat/
title: La santé des sols canadiens en péril : Rapport du Sénat
hash: ����u�^yP ���A
attributes: {"enclosures":[]}
link:
https://sencanada.ca//fr/salle-de-nouvelles/agfo-la-sante-des-sols-canadiens-en-peril-rapport-du-senat/


title: Le Comité sénatorial de l’audit et de la surveillance publie son rapport annuel
hash: J��·���Z`���_
attributes: {"enclosures":[]}
guid:
/fr/salle-de-nouvelles/aovs-le-comite-senatorial-de-laudit-et-de-la-surveillance-publie-son-rapport-annuel-2024/

link:
https://sencanada.ca//fr/salle-de-nouvelles/aovs-le-comite-senatorial-de-laudit-et-de-la-surveillance-publie-son-rapport-annuel-2024/


title: « Je suis reconnaissant envers mon pays d’adoption » : Le sénateur Oh prend sa retraite
hash: ��'�"]��q��
attributes: {"enclosures":[]}
guid:
/fr/sencaplus/personnalites/je-suis-reconnaissant-envers-mon-pays-dadoption-le-senateur-oh-prend-sa-retraite/

link:
https://sencanada.ca//fr/sencaplus/personnalites/je-suis-reconnaissant-envers-mon-pays-dadoption-le-senateur-oh-prend-sa-retraite/


hash: ��f[�� �%G��$��
attributes: {"enclosures":[]}
guid:
/fr/sencaplus/opinion/les-veritables-implications-du-projet-de-loi-c-50-pour-lindustrie-energetique-de-t-n-l-ce-nest-pas-beau-a-voir-senateur-wells/

title:
Les véritables implications du projet de loi C-50 pour l’industrie énergétique de T.-N.-L. – ce n’est pas beau à voir : sénateur Wells

link:
https://sencanada.ca//fr/sencaplus/opinion/les-veritables-implications-du-projet-de-loi-c-50-pour-lindustrie-energetique-de-t-n-l-ce-nest-pas-beau-a-voir-senateur-wells/


guid: /fr/sencaplus/opinion/un-partenariat-canadien-avec-lafrique-est-attendu-senatrice-gerba/
title: Un partenariat canadien avec l’Afrique est attendu : sénatrice Gerba
hash: ��u����P�ǬF�
attributes: {"enclosures":[]}
link:
https://sencanada.ca//fr/sencaplus/opinion/un-partenariat-canadien-avec-lafrique-est-attendu-senatrice-gerba/


guid: https://scottjehl.com/posts/squarespace/
title: Joining Squarespace
author: ;Scott Jehl
link: https://scottjehl.com/posts/squarespace/
hash: >� m� � <�?0� ��
attributes: {"enclosures":[]}
content:
<p><strong>Big News! I'm excited to share that I'll soon be joining <a href="https://www.squarespace.com/">Squarespace</a> as a software engineer on the web performance team!</strong></p>
<p>As you may already know, Squarespace is a website design, development, management, and delivery platform that has been used to create millions of websites for online businesses, artists, bloggers, restaurants, bands, and more. In this role, I know there will be loads of opportunities for me to learn and grow, not just from the great folks on the perf team with whom I'll be working directly, but also on the complementary accessibility team, and from the many <a href="https://engineering.squarespace.com/blog/2020/the-nuts-and-bolts-with-tanya-reilly">incredibly talented folks</a> in the broader organization.</p>
<figure>
    <img alt="A photograph from of the Squarespace rooftop terrace with umbrella tables and several employees sitting and chatting, and in the background you can see lower Manhattan" src="https://scottjehl.com/assets/ssroof.jpeg">
  <figcaption>Squarespace's rooftop terrace in the West Village. <a href="https://www.squarespace.com/about/company">Source: Squarespace</a></figcaption>
</figure>
<p>The potential for impact in this position is inspiring: the performance team's work quite directly improves the experience of users and businesses at a truly <em>massive</em> scale. I've long thought of Squarespace as a company that visibly prioritizes good design, and <a href="https://www.squarespace.com/about/company">their values</a> and <a href="https://www.squarespace.com/showcase">showcase</a> certainly attest to that. Tools that offer a high level of creative and design flexibility to their users can make for some of the toughest and most interesting performance challenges. All the while, the ways we can performantly and accessibly deliver engaging multimedia content on the web have been <a href="https://scottjehl.com/posts/speculation-rules/">evolving</a> and <a href="https://scottjehl.com/posts/using-responsive-video/">improving</a> rapidly.</p>
<p>In joining this team, I'm excited to put into practice the many things I've learned over the years as an independent web designer and developer, <a href="https://www.catchpoint.com/blog/will-serving-real-html-content-make-a-website-faster-lets-experiment">tools developer</a>, <a href="https://scottjehl.com/posts/responsive-video/">web standards contributor</a>, and big fan of the web.</p>
<p>Well, that's it for now–<a href="https://scottjehl.com/learn/webcomponentsdemystified/">I've got an online course to finish</a>!</p>
<p>Thanks for reading. Onward!</p>


title: Technologie de pointe : Nouveau système de climatisation et de chauffage vert à l’édifice du Centre
hash: Y�y1�}��������
attributes: {"enclosures":[]}
guid:
/fr/sencaplus/comment-pourquoi/technologie-de-pointe-nouveau-systeme-de-climatisation-et-de-chauffage-vert-a-ledifice-du-centre/

link:
https://sencanada.ca//fr/sencaplus/comment-pourquoi/technologie-de-pointe-nouveau-systeme-de-climatisation-et-de-chauffage-vert-a-ledifice-du-centre/


guid: /fr/sencaplus/opinion/cessons-de-traiter-la-terre-comme-de-la-salete-senatrice-simons/
title: Cessons de traiter la terre comme de la saleté : sénatrice Simons
hash: �,�TU��+�r�+�_�
attributes: {"enclosures":[]}
link:
https://sencanada.ca//fr/sencaplus/opinion/cessons-de-traiter-la-terre-comme-de-la-salete-senatrice-simons/


guid: /fr/sencaplus/personnalites/rencontre-avec-la-presidente-du-senat-raymonde-gagne/
title: Rencontre avec la Présidente du Sénat Raymonde Gagné
hash: ��Cɾ���G�H.�b
attributes: {"enclosures":[]}
link:
https://sencanada.ca//fr/sencaplus/personnalites/rencontre-avec-la-presidente-du-senat-raymonde-gagne/


