<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Cleared</title><description>A monthly newsletter on HTML and CSS in the browsers: the features that just became safe, the fallbacks you can finally remove, and a verdict on each one. Free.</description><link>https://cleared.page/</link><language>en</language><atom:link href="https://cleared.page/rss.xml" rel="self" type="application/rss+xml"/><item><title>Delete your text-stroke hack</title><link>https://cleared.page/2026-09/</link><guid isPermaLink="true">https://cleared.page/2026-09/</guid><description>What became safe to use, and to delete, in September 2026.</description><pubDate>Mon, 05 Oct 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Safari 27 shipped on the 14th and made more features newly available in one day than the rest of the month did. Most of them are JavaScript features though. On the CSS front, it’s a mixed bag: &lt;code&gt;light-dark()&lt;/code&gt; image support is ready, but scroll anchoring (which Chrome and Firefox have done for years) is not, and neither is the new &lt;code&gt;alpha()&lt;/code&gt; function. Firefox completed &lt;code&gt;progress()&lt;/code&gt; but Chrome holds it back. The deletion this month is &lt;code&gt;paint-order&lt;/code&gt;, which retires the duplicate text hack to draw a stroke behind a headline.&lt;/p&gt;
&lt;h2&gt;01. &lt;code&gt;paint-order&lt;/code&gt;&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Verdict: Cleared&lt;/strong&gt; · Safe everywhere as of September 22, 2026&lt;/p&gt;&lt;p&gt;Text fill is painted first, then the stroke, on top. A stroke is centered on the outline of the letter, so half of it covers the fill: a 6px stroke is 3px into the text and 3px outside. Using &lt;code&gt;paint-order: stroke&lt;/code&gt; paints the stroke first and the fill over it. The fill covers the inner 3px, so the letter keeps its full shape and what you see is a 3px outline. The stroke itself comes from &lt;code&gt;-webkit-text-stroke&lt;/code&gt;. (The prefix is part of the property’s name in every browser. No unprefixed form exists.) SVG has had the property for years, and Chrome 123 was the last browser to extend it to HTML text, in March 2024, 30 months before this September.&lt;/p&gt;
&lt;p class=&quot;issueItem_delete&quot;&gt;&lt;strong&gt;Delete:&lt;/strong&gt; the second copy of the text that draws the stroke behind the real one, usually a pseudo-element.&lt;/p&gt;
&lt;figure class=&quot;codeBlock&quot;&gt;&lt;figcaption class=&quot;codeBlock_caption&quot;&gt;&lt;span&gt;CSS · before &lt;svg width=&quot;12&quot; height=&quot;12&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; aria-hidden=&quot;true&quot; class=&quot;arrow arrow-lead&quot;&gt;&lt;path d=&quot;M5 12h14&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m12 5 7 7-7 7&quot;&gt;&lt;/path&gt;&lt;/svg&gt; after&lt;/span&gt;&lt;button type=&quot;button&quot; class=&quot;codeBlock_copy&quot; data-copy=&quot;&quot; aria-label=&quot;Copy code sample 1&quot; hidden&gt;Copy&lt;/button&gt;&lt;span class=&quot;a11y-srOnly&quot; role=&quot;status&quot; data-copy-status=&quot;&quot;&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre class=&quot;codeBlock_pre&quot; style=&quot;background-color:var(--code-bg);color:var(--ink)&quot; tabindex=&quot;0&quot; role=&quot;region&quot; aria-label=&quot;Code sample 1, before and after&quot;&gt;&lt;code&gt;&lt;span class=&quot;codeBlock_line-removed&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;−&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;/* the text twice, with the stroke on the copy behind */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;codeBlock_line-removed&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;−&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-weight:bold&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;title&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; position&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt; relative&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; z-index&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;codeBlock_line-removed&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;−&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-weight:bold&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;title&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-weight:bold&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;before&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;codeBlock_line-removed&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;−&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;  content&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; attr&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt;data-text&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;codeBlock_line-removed&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;−&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;  position&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt; absolute&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; inset&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; z-index&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt; -1&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;codeBlock_line-removed&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;−&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt;  -webkit-text-stroke&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt; 6&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt; white&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;codeBlock_line-removed&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;−&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;codeBlock_line-added&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-weight:bold&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;title&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt; -webkit-text-stroke&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt; 6&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt; white&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; paint-order&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt; stroke&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt; }&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
&lt;p&gt;Failure is graceful: a browser without the property paints the stroke on top, and the outline looks thinner. Firefox’s summary score on this feature is low, but none of what it fails is relevant to stroked HTML text. The stroke sits behind the fill in Firefox too.&lt;/p&gt;
&lt;h2&gt;02. Scroll anchoring&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Verdict: Hold&lt;/strong&gt; · Not yet&lt;/p&gt;&lt;p&gt;When something above the part of the page you are reading changes size, an image loading for instance, the content under your eyes jumps. Scroll anchoring is how browsers manage this issue: they pick an element in view as the anchor, and when content above it grows or shrinks, they move the scroll position by the same amount. Chrome has done this since 2017 and Firefox since 2019. Safari 27 is the last to join, and &lt;code&gt;overflow-anchor: none&lt;/code&gt; switches it off.&lt;/p&gt;
&lt;p&gt;Baseline’s score for Safari is 1 but it measures the wrong thing: the tests that check the property’s syntax and the opt-out pass, but the tests of the anchoring itself are where Safari 27 falls short. When text above rewraps, Safari does not adjust, and inside a scrolling element rather than the page, it misplaces the anchor when content above it shrinks. So keep the code that restores the scroll position after you insert content above the fold. And if you have a custom scroller in your code, put &lt;code&gt;overflow-anchor: none&lt;/code&gt; on it so the browser leaves it alone. Chrome and Firefox already needed that. Safari 27 onward does too.&lt;/p&gt;
&lt;figure class=&quot;codeBlock&quot;&gt;&lt;figcaption class=&quot;codeBlock_caption&quot;&gt;&lt;span&gt;CSS&lt;/span&gt;&lt;button type=&quot;button&quot; class=&quot;codeBlock_copy&quot; data-copy=&quot;&quot; aria-label=&quot;Copy code sample 1&quot; hidden&gt;Copy&lt;/button&gt;&lt;span class=&quot;a11y-srOnly&quot; role=&quot;status&quot; data-copy-status=&quot;&quot;&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre class=&quot;codeBlock_pre&quot; style=&quot;background-color:var(--code-bg);color:var(--ink)&quot; tabindex=&quot;0&quot; role=&quot;region&quot; aria-label=&quot;Code sample 1&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;/* Works in Safari 27: a block above the viewport grows.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;   Fails in Safari 27: the text above rewraps, or a scrolling&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;   div loses content above the anchor. */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;/* Where you manage a scroller&apos;s position yourself */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--muted);font-weight:bold&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; overflow-anchor&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt; none&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt; }&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
&lt;h2&gt;03. &lt;code&gt;progress()&lt;/code&gt;&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Verdict: Hold&lt;/strong&gt; · Not yet&lt;/p&gt;&lt;p&gt;&lt;code&gt;progress(value, start, end)&lt;/code&gt; returns how far a value sits between two others, as a plain number from 0 to 1. It replaces the ratio you compute by hand in &lt;code&gt;calc()&lt;/code&gt;, with one difference: the result is clamped between 0 and 1 unless you add the &lt;code&gt;no-clamp&lt;/code&gt; keyword.&lt;/p&gt;
&lt;p&gt;Firefox 155 completed support on September 1. Chrome is the blocker. Version 154 accepts the plain form and little else: it rejects &lt;code&gt;no-clamp&lt;/code&gt;, which Firefox 155 and Safari 27 both accept; it rejects a percentage mixed with lengths, &lt;code&gt;progress(50%, 0px, 100px)&lt;/code&gt;; and when &lt;code&gt;start&lt;/code&gt; equals &lt;code&gt;end&lt;/code&gt; and the value sits above them, it returns &lt;code&gt;1&lt;/code&gt; where the spec says &lt;code&gt;0&lt;/code&gt;.&lt;/p&gt;
&lt;figure class=&quot;codeBlock&quot;&gt;&lt;figcaption class=&quot;codeBlock_caption&quot;&gt;&lt;span&gt;CSS&lt;/span&gt;&lt;button type=&quot;button&quot; class=&quot;codeBlock_copy&quot; data-copy=&quot;&quot; aria-label=&quot;Copy code sample 1&quot; hidden&gt;Copy&lt;/button&gt;&lt;span class=&quot;a11y-srOnly&quot; role=&quot;status&quot; data-copy-status=&quot;&quot;&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre class=&quot;codeBlock_pre&quot; style=&quot;background-color:var(--code-bg);color:var(--ink)&quot; tabindex=&quot;0&quot; role=&quot;region&quot; aria-label=&quot;Code sample 1&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;/* The ratio by hand. It can go below 0 or above 1 */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;opacity: calc((var(--value&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;- var(--min&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt;)) / (&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;var(--max&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;- var(--min&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt;)));&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;/* The same ratio, clamped to 0 to 1 unless you say otherwise */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;opacity: progress(var(--value&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt;), &lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;var(--min&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt;), &lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;var(--max&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt;));&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;/* Chrome 154 ignores both of these */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;opacity: progress(no-clamp 150&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-weight:bold&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; 0&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-weight:bold&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; 100&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;margin-left: calc(progress(50%&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-weight:bold&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; 0px&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-weight:bold&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; 100px&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;* 10px&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
&lt;h2&gt;04. &lt;code&gt;light-dark()&lt;/code&gt; image values&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Verdict: Cleared&lt;/strong&gt; · New this month, September 14, 2026&lt;/p&gt;&lt;p&gt;&lt;code&gt;light-dark()&lt;/code&gt; takes two values and uses the first in a light color scheme and the second in a dark one. Until now it took only colors. It now works with images too. Firefox has had this since April and Chrome since June. Safari 27 completed the set.&lt;/p&gt;
&lt;p class=&quot;issueItem_delete&quot;&gt;&lt;strong&gt;Delete:&lt;/strong&gt; the per-theme override rule that swaps an image.&lt;/p&gt;
&lt;figure class=&quot;codeBlock&quot;&gt;&lt;figcaption class=&quot;codeBlock_caption&quot;&gt;&lt;span&gt;CSS · before &lt;svg width=&quot;12&quot; height=&quot;12&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; aria-hidden=&quot;true&quot; class=&quot;arrow arrow-lead&quot;&gt;&lt;path d=&quot;M5 12h14&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m12 5 7 7-7 7&quot;&gt;&lt;/path&gt;&lt;/svg&gt; after&lt;/span&gt;&lt;button type=&quot;button&quot; class=&quot;codeBlock_copy&quot; data-copy=&quot;&quot; aria-label=&quot;Copy code sample 1&quot; hidden&gt;Copy&lt;/button&gt;&lt;span class=&quot;a11y-srOnly&quot; role=&quot;status&quot; data-copy-status=&quot;&quot;&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre class=&quot;codeBlock_pre&quot; style=&quot;background-color:var(--code-bg);color:var(--ink)&quot; tabindex=&quot;0&quot; role=&quot;region&quot; aria-label=&quot;Code sample 1, before and after&quot;&gt;&lt;code&gt;&lt;span class=&quot;codeBlock_line-removed&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;−&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;/* one rule per theme */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;codeBlock_line-removed&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;−&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-weight:bold&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;logo&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; background-image&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; url&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt;light.svg&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;);&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;codeBlock_line-removed&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;−&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-weight:bold&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;dark &lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-weight:bold&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;logo&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; background-image&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; url&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt;dark.svg&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;);&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;codeBlock_line-added&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;/* one declaration. (The first line is the fallback) */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;codeBlock_line-added&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-weight:bold&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;logo&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;codeBlock_line-added&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;  background-image&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; url&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt;light.svg&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;codeBlock_line-added&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;  background-image&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt; light-dark(&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;url&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt;light.svg&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;),&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; url&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt;dark.svg&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;codeBlock_line-added&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
&lt;p&gt;Every current browser passes the tests. Make sure you keep the fallback for earlier browsers.&lt;/p&gt;
&lt;h2&gt;05. &lt;code&gt;alpha()&lt;/code&gt;&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Verdict: Hold&lt;/strong&gt; · Not yet&lt;/p&gt;&lt;p&gt;&lt;code&gt;alpha(from &amp;#x3C;color&gt; / &amp;#x3C;alpha&gt;)&lt;/code&gt; takes a color and returns it with a different opacity and nothing else changed. It is the short form of relative color syntax: &lt;code&gt;alpha(from var(--accent) / 50%)&lt;/code&gt; instead of &lt;code&gt;rgb(from var(--accent) r g b / 50%)&lt;/code&gt;. Chrome shipped it in August, Firefox on September 1, and Safari 27 completed the set on September 14.&lt;/p&gt;
&lt;p&gt;All three implementations are a few weeks old, and past the plain case they differ. For &lt;code&gt;alpha(from red / 50%)&lt;/code&gt; every browser produces the same color. Beyond that, Safari and Chrome fail a good share of the tests, mostly on how the result reads back from JavaScript, and Safari turns an alpha of &lt;code&gt;none&lt;/code&gt; into zero. And the draft is still moving. In the current editor’s draft the alpha part is optional, so &lt;code&gt;alpha(from red)&lt;/code&gt; is valid, which Chrome and Safari accept and Firefox and the tests reject. Wait a release or two. The long form does the same job today.&lt;/p&gt;
&lt;figure class=&quot;codeBlock&quot;&gt;&lt;figcaption class=&quot;codeBlock_caption&quot;&gt;&lt;span&gt;CSS&lt;/span&gt;&lt;button type=&quot;button&quot; class=&quot;codeBlock_copy&quot; data-copy=&quot;&quot; aria-label=&quot;Copy code sample 1&quot; hidden&gt;Copy&lt;/button&gt;&lt;span class=&quot;a11y-srOnly&quot; role=&quot;status&quot; data-copy-status=&quot;&quot;&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre class=&quot;codeBlock_pre&quot; style=&quot;background-color:var(--code-bg);color:var(--ink)&quot; tabindex=&quot;0&quot; role=&quot;region&quot; aria-label=&quot;Code sample 1&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;/* The long form you may already write */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;color: rgb(from var(--accent&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;r g b&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt; / 50%);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;/* The short form. The same color in every current run */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;color: alpha(from var(--accent&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt;) / 50%);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;/* Safari 27 makes this fully transparent */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;color: alpha(from var(--accent&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt;) / &lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;none&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
&lt;p&gt;That was September: one deletion, one declaration to start using, and three features that the label calls ready and the tests do not.&lt;/p&gt;</content:encoded><category>September 2026</category></item><item><title>Delete your declarative shadow DOM polyfill</title><link>https://cleared.page/2026-08/</link><guid isPermaLink="true">https://cleared.page/2026-08/</guid><description>What became safe to use, and to delete, in August 2026.</description><pubDate>Mon, 14 Sep 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Two features became newly available in August, both CSS, and both are Holds. One because Safari and Firefox are behind Chrome on it. The other because the label says every browser has shipped it, and Chrome has not. One feature finished its 30 months of support, Declarative shadow DOM, and it retires a script you may still be loading on every page.&lt;/p&gt;
&lt;h2&gt;01. Declarative shadow DOM&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Verdict: Cleared&lt;/strong&gt; · Safe everywhere as of August 20, 2026&lt;/p&gt;&lt;p&gt;A web component keeps its internal markup and styles in a shadow root, and until recently the only way to create one was from JavaScript, by calling &lt;code&gt;attachShadow()&lt;/code&gt;. Declarative shadow DOM lets you write the shadow root in the HTML instead. Put a &lt;code&gt;&amp;#x3C;template shadowrootmode=&quot;open&quot;&gt;&lt;/code&gt; inside an element, and the browser turns it into that element’s shadow root while it parses the page. A server can send a component fully rendered, and it looks right before any script has loaded.&lt;/p&gt;
&lt;p class=&quot;issueItem_delete&quot;&gt;&lt;strong&gt;Delete:&lt;/strong&gt; the script that finds every &lt;code&gt;&amp;#x3C;template shadowrootmode&gt;&lt;/code&gt; and attaches its shadow root by hand. Keep it only for components that are HTML only, with no JavaScript to render them.&lt;/p&gt;
&lt;figure class=&quot;codeBlock&quot;&gt;&lt;figcaption class=&quot;codeBlock_caption&quot;&gt;&lt;span&gt;JS · before &lt;svg width=&quot;12&quot; height=&quot;12&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; aria-hidden=&quot;true&quot; class=&quot;arrow arrow-lead&quot;&gt;&lt;path d=&quot;M5 12h14&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m12 5 7 7-7 7&quot;&gt;&lt;/path&gt;&lt;/svg&gt; after&lt;/span&gt;&lt;button type=&quot;button&quot; class=&quot;codeBlock_copy&quot; data-copy=&quot;&quot; aria-label=&quot;Copy code sample 1&quot; hidden&gt;Copy&lt;/button&gt;&lt;span class=&quot;a11y-srOnly&quot; role=&quot;status&quot; data-copy-status=&quot;&quot;&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre class=&quot;codeBlock_pre&quot; style=&quot;background-color:var(--code-bg);color:var(--ink)&quot; tabindex=&quot;0&quot; role=&quot;region&quot; aria-label=&quot;Code sample 1, before and after&quot;&gt;&lt;code&gt;&lt;span class=&quot;codeBlock_line-removed&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;−&lt;/span&gt;&lt;span&gt;/* the polyfill, on every page */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;codeBlock_line-removed&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;−&lt;/span&gt;&lt;span&gt;document.querySelectorAll(&apos;template[shadowrootmode]&apos;).forEach((t) =&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;codeBlock_line-removed&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;−&lt;/span&gt;&lt;span&gt;  const mode = t.getAttribute(&apos;shadowrootmode&apos;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;codeBlock_line-removed&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;−&lt;/span&gt;&lt;span&gt;  t.parentNode.attachShadow({ mode }).append(t.content);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;codeBlock_line-removed&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;−&lt;/span&gt;&lt;span&gt;  t.remove();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;codeBlock_line-removed&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;−&lt;/span&gt;&lt;span&gt;});&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;codeBlock_line-added&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;+&lt;/span&gt;&lt;span&gt;/* the parser already did this */&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
&lt;p&gt;One more thing to check before deleting. The browser only creates these shadow roots when it parses HTML as the page loads. If your JavaScript builds the same markup later and inserts it with &lt;code&gt;innerHTML&lt;/code&gt;, nothing happens: the &lt;code&gt;&amp;#x3C;template&gt;&lt;/code&gt; stays a plain template and no shadow root is created. This is deliberate. The spec disables declarative shadow roots for &lt;code&gt;innerHTML&lt;/code&gt;, and the test suite confirms it for every HTML element. So check your code for any &lt;code&gt;innerHTML&lt;/code&gt; that inserts markup containing &lt;code&gt;shadowrootmode&lt;/code&gt;. For those, either switch to &lt;code&gt;setHTMLUnsafe()&lt;/code&gt;, a newer method that does create the shadow roots, or keep the polyfill for that one call.&lt;/p&gt;
&lt;p&gt;Every test that matters for this deletion passes in all five current stable runs. The few misses are a newer attribute Safari has not shipped and two &lt;code&gt;document.open()&lt;/code&gt; edge cases.&lt;/p&gt;
&lt;p&gt;HTML-only components are the one case to keep the polyfill for because they break completely in browsers without this feature. The &lt;code&gt;&amp;#x3C;template&gt;&lt;/code&gt; is ignored and the component’s internal markup never appears.&lt;/p&gt;
&lt;h2&gt;02. &lt;code&gt;sibling-index()&lt;/code&gt; and &lt;code&gt;sibling-count()&lt;/code&gt;&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Verdict: Hold&lt;/strong&gt; · Not yet&lt;/p&gt;&lt;p&gt;Two new CSS functions. &lt;code&gt;sibling-index()&lt;/code&gt; gives an element’s position among its siblings, starting at 1, and &lt;code&gt;sibling-count()&lt;/code&gt; gives how many siblings there are. Both return plain numbers you can use in &lt;code&gt;calc()&lt;/code&gt;. If all you want is a staggered animation on a list that does not change, this works today. Anything beyond that, wait.&lt;/p&gt;
&lt;figure class=&quot;codeBlock&quot;&gt;&lt;figcaption class=&quot;codeBlock_caption&quot;&gt;&lt;span&gt;CSS&lt;/span&gt;&lt;button type=&quot;button&quot; class=&quot;codeBlock_copy&quot; data-copy=&quot;&quot; aria-label=&quot;Copy code sample 1&quot; hidden&gt;Copy&lt;/button&gt;&lt;span class=&quot;a11y-srOnly&quot; role=&quot;status&quot; data-copy-status=&quot;&quot;&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre class=&quot;codeBlock_pre&quot; style=&quot;background-color:var(--code-bg);color:var(--ink)&quot; tabindex=&quot;0&quot; role=&quot;region&quot; aria-label=&quot;Code sample 1&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;/* Works in every current run */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;li&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; animation-delay&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; calc&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt;sibling-index(&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt; * 80&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;ms&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;/* Fails in Safari 26.6: the index inside a gradient */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;li&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; background&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; linear-gradient&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt;blue &lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;calc&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt;10&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;px&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; *&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt; sibling-index(&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;)),&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt; yellow)&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;/* Fails in Firefox 155 and Safari 26.6: the index inside @keyframes&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;   stops updating when a sibling is removed */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--muted);font-weight:bold&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;keyframes&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt; rise &lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt; from &lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; z-index&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt; sibling-index()&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt; }&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt; }&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
&lt;p&gt;Firefox 154 shipped the last piece on August 18, and the simple uses work everywhere: the index or the count inside &lt;code&gt;calc()&lt;/code&gt;, on the element itself, on &lt;code&gt;::before&lt;/code&gt;, on the root. The trouble starts when the index is read somewhere other than a plain declaration. Safari 26.6 passes only three of the suite’s 22 tests whole. It fails when the index is used in a gradient, in a container query, or inside a shadow tree. Both Safari 26.6 and Firefox 155 fail when the index is used inside &lt;code&gt;@keyframes&lt;/code&gt; and the list then changes: remove an element before the animated one, and the animation keeps the old position number instead of updating. Outside keyframes, the same removal updates correctly in every browser.&lt;/p&gt;
&lt;h2&gt;03. Media element pseudo-classes&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Verdict: Hold&lt;/strong&gt; · Not yet&lt;/p&gt;&lt;p&gt;Seven CSS pseudo-classes that match a &lt;code&gt;&amp;#x3C;video&gt;&lt;/code&gt; or &lt;code&gt;&amp;#x3C;audio&gt;&lt;/code&gt; element by what it is doing: &lt;code&gt;:playing&lt;/code&gt;, &lt;code&gt;:paused&lt;/code&gt;, &lt;code&gt;:seeking&lt;/code&gt;, &lt;code&gt;:buffering&lt;/code&gt;, &lt;code&gt;:stalled&lt;/code&gt;, &lt;code&gt;:muted&lt;/code&gt; and &lt;code&gt;:volume-locked&lt;/code&gt;. If you have built a custom player, you probably listen for the &lt;code&gt;play&lt;/code&gt; and &lt;code&gt;pause&lt;/code&gt; events and toggle a class like &lt;code&gt;is-playing&lt;/code&gt; so the CSS can swap the button. These pseudo-classes replace the need for that listener, but keep it for now. Chrome has not shipped this feature, whatever the label says.&lt;/p&gt;
&lt;figure class=&quot;codeBlock&quot;&gt;&lt;figcaption class=&quot;codeBlock_caption&quot;&gt;&lt;span&gt;CSS&lt;/span&gt;&lt;button type=&quot;button&quot; class=&quot;codeBlock_copy&quot; data-copy=&quot;&quot; aria-label=&quot;Copy code sample 1&quot; hidden&gt;Copy&lt;/button&gt;&lt;span class=&quot;a11y-srOnly&quot; role=&quot;status&quot; data-copy-status=&quot;&quot;&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre class=&quot;codeBlock_pre&quot; style=&quot;background-color:var(--code-bg);color:var(--ink)&quot; tabindex=&quot;0&quot; role=&quot;region&quot; aria-label=&quot;Code sample 1&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;/* The deletion waiting here */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--muted);font-weight:bold&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;player&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-weight:bold&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;is-playing &lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-weight:bold&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;play-button&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; display&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt; none&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;/* Blocked by Chrome, for now */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--muted);font-weight:bold&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;player&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-weight:bold&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;has&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-weight:bold&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;video:playing&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-weight:bold&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-weight:bold&quot;&gt; .&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;play-button&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; display&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt; none&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt; }&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
&lt;p&gt;Baseline says Chrome 152 shipped these on August 25, which is what made the feature newly available on August 28. That date comes from a single entry in the browser compatibility data, and it is wrong. Chrome’s own status tracker lists the feature as proposed, with a shipping target of Chrome 155. Every stable Chrome run since 152 fails all six checks in the test suite: a video whose outline should turn green when it plays never changes, and &lt;code&gt;:playing&lt;/code&gt;, &lt;code&gt;:seeking&lt;/code&gt; and &lt;code&gt;:muted&lt;/code&gt; never match through &lt;code&gt;:has()&lt;/code&gt;. Edge fails the same way. Firefox 155 and Safari 26.6 pass everything, and so does Chrome’s pre-release channel, so the implementation exists. It is just not in the browser most of your visitors are running.&lt;/p&gt;
&lt;p&gt;That was August: one polyfill to delete, one new feature to wait on, and one feature that Baseline says is ready but Chrome has not shipped.&lt;/p&gt;</content:encoded><category>August 2026</category></item><item><title>AVIF cleared: one fallback can go</title><link>https://cleared.page/2026-07/</link><guid isPermaLink="true">https://cleared.page/2026-07/</guid><description>What became safe to use, and to delete, in July 2026.</description><pubDate>Mon, 03 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;July was thin. One feature arrived in the whole month, a JavaScript locale API outside the CSS and HTML this publication covers, and three crossed 30 months, all that a quiet January 2024 had set in motion. Two of the three ask nothing of you. The third is AVIF, and it retires one of your image fallbacks.&lt;/p&gt;
&lt;h2&gt;01. AVIF&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Verdict: Cleared&lt;/strong&gt; · Safe everywhere as of July 25, 2026&lt;/p&gt;&lt;p&gt;The AV1 image format. Chrome has decoded it since 2020; Edge completed the core set on January 25, 2024, and the 30-month clock ran out on July 25. If your images ship as a three-format stack, AVIF on top, WebP in the middle, JPEG at the floor, the middle is now dead weight.&lt;/p&gt;
&lt;p class=&quot;issueItem_delete&quot;&gt;&lt;strong&gt;Delete:&lt;/strong&gt; the WebP sources in your &lt;code&gt;&amp;#x3C;picture&gt;&lt;/code&gt; elements, and the encode step that produces them.&lt;/p&gt;
&lt;figure class=&quot;codeBlock&quot;&gt;&lt;figcaption class=&quot;codeBlock_caption&quot;&gt;&lt;span&gt;HTML · before &lt;svg width=&quot;12&quot; height=&quot;12&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; aria-hidden=&quot;true&quot; class=&quot;arrow arrow-lead&quot;&gt;&lt;path d=&quot;M5 12h14&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m12 5 7 7-7 7&quot;&gt;&lt;/path&gt;&lt;/svg&gt; after&lt;/span&gt;&lt;button type=&quot;button&quot; class=&quot;codeBlock_copy&quot; data-copy=&quot;&quot; aria-label=&quot;Copy code sample 1&quot; hidden&gt;Copy&lt;/button&gt;&lt;span class=&quot;a11y-srOnly&quot; role=&quot;status&quot; data-copy-status=&quot;&quot;&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre class=&quot;codeBlock_pre&quot; style=&quot;background-color:var(--code-bg);color:var(--ink)&quot; tabindex=&quot;0&quot; role=&quot;region&quot; aria-label=&quot;Code sample 1, before and after&quot;&gt;&lt;code&gt;&lt;span class=&quot;codeBlock_line-removed&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;−&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;source&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; srcset&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-style:italic&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-style:italic&quot;&gt;chart.avif&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-style:italic&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-style:italic&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-style:italic&quot;&gt;image/avif&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-style:italic&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;codeBlock_line-removed&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;−&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;source&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; srcset&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-style:italic&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-style:italic&quot;&gt;chart.webp&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-style:italic&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-style:italic&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-style:italic&quot;&gt;image/webp&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-style:italic&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;codeBlock_line-removed&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;−&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;img&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; src&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-style:italic&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-style:italic&quot;&gt;chart.jpg&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-style:italic&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; alt&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-style:italic&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-style:italic&quot;&gt;Monthly revenue&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-style:italic&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;codeBlock_line-added&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;source&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; srcset&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-style:italic&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-style:italic&quot;&gt;chart.avif&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-style:italic&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-style:italic&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-style:italic&quot;&gt;image/avif&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-style:italic&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;codeBlock_line-added&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;img&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; src&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-style:italic&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-style:italic&quot;&gt;chart.jpg&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-style:italic&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; alt&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-style:italic&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-style:italic&quot;&gt;Monthly revenue&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-style:italic&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
&lt;p&gt;A browser takes the first source whose &lt;code&gt;type&lt;/code&gt; it supports, and every browser in the core set now takes the AVIF. The browsers still outside the set never reached the WebP for its format; they needed a floor they could render, and that is the JPEG’s job. What the WebP bought them was bytes: without it they download the same picture, heavier. That is the whole cost of the deletion, and it falls on a shrinking audience.&lt;/p&gt;
&lt;p&gt;The floor stays. AVIF sits at about 93% of global traffic on caniuse’s counters, so a bare &lt;code&gt;.avif&lt;/code&gt; in &lt;code&gt;src&lt;/code&gt; with no fallback is a broken image for about one visitor in fifteen: desktop Safari before 16.4, iOS before 16.1, and every browser too old to have met the format. A missing image does not degrade, it is simply absent. Delete the middle of the stack, never the bottom.&lt;/p&gt;
&lt;p&gt;Most sites never built this stack. In the HTTP Archive’s 2024 almanac, about one image in eight was a WebP and about one in a hundred an AVIF, and a &lt;code&gt;&amp;#x3C;picture&gt;&lt;/code&gt; that switches on format appeared on a few pages in a hundred. Search your templates for &lt;code&gt;type=&quot;image/webp&quot;&lt;/code&gt;: if nothing comes back, or the floor under your sources is itself a &lt;code&gt;.webp&lt;/code&gt;, there is no middle to delete and nothing to do this month.&lt;/p&gt;
&lt;p&gt;One number needed a look before this verdict could ship. webstatus.dev scores stable Firefox at 0 on AVIF’s tests. The suite behind that number is two rendering tests, and ordinary still-image decoding is in neither: one advances an animated AVIF to its second frame, the other renders a file carrying a progressive-rendering flag. Firefox currently fails both. For a static image stack, the deletion above, they say nothing. If you ship animated or progressively encoded AVIF, test those files in Firefox before leaning on them.&lt;/p&gt;
</content:encoded><category>July 2026</category></item><item><title>Nesting cleared: delete a build step</title><link>https://cleared.page/2026-06/</link><guid isPermaLink="true">https://cleared.page/2026-06/</guid><description>What became safe to use, and to delete, in June 2026.</description><pubDate>Mon, 06 Jul 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;June was a deletion month. A single Firefox release produced exactly one new arrival, while sixteen features quietly finished their 30 months of support. The best of them is nesting: your CSS can nest itself now, and a build step can go.&lt;/p&gt;
&lt;h2&gt;01. Nesting&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Verdict: Cleared&lt;/strong&gt; · Safe everywhere as of June 11, 2026&lt;/p&gt;&lt;p&gt;CSS rules can nest inside other rules, natively.&lt;/p&gt;
&lt;p class=&quot;issueItem_delete&quot;&gt;&lt;strong&gt;Delete:&lt;/strong&gt; the build step that exists only to expand nesting. The source stays as written.&lt;/p&gt;
&lt;p&gt;One difference to know about. A nested rule resolves the way &lt;code&gt;:is()&lt;/code&gt; does: &lt;code&gt;&amp;#x26;&lt;/code&gt; takes the specificity of the most specific selector in the parent list. A preprocessor expands the same source into a plain selector list, where each branch keeps its own.&lt;/p&gt;
&lt;figure class=&quot;codeBlock&quot;&gt;&lt;figcaption class=&quot;codeBlock_caption&quot;&gt;&lt;span&gt;CSS&lt;/span&gt;&lt;button type=&quot;button&quot; class=&quot;codeBlock_copy&quot; data-copy=&quot;&quot; aria-label=&quot;Copy code sample 1&quot; hidden&gt;Copy&lt;/button&gt;&lt;span class=&quot;a11y-srOnly&quot; role=&quot;status&quot; data-copy-status=&quot;&quot;&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre class=&quot;codeBlock_pre&quot; style=&quot;background-color:var(--code-bg);color:var(--ink)&quot; tabindex=&quot;0&quot; role=&quot;region&quot; aria-label=&quot;Code sample 1&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--muted);font-weight:bold&quot;&gt;#&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;a&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-weight:bold&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; b&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt;  &amp;#x26; c { &lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;color&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt; blue&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt; }&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt; /* &amp;#x26; is [1,0,0] for both, so [1,0,1] */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;/* Your build step expanded that to: */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--muted);font-weight:bold&quot;&gt;#&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;a c&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt; }&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt; /* [1,0,1], same */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;b c&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;  {&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt; }&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt; /* [0,0,2], weaker than the native version */&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
&lt;p&gt;The two agree until a parent selector list mixes specificity levels. Before switching, search your source for comma-separated parent selectors containing an ID.&lt;/p&gt;
&lt;h2&gt;02. Lazy-loading images and iframes&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Verdict: Cleared&lt;/strong&gt; · Safe everywhere as of June 19, 2026&lt;/p&gt;&lt;p&gt;&lt;code&gt;loading=&quot;lazy&quot;&lt;/code&gt; defers offscreen images and iframes until the user scrolls near them.&lt;/p&gt;
&lt;p class=&quot;issueItem_delete&quot;&gt;&lt;strong&gt;Delete:&lt;/strong&gt; the lazy-loading script and its &lt;code&gt;data-src&lt;/code&gt; markup.&lt;/p&gt;
&lt;figure class=&quot;codeBlock&quot;&gt;&lt;figcaption class=&quot;codeBlock_caption&quot;&gt;&lt;span&gt;HTML · before &lt;svg width=&quot;12&quot; height=&quot;12&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; aria-hidden=&quot;true&quot; class=&quot;arrow arrow-lead&quot;&gt;&lt;path d=&quot;M5 12h14&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m12 5 7 7-7 7&quot;&gt;&lt;/path&gt;&lt;/svg&gt; after&lt;/span&gt;&lt;button type=&quot;button&quot; class=&quot;codeBlock_copy&quot; data-copy=&quot;&quot; aria-label=&quot;Copy code sample 1&quot; hidden&gt;Copy&lt;/button&gt;&lt;span class=&quot;a11y-srOnly&quot; role=&quot;status&quot; data-copy-status=&quot;&quot;&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre class=&quot;codeBlock_pre&quot; style=&quot;background-color:var(--code-bg);color:var(--ink)&quot; tabindex=&quot;0&quot; role=&quot;region&quot; aria-label=&quot;Code sample 1, before and after&quot;&gt;&lt;code&gt;&lt;span class=&quot;codeBlock_line-removed&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;−&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;img&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; data-src&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-style:italic&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-style:italic&quot;&gt;chart.png&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-style:italic&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; class&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-style:italic&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-style:italic&quot;&gt;lazyload&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-style:italic&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;codeBlock_line-removed&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;−&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;script&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;&gt;&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;/* a script you no longer need */&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;script&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;codeBlock_line-added&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;img&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; src&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-style:italic&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-style:italic&quot;&gt;chart.png&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-style:italic&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; loading&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-style:italic&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-style:italic&quot;&gt;lazy&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-style:italic&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
&lt;p&gt;The core image and iframe cases pass their tests in every browser. What still fails anywhere is edge cases: an image whose URL is changed repeatedly from script, base-URL changes mid-load, lazy iframes during unusual navigations. Keep the image at the top of the page eager; deferring what is already on screen only delays it.&lt;/p&gt;
&lt;h2&gt;03. &lt;code&gt;:has()&lt;/code&gt;&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Verdict: Cleared&lt;/strong&gt; · Safe everywhere as of June 19, 2026&lt;/p&gt;&lt;p&gt;The parent selector: style an element by what it contains. It appears on about one in two hundred page loads.&lt;/p&gt;
&lt;p class=&quot;issueItem_delete&quot;&gt;&lt;strong&gt;Delete:&lt;/strong&gt; the JavaScript that watches children and toggles state classes on their parents.&lt;/p&gt;
&lt;figure class=&quot;codeBlock&quot;&gt;&lt;figcaption class=&quot;codeBlock_caption&quot;&gt;&lt;span&gt;CSS · before &lt;svg width=&quot;12&quot; height=&quot;12&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; aria-hidden=&quot;true&quot; class=&quot;arrow arrow-lead&quot;&gt;&lt;path d=&quot;M5 12h14&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m12 5 7 7-7 7&quot;&gt;&lt;/path&gt;&lt;/svg&gt; after&lt;/span&gt;&lt;button type=&quot;button&quot; class=&quot;codeBlock_copy&quot; data-copy=&quot;&quot; aria-label=&quot;Copy code sample 1&quot; hidden&gt;Copy&lt;/button&gt;&lt;span class=&quot;a11y-srOnly&quot; role=&quot;status&quot; data-copy-status=&quot;&quot;&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre class=&quot;codeBlock_pre&quot; style=&quot;background-color:var(--code-bg);color:var(--ink)&quot; tabindex=&quot;0&quot; role=&quot;region&quot; aria-label=&quot;Code sample 1, before and after&quot;&gt;&lt;code&gt;&lt;span class=&quot;codeBlock_line-removed&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;−&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;/* a script adds .has-error to the form */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;codeBlock_line-removed&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;−&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;form&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-weight:bold&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;has-error&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; border-color&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt; firebrick&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;codeBlock_line-added&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;form&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-weight:bold&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;has&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-weight:bold&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-weight:bold&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;invalid&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-weight:bold&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; border-color&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt; firebrick&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt; }&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
&lt;p&gt;One boundary, from Safari’s current test run. Parent, ancestor, adjacent and sibling positions all match Chrome exactly: &lt;span class=&quot;count&quot;&gt;211 of 211&lt;/span&gt;, &lt;span class=&quot;count&quot;&gt;337 of 337&lt;/span&gt;, &lt;span class=&quot;count&quot;&gt;295 of 295&lt;/span&gt;, &lt;span class=&quot;count&quot;&gt;295 of 295&lt;/span&gt;. The gap is re-matching while a script inserts and removes siblings: &lt;span class=&quot;count&quot;&gt;14 of 28&lt;/span&gt;. If a &lt;code&gt;:has()&lt;/code&gt; rule watches a sibling list under live mutation, keep the class for that one case.&lt;/p&gt;
&lt;h2&gt;04. &lt;code&gt;field-sizing&lt;/code&gt;&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Verdict: Cleared&lt;/strong&gt; · New this month, June 16, 2026&lt;/p&gt;&lt;p&gt;&lt;code&gt;field-sizing: content&lt;/code&gt; makes inputs and textareas grow and shrink with what is typed. June’s only new arrival, completed by Firefox 152.&lt;/p&gt;
&lt;p class=&quot;issueItem_delete&quot;&gt;&lt;strong&gt;Delete:&lt;/strong&gt; the textarea autosize script, on new work.&lt;/p&gt;
&lt;figure class=&quot;codeBlock&quot;&gt;&lt;figcaption class=&quot;codeBlock_caption&quot;&gt;&lt;span&gt;CSS&lt;/span&gt;&lt;button type=&quot;button&quot; class=&quot;codeBlock_copy&quot; data-copy=&quot;&quot; aria-label=&quot;Copy code sample 1&quot; hidden&gt;Copy&lt;/button&gt;&lt;span class=&quot;a11y-srOnly&quot; role=&quot;status&quot; data-copy-status=&quot;&quot;&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre class=&quot;codeBlock_pre&quot; style=&quot;background-color:var(--code-bg);color:var(--ink)&quot; tabindex=&quot;0&quot; role=&quot;region&quot; aria-label=&quot;Code sample 1&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;textarea&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt;  field-sizing&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt; content&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;  min-height&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt; 4&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;  max-height&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt; 16&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
&lt;p&gt;A textarea that grows as you type, which is what this deletion is about, works in every current browser run. The misses are all at the edges: Firefox fails to re-fit a number input after a script changes its value, Chromium gives a disabled empty textarea more than one line of height, and Safari draws a search input’s caret taller than its placeholder. A month of Baseline means some of your users are still catching up, and for them the failure is the one you already ship: a fixed-size box with a scrollbar.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Correction, August 27, 2026: was Hold, now Cleared.&lt;/strong&gt; I read the &lt;code&gt;-svg&lt;/code&gt; in &lt;code&gt;mask-repeat-1-svg&lt;/code&gt;, &lt;code&gt;-2-svg&lt;/code&gt; and &lt;code&gt;-3-svg&lt;/code&gt; as naming the mask source. It names the masked content. Delete your fallback when masking an HTML element (most common) but keep it when masking SVG content, or where a mask stacks more than one layer, or when you use &lt;code&gt;mask-clip&lt;/code&gt;, &lt;code&gt;mask-origin&lt;/code&gt;, &lt;code&gt;mask-composite&lt;/code&gt; or &lt;code&gt;mask-mode&lt;/code&gt;, all of which Safari 26.6 still fails.&lt;/p&gt;&lt;h2&gt;05. Masks&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Verdict: Hold&lt;/strong&gt; · Not yet&lt;/p&gt;&lt;p&gt;CSS masks crossed 30 months of support on June 7, and appear on about 0.4% of page loads. The label says delete your fallbacks. The tests say not yet.&lt;/p&gt;
&lt;p&gt;In Safari 26.5.2’s current run, masks repeat correctly from a raster image and fail the same three tests when the mask source is an SVG: &lt;code&gt;mask-repeat-1-svg&lt;/code&gt;, &lt;code&gt;-2-svg&lt;/code&gt; and &lt;code&gt;-3-svg&lt;/code&gt;. Chrome passes all six. An SVG source is the common case, and a mask that fails to apply does not degrade: it reveals or hides the wrong thing. Keep whatever fallback you have until Safari’s SVG path catches up.&lt;/p&gt;
</content:encoded><category>June 2026</category></item><item><title>Delete your form’s touched classes</title><link>https://cleared.page/2026-05/</link><guid isPermaLink="true">https://cleared.page/2026-05/</guid><description>What became safe to use, and to delete, in May 2026.</description><pubDate>Mon, 08 Jun 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Seven features became newly available in May, and five finished their 30 months of support. Four of the seven arrivals were old features that had been waiting on Chrome or Chrome Android; desktop Chrome has had shared workers since 2010, and Chrome Android shipped them this May. The thing worth deleting is in your forms.&lt;/p&gt;
&lt;h2&gt;01. &lt;code&gt;:user-valid&lt;/code&gt; and &lt;code&gt;:user-invalid&lt;/code&gt;&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Verdict: Cleared&lt;/strong&gt; · Safe everywhere as of May 2, 2026&lt;/p&gt;&lt;p&gt;Validity pseudo-classes that wait for the user. They match like &lt;code&gt;:valid&lt;/code&gt; and &lt;code&gt;:invalid&lt;/code&gt;, but only once the field has been altered, so a pristine required field stays quiet. A submit attempt counts as interaction too.&lt;/p&gt;
&lt;p class=&quot;issueItem_delete&quot;&gt;&lt;strong&gt;Delete:&lt;/strong&gt; the script that listens for blur and input events just to add a “touched” class, so error styles don’t fire before the user has typed anything.&lt;/p&gt;
&lt;figure class=&quot;codeBlock&quot;&gt;&lt;figcaption class=&quot;codeBlock_caption&quot;&gt;&lt;span&gt;CSS · before &lt;svg width=&quot;12&quot; height=&quot;12&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; aria-hidden=&quot;true&quot; class=&quot;arrow arrow-lead&quot;&gt;&lt;path d=&quot;M5 12h14&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m12 5 7 7-7 7&quot;&gt;&lt;/path&gt;&lt;/svg&gt; after&lt;/span&gt;&lt;button type=&quot;button&quot; class=&quot;codeBlock_copy&quot; data-copy=&quot;&quot; aria-label=&quot;Copy code sample 1&quot; hidden&gt;Copy&lt;/button&gt;&lt;span class=&quot;a11y-srOnly&quot; role=&quot;status&quot; data-copy-status=&quot;&quot;&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre class=&quot;codeBlock_pre&quot; style=&quot;background-color:var(--code-bg);color:var(--ink)&quot; tabindex=&quot;0&quot; role=&quot;region&quot; aria-label=&quot;Code sample 1, before and after&quot;&gt;&lt;code&gt;&lt;span class=&quot;codeBlock_line-removed&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;−&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;/* a script marks fields the user has visited */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;codeBlock_line-removed&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;−&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-weight:bold&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;touched&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-weight:bold&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;invalid&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; border-color&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt; firebrick&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;codeBlock_line-added&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;/* the browser tracks interaction itself */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;codeBlock_line-added&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;input:user-invalid&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; border-color&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt; firebrick&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt; }&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
&lt;p&gt;The core suite passes in every current stable run. One edge is unsettled: when these flip mid-edit inside multi-part fields like date inputs is covered only by a test still marked tentative, and Chrome is currently the only engine passing it. If your validation styling leans on the exact timing inside date or time inputs, keep the class for those. In a browser too old to have these, the rule never matches: no inline highlighting, not a broken form.&lt;/p&gt;
&lt;h2&gt;02. &lt;code&gt;lh&lt;/code&gt; unit&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Verdict: Hold&lt;/strong&gt; · Not yet&lt;/p&gt;&lt;p&gt;One line-height, as a unit: &lt;code&gt;3lh&lt;/code&gt; is three lines tall. It crossed 30 months of support on May 21, and the deletion it promises is every magic number that hard-codes a line-height multiple.&lt;/p&gt;
&lt;figure class=&quot;codeBlock&quot;&gt;&lt;figcaption class=&quot;codeBlock_caption&quot;&gt;&lt;span&gt;CSS&lt;/span&gt;&lt;button type=&quot;button&quot; class=&quot;codeBlock_copy&quot; data-copy=&quot;&quot; aria-label=&quot;Copy code sample 1&quot; hidden&gt;Copy&lt;/button&gt;&lt;span class=&quot;a11y-srOnly&quot; role=&quot;status&quot; data-copy-status=&quot;&quot;&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre class=&quot;codeBlock_pre&quot; style=&quot;background-color:var(--code-bg);color:var(--ink)&quot; tabindex=&quot;0&quot; role=&quot;region&quot; aria-label=&quot;Code sample 1&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;/* The deletion waiting here: */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--muted);font-weight:bold&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;toast&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; min-height&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; calc&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt;3 &lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt; 1.4&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;em&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;);&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt; }&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt; /* hoping 1.4 still matches */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;/* Blocked by Safari, for now: */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--muted);font-weight:bold&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;toast&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; min-height&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt; 3lh&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt; }&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
&lt;p&gt;The blocker is specific. Safari 26.5’s current run fails the suite’s inherited-line-height test: an element whose &lt;code&gt;line-height&lt;/code&gt; arrives from its parent, which is how line-height usually arrives, resolves &lt;code&gt;1lh&lt;/code&gt; against the wrong value. The other eight tests pass there, and Chrome, Edge and Firefox pass everything. Until that fix ships, the magic number is more predictable than the unit that replaces it. Its root-relative sibling &lt;code&gt;rlh&lt;/code&gt; cleared the same day and appears on about one page load in three million.&lt;/p&gt;
&lt;h2&gt;03. Container style queries&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Verdict: Hold&lt;/strong&gt; · Not yet&lt;/p&gt;&lt;p&gt;Style queries let a component ask what a custom property is set to on its container. Firefox 151 shipped the last piece on May 19, so the label now says Baseline. The label covers more than the browsers agree on.&lt;/p&gt;
&lt;figure class=&quot;codeBlock&quot;&gt;&lt;figcaption class=&quot;codeBlock_caption&quot;&gt;&lt;span&gt;CSS&lt;/span&gt;&lt;button type=&quot;button&quot; class=&quot;codeBlock_copy&quot; data-copy=&quot;&quot; aria-label=&quot;Copy code sample 1&quot; hidden&gt;Copy&lt;/button&gt;&lt;span class=&quot;a11y-srOnly&quot; role=&quot;status&quot; data-copy-status=&quot;&quot;&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre class=&quot;codeBlock_pre&quot; style=&quot;background-color:var(--code-bg);color:var(--ink)&quot; tabindex=&quot;0&quot; role=&quot;region&quot; aria-label=&quot;Code sample 1&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--muted);font-weight:bold&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;container&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt; style(--density: compact) &lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt; }&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt; /* passes everywhere */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--muted);font-weight:bold&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;container&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt; style(--columns &gt; 2) &lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt; }&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt; /* fails in every engine */&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
&lt;p&gt;The equality form passes its tests in the current Chrome, Edge, Firefox and Safari runs. The range form is another story: every engine passes 1 of the 7 dynamic range tests, Firefox included, and Firefox is the browser that just shipped the last piece. If you treat the equality form as a progressive enhancement, nothing stops you today. The Hold is for the feature as labeled, because the label does not tell you which half is broken.&lt;/p&gt;
&lt;p&gt;That was May: one deletion, and two labels running ahead of their implementations.&lt;/p&gt;</content:encoded><category>May 2026</category></item><item><title>Delete your role=&quot;search&quot; wrapper</title><link>https://cleared.page/2026-04/</link><guid isPermaLink="true">https://cleared.page/2026-04/</guid><description>What became safe to use, and to delete, in April 2026.</description><pubDate>Mon, 04 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;A thin month, and a backwards one. Baseline’s rhythm is usually set by Safari, the browser that ships least often. April’s two arrivals were both waiting on the Chromium side: Firefox and Safari had shipped &lt;code&gt;contrast-color()&lt;/code&gt; and &lt;code&gt;Math.sumPrecise()&lt;/code&gt; months earlier, and Chrome 147 landed on April 7 with Edge two days behind. Four more features finished their 30 months of support. One of them is a deletion.&lt;/p&gt;
&lt;h2&gt;01. &lt;code&gt;&amp;lt;search&amp;gt;&lt;/code&gt;&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Verdict: Cleared&lt;/strong&gt; · Safe everywhere as of April 13, 2026&lt;/p&gt;&lt;p&gt;An HTML element for the region that holds your search box. It maps to the same search landmark the role attribute gave you, so screen reader users can jump straight to it without you writing any ARIA.&lt;/p&gt;
&lt;p class=&quot;issueItem_delete&quot;&gt;&lt;strong&gt;Delete:&lt;/strong&gt; the &lt;code&gt;role=&quot;search&quot;&lt;/code&gt; attribute, and usually the &lt;code&gt;&amp;#x3C;div&gt;&lt;/code&gt; it sits on.&lt;/p&gt;
&lt;figure class=&quot;codeBlock&quot;&gt;&lt;figcaption class=&quot;codeBlock_caption&quot;&gt;&lt;span&gt;HTML · before &lt;svg width=&quot;12&quot; height=&quot;12&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; aria-hidden=&quot;true&quot; class=&quot;arrow arrow-lead&quot;&gt;&lt;path d=&quot;M5 12h14&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m12 5 7 7-7 7&quot;&gt;&lt;/path&gt;&lt;/svg&gt; after&lt;/span&gt;&lt;button type=&quot;button&quot; class=&quot;codeBlock_copy&quot; data-copy=&quot;&quot; aria-label=&quot;Copy code sample 1&quot; hidden&gt;Copy&lt;/button&gt;&lt;span class=&quot;a11y-srOnly&quot; role=&quot;status&quot; data-copy-status=&quot;&quot;&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre class=&quot;codeBlock_pre&quot; style=&quot;background-color:var(--code-bg);color:var(--ink)&quot; tabindex=&quot;0&quot; role=&quot;region&quot; aria-label=&quot;Code sample 1, before and after&quot;&gt;&lt;code&gt;&lt;span class=&quot;codeBlock_line-removed&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;−&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;&amp;#x3C;!-- a div doing an element&apos;s job --&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;codeBlock_line-removed&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;−&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; role&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-style:italic&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-style:italic&quot;&gt;search&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-style:italic&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;codeBlock_line-removed&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;−&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;  &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;form&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; action&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-style:italic&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-style:italic&quot;&gt;/search&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-style:italic&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;&gt;&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt;…&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;form&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;codeBlock_line-removed&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;−&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;div&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;codeBlock_line-added&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;search&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;codeBlock_line-added&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;  &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;form&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; action&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-style:italic&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-style:italic&quot;&gt;/search&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-style:italic&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;&gt;&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt;…&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;form&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;codeBlock_line-added&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;&amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;search&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
&lt;p&gt;One thing to style yourself. Browsers that know the tag give it &lt;code&gt;display: block&lt;/code&gt; in the user agent stylesheet. A browser too old to know it gives it nothing, and the initial value of &lt;code&gt;display&lt;/code&gt; is &lt;code&gt;inline&lt;/code&gt;. If old browsers matter to you, declare &lt;code&gt;search { display: block }&lt;/code&gt; yourself: one line, inert wherever the browser already does it. Beyond that, failure is graceful. The contents render everywhere, and an old browser loses the landmark, not the page.&lt;/p&gt;
&lt;p&gt;A note on the numbers: the summary scoreboard currently shows Safari at zero on this feature. That zero comes down to one missing line in Safari’s stylesheet. Only two tests are scored here, both checking the element’s default styles, and Safari fails one check in each: it does not give &lt;code&gt;&amp;#x3C;search&gt;&lt;/code&gt; the &lt;code&gt;unicode-bidi: isolate&lt;/code&gt; the spec asks for. The role-mapping suite passes whole. So the landmark works and the layout is fine. What you lose is bidi isolation, which matters if you put text of mixed direction inside the element.&lt;/p&gt;
&lt;h2&gt;02. &lt;code&gt;contrast-color()&lt;/code&gt;&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Verdict: Hold&lt;/strong&gt; · Not yet&lt;/p&gt;&lt;p&gt;Hand it a background color and it returns white or black, whichever contrasts more. New this month, April 10, 2026. The deletion it promises is every hand-maintained pair of background and text custom properties.&lt;/p&gt;
&lt;figure class=&quot;codeBlock&quot;&gt;&lt;figcaption class=&quot;codeBlock_caption&quot;&gt;&lt;span&gt;CSS&lt;/span&gt;&lt;button type=&quot;button&quot; class=&quot;codeBlock_copy&quot; data-copy=&quot;&quot; aria-label=&quot;Copy code sample 1&quot; hidden&gt;Copy&lt;/button&gt;&lt;span class=&quot;a11y-srOnly&quot; role=&quot;status&quot; data-copy-status=&quot;&quot;&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre class=&quot;codeBlock_pre&quot; style=&quot;background-color:var(--code-bg);color:var(--ink)&quot; tabindex=&quot;0&quot; role=&quot;region&quot; aria-label=&quot;Code sample 1&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--muted);font-weight:bold&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;badge&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;  background&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; var&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt;--accent&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;  color&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt; contrast-color(&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;var&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt;--accent&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;/* Which of white or black wins on a mid-tone&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;   background is the browser&apos;s call, not yours. */&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
&lt;p&gt;The label is running ahead of the paperwork. The function’s spec is an editor’s draft that still carries the banner “This spec is not yet ready for implementation”, and in the only form browsers ship, with no target contrast stated, the spec leaves the choice of contrast algorithm to the browser. Two engines can legitimately disagree about which of white or black a mid-tone background gets. The tests show real disagreements: Firefox’s current stable run fails both cases where &lt;code&gt;contrast-color()&lt;/code&gt; takes container units inside &lt;code&gt;calc()&lt;/code&gt;, and Safari’s fails to repaint a gradient whose color stop uses &lt;code&gt;contrast-color(currentColor)&lt;/code&gt;. One more thing the name does not say: it maximizes contrast, it guarantees none. Against a mid-gray background the winner clears no bar, it just loses less. For now, picking the text color yourself is the only way to know what it will be.&lt;/p&gt;
&lt;p&gt;That was April: one attribute to delete, and one new function whose own spec asks you to wait. The other four transitions gave you nothing to do, which is the honest truth about most features in most months.&lt;/p&gt;</content:encoded><category>April 2026</category></item><item><title>Delete your equal-height card hack</title><link>https://cleared.page/2026-03/</link><guid isPermaLink="true">https://cleared.page/2026-03/</guid><description>What became safe to use, and to delete, in March 2026.</description><pubDate>Mon, 06 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Eight of March’s ten arrivals landed on a single day, March 24, when Firefox 149 and Safari 26.4 both shipped. One was baseline-shift, a property Chrome has carried since 2008. But the month’s real business is in the eleven features that finished their 30 months of support, because three of them let you delete something. Start with your card grids.&lt;/p&gt;
&lt;h2&gt;01. Subgrid&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Verdict: Cleared&lt;/strong&gt; · Safe everywhere as of March 15, 2026&lt;/p&gt;&lt;p&gt;A nested grid can adopt its parent’s rows or columns instead of declaring its own: the track sizes come from the parent, and the subgrid’s items feed their sizes back up.&lt;/p&gt;
&lt;p class=&quot;issueItem_delete&quot;&gt;&lt;strong&gt;Delete:&lt;/strong&gt; the script that measures card sections and equalizes their heights, or the fixed row heights doing the same job with magic numbers.&lt;/p&gt;
&lt;figure class=&quot;codeBlock&quot;&gt;&lt;figcaption class=&quot;codeBlock_caption&quot;&gt;&lt;span&gt;CSS · before &lt;svg width=&quot;12&quot; height=&quot;12&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; aria-hidden=&quot;true&quot; class=&quot;arrow arrow-lead&quot;&gt;&lt;path d=&quot;M5 12h14&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m12 5 7 7-7 7&quot;&gt;&lt;/path&gt;&lt;/svg&gt; after&lt;/span&gt;&lt;button type=&quot;button&quot; class=&quot;codeBlock_copy&quot; data-copy=&quot;&quot; aria-label=&quot;Copy code sample 1&quot; hidden&gt;Copy&lt;/button&gt;&lt;span class=&quot;a11y-srOnly&quot; role=&quot;status&quot; data-copy-status=&quot;&quot;&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre class=&quot;codeBlock_pre&quot; style=&quot;background-color:var(--code-bg);color:var(--ink)&quot; tabindex=&quot;0&quot; role=&quot;region&quot; aria-label=&quot;Code sample 1, before and after&quot;&gt;&lt;code&gt;&lt;span class=&quot;codeBlock_line-removed&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;−&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;/* every card hard-codes the shared row plan */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;codeBlock_line-removed&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;−&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-weight:bold&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;card&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;  {&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; display&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt; grid&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; grid-template-rows&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt; 3&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt; 6&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt; 2&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;rem&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;codeBlock_line-added&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;/* cards borrow their rows from the grid they sit in */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;codeBlock_line-added&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-weight:bold&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;cards&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; display&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt; grid&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; grid-template-columns&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; repeat&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;fr&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;codeBlock_line-added&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;         grid-template-rows&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; repeat&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt; auto&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;);&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;codeBlock_line-added&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-weight:bold&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;card&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;  {&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; display&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt; grid&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; grid-row&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt; span 3&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;codeBlock_line-added&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;         grid-template-rows&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt; subgrid&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt; }&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
&lt;p&gt;Track sizing, gaps and line names pass in all four current stable runs. The exception is baseline alignment: Firefox still fails most of the suite’s baseline tests inside subgrids. Before deleting, search your grid code for &lt;code&gt;align-items: baseline&lt;/code&gt; and &lt;code&gt;align-self: baseline&lt;/code&gt;, and check those in Firefox. In a browser without subgrid the declaration drops and rows fall back to auto: misaligned cards, not broken ones.&lt;/p&gt;
&lt;h2&gt;02. Hyphenation&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Verdict: Cleared&lt;/strong&gt; · Safe everywhere as of March 18, 2026&lt;/p&gt;&lt;p&gt;&lt;code&gt;hyphens: auto&lt;/code&gt; breaks words at dictionary-approved points. Safari 17 completed the set in September 2023; the 30 months ran out on March 18. It already appears on about one page load in a thousand.&lt;/p&gt;
&lt;p class=&quot;issueItem_delete&quot;&gt;&lt;strong&gt;Delete:&lt;/strong&gt; the script or build step that sprays soft hyphens into your text.&lt;/p&gt;
&lt;figure class=&quot;codeBlock&quot;&gt;&lt;figcaption class=&quot;codeBlock_caption&quot;&gt;&lt;span&gt;HTML · before &lt;svg width=&quot;12&quot; height=&quot;12&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; aria-hidden=&quot;true&quot; class=&quot;arrow arrow-lead&quot;&gt;&lt;path d=&quot;M5 12h14&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m12 5 7 7-7 7&quot;&gt;&lt;/path&gt;&lt;/svg&gt; after&lt;/span&gt;&lt;button type=&quot;button&quot; class=&quot;codeBlock_copy&quot; data-copy=&quot;&quot; aria-label=&quot;Copy code sample 1&quot; hidden&gt;Copy&lt;/button&gt;&lt;span class=&quot;a11y-srOnly&quot; role=&quot;status&quot; data-copy-status=&quot;&quot;&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre class=&quot;codeBlock_pre&quot; style=&quot;background-color:var(--code-bg);color:var(--ink)&quot; tabindex=&quot;0&quot; role=&quot;region&quot; aria-label=&quot;Code sample 1, before and after&quot;&gt;&lt;code&gt;&lt;span class=&quot;codeBlock_line-removed&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;−&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;&amp;#x3C;!-- generated markup --&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;codeBlock_line-removed&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;−&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt;Silben&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-style:italic&quot;&gt;&amp;#x26;&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-style:italic&quot;&gt;shy&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-style:italic&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt;trennung&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;codeBlock_line-added&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;&amp;#x3C;!-- requires lang=&quot;de&quot; (or whatever applies) on the markup --&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;codeBlock_line-added&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;style&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;&gt;&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; article&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; hyphens&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt; auto&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt; }&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt; &amp;#x3C;/&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;style&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
&lt;p&gt;The boundary is the language. The spec only requires hyphenation where the content language is known and the browser has a dictionary for it, so &lt;code&gt;hyphens: auto&lt;/code&gt; without a &lt;code&gt;lang&lt;/code&gt; attribute is a no-op by design. Coverage is also uneven: the suite’s eleven language-specific tests currently fail in all four stable runs, which names no single blocker but does say to spot-check the languages you actually publish. Failure is the gentle kind: no dictionary, no hyphens, a ragged edge.&lt;/p&gt;
&lt;h2&gt;03. &lt;code&gt;image-set()&lt;/code&gt;&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Verdict: Cleared&lt;/strong&gt; · Safe everywhere as of March 18, 2026&lt;/p&gt;&lt;p&gt;Resolution switching for CSS backgrounds, the &lt;code&gt;srcset&lt;/code&gt; of &lt;code&gt;background-image&lt;/code&gt;. Chromium dropped the prefix in May 2023; Safari 17 was the last piece.&lt;/p&gt;
&lt;p class=&quot;issueItem_delete&quot;&gt;&lt;strong&gt;Delete:&lt;/strong&gt; the &lt;code&gt;-webkit-image-set()&lt;/code&gt; line.&lt;/p&gt;
&lt;figure class=&quot;codeBlock&quot;&gt;&lt;figcaption class=&quot;codeBlock_caption&quot;&gt;&lt;span&gt;CSS · before &lt;svg width=&quot;12&quot; height=&quot;12&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; aria-hidden=&quot;true&quot; class=&quot;arrow arrow-lead&quot;&gt;&lt;path d=&quot;M5 12h14&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m12 5 7 7-7 7&quot;&gt;&lt;/path&gt;&lt;/svg&gt; after&lt;/span&gt;&lt;button type=&quot;button&quot; class=&quot;codeBlock_copy&quot; data-copy=&quot;&quot; aria-label=&quot;Copy code sample 1&quot; hidden&gt;Copy&lt;/button&gt;&lt;span class=&quot;a11y-srOnly&quot; role=&quot;status&quot; data-copy-status=&quot;&quot;&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre class=&quot;codeBlock_pre&quot; style=&quot;background-color:var(--code-bg);color:var(--ink)&quot; tabindex=&quot;0&quot; role=&quot;region&quot; aria-label=&quot;Code sample 1, before and after&quot;&gt;&lt;code&gt;&lt;span class=&quot;codeBlock_line-removed&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;−&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;background-image: url(hero&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-weight:bold&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;png&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;codeBlock_line-removed&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;−&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;background-image: -webkit-image-set(url(hero&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-weight:bold&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;png&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt;) 1&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;x&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-weight:bold&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; url(hero&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-weight:bold&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;2x&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt;.png) 2x)&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;codeBlock_line-removed&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;−&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;background-image: image-set(url(hero&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-weight:bold&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;png&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt;) 1&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;x&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-weight:bold&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; url(hero&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-weight:bold&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;2x&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt;.png) 2x)&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;codeBlock_line-added&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;/* keep the plain url() line */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;codeBlock_line-added&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;background-image: url(hero&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-weight:bold&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;png&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;codeBlock_line-added&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;background-image: image-set(url(hero&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-weight:bold&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;png&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt;) 1&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;x&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-weight:bold&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; url(hero&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-weight:bold&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;2x&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt;.png) 2x)&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
&lt;p&gt;Every rendering test passes in all four current stable runs. The only misses anywhere are in parsing, where Chrome, Edge and Firefox each pass &lt;span class=&quot;count&quot;&gt;138 of 142&lt;/span&gt; subtests and Safari passes all 142. Do keep the plain &lt;code&gt;url()&lt;/code&gt; line: in a browser outside the core set that lacks &lt;code&gt;image-set()&lt;/code&gt;, it is the difference between a low-resolution image and no image.&lt;/p&gt;
&lt;h2&gt;04. Custom highlights&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Verdict: Hold&lt;/strong&gt; · Not yet&lt;/p&gt;&lt;p&gt;Style ranges of text from script without wrapping them in elements: register a &lt;code&gt;Highlight&lt;/code&gt;, style it with &lt;code&gt;::highlight()&lt;/code&gt;. Firefox 149 shipped the last piece on March 24.&lt;/p&gt;
&lt;figure class=&quot;codeBlock&quot;&gt;&lt;figcaption class=&quot;codeBlock_caption&quot;&gt;&lt;span&gt;CSS&lt;/span&gt;&lt;button type=&quot;button&quot; class=&quot;codeBlock_copy&quot; data-copy=&quot;&quot; aria-label=&quot;Copy code sample 1&quot; hidden&gt;Copy&lt;/button&gt;&lt;span class=&quot;a11y-srOnly&quot; role=&quot;status&quot; data-copy-status=&quot;&quot;&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre class=&quot;codeBlock_pre&quot; style=&quot;background-color:var(--code-bg);color:var(--ink)&quot; tabindex=&quot;0&quot; role=&quot;region&quot; aria-label=&quot;Code sample 1&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;::highlight(search-match&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;{&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; background-color&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt; Mark&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt; }&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
&lt;p&gt;The scores say wait. Chrome and Edge pass 94% of the stable suite. Safari, which has had the feature since late 2023, passes 66%. Firefox 149, the release that flipped the label, passes 70%, and it fails nearly the same tests Safari does. The failures are the visible kind: highlight painting over text sized with font-relative or container-relative units, vertical writing mode, and in Safari’s case text shadows inside highlights. Until both catch up, the span-wrapping you already do is the more predictable renderer.&lt;/p&gt;
&lt;h2&gt;05. &lt;code&gt;text-indent: hanging&lt;/code&gt;&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Verdict: Cleared&lt;/strong&gt; · New this month, March 13, 2026&lt;/p&gt;&lt;p&gt;One keyword inverts &lt;code&gt;text-indent&lt;/code&gt;, so every line except the first is indented: the hanging indent of bibliographies and transcripts.&lt;/p&gt;
&lt;p class=&quot;issueItem_delete&quot;&gt;&lt;strong&gt;Delete:&lt;/strong&gt; the two-declaration pair that fakes it.&lt;/p&gt;
&lt;figure class=&quot;codeBlock&quot;&gt;&lt;figcaption class=&quot;codeBlock_caption&quot;&gt;&lt;span&gt;CSS · before &lt;svg width=&quot;12&quot; height=&quot;12&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; aria-hidden=&quot;true&quot; class=&quot;arrow arrow-lead&quot;&gt;&lt;path d=&quot;M5 12h14&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m12 5 7 7-7 7&quot;&gt;&lt;/path&gt;&lt;/svg&gt; after&lt;/span&gt;&lt;button type=&quot;button&quot; class=&quot;codeBlock_copy&quot; data-copy=&quot;&quot; aria-label=&quot;Copy code sample 1&quot; hidden&gt;Copy&lt;/button&gt;&lt;span class=&quot;a11y-srOnly&quot; role=&quot;status&quot; data-copy-status=&quot;&quot;&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre class=&quot;codeBlock_pre&quot; style=&quot;background-color:var(--code-bg);color:var(--ink)&quot; tabindex=&quot;0&quot; role=&quot;region&quot; aria-label=&quot;Code sample 1, before and after&quot;&gt;&lt;code&gt;&lt;span class=&quot;codeBlock_line-removed&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;−&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;/* indent everything, pull the first line back */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;codeBlock_line-removed&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;−&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-weight:bold&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;ref&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; padding-left&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt; 2&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;em&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; text-indent&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt; -2&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;em&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;codeBlock_line-added&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-weight:bold&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;ref&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; text-indent&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt; 2&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;em&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt; hanging&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt; }&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
&lt;p&gt;Chromium shipped it on March 10, three days before the label; Safari has had it since 2021, Firefox since 2023. Every test passes in every current stable run, mobile included, which is rare enough this month to be worth saying. In an older browser the declaration is invalid and drops: lines sit flush, nothing breaks. Its sibling &lt;code&gt;each-line&lt;/code&gt; went Baseline the same day.&lt;/p&gt;
&lt;p&gt;That was March: four deletions and one wait, courtesy of test runs that say what the label does not.&lt;/p&gt;</content:encoded><category>March 2026</category></item><item><title>Delete your RTL-detection script</title><link>https://cleared.page/2026-02/</link><guid isPermaLink="true">https://cleared.page/2026-02/</guid><description>What became safe to use, and to delete, in February 2026.</description><pubDate>Mon, 09 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Five features became newly available in February, and exactly one finished its 30 months of support. Four of the five arrivals live in JavaScript, WebAssembly, HTTP compression and a security API, outside this newsletter’s beat, so this is a thin month with two items: one CSS arrival worth starting now, and one deletion fourteen years in the making.&lt;/p&gt;
&lt;h2&gt;01. &lt;code&gt;dirname&lt;/code&gt;&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Verdict: Cleared&lt;/strong&gt; · Safe everywhere as of February 1, 2026&lt;/p&gt;&lt;p&gt;An attribute for text fields. Add &lt;code&gt;dirname&lt;/code&gt; and the browser submits a second field alongside the value: the direction the text was typed in, &lt;code&gt;ltr&lt;/code&gt; or &lt;code&gt;rtl&lt;/code&gt;. Chrome and Safari have shipped it since 2012. Firefox 116 completed the set in August 2023, and the 30-month clock ran out on February 1.&lt;/p&gt;
&lt;p class=&quot;issueItem_delete&quot;&gt;&lt;strong&gt;Delete:&lt;/strong&gt; the direction-guessing code. If your site stores user text that might be Arabic or Hebrew, something today inspects each comment to decide whether it needs &lt;code&gt;dir=&quot;rtl&quot;&lt;/code&gt; when displayed again, a client script or a server-side heuristic. The browser already knows; let it tell you.&lt;/p&gt;
&lt;figure class=&quot;codeBlock&quot;&gt;&lt;figcaption class=&quot;codeBlock_caption&quot;&gt;&lt;span&gt;HTML · before &lt;svg width=&quot;12&quot; height=&quot;12&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; aria-hidden=&quot;true&quot; class=&quot;arrow arrow-lead&quot;&gt;&lt;path d=&quot;M5 12h14&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m12 5 7 7-7 7&quot;&gt;&lt;/path&gt;&lt;/svg&gt; after&lt;/span&gt;&lt;button type=&quot;button&quot; class=&quot;codeBlock_copy&quot; data-copy=&quot;&quot; aria-label=&quot;Copy code sample 1&quot; hidden&gt;Copy&lt;/button&gt;&lt;span class=&quot;a11y-srOnly&quot; role=&quot;status&quot; data-copy-status=&quot;&quot;&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre class=&quot;codeBlock_pre&quot; style=&quot;background-color:var(--code-bg);color:var(--ink)&quot; tabindex=&quot;0&quot; role=&quot;region&quot; aria-label=&quot;Code sample 1, before and after&quot;&gt;&lt;code&gt;&lt;span class=&quot;codeBlock_line-removed&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;−&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;&amp;#x3C;!-- a script sniffs the value, fills a hidden field --&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;codeBlock_line-removed&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;−&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-style:italic&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-style:italic&quot;&gt;text&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-style:italic&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; name&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-style:italic&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-style:italic&quot;&gt;comment&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-style:italic&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;codeBlock_line-added&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;&amp;#x3C;!-- the browser reports direction at submission --&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;codeBlock_line-added&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; type&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-style:italic&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-style:italic&quot;&gt;text&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-style:italic&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; name&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-style:italic&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-style:italic&quot;&gt;comment&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-style:italic&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; dirname&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-style:italic&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-style:italic&quot;&gt;comment.dir&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-style:italic&quot;&gt;&quot;&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;codeBlock_line-added&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;&amp;#x3C;!-- comment=%D9%85%D8%B1%D8%AD%D8%A8%D8%A7&amp;#x26;comment.dir=rtl --&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
&lt;p&gt;The edges are less settled. On input types where the spec says the attribute does not apply, current stable runs disagree: Firefox 148 and Safari 26.3 submit the direction pair for a &lt;code&gt;month&lt;/code&gt; input anyway, while Chrome 146 and Edge 145 omit it. Keep &lt;code&gt;dirname&lt;/code&gt; on plain text fields and textareas, where every current run passes, and treat the extra field as optional on the server. A browser too old to know the attribute never sends it: your default direction applies, and nothing breaks.&lt;/p&gt;
&lt;h2&gt;02. &lt;code&gt;shape()&lt;/code&gt;&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Verdict: Cleared&lt;/strong&gt; · New this month, February 24, 2026&lt;/p&gt;&lt;p&gt;A clip-path drawn with path commands in CSS syntax: lines, curves, arcs, in any CSS unit. The &lt;code&gt;path()&lt;/code&gt; function it improves on takes one SVG string and, as the spec puts it, implicitly allows only the &lt;code&gt;px&lt;/code&gt; unit. The spec defines &lt;code&gt;shape()&lt;/code&gt; as a superset of &lt;code&gt;path()&lt;/code&gt;: the same commands, but percentages, &lt;code&gt;em&lt;/code&gt;, &lt;code&gt;var()&lt;/code&gt; and &lt;code&gt;calc()&lt;/code&gt; all work, so a curved shape can finally follow the box it clips.&lt;/p&gt;
&lt;p&gt;The scoreboard argues. webstatus.dev shows stable Safari passing a third of the suite, which reads like a Hold. It is not. The current Safari 26.3 run fails seven subtests, and every one is the same complaint: when style is read back, Safari keeps the default &lt;code&gt;from start&lt;/code&gt; and &lt;code&gt;from origin&lt;/code&gt; keywords instead of dropping them from the serialization. Every parsing and computing subtest for the geometry itself passes, as it does in the current Chrome, Edge and Firefox runs. Nothing renders differently.&lt;/p&gt;
&lt;p&gt;Firefox shipped it last, on February 24, so declare a fallback on the line above; a browser without &lt;code&gt;shape()&lt;/code&gt; drops the declaration it cannot parse and keeps the earlier one:&lt;/p&gt;
&lt;figure class=&quot;codeBlock&quot;&gt;&lt;figcaption class=&quot;codeBlock_caption&quot;&gt;&lt;span&gt;CSS&lt;/span&gt;&lt;button type=&quot;button&quot; class=&quot;codeBlock_copy&quot; data-copy=&quot;&quot; aria-label=&quot;Copy code sample 1&quot; hidden&gt;Copy&lt;/button&gt;&lt;span class=&quot;a11y-srOnly&quot; role=&quot;status&quot; data-copy-status=&quot;&quot;&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre class=&quot;codeBlock_pre&quot; style=&quot;background-color:var(--code-bg);color:var(--ink)&quot; tabindex=&quot;0&quot; role=&quot;region&quot; aria-label=&quot;Code sample 1&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;clip-path: polygon(0 0&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-weight:bold&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; 100% 0&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-weight:bold&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; 100% 85%&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-weight:bold&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; 0 100%&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt;); &lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;/* older browsers stop here */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;clip-path: shape(from 0 0&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-weight:bold&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; line to 100% 0&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-weight:bold&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;                 line to 100% 85%&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-weight:bold&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; curve to 0 100% with 50% 80%&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
&lt;p&gt;Two footnotes. If your tests compare &lt;code&gt;getComputedStyle&lt;/code&gt; strings for &lt;code&gt;clip-path&lt;/code&gt;, Safari’s extra keywords will trip them; that is the entire defect. And Firefox Android has no current measurement: its newest test run predates the release that shipped the feature, so the low score there is a blank, not a fail. If it did turn out broken, the fallback line above is what those users would see.&lt;/p&gt;
&lt;p&gt;That was February: a thin month for arrivals, and one deletion that waited fourteen years for its clock to run out.&lt;/p&gt;</content:encoded><category>February 2026</category></item><item><title>Delete your is-transitioning class</title><link>https://cleared.page/2026-01/</link><guid isPermaLink="true">https://cleared.page/2026-01/</guid><description>What became safe to use, and to delete, in January 2026.</description><pubDate>Mon, 09 Feb 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;January was one release wide. Firefox 147, on January 13, closed out all seven of the month’s arrivals by itself; nothing else moved. Four of the seven are the root-font versions of existing length units, full marks everywhere and nothing to do with them. The Navigation API reached Baseline the same day, but it is JavaScript, and this letter’s beat is CSS and HTML; it lives in the archive links below. The deletion this month belongs to everyone already running view transitions.&lt;/p&gt;
&lt;h2&gt;01. &lt;code&gt;:active-view-transition&lt;/code&gt;&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Verdict: Cleared&lt;/strong&gt; · New this month, January 13, 2026&lt;/p&gt;&lt;p&gt;A pseudo-class that matches the root element while a view transition is running, and stops matching when it settles. Chromium has shipped it since May 2024; Firefox 147 was the last browser in.&lt;/p&gt;
&lt;p class=&quot;issueItem_delete&quot;&gt;&lt;strong&gt;Delete:&lt;/strong&gt; the script that adds a marker class to the root before &lt;code&gt;document.startViewTransition()&lt;/code&gt; and removes it when the transition finishes, just so your stylesheet can tell a transition is underway.&lt;/p&gt;
&lt;figure class=&quot;codeBlock&quot;&gt;&lt;figcaption class=&quot;codeBlock_caption&quot;&gt;&lt;span&gt;CSS · before &lt;svg width=&quot;12&quot; height=&quot;12&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentColor&quot; stroke-width=&quot;2&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; aria-hidden=&quot;true&quot; class=&quot;arrow arrow-lead&quot;&gt;&lt;path d=&quot;M5 12h14&quot;&gt;&lt;/path&gt;&lt;path d=&quot;m12 5 7 7-7 7&quot;&gt;&lt;/path&gt;&lt;/svg&gt; after&lt;/span&gt;&lt;button type=&quot;button&quot; class=&quot;codeBlock_copy&quot; data-copy=&quot;&quot; aria-label=&quot;Copy code sample 1&quot; hidden&gt;Copy&lt;/button&gt;&lt;span class=&quot;a11y-srOnly&quot; role=&quot;status&quot; data-copy-status=&quot;&quot;&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;pre class=&quot;codeBlock_pre&quot; style=&quot;background-color:var(--code-bg);color:var(--ink)&quot; tabindex=&quot;0&quot; role=&quot;region&quot; aria-label=&quot;Code sample 1, before and after&quot;&gt;&lt;code&gt;&lt;span class=&quot;codeBlock_line-removed&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;−&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;/* a script toggles this class on &amp;#x3C;html&gt; */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;codeBlock_line-removed&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;−&lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-weight:bold&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;is-transitioning &lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-weight:bold&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;toolbar&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; pointer-events&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt; none&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;codeBlock_line-added&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;/* the selector tracks the transition itself */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;codeBlock_line-added&quot;&gt;&lt;span class=&quot;codeBlock_gutter&quot; aria-hidden=&quot;true&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;html:active-view-transition &lt;/span&gt;&lt;span style=&quot;color:var(--muted);font-weight:bold&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt;toolbar&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;color:var(--ink);font-weight:bold&quot;&gt; pointer-events&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;color:var(--ink)&quot;&gt; none&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt;;&lt;/span&gt;&lt;span style=&quot;color:var(--muted)&quot;&gt; }&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
&lt;p&gt;One thing to watch. In a browser too old to know this pseudo-class, the selectors spec makes any selector list containing an invalid selector invalid, whole. Appended to an existing comma-separated rule, &lt;code&gt;:active-view-transition&lt;/code&gt; takes the other selectors down with it. Give it its own block, or wrap it in &lt;code&gt;:where()&lt;/code&gt;, which parses forgivingly. Done that way, failure is graceful twice over: the rule never matches, and a browser without view transitions has no transition to style anyway.&lt;/p&gt;
&lt;p&gt;The four desktop stable runs pass the feature’s tests without exception. Neither Android runner produces a number worth reading: Chrome Android fails the suite’s reftests wholesale at the same engine version that passes on desktop, so the fault is more likely in the test harness than in the browser, and Firefox Android’s runs carry no results for these reftests at all. If current Firefox on Android is broken here, the cost is that your transition styles do not apply. Usage is early, about one page load in a hundred thousand, which is also the audience: no view transitions, nothing to delete yet.&lt;/p&gt;
&lt;h2&gt;02. &lt;code&gt;animation-composition&lt;/code&gt;&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Verdict: Skip&lt;/strong&gt; · Safe everywhere as of January 4, 2026&lt;/p&gt;&lt;p&gt;Skip, unless you run two animations against the same property of the same element. Then this is for you: it decides whether the second animation replaces the first, the default, or adds to it, or accumulates with it.&lt;/p&gt;
&lt;p&gt;It finished its 30 months of support on January 4 with a perfect score in every current stable run, and Chrome’s developer site gave it a dedicated write-up, more promotion than a property this situational usually gets. Hence the printed verdict: in most stylesheets two animations never meet on one property, so there is nothing to delete and nothing to start. Where they do meet, it works everywhere today.&lt;/p&gt;
&lt;p&gt;That was January: one release, one deletion, and a clearing shelf with nothing on it that needs removing.&lt;/p&gt;</content:encoded><category>January 2026</category></item></channel></rss>