<?xml version="1.0" encoding="utf-8"?>
  <rss version="2.0"
    xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:wfw="http://wellformedweb.org/CommentAPI/"
    xmlns:dc="http://purl.org/dc/elements/1.1/"
    xmlns:atom="http://www.w3.org/2005/Atom"
    xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
    xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
    xmlns:georss="http://www.georss.org/georss"
    xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#"
  >
    <channel>
      <title>Piccalilli - Articles</title>
      <link>https://piccalil.li/</link>
      <atom:link href="https://piccalil.li/articles.xml" rel="self" type="application/rss+xml" />
      <description>We are Piccalilli. A publication dedicated to providing high quality educational content to level up your front-end skills.</description>
      <language>en-GB</language>
      <copyright>Piccalilli - Articles 2026</copyright>
      <docs>https://www.rssboard.org/rss-specification</docs>
      <pubDate>Tue, 07 Apr 2026 01:01:30 GMT</pubDate>
      <lastBuildDate>Tue, 07 Apr 2026 01:01:30 GMT</lastBuildDate>

      
      <item>
        <title>A quick guide to creating syndication feeds</title>
        <link>https://piccalil.li/blog/a-quick-guide-to-creating-syndication-feeds/?ref=articles-rss-feed</link>
        <dc:creator><![CDATA[Declan Chidlow]]></dc:creator>
        <pubDate>Thu, 02 Apr 2026 11:55:00 GMT</pubDate>
        <guid isPermaLink="true">https://piccalil.li/blog/a-quick-guide-to-creating-syndication-feeds/?ref=articles-rss-feed</guid>
        <description><![CDATA[<p>News of RSS' death following the <a href="https://en.wikipedia.org/wiki/Google_Reader#Discontinuation">demise of Google Reader</a> has been greatly exaggerated. RSS is alive, well, and as omnipresent as ever. You aren't properly publishing content on the web if you aren't also publishing in syndication formats.</p>
<p>This is a general guide designed to help you understand, build, and distribute various formats of web feeds, even if you've never touched them before. We're not going to run through all the uses and details of syndication feeds, because they've been covered ad nauseam elsewhere. Instead, this article is designed to act as a reference which focuses on the principles of various feed formats so that people can subscribe to your content.</p>
<p>Consider this your article as a point of entry, or reference cheat-sheet.</p>
<div><h2>FYI</h2>
<p>In most cases, you won't need to hand-roll your own feeds. Most tools you encounter already have functionality for generating them automatically, but understanding them is to your strength.</p>
<p>This knowledge doesn't just apply to creating feeds but also parsing them and using them. In any case, when things go awry, actually understanding the formats will help you get back on track.</p>
</div>
<h2>RSS</h2>
<p>RSS has the best support out of any feed format but is also the oldest and has some design issues that can make it unideal. RSS files should be served with the MIME type <code>application/rss+xml</code>. For an example of a full RSS feed, you can view the feed for <a href="https://piccalil.li/the-index/">The Index</a>: <a href="https://piccalil.li/the-index/feed.xml">https://piccalil.li/the-index/feed.xml</a></p>
<h3>Boilerplate</h3>
<p>Like all of the formats this article will be discussing, RSS is just text. In this case, structured XML. RSS wraps everything in an <code>&lt;rss&gt;</code> tag with a version number, and then a single <code>&lt;channel&gt;</code> tag, which all of our RSS content will be held within.</p>
<pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;rss version="2.0"&gt;
  &lt;channel&gt;
  &lt;/channel&gt;
&lt;/rss&gt;
</code></pre>
<h3>Metadata</h3>
<p>Before listing our articles, we need to describe the feed itself. We are required to have at least a <code>title</code>, <code>link</code>, and <code>description</code>, like so:</p>
<pre><code>&lt;title&gt;Name of our feed&lt;/title&gt;
&lt;link&gt;https://example.com&lt;/link&gt;
&lt;description&gt;A short description of the feed.&lt;/description&gt;
</code></pre>
<p>However, there are also many additional optional values we can include: <code>language</code>, <code>copyright</code>, <code>managingEditor</code>, <code>webMaster</code>, <code>pubDate</code>, <code>lastBuildDate</code>, <code>category</code>, <code>generator</code>, <code>docs</code>, <code>cloud</code>, <code>ttl</code>, <code>image</code>, <code>rating</code>, <code>textInput</code>, <code>skipHours</code>, <code>skipDays</code>.</p>
<p>Dates in RSS conform to <a href="https://www.w3.org/Protocols/rfc822/#z28">RFC-822</a>. This means they look like this: <code>Tue, 11 Jun 2024 15:00:00 GMT</code>. Though RFC-822 does permit two-digit years, four digits are widely preferred.</p>
<h3>Items</h3>
<p>Items are the individual entries in your RSS feed, whether they be posts or something else. There are two schools of thought for what content should be included here. One follows the idea that feeds should contain the entire content, unabridged. Others think that feeds should only contain a summary of the content and that it should be read on the site. The preference differs by user, but there is no downside to supplying both if you wish.</p>
<p>The items are the meat of the feed. You loop through your posts and output an item for each one. In RSS, each post is an <code>&lt;item&gt;</code>. All elements in an item are optional, but you must have at least a title or description.</p>
<pre><code>&lt;item&gt;
  &lt;title&gt;A quick and easy guide to Markdown&lt;/title&gt;
  &lt;link&gt;https://piccalil.li/blog/markdown-guide/&lt;/link&gt;
  &lt;pubDate&gt;Tue, 11 Jun 2024 15:00:00 GMT&lt;/pubDate&gt;
  &lt;description&gt;This is the summary of the post...&lt;/description&gt;
&lt;/item&gt;
</code></pre>
<p>As a word on etiquette, don't publish items with future dates. Most feed readers will just omit them, but some will display them at the top, which is attention-grabbing. Many users consider this bad manners and will probably unsubscribe.</p>
<p></p>
<h2>Atom</h2>
<p>Like RSS, Atom is XML-based, but is a little bit stricter and more finely specced than RSS, which makes it slightly less forgiving to author, but much nicer to parse. Atom files should be served with the MIME type <code>application/atom+xml</code>.</p>
<p>You can see a full example of an Atom feed <a href="https://sample-feeds.rowanmanning.com/examples/64968fb0e3685ef07a3e2a27b8d64c01/feed.xml">here</a>.</p>
<h3>Boilerplate</h3>
<p>Atom uses a root <code>&lt;feed&gt;</code> element and requires an XML namespace (<code>xmlns</code>).</p>
<pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;feed xmlns="http://www.w3.org/2005/Atom"&gt;
&lt;/feed&gt;
</code></pre>
<h3>Metadata</h3>
<p>You need an <code>id</code>, <code>title</code>, and an <code>updated</code> timestamp. The homepage URL is often used for the <code>id</code> value. <code>author</code> is also required, unless every single entry has an <code>author</code> value.</p>
<p>Atom dates are written in accordance with <a href="https://www.rfc-editor.org/rfc/rfc3339">RFC-3339</a>, which is based on ISO-8601, and looks like this: <code>2024-06-11T15:00:00Z</code>.</p>
<pre><code>&lt;title&gt;Piccalilli&lt;/title&gt;
&lt;link href="https://piccalil.li/"/&gt;
&lt;updated&gt;2024-06-11T15:00:00Z&lt;/updated&gt;
&lt;id&gt;https://piccalil.li/&lt;/id&gt;
&lt;author&gt;
  &lt;name&gt;Andy Bell&lt;/name&gt;
&lt;/author&gt;
</code></pre>
<h3>Entries</h3>
<p>In Atom, each post is an <code>&lt;entry&gt;</code>. Only <code>id</code>, <code>title</code>, and <code>updated</code> value are required, though you can optionally include <code>author</code>, <code>content</code>, <code>link</code>, <code>summary</code>, <code>category</code>, <code>contributor</code>, <code>published</code>, <code>rights</code>, and <code>source</code>. <code>id</code> must be unique for the entry and must not change.</p>
<pre><code>&lt;entry&gt;
  &lt;title&gt;A quick and easy guide to Markdown&lt;/title&gt;
  &lt;link href="https://piccalil.li/blog/markdown-guide/"/&gt;
  &lt;id&gt;https://piccalil.li/blog/markdown-guide/&lt;/id&gt;
  &lt;updated&gt;2024-06-11T15:00:00Z&lt;/updated&gt;
  &lt;summary&gt;This is the summary...&lt;/summary&gt;
&lt;/entry&gt;
</code></pre>
<h2>JSON Feed</h2>
<p>JSON Feed is the newest format discussed here and, as the name suggests, is JSON based rather than XML based. JSON Feed files should be served with the MIME type <code>application/feed+json</code>.</p>
<p>For an example of a JSON Feed, you can view the one for posts on my personal website: <a href="https://vale.rocks/posts/feed.json">https://vale.rocks/posts/feed.json</a></p>
<h3>Boilerplate and metadata</h3>
<p>JSON Feed doesn't have much boilerplate compared to RSS and Atom. You must create an object, and that object must contain the JSON Feed version and a <code>title</code>. Though there are many optional values, many of which you should include: <code>home_page_url</code>, <code>feed_url</code>, <code>description</code>, <code>user_comment</code>, <code>next_url</code>, <code>icon</code>, <code>favicon</code>, <code>authors</code>, <code>language</code>, <code>expired</code>, and <code>hubs</code>.</p>
<pre><code>{
	"version": "https://jsonfeed.org/version/1.1",
	"title": "My Blog"
}
</code></pre>
<h2>Items</h2>
<p>Items is represented as an array. The only truly required values are <code>id</code> — which uniquely identifies the item — and <code>content_html</code> and/or <code>content_text</code>. The optional values are <code>url</code>, <code>external_url</code>, <code>title</code>, <code>summary</code>, <code>image</code>, <code>banner_image</code>, <code>date_published</code>, <code>date_modified</code>, <code>authors</code>, <code>tags</code>, and <code>language</code>.</p>
<p>You can also provide attachments on an item.</p>
<pre><code>"items": [
    {
        "id": "1",
        "content_text": "This is an item in the feed.",
        "url": "https://example.org/item-one"
    }
]
</code></pre>
<h2>Auto-discovery</h2>
<p>Many feed readers and other tools can automatically detect your feeds if you configure them correctly. You should add <code>&lt;link&gt;</code> tags to the <code>&lt;head&gt;</code> of your HTML to aide discovery.</p>
<pre><code>&lt;link rel="alternate" type="application/rss+xml" title="My Site's RSS Feed" href="https://example.com/rss.xml" /&gt;
&lt;link rel="alternate" type="application/atom+xml" title="My Site's Atom Feed" href="https://example.com/atom.xml" /&gt;
&lt;link rel="alternate" type="application/feed+json" title="My Site's JSON Feed" href="https://example.com/feed.json" /&gt;
</code></pre>
<p>Different tools interpret these tags differently. Some feed readers will, for example, provide users with the choice to select what feed they want from the provided options. Others will pick the first valid feed in the list, or pick the last. There is, unfortunately, very little consistency.</p>
<p></p>
<h2>Implementation gotchas</h2>
<p>Feeds are consumed by all sorts of tools in all sorts of contexts, so what works in one case might cause issues in another. It is important to stick close to the specs and consider defensive precautions.</p>
<h3>Relative content</h3>
<p>Feed readers are disconnected from your site. Relative links like <code>&lt;img src="/images/cat.jpg"&gt;</code> will often break because they are not relative to the website. Some feed readers may work around this problem, but you should convert all links (images, anchors, etc) to full, absolute URLs to ensure they work in all contexts.</p>
<h3>Encoding</h3>
<p>One of XML's most notorious attributes is that it is rather fragile. For example, if your blog post title is <code>Tips &amp; Tricks</code>, and you put that raw into XML, it breaks:</p>
<pre><code>&lt;title&gt;Tips &amp; Tricks&lt;/title&gt;
</code></pre>
<p>This is due to the <code>&amp;</code> character being reserved. For cases like this, you have two main options:</p>
<ol>
<li>
<p><strong>Entity Escaping</strong> <br />
Convert special characters to their HTML entities.</p>
<pre><code>&lt;title&gt;Tips &amp;amp; Tricks&lt;/title&gt;
</code></pre>
</li>
<li>
<p><strong>CDATA</strong> <br />
Wrap the whole thing in a CDATA block. This tells the XML parser, 'Ignore everything inside here. It's literally just text', which is great for the body of your content where you have lots of HTML tags and special characters, where it might be laborious to transform them.</p>
<pre><code>&lt;description&gt;
  &lt;![CDATA[
    &lt;p&gt;Here are my &lt;strong&gt;Tips &amp; Tricks&lt;/strong&gt;...&lt;/p&gt;
  ]]&gt;
&lt;/description&gt;
</code></pre>
</li>
</ol>
<h3>Feed access controls</h3>
<p>We often configure bot and scraping protection on our sites, but in this case we <em>want</em> our feeds to be scraped. We also likely want to make images and other resources able to be displayed in readers, so we may need to relax our protections. Our sites are also often served cached. Ensure your caching policy aligns with your feed updates — there is no point updating a feed if the cache means it won't reach readers!</p>
<p>Something else worth keeping in mind are security policies, such as CORS. While feeds are usually fetched server-side by aggregators, some web-based feed readers fetch feeds directly via the browser. Setting an <code>Access-Control-Allow-Origin: *</code> header on your XML/JSON files ensures these web-based clients don't get blocked by security policies.</p>

<p><a href="https://www.blogsareback.com/guides/enable-cors?platform=Netlify">There’s a great resource here</a> to help you with CORS, by the browser-based RSS reader, <a href="https://www.blogsareback.com/">Blogs Are Back</a>.</p>

<h3>Limited display</h3>
<p>Many feed readers only display certain elements, such as text, images, and blockquotes, then apply their own formatting. This makes proper semantic HTML important, because non-semantic elements will not be understood or styled by readers.</p>
<p>The removal of provided formatting could cause issues if your content is complex or dynamic. In such a case, it can be worth only providing a summary or incorporating a notice directly into your feed noting that the content is best viewed on the web.</p>
<h2>Validation and testing your feeds</h2>
<p>Checking your feeds are proper by eye can be tricky, which is where validators are valuable.</p>
<ul>
<li>For RSS and Atom, you can use the <a href="https://validator.w3.org/feed/">W3C Feed Validation Service</a>.</li>
<li>For JSON Feeds, you can use the <a href="https://validator.jsonfeed.org/">JSON Feed Validator</a>.</li>
</ul>
<p>These validators will catch those pesky date format errors and unescaped content instantly. There are also many libraries and other tools out there that you can incorporate as part of your processes so that broken feeds are caught before they can hit production.</p>
<p>You should also try opening your feeds in a few feed readers and other syndication feed tools, just to confirm all works without issue — much like you already test a website across a few browsers.</p>
<h2>Wrapping up</h2>
<p>This article has only skipped along the top of the syndication feed ocean but has hopefully given you a level of knowledge ready to start building feeds. Having feeds for your content is not just vital for distribution but also contributes to a strong and healthy web.</p>
<p>If you're looking to dive deep into the feed ocean, these further reading links will hopefully provide you with some solid entry points:</p>
<ul>
<li><a href="https://www.rssboard.org/rss-specification">RSS 2.0 Specification</a></li>
<li><a href="https://validator.w3.org/feed/docs/atom.html">Introduction to Atom</a></li>
<li><a href="https://www.rfc-editor.org/rfc/rfc4287">RFC 4287: The Atom Syndication Format</a></li>
<li><a href="https://www.jsonfeed.org/version/1.1/">JSON Feed Version 1.1 Explainer</a></li>
</ul>
        
        ]]></description>
        
      </item>
    
      <item>
        <title>Applying accessibility fixes with stealth for the greater good</title>
        <link>https://piccalil.li/blog/applying-accessibility-fixes-with-stealth-for-the-greater-good/?ref=articles-rss-feed</link>
        <dc:creator><![CDATA[Steve Frenzel]]></dc:creator>
        <pubDate>Thu, 26 Mar 2026 11:55:00 GMT</pubDate>
        <guid isPermaLink="true">https://piccalil.li/blog/applying-accessibility-fixes-with-stealth-for-the-greater-good/?ref=articles-rss-feed</guid>
        <description><![CDATA[<p>Accessibility had never really played a significant role since I started working as a front-end developer in 2019. It didn’t have a significant role in my boot camp, or in YouTube tutorials I watched, and certainly not in my job.</p>
<p>At some point I got very invested in accessibility, because it was the missing link for me in my profession. Suddenly, the things I built not only looked good, but they also worked as expected when using a keyboard and a screen reader. Slowly, practicing web development with accessibility in mind became the new normal for me. Unfortunately though, <a href="https://webaim.org/projects/million/#errors">accessibility is still far from normal in the tech industry</a>.</p>
<p>Before I get into the craft, technical aspects and how to sneak fixes in, I would first like to address that a major inspiration for this piece was <a href="https://dpersing.com/book/">The Accessibility Operations Guidebook</a> by <a href="https://dpersing.com/">Devon Persing</a>.</p>
<h2>Ableism (in the tech industry)</h2>
<p>If you haven't heard this term before, here's a summary from the <a href="https://en.wikipedia.org/wiki/Ableism">Wikipedia on ableism</a>:</p>
<blockquote>
<p>Ableism […] is discrimination and social prejudice against physically or mentally disabled people. Ableism characterises people as they are defined by their disabilities and also classifies disabled people as being inferior to non-disabled people.</p>
</blockquote>
<p>In the following, I will try to use my own experiences to illustrate when I have encountered ableism during my job.</p>
<h3>Medical model of disability</h3>
<p>Whenever I brought up the topic and pointed out barriers, it was assumed that these barriers arose or existed because people with disabilities were using the product. So the fault lies with the people, not the product.</p>
<p>This is the <a href="https://en.wikipedia.org/wiki/Medical_model_of_disability">medical model of disability</a>, which assumes that people, rather than their environment, are the problem:</p>
<blockquote>
<p>This model links a disability diagnosis to an individual's physical body. The model supposes that a disability may reduce the individual's quality of life and aims to correct or diminish the disability with medical intervention.</p>
</blockquote>
<p>As long as you can operate everything with the mouse and you can still somewhat recognise the light grey font on a white background with font size 10, everything is fine, right? This attitude is ableist because, among other things, it excludes not only keyboard users but also people with poor, or even <em>no</em> vision.</p>
<p>People with disabilities don't use the product anyway, so why invest time and money to make it accessible to a few blind people, right? This attitude is also ableist, because in Germany alone, the <a href="https://www.destatis.de/EN/Themes/Society-Environment/Health/Disabled-People/_node.html">official number of people with severe disabilities</a> is 7.9 million, and the real number is very likely much higher. From an economic point of view alone, it makes no sense to ignore the potential purchasing power of these people.</p>
<p><a href="https://en.wikipedia.org/wiki/Medical_model_of_disability">Wikipedia explicitly addresses this very attitude</a>:</p>
<blockquote>
<p>In ableist societies, the lives of disabled people are considered less worth living, or disabled people less valuable, even sometimes expendable.</p>
</blockquote>
<p>This ableist attitude is reflected in statements such as “We don't have any customers with disabilities.” or “We don't have any blind users, so it doesn't need to be keyboard-accessible.” These and many other myths are debunked on the <a href="https://a11ymyths.com/">Accessibility Myths Debunked</a> website. Fortunately, there is also a counter-model for this, namely:</p>
<h3>Social model of disability</h3>
<p>The <a href="https://en.wikipedia.org/wiki/Social_model_of_disability">social model of disability</a> is summarised as follows on Wikipedia:</p>
<blockquote>
<p>The social model of disability proposes that people are disabled by systemic barriers, negative attitudes, and social exclusion, rather than by their own physical or mental differences.</p>
</blockquote>
<p>Here, we recognise that the problem is not <em>people</em> with disabilities who can only use the product to a limited extent or not at all. Instead, it shows us that <em>we ourselves</em> have created these barriers through our ableist attitudes.</p>
<p>This realisation can lead us to start making real changes and improvements, starting with the people, through the tools we use every day, to the product we create.</p>
<p>My personal recommendation is always to start with the <a href="https://webaim.org/projects/million/#wcag">six most common problems</a> and then continue with the <a href="https://www.w3.org/WAI/test-evaluate/easy-checks/">Easy Checks</a>. Many so-called “low hanging fruits” can be detected using automated tools such as <a href="https://www.tpgi.com/arc-platform/arc-toolkit/">ARC Toolkit</a>, <a href="https://www.deque.com/axe/devtools/">Axe DevTools</a>, and <a href="https://wave.webaim.org/">WAVE</a>. This makes it easier to document and fix problems at the beginning before tackling more complex issues where these tools reach their limits.</p>
<p>However, we still need to dig deeper to understand why this article you’re reading right now, exists in the first place.</p>
<p>With a few exceptions, the teams I work in have been, and continue to be predominantly white and male. This is certainly also due to the fact that I live and work in Germany, which is why I asked my friends who also work in development how diverse their working environment is.</p>
<p>Their situation is similar to mine (they also live and work in Germany), and they too have noticed that female colleagues are more likely to be found in the design, marketing, and management departments. In development, however, their colleagues are also predominantly white and male, which brings me to the next topic:</p>
<p></p>
<h2>Battling against ableism in the tech industry</h2>
<p>In her essay <a href="https://www.whitesupremacyculture.info/">White Supremacy Culture</a>, Tema Okun touches on many topics that overlap with my professional career as a front-end developer. Lots of companies seem to have embodied and implemented these awful characteristics and from what I can tell, this seems to be the default behaviour. The <a href="https://en.wikipedia.org/wiki/White_Supremacy_Culture#Contents">Wikipedia article on her essay</a> lists 15 characteristics, of which I will quote three that I have experienced myself:</p>
<blockquote>
<p><strong>Sense of urgency:</strong> Emphasising speed and immediate results at the cost of thoughtful reflection or long-term solutions.</p>
</blockquote>
<p>Who among you has been told that there is no time or money to make the product accessible? Or that it will be done later because it has to go live now due to pressure from management and/or stakeholders?</p>
<p>This <a href="https://en.wikipedia.org/wiki/Meta_Platforms#History">move fast and break things</a> attitude leads to products reaching the market that were created for the majority but exclude minorities. In addition, in the long term, it can lead to enormous time and cost expenditures if accessibility is only considered at the end of the cycle.</p>
<p>If <a href="https://www.deque.com/blog/design-code-thinking-accessibility-ground/">companies shift to the left</a> instead and work according to the motto <a href="https://piccalil.li/complete-css/lessons/5">“Slow is smooth. Smooth is fast.”</a> they will not only aim to create the most inclusive product possible, but also offer added value in other areas:</p>
<ul>
<li>You reach a larger customer base</li>
<li>The risk of being sued can be vastly reduced or even completely eliminated</li>
<li>By focusing on accessibility, product quality and employee mindset can be greatly improved</li>
</ul>
<p>The whole team is responsible, not just the development team. We can only make lasting changes and avoid making people responsible if we take a comprehensive approach that includes everyone.</p>
<blockquote>
<p><strong>Quantity over quality:</strong> Prioritising "things that can be measured" over things that cannot, such as relationships and conflict resolution.</p>
</blockquote>
<p>It is now (for better or worse) normal for websites to measure where people click, how long they watch videos, whether they skip certain sections, and so on. Thanks to automated testing, many accessibility issues can also be recorded as metrics. However, this does not mean that a product is 100% accessible as soon as these tests no longer show any errors! You can <a href="https://www.matuzo.at/blog/building-the-most-inaccessible-site-possible-with-a-perfect-lighthouse-score/">build the most inaccessible website with a perfect Lighthouse score</a>, as Manuel Matuzović has impressively proven. Automated tests are an indicator of how compliant something is, but not how well people can actually use it.</p>
<p>That's why it's very difficult, if not impossible, to quantify the return on investment (ROI) for accessibility. So-called “invisible wins” are particularly difficult to sell if the focus is not on the structure, but only on the appearance of a product.</p>
<p>If you just click through with the mouse, quality of life improvements such as consistent, clearly visible keyboard focus, landmark elements, and the correct use of <a href="https://www.w3.org/WAI/standards-guidelines/aria/">WAI-ARIA</a> unfortunately go unnoticed.</p>
<p>Simply taking these three things into account can lead to more people being able to use the product, regardless of whether they have a disability or not. This can lead to more satisfied customers, who are very likely to recommend the product to others. This can expand the customer base, which in turn can lead to increased sales.</p>
<blockquote>
<p><strong>Only one right way:</strong> Believing that there is only one correct way to do things, excluding diverse approaches and perspectives.</p>
</blockquote>
<p>One of the websites I share most often is <a href="https://viewports.fyi/">The ideal viewport doesn't exist</a>. It uses real data and practical examples to show us that it no longer makes sense to stick to the rigid concept of breakpoints. How are you supposed to know what screen width a “desktop,” “tablet,” or “phone” has?</p>
<p>Doesn't it make much more sense to <a href="https://buildexcellentwebsit.es/">be the browsers mentor, not its micromanager</a>? We have long had the ability to implement <a href="https://utopia.fyi/">fluid typography and UI</a> that adapts to the respective screen widths. CSS allows us to do this thanks to <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Guides/Cascading_variables/Using_custom_properties">custom properties</a>, the <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Values/clamp">clamp()</a> and <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Values/minmax">minmax()</a> functions, and <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/At-rules/@container">container queries</a>.</p>
<p>The advantages are as numerous as they are obvious:</p>
<ul>
<li>No need to think up or research arbitrary breakpoint sizes. A design is created for the maximum and minimum width, and browsers take care of everything in between.</li>
<li>Realising that the pixel-perfect approach is like chasing the dragon: it's the pursuit of an unattainable goal. Designs for websites are just paintings of them. <a href="https://adamsilver.io/blog/design-in-code-get-praise/">Actual software is alive; it responds, it adapts, it moves, it errors, it loads.</a></li>
<li>The amount of CSS code can be drastically reduced because edge cases no longer need to be taken into account. <a href="https://ishadeed.com/article/cascade-layers/">Cascade layers</a> could then be used for fine-tuning.</li>
<li>The code base is easier to read, more robust, and future-proof because these features tend to be used more in the foreseeable future.</li>
</ul>
<p>Am I making sense here? I think I do! After I made this pitch, however, the reactions were mostly “but we've always done it this way” (<em>love</em> this one) or “But what breakpoint sizes do we use then?” in addition to huge question marks above the heads of the respective recipients.</p>
<p>My suggestion to modify a small side project or the current main project according to this principle was often rejected because the concept is too new, too alien and people would have to move out of their comfort zone and adapt their way of working.</p>
<p>After dealing with these uncomfortable topics that need to be addressed and discussed, and perhaps feeling that it is impossible for you to bring about any change, you may ask yourself the following:</p>
<p></p>
<h2>Why would you do it if it’s not part of your job?</h2>
<p>Perhaps, like me, you are officially a front-end developer and your contract more or less specifies your area of responsibility. So why should you be doing the work of an accessibility practitioner / designer / engineer? My answer is always: because it's <strong>part of the work</strong>.</p>
<p>Among all the things that lead from the initial idea to the final website, I don't see any distinction between ‘normal’ work (i.e. what's in your contract) and work in the realm of accessibility. Three examples from the top of my head to get my point across:</p>
<ol>
<li>The work is not done if the thing we are working on cannot be operated with a keyboard</li>
<li>The work is not done if complex widgets do not have a meaningful semantic role and an accessible name</li>
<li>The work is not done if there are problems with colour contrast because the brand colours are always to be used</li>
</ol>
<p>As already mentioned, accessibility is not yet as normalised as many other topics. But if it is as important to you as it is to me, you will have to ask yourself another question:</p>
<h2>Why wouldn’t you tell your boss?</h2>
<p>Here, too, the answer can be complex and individual. A few possible scenarios could be:</p>
<h3>It’s not part of your job description</h3>
<p>If your employer thinks that accessibility isn't part of your job and is something separate, then they're not entirely wrong. If you're dealing with this issue at management level, for example, in order to integrate it into all processes throughout the company, it really is a full-time job. But I digress!</p>
<p>Your contract does not explicitly state that accessibility is part of your job, and you don't want to fall out with your employer. It may also be that you have a very strict employer, which would be another reason to keep it secret.</p>
<h3>“No time and money for accessibility”</h3>
<p>One of the most popular myths! This one is also disproved succinctly at <a href="https://a11ymyths.com/">Accessibility Myths Debunked</a>:</p>
<blockquote>
<p>It may not be the case if accessibility is considered from the beginning of the project and a development team has proper skills. When accessibility has become a habit, the <strong>development time doesn't change</strong> or changes a little.</p>
</blockquote>
<p>Unfortunately, that doesn't change the fact that your boss insists on it and you feel compelled to improve the website behind their back.</p>
<h3>No interest or pushback</h3>
<blockquote>
<p>“I don't give a damn about accessibility, I'm not interested in it! But I think it's good that you're involved in it and know about it.”</p>
</blockquote>
<p>This is something a front-end developer once said to me. They simply have no interest because they have never used a website with a keyboard in their lives or are firmly convinced <a href="https://tetralogical.com/blog/2025/12/03/common-misconceptions-about-disability/">that it only affects people with disabilities</a>, who are not their customers anyway. Could this be because the website is not accessible? Maybe, but I don't want to digress again!</p>
<p>They may even react irritably or go on the offensive when you bring up the subject. This can happen very quickly when you show people that they have an ableist approach to an issue. Caution is advised here, because it can quickly become personal. That would be another reason to take a low-key approach to the issue.</p>
<p>Do these scenarios sound familiar, and do you still see it as your responsibility to make the product you are working on as accessible as possible, even though it is not officially your job? Then, in the following sections, we will discuss how to find allies and work with them to create leverage.</p>
<h2>Culture, climate and power lines</h2>
<p>In this scenario, we assume that we will not receive any support “from the top” and will have to organise ourselves like a <a href="https://en.wikipedia.org/wiki/Grassroots">grassroots movement</a> from the bottom up. For this to work, we need allies, no matter how big or small our company is. This will not only help us to distribute tasks and responsibilities, but also <a href="https://aaardvarkaccessibility.com/accessibility-without-burnout/">reduce the potential psychological pressure</a> that can come with it.</p>
<p>To understand how we can reach and communicate with the respective people, we need to understand the difference between culture and climate and how we can use power lines for our purposes. The following quotes are taken directly from The Accessibility Operations Guidebook by Devon Persing:</p>
<blockquote>
<p>Organisations are impacted both by their <strong>culture</strong>, which is driven by a minority in leadership, and their <strong>climate</strong>, which is driven by the majority of people in the organisation. Resources, support and information flow through organisations along <strong>power lines</strong>.</p>
</blockquote>
<p>She further explains that “organisational culture is formal and systemic”, while “organisational climate is informal, a kind of ‘shared perception’ of the organisation’s day-to-day”.</p>
<blockquote>
<p><strong>People in official leadership roles create an organisation’s culture.</strong> They communicate this culture to other members through management.</p>
</blockquote>
<p>This can be understood as the “official stance of the organisation”, like a mission statement, for example. It is “perpetuated in the same way it is in the larger culture, with ceremonies and rituals (meetings, events) and institutional myths (stories) by leadership.”</p>
<blockquote>
<p><strong>Climate, in comparison to culture, is less official. It’s a vibe.</strong> It’s the feel of the organisation, how structured or loosey-goosey it is.</p>
</blockquote>
<p>This describes “how much freedom workers really have, and how much actual support they have from leadership to try new things or make the workplace better.”</p>
<p>She continues by explaining that culture (top) can obviously can push down on climate (bottom), but that climate can also push up on culture.</p>
<p>One example for the former is “an organisation requiring workers to return to corporate offices with the supposed end of the COVID-19 pandemic, despite public opinion and scientific data supporting the positives of working from home.”</p>
<p><a href="https://pubmed.ncbi.nlm.nih.gov/35162145/">Healthy and Happy Working from Home? Effects of Working from Home on Employee Health and Job Satisfaction</a></p>
<p>An example for the latter is “the wave of <a href="https://en.wikipedia.org/wiki/Diversity,_equity,_and_inclusion">diversity, equality and inclusion</a> (DEI) efforts that happened because of Black workers’ need to hold space around ongoing and escalating police brutality.”</p>
<p><a href="https://scholarlycommons.law.emory.edu/ecgar/vol8/iss1/6/">How the Black Lives Matter Movement Enhanced Corporate Governance in 2020</a></p>
<blockquote>
<p>In an organisation, power lines are usually connected to people like managers who represent their teams or departments. […] The way that culture and climate can push each other is a form of power […]</p>
</blockquote>
<p>She explains that “power lines are usually connected to people like managers who represent their teams or departments.” and she’s mentioning specialists, meaning people that have a focus on a certain topic, who can “become conduits for these types of lines, too”.</p>
<p>In case of the (accessibility) specialist, she’s warning that it can be “easy to become a bottleneck for other people while you’re trying to do accessibility work across an organisation, even if that’s not your intent.”</p>
<p>With this basic understanding, let's look at the most important point so that we can successfully sneak in accessibility fixes without telling our boss.</p>
<h2>Finding allies</h2>
<p>I'll be honest with you: I can't give you bulletproof instructions on how to find allies in your company because it depends on so many variables, including (but not limited to):</p>
<ul>
<li>Your personality, professional experience, expertise, and rhetorical skills</li>
<li>The culture and climate in your current company</li>
<li>The personality, professional experience, expertise, and rhetorical skills of your colleagues</li>
</ul>
<p>Instead, I'll tell you a few anecdotes about how I've been able to make a difference in the area of accessibility, sometimes more, sometimes less.</p>
<h3>Being upfront</h3>
<p>As I wrote at the beginning, it was only during the course of my career that I began to focus clearly on the topic of accessibility. At a certain point, I made it very clear in interviews (for permanent positions and freelance jobs alike) that I would be concentrating on this area.</p>
<p>My pitch was more or less what I wrote under <a href="#why-would-you-do-it-if-its-not-part-of-your-job"><em>Why would you do it, if it’s not part of your job?</em></a> I also made it clear that I work holistically and don't see the topic as my sole responsibility. It affects development, design, management, human resources, and other departments equally.</p>
<p>When I was first introduced to a team, it was mentioned that I was very knowledgeable about the topic and an expert (which is not true, and I clarified that right away). I was also allowed to repeat my pitch in front of the assembled team, which signalled to interested colleagues, “Aha, he's one of us!” or “Nice, I have a few questions on the topic.”</p>
<p>From that point on, I was “the accessibility guy,” which can have advantages, but also disadvantages, as some colleagues might associate it with something negative. Very often, people approached me proactively afterwards or were very open when I talked about it. Not just developers and designers, but also product owners and marketing people!</p>
<h3>Sharing knowledge</h3>
<p>As mentioned earlier, I don't see it as my responsibility to carry the burden of this issue alone. That's why I first check the respective communication tool (Slack, Teams, etc.) to see if there is a channel for accessibility so that I can share knowledge.</p>
<p>Unfortunately, in the past, creating this channel and inviting people has not been very effective. Either the topic is too overwhelming for them, or they are not interested because it is not directly related to their daily business. More often than not, I was just screaming into the void, and there was no real interaction except for an emoji here and there.</p>
<p>Since we are pursuing a grassroots movement approach, I recommend instead looking for a channel where knowledge is actively shared among developers and/or designers. Maybe there are even a few people from management in this channel! In any case, this channel must be alive.</p>
<p>Here I often share articles that I read in my favourite newsletters: <a href="https://a11yweekly.com/">Accessibility Weekly</a>, <a href="https://webweekly.email/">Web Weekly</a>, and <em>of course</em> <a href="https://piccalil.li/the-index/">The Index</a>. These sources provide enough material to keep the digital fire burning and share something at least once a week.</p>
<h3>Showing examples</h3>
<p>I had the biggest breakthroughs when I showed people directly on the respective product what positive effects improved accessibility can have.</p>
<p>In development, it was for example the use of native elements instead of third-party solutions. Everyone in this department is happy when <em>even more</em> dependencies and potential security risks are not added to <code>package.json</code>. Another great example for low effort and big impact: <a href="https://www.stevefrenzel.dev/posts/x-marks-the-spot-landmark-elements/">Landmark elements</a>!</p>
<p>Even seemingly small things like using headings correctly can have a big impact. Especially after I navigated them with a screen reader and explained why it is so important for users of this software. Some people were amazed that screen readers exist and that content can be consumed in this way!</p>
<p>Using the <a href="https://www.figma.com/community/plugin/732603254453395948/stark-contrast-accessibility-checker">Stark plugin for Figma</a>, I was able to show designers how they can take this topic into account during creation and handover. I even wrote an article about it, <a href="https://www.stevefrenzel.dev/posts/fuck-off-to-hand-off-holistic-web-design/">“Fuck off” to hand-off: Holistic web design</a>.</p>
<p></p>
<h2>Different roles require different techniques</h2>
<p>I'm an RPG fan, by which I mean Final Fantasy 7 to 12, Dragon Quest, Ni No Kuni, you name it. That's why in this section I'm introducing four roles (or avatars?) that have specific skills to promote accessibility within the organisation.</p>
<p>Depending on our role in the company, our skills and allies, and how much support we receive from our colleagues, we can take on different roles.</p>
<p>A role also depends on when we join a project. The earlier we become involved, the more likely it is that we will have taken on every role at some point.</p>
<h3>The adviser</h3>
<p>This is my personal favourite role, because it allows us to avoid future mistakes and do a lot of educational work.</p>
<p>Is the project supposed to be a simple landing page that won't really be maintained by the customer, or hardly at all? Then we can advise against using heavyweights like React or Vue.js and instead recommend a static site generator like <a href="https://astro.build/">Astro</a> or <a href="https://www.11ty.dev/">Eleventy</a> (now called Build Awesome).</p>
<p>Do your colleagues want to use a UI library to speed up the design and development process? Fair enough, but it should be tested beforehand to ensure that it is accessible and that, in individual cases, <a href="https://paulmakeswebsites.com/writing/shadcn-radio-button/">components can be replaced with native HTML elements</a>.</p>
<p>This stage of the process is also a good time to talk about <a href="https://piccalil.li/blog/its-about-time-i-tried-to-explain-what-progressive-enhancement-actually-is/">progressive enhancement</a>. Not only does it bring many benefits for users, but it will also increase the skill level of the designers and developers involved.</p>
<h3>The mediator</h3>
<p>This role can overlap somewhat with that of an adviser, depending on how open and flexible the designers are, how good our communication skills are, and how much time is available for any changes.</p>
<p>At this stage, designs have already been created and are ready to be handed over to development. Ideally, they will first be reviewed by a developer and only passed on once all changes have been implemented and the go-ahead has been given.</p>
<p>Here, too, we can do a lot of educational work on the topic of progressive enhancement, explain the power of native HTML and CSS, and suggest tools that make the handover even smoother. The goal is to minimise follow-up questions from the development team so that they can get started right away.</p>
<p>The article <a href="https://stephaniewalter.design/blog/accessibility-resources-tools-articles-books-for-designer/">Accessibility for designers: where do I start?</a> by Stephanie Walter is a treasure trove for exactly this scenario, providing you with the resources you need to support your designers. I also strongly agree that <a href="https://piccalil.li/blog/the-time-for-designers-to-learn-to-code-is-now/">the time for designers to learn to code is now</a>.</p>
<h3>The smuggler</h3>
<p>The following example comes from <a href="https://amberhinds.com/">Amber Hinds</a>, thank you for sharing!</p>
<blockquote>
<p>We have clients who really care about SEO, some of whom are legacy clients on marketing retainers. Because there's so much overlap, we are able to use SEO hours to fix accessibility. We put our Accessibility Checker WordPress plugin on the site to find issues and fix things like empty links, links with ambiguous anchors, headings out of order, empty or missing alternative text, etc. I don't think that these clients would ever sign up for an accessibility retainer, but because of SEO we can do it.</p>
</blockquote>
<p>We often slip into this role when we’re actively working on development and can make various small to medium fixes that don't slow us down in our main task.</p>
<p>This is not only a good “selling point” for our superiors, but also another opportunity to show our colleagues, using practical examples, that accessibility doesn't have to be difficult.</p>
<p>During these sneaky fixes, wen can often notice larger, global problems, such as:</p>
<ul>
<li>Insufficient colour contrast and font sizes</li>
<li>Poorly recognisable or non-existent keyboard focus</li>
<li>Missing or incorrectly used landmark elements</li>
</ul>
<p>These should at least be documented and, best case, turned into a ticket that can be <a href="https://intopia.digital/articles/straight-to-the-pool-room-the-pitfalls-of-placing-accessibility-issues-in-the-backlog/">dealt with in a timely manner so they won’t catch dust in the backlog</a>.</p>
<h3>The hacker</h3>
<p>This role is exclusively for developers and overlaps somewhat with the adviser role. It can be a rather passive role, as we ask, for example, whether an <a href="https://docs.deque.com/linter/4.0.0/en/using-linter-home">accessibility linter</a> is used in the code editor (very often Visual Studio Code or JetBrains) to identify potential problems during development.</p>
<p>Or whether an accessibility linter can be integrated into a <a href="https://typicode.github.io/husky/">pre-commit hook</a> so that non-accessible code cannot be pushed in the first place. Another option would be to add this linter to the pipeline.</p>
<p>Regardless of whether it is part of the definition of done (if there is one) or not: as soon as we find potential accessibility issues during a code review, we should at least leave a comment.</p>
<p>Best case, we can mark the respective pull request as “not approved” until the issue has been resolved. However, a delicate touch and open, transparent communication with our colleagues is important here so that they don't wonder why we have commented on code that is OK for them but not for us.</p>
<h2>Wrapping up</h2>
<p>This article shouldn't exist. Accessibility should be as normal in conversation as performance, security, SEO, and “AI”. Unfortunately, the tech industry has a big problem with ableism and white supremacy, which is why I wrote this article.</p>
<p>Understanding the culture, climate, and power lines within your organisation can help you find allies so you can organise like a grassroots movement from the bottom up. You can take on different roles to support each other, share knowledge and bring about change without <a href="https://en.wikipedia.org/wiki/The_Man">the man</a> noticing.</p>
<p>The most important tool when it comes to accessibility is not browser extensions, newsletter subscriptions, or screen readers. They play an important role, but none is as important as the community you have around you. Always make sure you're on the same page as your allies and that you're all working toward the same goal, even if you might take different paths to get there.</p>
        
        ]]></description>
        
      </item>
    
      <item>
        <title>Building dynamic toggletips using anchored container queries</title>
        <link>https://piccalil.li/blog/building-dynamic-toggletips-using-anchored-container-queries/?ref=articles-rss-feed</link>
        <dc:creator><![CDATA[Daniel Schwarz]]></dc:creator>
        <pubDate>Thu, 12 Mar 2026 11:55:00 GMT</pubDate>
        <guid isPermaLink="true">https://piccalil.li/blog/building-dynamic-toggletips-using-anchored-container-queries/?ref=articles-rss-feed</guid>
        <description><![CDATA[<p>To add to the <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Guides/Containment/Container_queries">container query options that we already have</a> (size queries, style queries, scroll-state queries), as well as the container query range syntax and many upgrades to all of the above, we can now use <em>anchored</em> container queries from Chrome 143.</p>
<p><a href="https://developer.chrome.com/blog/anchored-container-queries">Chrome’s announcement post</a> demonstrates how, if we were using anchor positioning, we could use anchored container queries to query the currently active fallback position (if any). They’ve provided a little demo in the post where a toggletip caret is anchored to the side of a toggletip, but if the toggletip needs to be anchored to a different side of the trigger due to lack of space, the caret is anchored to a different side as well. So in this case, anchored container queries are used to determine which position the toggletip is in, so that we can position the caret accordingly.</p>
<p>This is a pretty good use-case for anchored container queries, but also a great opportunity to look at how we might build toggletips in the (hopefully) near future. You’ll learn about popovers and anchor positioning, which are already baseline and will ensure that the toggletips at least work, as well as declarative anchors, ‘modern’ <code>attr()</code>, and <code>corner-shape</code>, progressive enhancements en<em>chant</em>ments that provide a range of magical benefits.</p>
<p>Here’s what we’ll be making:</p>
<p></p><p>See the Pen <a href="https://codepen.io/piccalilli/pen/gbrMGYx">Anchored container queries demo</a> by Andy Bell (<a href="https://codepen.io/piccalilli/">@piccalilli</a>) on <a href="https://codepen.io">CodePen</a>.</p><p></p>
<p>In Chrome you’ll see toggletip carets that flip to the appropriate side depending on the amount of space available, but in other web browsers you’ll get the toggletips without carets.</p>
<p>Let’s get into it!</p>
<h2>Setting up the popover and anchor associations</h2>
<p>We’ll be using popovers to mark up the toggletips, as that’s the semantic way to do so these days, but before we begin it’s worth mentioning that they’re implicitly anchored. However, since you might want to use anchored container queries without popovers, I’ll show you how to set up anchor associations anyway.</p>
<p>To set up the popover and anchor associations in a declarative but progressively enhanced way, we’ll need the following HTML markup:</p>
<pre><code>&lt;div anchor="leftButton" id="--leftPopover" popover&gt;Toggletip&lt;/div&gt;
&lt;div anchor="centerButton" id="--centerPopover" popover&gt;Toggletip&lt;/div&gt;
&lt;div anchor="rightButton" id="--rightPopover" popover&gt;Toggletip&lt;/div&gt;

&lt;button id="leftButton" popovertarget="--leftPopover"&gt;Button&lt;/button&gt;
&lt;button id="centerButton" popovertarget="--centerPopover"&gt;Button&lt;/button&gt;
&lt;button id="rightButton" popovertarget="--rightPopover"&gt;Button&lt;/button&gt;
</code></pre>
<p>The most familiar part of this is probably the popover markup. We’ve given the toggletips the <code>popover</code> attribute, and then an <code>id</code> so that each trigger can reference a popover using the <code>popovertarget</code> attribute. The strange part is that we’ve used custom-ident values (e.g., <code>--leftPopover</code>), but I’ll explain why shortly. That’s the popover functionality set up.</p>
<p>For the anchor positioning we’ve also given <code>id</code>s to the triggers, and then referenced them from <code>anchor</code> attributes set on the toggletips. These values <em>don’t</em> have to be custom idents.</p>
<p>However, for web browsers that don’t support the <code>anchor</code> attribute, we’ll need to use CSS instead, and there’s a shorter and a longer way to do that depending on whether or not modern <code>attr()</code> is supported.</p>
<p>The shorter, modern <code>attr()</code> way:</p>
<pre><code>/* Modern attr() supported */
@supports (x: attr(x type(*))) {
  button {
    /* Reuse the name from popovertarget */
    anchor-name: attr(popovertarget type(&lt;custom-ident&gt;));
  }

  [popover] {
    /* Anchor to the relevant button */
    position-anchor: attr(id type(&lt;custom-ident&gt;));
  }
}
</code></pre>
<p>Basically, if modern <code>attr()</code> is supported, we reuse the <code>popovertarget</code> values of the buttons as anchor names while making it clear that we want to parse them as custom idents. After that, we match the <code>id</code> values of the popovers to said anchors, thus setting up the anchor positioning associations. The <code>anchor-name</code> and <code>position-anchor</code> CSS properties only accept custom idents (e.g. <code>--leftPopover</code>), so that’s why we're making a big fuss about them.</p>
<p>Next, if modern <code>attr()</code> <em>isn’t</em> supported, name each anchor manually:</p>
<pre><code>/* Modern attr() not supported */
@supports not (x: attr(x type(*))) {
  /* Assign anchor name */
  #leftButton {
    anchor-name: --leftButton;
  }

  /* Anchor to button */
  #leftPopover {
    position-anchor: --leftButton;
  }

  /* And so on... */
  #centerButton {
    anchor-name: --centerButton;
  }

  #centerPopover {
    position-anchor: --centerButton;
  }

  /* And so on... */
  #rightButton {
    anchor-name: --rightButton;
  }

  #rightPopover {
    position-anchor: --rightButton;
  }
}
</code></pre>
<p>Once modern <code>attr()</code> is <em>Baseline widely available</em>, we can delete this block, and then once the <code>anchor</code> attribute is <em>Baseline widely available</em>, we can delete <em>all</em> of this CSS. You won’t even need to use custom-ident values, so <code>--leftPopover</code> can become <code>leftPopover</code>, for example.</p>
<p>Note: if we’d rather that the toggletips be triggered on <code>:hover</code> (making them tooltips instead of toggletips), we can swap <code>popovertarget</code> for <code>interestfor</code>, but note that <a href="https://css-tricks.com/a-first-look-at-the-interest-invoker-api-for-hover-triggered-popovers/">interest invokers</a> are only supported in Chrome 142 and above. Keep them in mind for the future!</p>
<p></p>
<h2>Aligning and styling the toggletips</h2>
<p>Like last time, I’ll drop the code right here so you can skim through it before we look at it line-by-line:</p>
<pre><code>[popover] {
  position: fixed;

  /* Align to right/implied center */
  position-area: right;

  /* If no space, flip to other inline side */
  position-try: flip-inline;

  /*
    1rem of spacing between the button and
    toggletip that also flips side accordingly
  */
  margin-inline-start: 1rem;

  /* Anchor toggletip caret to this */
  anchor-name: --toggletip;

  /* Used to query this container’s fallbacks */
  container-type: anchored;

  /* Scooped corners, if supported */
  @supports (corner-shape: squircle) {
    border-radius: 3rem;
    corner-shape: squircle;
  }

  /* Normal corners, if not supported */
  @supports not (corner-shape: squircle) {
    border-radius: 1rem;
  }
}
</code></pre>
<p>First, we must declare <code>position: fixed</code> on the anchored element (in this case though, popovers already have it).</p>
<p>Next, we need to position the toggletip relative to the button (let’s say the center-right) using the <code>position-area</code> property. Now, you might think that <code>position-area: center right</code> is the correct declaration here, but here’s what that actually does:</p>
<p><img src="https://piccalil.b-cdn.net/images/blog/anchor-toggle-tips-wrong.png" alt="An Inset-Modified Containing Block where an anchored toggletip is overflowing the center-right tile." /></p>
<p>As you can see, it’s overflowing the center-right tile, which is wrong but forgiving, since web browsers declare <code>align-self: anchor-center</code> under the hood to make it work anyway. This is declared on what’s called the Inset-Modified Containing Block (IMCB), which again is the center-right tile.</p>
<p>However, <a href="https://nerdy.dev/why-isnt-my-position-try-fallback-working-in-small-spaces">for reasons unknown, web browsers aren’t so forgiving when a fallback position is activated</a>. The trick is to use <code>position-area: right</code> instead. By omiting the <code>center</code> keyword, it resolves to <code>position-area: span-all right</code>, which does this:</p>
<p><img src="https://piccalil.b-cdn.net/images/blog/anchor-toggle-tips-right.png" alt="An Inset-Modified Containing Block where an anchored toggletip is contained within the right-side tiles and then vertically centered." /></p>
<p>Now the toggletip <em>does</em> fit into the tile (IMCB). And again, it’s vertically aligned within the center of it due to <code>align-self: anchor-center</code>.</p>
<p>We can safely use <code>position-try: flip-inline</code>, which turns <code>right</code> into <code>left</code> whenever the toggletip overflows the viewport. Later on, anchored container queries will query whether this is happening or not.</p>
<p>After that, <code>margin-inline-start: 1rem</code> adds <code>1rem</code> of spacing between the button and the toggletip at the start of the inline axis, which also flips accordingly.</p>
<p></p>
<p><code>anchor-name: --toggletip</code> turns the popovers into anchors so that we can create toggletip carets and anchor them to said popovers. Normally this’d be a naming collision waiting to happen (because three different popovers are now called <code>--toggletip</code>, right?), but the toggletip carets will be nested inside the popovers, so they’re somewhat scoped.</p>
<p>And remember, we’ll be flipping the toggletip’s caret to the opposite side whenever the toggletip is flipped, and that’s what <code>container-type: anchored</code> is for — it’s a totally new type of container and we’ll be querying it’s fallback position to determine the correct side.</p>
<p>One more thing, though…</p>
<p>If <code>corner-shape: squircle</code> is supported (<code>@supports (corner-shape: squircle)</code>), then we use it with <code>border-radius: 3rem</code> to create corners that aren’t quite rounded but aren’t quite square either. If it’s <em>not</em> supported then we just use <code>border-radius: 1rem</code>. This is optional of course, but <code>corner-shape</code> will play a bigger role when we use it again in a moment:</p>
<pre><code>/* Scooped corners, if supported */
@supports (corner-shape: squircle) {
	border-radius: 3rem;
	corner-shape: squircle;
}

/* Normal corners, if not supported */
@supports not (corner-shape: squircle) {
	border-radius: 1rem;
}
</code></pre>
<h2>Creating and positioning the toggletip’s caret</h2>
<p>Similar to how we anchored the toggletips to the buttons, the following code anchors the toggletip carets to the toggletips:</p>
<pre><code>[popover] {
	/* Previous section code */

  /* Toggletip caret */
  &amp;::after {
    /*
      Only create carets if anchored
      container queries are supported
    */
    @supports (container-type: anchored) {
      /* Create caret */
      content: "";

      /* Anchor to toggletip */
      position: fixed;
      position-anchor: --toggletip;

      /* Scooped carets, if supported */
      @supports (corner-shape: scoop) {
        height: 1rem;
        aspect-ratio: 1/2;
        corner-shape: scoop;
        background: inherit;
      }

      /* Normal carets, if not supported */
      @supports not (corner-shape: scoop) {
        /* Hack to create a triangle */
        width: 0;
        height: 0;
        border-top: 0.5rem solid transparent;
        border-bottom: 0.5rem solid transparent;
      }

      /* If no fallback */
      @container anchored(fallback: none) {
        /* Position caret on the left */
        position-area: left;

        /* Needed for scooped carets */
        @supports (corner-shape: scoop) {
          border-top-left-radius: 100% 50%;
          border-bottom-left-radius: 100% 50%;
        }

        /* Needed for normal carets */
        @supports not (corner-shape: scoop) {
          /* Part of the triangle hack */
          border-right: 0.5rem solid var(--toggletip-color);
        }
      }

      /* If flip-inline fallback triggered */
      @container anchored(fallback: flip-inline) {
        position-area: right;

        @supports (corner-shape: scoop) {
          border-top-right-radius: 100% 50%;
          border-bottom-right-radius: 100% 50%;
        }

        @supports not (corner-shape: scoop) {
          border-left: 0.5rem solid var(--toggletip-color);
        }
      }
    }
  }
}
</code></pre>
<p>First of all, the toggletip carets are CSS-generated using the <code>::after</code> pseudo-element:</p>
<pre><code>[popover] {
  &amp;::after {
    /* Toggletip caret */
	}
}
</code></pre>
<p>Then, within that, we need to see if the web browser supports anchored container queries (if not, the toggletip carets simply aren’t generated, although the toggletips will still work):</p>
<pre><code>[popover] {
  &amp;::after {
		@supports (container-type: anchored) {
	    /*
	      Only create carets if anchored
	      container queries are supported
	    */
		}
	}
}
</code></pre>
<p>Within that, <code>content: ""</code> generates the toggletip carets (or, rather, it generates a pseudo-element with no content that we’ll style <em>into</em> carets).</p>
<p><code>position: fixed</code> and <code>position-anchor: --toggletip</code> anchors them to the toggletips.</p>
<p>After that, we again leverage <code>corner-shape</code> to create scooped toggletips. Or, if <code>corner-shape</code> isn’t supported, then we use the classic <a href="https://css-tricks.com/snippets/css/css-triangle/">border trick to create triangle-shaped carets</a>.</p>
<p>We also — finally — implement those anchored container queries to position the carets to the correct side of the toggletips. When a fallback isn’t active, <code>@container anchored(fallback: none)</code> will match, but when a fallback <em>is</em> active, <code>@container anchored(fallback: flip-inline)</code> will match. The value of <code>fallback</code> simply needs to match a value of <code>position-try</code>:</p>
<p><code>position-try: flip-inline</code>, in our case</p>
<pre><code>/* Scooped carets, if supported */
@supports (corner-shape: scoop) {
	height: 1rem;
	aspect-ratio: 1/2;
	corner-shape: scoop; /* (Border radius is set later) */
	background: inherit;
}

/* Normal carets, if not */
@supports not (corner-shape: scoop) {
	/* Hack to create a triangle */
	width: 0;
	height: 0;
	border-block: 0.5rem solid transparent; /* (Side is set later) */
}

/* If no fallback */
@container anchored(fallback: none) {
	/* Position caret on the left */
	position-area: left;

	/* Left border radii for scooped carets */
	@supports (corner-shape: scoop) {
		border-top-left-radius: 100% 50%;
		border-bottom-left-radius: 100% 50%;
	}

	/* ‘Left’ border for normal carets */
	@supports not (corner-shape: scoop) {
		border-right: 0.5rem solid var(--toggletip-color);
	}
}

/* If flip-inline fallback triggered */
@container anchored(fallback: flip-inline) {
	position-area: right;

	/* Right border radii for scooped carets */
	@supports (corner-shape: scoop) {
		border-top-right-radius: 100% 50%;
		border-bottom-right-radius: 100% 50%;
	}

	/* ‘Right’ border for normal carets */
	@supports not (corner-shape: scoop) {
		border-left: 0.5rem solid var(--toggletip-color);
	}
}
</code></pre>
<p>As a reminder, here’s the final demo:</p>
<p></p><p>See the Pen <a href="https://codepen.io/piccalilli/pen/gbrMGYx">Anchored container queries demo</a> by Andy Bell (<a href="https://codepen.io/piccalilli/">@piccalilli</a>) on <a href="https://codepen.io">CodePen</a>.</p><p></p>
<h2>Wrapping up</h2>
<p>Container queries are evolving beautifully, especially with the newest addition, <em>anchored</em> container queries. And, thanks to other modern CSS features such as the <code>anchor</code> attribute, ‘modern’ <code>attr()</code>, <code>corner-shape</code>, and even interest invokers, we can include all kinds of progressive enhancements to create some really awesome — in this case — toggletips.</p>
<p>If you want to go ahead and implement this (full code in <a href="https://codepen.io/mrdanielschwarz/pen/gbrMGYx">the demo</a>), you totally can. If something isn’t supported it’ll simply revert to something that is, and then as new features become baseline, you can very easily remove the code that’s no longer needed.</p>
        
        ]]></description>
        
      </item>
    
      <item>
        <title>Finding an accessibility-first culture in npmx</title>
        <link>https://piccalil.li/blog/finding-an-accessibility-first-culture-in-npmx/?ref=articles-rss-feed</link>
        <dc:creator><![CDATA[Abbey Perini]]></dc:creator>
        <pubDate>Tue, 03 Mar 2026 13:55:00 GMT</pubDate>
        <guid isPermaLink="true">https://piccalil.li/blog/finding-an-accessibility-first-culture-in-npmx/?ref=articles-rss-feed</guid>
        <description><![CDATA[<p>Back in January, I found myself longing for an accessibility-first culture and for a while, I’ve also been looking for ways to learn senior-level accessibility skills. I expected to find one of those needs, but not <em>both</em>, when I joined <a href="https://npmx.dev/">npmx</a> on a whim. Today is the <a href="https://npmx.dev/blog/alpha-release">alpha release of npmx</a>, and I’m happy to share how they’ve already exemplified an accessibility-first community.</p>
<h2>Missing an accessibility-first community</h2>
<p>It's hard to put into words how lonely it is when you’re the only person ensuring that there aren't click handlers on generic elements. I've come to accept that the bar for "accessibility advocate" is just "still cares about accessibility in spite of it all." I'm used to being the only one giving accessibility feedback when joining a new project. It's exhausting having to explain the same small issues over — the same issues that are easily caught by automated accessibility testing tools. Sometimes, it's tempting to just delete the repository and start over.</p>
<p>When you know anything about digital accessibility, you know that compliance doesn't always have to be a never-ending slog of fixes. It <em>can</em> be baked in from the start.</p>
<p><img src="https://piccalil.b-cdn.net/images/blog/npmx-eggs-slide.jpg" alt="A purple and yellow cupcake You can't sprinkle eggs on the cupcake after baking it. Fixing accessibility later is messy, slow, ineffective! “Later” and “messy, slow, ineffective”" title="Stef Walter’s AxeCon talk, &lt;a href='https://www.deque.com/axe-con/sessions/how-to-convince-people-to-care-and-invest-in-accessibility/'&gt;How to Convince People to Care and Invest in Accessibility&lt;/a&gt;" /></p>
<p>In many ways, I am lucky. At work, my recommendations are respected and my coworkers want to learn. When I come across hard questions, I can always reach out to former coworkers from my previous job at a digital accessibility company. When I need someone to check my assumptions, I just talk to the accessibility expert friends who always support me. I’ve never asked for permission to fix accessibility issues or build accessibly because accessibility has consistently improved the user experience, that’s worked in my favor.</p>
<p>Recently however, I got the chance to catch up with some of my former coworkers. There was a moment when I said "I don't know if the automated captions are better or worse." One of them responded "Yeah, they're really wrong - a live captioner would be a lot better." I closed my eyes, leaned back in my chair, and sighed "It's nice not to have to explain." Then, I remembered how nice it was to have a live captioner in our meetings. The next week, I started looking at expensive certifications. I wanted a reason to start learning deeply about accessibility again.</p>
<p></p>
<h2>Finding an accessibility-first community</h2>
<p>When I joined npmx the next month, I was curious and hoped I'd get to learn from brilliant developers. At <a href="https://vueconf.us/">VueConf 2025</a>, I had learned that <a href="https://bsky.app/profile/danielroe.dev">Daniel Roe</a> wrote a script that automatically registers an <a href="https://docs.npmjs.com/packages-and-modules">npm package</a> every time he buys a domain. I figured he’d probably know a thing or two about npm.</p>
<p>From an accessibility standpoint, I was expecting more of the same. I assumed I would still be the only person insisting "accessibility is a right, not a privilege." Explaining that screen reader users use several lists of things to navigate a webpage: links, headings, <a href="https://www.w3.org/WAI/ARIA/apg/practices/landmark-regions/">landmark regions</a>. That’s why your <code>&lt;header&gt;</code> should be outside of <code>&lt;main&gt;</code> and your link text shouldn’t all be “click here!”</p>
<p>Inside the <a href="https://chat.npmx.dev/">npmx Discord</a>, I didn't expect to see a dedicated accessibility channel. I was delighted to see automated accessibility tests when I opened up my first pull request for review. There were other people already hard at work making sure there were no click handlers on generic elements. I started to feel things that I hadn't felt since working in digital accessibility full time.</p>
<p>Immediately, I started learning deeply about accessibility again. Some things were small, like HTML’s struggle with headings inside <code>&lt;details&gt;</code>/<code>&lt;summary&gt;</code> but I was also getting to have the big conversations about architecture and design that I missed having. I didn’t even have to explain what a <a href="https://rightbadcode.com/accessibility-conformance-reports-setting-expectations">VPAT</a> was. Most importantly, our conversations are being treated as important. If there's a possible accessibility issue in another conversation, accessibility experts are tagged in. It’s all filling a bucket I hadn’t even realized was empty.</p>
<p>Of course, there are things we weren’t able to fix before the alpha release — that’s how software is: perpetually unfinished, never 100% accessible — but I don’t have to justify a fix with a business logic bug because we’re already auditing. Earlier this week, someone asked how the accessibility channel felt about accessible color contrast. I had already typed out a justification for sufficient color contrast before I realized it was an invitation to review a pull request.</p>
<p></p>
<h2>Wrapping up with some tips for building an accessibility-first culture</h2>
<p>For many reasons, the first step is writing documentation. In your onboarding documentation, encourage developers to install <a href="https://dev.to/steady5063/automated-accessibility-part-1-linting-5378">accessibility linters</a>. Document the accessibility problems you’ve already solved, patterns for interactive controls and colors that have sufficient contrast together.</p>
<p>Bonus points if you have the documentation available in multiple forms (e.g. text, diagrams, and videos). </p>
<p>Tests are another form of documentation and useful for preventing regressions and always use <a href="https://docs.cypress.io/app/guides/accessibility-testing">accessibility testing tools</a>. Write your components and types in ways that enforce accessibility. An <code>&lt;input&gt;</code> should always have a label, so the <code>labelText</code> prop for your component with an <code>&lt;input&gt;</code> should be required, right?</p>
<p>Think of accessibility concerns as early as possible, such as in the design and planning phases. Accessibility auditing is part of quality assurance (QA). If you have the budget, pay accessibility testing experts to do manual testing and also, testing with users with disabilities. When accessibility experts raise concerns, <strong>take them seriously</strong>. Also celebrate the little wins — sufficient color contrast and <a href="https://accessibility.huit.harvard.edu/describe-content-images">alt text</a> mean a <em>lot</em> to a lot of people.</p>
<p>Finally, respond with humility when you get it wrong, because you <em>will</em> get it wrong. Use those moments as learning and improvement opportunities because your ultimate goal <em>should</em> be inclusion. It makes a lot of sense listen to the people who are excluded.</p>
        
        ]]></description>
        
      </item>
    
      <item>
        <title>A 2026 Piccalilli homepage redesign</title>
        <link>https://piccalil.li/blog/a-2026-piccalilli-homepage-redesign/?ref=articles-rss-feed</link>
        <dc:creator><![CDATA[Andy Bell]]></dc:creator>
        <pubDate>Tue, 24 Feb 2026 11:55:00 GMT</pubDate>
        <guid isPermaLink="true">https://piccalil.li/blog/a-2026-piccalilli-homepage-redesign/?ref=articles-rss-feed</guid>
        <description><![CDATA[<p>Last year, we invested lots of time, working out how this publication was being <em>perceived</em>, via a couple of surveys and one-on-one interviews with our readers. We learned a hell of a lot, but the main thing that stuck out was that people were confused about what we're all about. Are we a blog, are we a publication? Turns out not many know, which is not ideal 😅</p>
<p>Well, we've aimed to address and highlight all of that in a <a href="https://piccalil.li">homepage redesign that we've just launched</a>.</p>
<p><img src="https://piccalil.b-cdn.net/images/blog/2026-homepage.jpg" alt="A clip of the new homepage that has a big headline at the top: &quot;No hype, no AI slop, just high quality, pragmatic education&quot;, followed by &quot;We’re not in the business of chasing clicks, tech industry fads or hype cycles. Instead, our premium courses, articles, links and newsletter give you a real-world, industry-relevant education that will outlive the hype and help you to level up your career.&quot;" /></p>
<p>As you can see, we're not messing around in terms of our positioning and messaging. I'm really confident we're hitting the appropriate tone for 2026 too. <a href="https://piccalil.li/blog/our-principles-on-ai/">We're already clear on our stance on AI/LLMs</a>, but we also wanted to really highlight that with this redesign, so people know — right from the start — what we're all about.</p>
<p>We know we're sailing against the current here, but we're cool with that. Being unapologetically <em>for</em> the web platform and <a href="https://piccalil.li/blog/its-about-time-i-tried-to-explain-what-progressive-enhancement-actually-is/">progressive enhancement</a> since day one has always had us sailing against the current. We've just got bigger sails now to go <em>against</em> the onslaught of AI-boosting by providing really high quality educational material for humans, written by humans, always.</p>
<p>That's <em>exactly</em> what we do here.</p>
<p><a href="https://piccalil.li">Check out the new homepage</a></p>
        
        ]]></description>
        
      </item>
    
    </channel>
  </rss>
