<?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 - Accessibility topic archive</title>
      <link>https://piccalil.li/</link>
      <atom:link href="https://piccalil.li/category/accessibility.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 - Accessibility topic archive 2026</copyright>
      <docs>https://www.rssboard.org/rss-specification</docs>
      <pubDate>Tue, 07 Apr 2026 01:02:02 GMT</pubDate>
      <lastBuildDate>Tue, 07 Apr 2026 01:02:02 GMT</lastBuildDate>

      
      <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=accessibility-category-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=accessibility-category-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>Finding an accessibility-first culture in npmx</title>
        <link>https://piccalil.li/blog/finding-an-accessibility-first-culture-in-npmx/?ref=accessibility-category-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=accessibility-category-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>You might not need role=&quot;presentation&quot;</title>
        <link>https://piccalil.li/blog/you-might-not-need-rolepresentation/?ref=accessibility-category-rss-feed</link>
        <dc:creator><![CDATA[Steve Frenzel]]></dc:creator>
        <pubDate>Thu, 12 Feb 2026 11:55:00 GMT</pubDate>
        <guid isPermaLink="true">https://piccalil.li/blog/you-might-not-need-rolepresentation/?ref=accessibility-category-rss-feed</guid>
        <description><![CDATA[<p>For a brief moment in time, my main job was to assess the compliance of a selection of websites and document this in a report that was handed over to the customer. I carried out this assessment using the so-called <a href="https://bitvtest.de/en/tests-und-beratung/bik-bitv-test-web">BIK BITV test</a> and, in test step <a href="https://bitvtest.de/pruefschritt/bitv-20-plus-web/bitv-20-plus-web-9-4-1-2-name-rolle-wert-verfuegbar">9.4.1.2 Name, Role, Value</a>, I noticed time and again that <code>role="presentation"</code> was used in a way that was either technically questionable or even degraded accessibility.</p>
<p>Because I have seen this pattern so often, I'm going to to use a couple of real-life examples to find out why this is the case. The examples have been edited and shortened to make them easier to understand.</p>
<p>I will use the code to assess what the intention for using <code>role="presentation"</code> might have been and what could have been done differently. In my experience, there’s only a few real use cases for this attribute value, which we will get to later in the article.</p>
<h2>What you might read about this attribute</h2>
<p>We will use the specifications to take a closer look at what <code>role="presentation"</code> does, how it is used in the wild, and what it should actually be used for.</p>
<h2>The official specs</h2>
<div><h2>FYI</h2>
<p>Whenever you see a blockquote following a code sample in this section, it is an excerpt from the <a href="https://www.w3.org/TR/wai-aria-1.1/#presentation">specification</a>.</p>
</div>
<p>If you take a look at the <a href="https://www.w3.org/TR/wai-aria-1.2/#presentation">specification</a>, you will immediately notice the prominent note right at the beginning (emphasis ours):</p>
<blockquote>
<p>In ARIA 1.1, the working group introduced none as a synonym to the presentation role, due to author confusion surrounding the intended meaning of the word "presentation" or "presentational." Many individuals erroneously consider <code>role="presentation"</code> to be synonymous with <code>aria-hidden="true"</code>, and we believe <code>role="none"</code> conveys the actual meaning more unambiguously.</p>
</blockquote>
<p>This gives us an initial indication of why this attribute might be used incorrectly.</p>
<p>Authors seem to understand “presentational” as “only to be seen”; not heard. This is the behaviour of <code>aria-hidden</code>, which hides an element in the accessibility tree so that it is no longer announced when assistive technology is used. <code>role="presentation"</code> only affects the role, but not an element and its content.</p>
<blockquote>
<p>The intended use is when an element is used to change the look of the page but does not have all the functional, interactive, or structural relevance implied by the element type, or may be used to provide for an accessible fallback in older browsers that do not support WAI-ARIA.</p>
</blockquote>
<p>Spoiler: they’re describing layout tables here, which we’ll get into later in the article.</p>
<blockquote>
<p>An element whose content is completely presentational (like a spacer image, decorative graphic, or clearing element);</p>
</blockquote>
<p>The first two examples sound like image elements. If it is a decorative <code>svg</code> element, <code>aria-hidden="true"</code> would make more sense. Whereas for an <code>img</code> element <code>alt=""</code> would be more appropriate for hiding it, as this makes the intention much more obvious and it comes for free with the <code>img</code> element.</p>
<p>“Clearing element” might refer to using an element to clear float behaviour, where you would use <code>clear: both;</code> after using <code>float: left;</code> or <code>float: right;</code>, so it wouldn’t get dragged up the flow and break the layout.</p>
<p></p>
<blockquote>
<p>An image that is in a container with the <code>img</code> role and where the full text alternative is available and is marked up with <code>aria-labelledby</code> and (if needed) <code>aria-describedby</code>;</p>
</blockquote>
<p>To be completely honest, I have never seen the following example in the wild, and it is much easier to implement — and for users to read — if you use the <code>alt</code> attribute for alternative text in an image.</p>
<p>In the following example, the <code>hidden</code> attribute is used to hide the <code>&lt;span&gt;</code> element visually. However, it’s still available in the DOM, so it can be referenced using <code>aria-labelledby</code> , up there in the sibling <code>&lt;div&gt;</code> element, for example.</p>
<pre><code>&lt;div role="img" aria-labelledby="image-title"&gt;
  &lt;img src="example-image.jpg" role="presentation"&gt;
  &lt;span id="image-title" hidden&gt;A beautiful sunset over the ocean&lt;/span&gt;
&lt;/div&gt;
</code></pre>
<p>In the accessibility tree, in that context, the image is displayed correctly with the corresponding alternative text, but not the source URL. If you use <a href="https://www.deque.com/axe/devtools/linter/">axe-linter</a> in development, removing <code>role="presentation"</code> will trigger an alarm that images need alternative text.</p>
<blockquote>
<p>An element used as an additional markup "hook" for CSS [...]</p>
</blockquote>
<p>This means that in CSS, you use this attribute to target an element with <code>role="presentation"</code>, for example like this:</p>
<pre><code>table[role=presentation] {
  /* Do something */
}
</code></pre>
<blockquote>
<p>A layout table and/or any of its associated rows, cells, etc.</p>
</blockquote>
<p>Again, we’ll get into this pattern later on.</p>
<p>The specification contains many more explanations and examples, which you are welcome to look at yourself. One of the most important sentences for me is this one: <em>“[…] the presentation role causes a given element to be treated as having no role or to be removed from the accessibility tree, but does not cause the content contained within the element to be removed from the accessibility tree.”</em></p>
<p>The following example is not intended for use in production, but is only meant to illustrate that when using <code>role="presentation"</code>, the element itself and the elements within it lose their semantic meaning, but the content is still available:</p>
<pre><code>&lt;!-- Output: One generic element containing 
two generic elements with content. --&gt;
&lt;ul role="presentation"&gt;
  &lt;li&gt; Sample Content &lt;/li&gt;
  &lt;li&gt; More Sample Content &lt;/li&gt;
&lt;/ul&gt;

&lt;!-- Output: Unordered list element containing two list items. --&gt;
&lt;ul&gt;
  &lt;li&gt; Sample Content &lt;/li&gt;
  &lt;li&gt; More Sample Content &lt;/li&gt;
&lt;/ul&gt;
</code></pre>
<p>The semantic HTML is still displayed in the source code, however, if you look at them in the accessibility tree, they are displayed as generic elements, so they could just as well be <code>&lt;div&gt;</code> or <code>&lt;span&gt;</code> elements.</p>
<p>Enough theory, let’s have a look at some real world examples!</p>
<h2>Questionable examples</h2>
<p>Some of these examples won’t create any real barriers for users and I consider them not nice, but more <em>harmless</em>. Others will cause problems, because <code>role="presentation"</code> has removed important semantic meaning, which can cause more issues because of nested elements.</p>
<p>You will quickly learn that I removed this attribute in <em>all</em> of my suggested fixes, as it’s just <strong>not necessary</strong>. It was also sometimes impossible for me to guess why developers used <code>role="presentation"</code> in the first place.</p>
<h3>The “invisible” <code>iframe</code> element</h3>
<pre><code>&lt;iframe src="..." title role="presentation" loading="eager" style="width: 0px; height: 0px; border: 0px; display: none;"&gt;
  &lt;!-- More code  --&gt;
&lt;/iframe&gt;
</code></pre>
<p>This <code>iframe</code> element contains a single <code>&lt;script&gt;</code> element for cookie logic. The intention here was most likely to hide it from assistive technology, as the CSS code suggests.</p>
<p>However, the content is still available because only the semantic meaning was removed from the <code>iframe</code> element. In addition, a <code>title</code> attribute without content was used here, which is incorrect.</p>
<p>Instead, the desired output could be implemented as follows:</p>
<pre><code>&lt;iframe aria-hidden="true" src="..." loading="eager"&gt;
  &lt;!-- More code  --&gt;
&lt;/iframe&gt;
</code></pre>
<h3>The list with no items</h3>
<pre><code>&lt;nav&gt;
	&lt;ul&gt;
	  &lt;li role="presentation"&gt;
	  	&lt;a href="/"&gt;To homepage&lt;/a&gt;
	  &lt;/li&gt;
	  &lt;!-- More code  --&gt;
	&lt;/ul&gt;
&lt;/nav&gt;
</code></pre>
<p>Why <code>role="presentation"</code> is applied to a list element here is beyond me. Especially since this is a navigation element and the semantics here have to be on point. Fortunately, it can be easily fixed by removing the attribute and using <code>aria-current="page"</code> for the current page.</p>
<h3>The “hidden” image</h3>
<pre><code>&lt;a href="/shop" aria-label="Shop"&gt;
  &lt;svg role="presentation"&gt;
    &lt;title&gt;Shopping cart&lt;/title&gt;
    &lt;!-- More code  --&gt;
  &lt;/svg&gt;
&lt;/a&gt;
</code></pre>
<p>As we learned from the <a href="https://www.w3.org/TR/wai-aria-1.1/#presentation">specification</a>, <code>role="presentation"</code> only removes the semantics of an element, but not its content, so the content of the <code>&lt;title&gt;</code> element should still be available, right? As <code>aria-label</code> is present, an accessible name is provided by this attribute, but <em>not</em> the <code>&lt;title&gt;</code> element itself.</p>
<p>If you would remove <code>aria-label</code>, it would have no accessible name at all, meaning <code>role="presentation"</code> has completely purged the <code>&lt;title&gt;</code> element from the accessibility tree! 🤯</p>
<p>The goal here was probably to hide the alternative text of the <code>&lt;svg&gt;</code> element, which worked. However, there are several ways to solve this use case more cleanly, and I would do it this way:</p>
<pre><code>&lt;a href="/shop"&gt;
  &lt;svg&gt;
    &lt;title&gt;Shop&lt;/title&gt;
    &lt;!-- More code  --&gt;
  &lt;/svg&gt;
&lt;/a&gt;
</code></pre>
<p>In this case, we do not need <code>aria-label</code>, as the alternative text of the image is used as the accessible name.</p>
<h3>Make it semantic, then undo it</h3>
<pre><code>&lt;a href="/retail"&gt;
  &lt;p role="presentation"&gt;Search store&lt;/p&gt;
&lt;/a&gt;
</code></pre>
<p>This is an awkward solution, but it does not present any real barriers for users, as the link text is still available. The developers probably wanted to hide the <code>&lt;p&gt;</code> element semantically, which is exactly what happens here. However, it could also have been done like this:</p>
<pre><code>&lt;a href="/retail"&gt;
  Search store
&lt;/a&gt;
</code></pre>
<h3>Technically meh, but still working</h3>
<pre><code>&lt;div role="presentation"&gt;
  &lt;section role="presentation" aria-label="Header"&gt;
    &lt;!-- More code  --&gt;
  &lt;/section&gt;
&lt;/div&gt;
</code></pre>
<p>This is a very interesting case! First of all, I don't understand why you would remove the semantic meaning but still use a semantic element.</p>
<p>In theory, <code>&lt;section&gt;</code> would be a generic element with an aria-label, which is prohibited according to the <a href="https://www.w3.org/TR/wai-aria-1.2/#generic">specification</a>, which would result in a failure of test step <a href="https://www.w3.org/WAI/WCAG21/Understanding/name-role-value">4.1.2 Name, Role, Value (Level A)</a>.</p>
<p>But because <code>aria-label</code> is present, this is ignored by the browser and the element is displayed correctly in the accessibility tree. Amazing! A technically clean solution would look like this:</p>
<pre><code>&lt;div&gt;
  &lt;section aria-label="Header"&gt;
    &lt;!-- More code  --&gt;
  &lt;/section&gt;
&lt;/div&gt;
</code></pre>
<h3>Adding an accessible name and then removing it</h3>
<pre><code>&lt;a href="/profile"&gt;
  &lt;div&gt;
    &lt;div&gt;
      &lt;img alt="Go to profile" role="presentation" src="..."&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/a&gt;
</code></pre>
<p>The intention is not clear to me here either, because there are some problems due to <code>role="presentation"</code>.</p>
<p>The <code>&lt;a&gt;</code> element needs an accessible name, which is not available because the <code>&lt;img&gt;</code> element has no semantic meaning and the <code>alt</code> attribute cannot be applied to a generic element.</p>
<p>Fortunately, these problems can be solved by removing <code>role="presentation"</code>! I also removed the <code>&lt;div&gt;</code> elements because personally, I don’t like the taste of <a href="https://cdn.matthewjamestaylor.com/img/gmail-div-soup.png">div soup</a>.</p>
<pre><code>&lt;a href="/profile"&gt;
  &lt;img alt="Go to profile" src="..."&gt;
&lt;/a&gt;
</code></pre>
<p>The alternative text is now linked to the image, and the accessible name of the link is provided by the alternative text. This one is similar to the “hidden” image example from earlier.</p>
<p></p>
<h2>The few good use cases of this attribute</h2>
<p>There are a couple of suggestions in the specs when you <em>could</em> use <code>role="presentation"</code>, but I think only a few use cases could apply: <a href="https://inclusive-components.design/tabbed-interfaces/">Tabbed interfaces</a>, <a href="https://www.stevefrenzel.dev/posts/menu-and-navigation-the-difference/#menu-example">menu pattern</a> and a layout table. Let’s have a closer look at a layout table, which is using a <code>&lt;table&gt;</code> element for page layout.</p>
<p>Thanks to <a href="https://nerdy.dev/cascading-secret-sauce">modern CSS</a>, there’s no real need to use layout tables for websites anymore! We can produce <a href="https://every-layout.dev/">flexible and robust designs by using flexbox and / or grid</a>. The one use case where <code>role="presentation"</code> might come in handy <em>could</em> be email templates though.</p>
<p>If you are forced to use layout tables for your emails, Harvard University has a great article for you on <a href="https://accessibility.huit.harvard.edu/creating-accessible-emails">creating accessible emails</a>. The most relevant part for this article is the following sentence (emphasis ours):</p>
<blockquote>
<p>If you must use tables for layout, add the attribute <code>role="presentation"</code> on every table element to ensure screen readers won’t treat them as data tables.</p>
</blockquote>
<p>In the <a href="https://www.w3.org/WAI/tutorials/tables/tips/">W3C Tips and Tricks section for tables</a>, they’re also <em>very</em> clear on the usage of layout tables (emphasis ours):</p>
<blockquote>
<p>Tables should not be used for layout purposes. Use Cascading Style Sheets (CSS) for layout. If there are already layout tables present, don’t use structural elements (like <code>&lt;th&gt;</code> or <code>&lt;caption&gt;</code>) [...], and do add <code>role="presentation"</code> to the <code>&lt;table&gt;</code> element.</p>
</blockquote>
<p>The <a href="https://accessibility.umich.edu/basics/concepts-principles/tables">University of Michigan</a> keeps it more brief but same advice:</p>
<blockquote>
<p>Only use tables to present tabular data, not to create a visual layout. Use CSS or styling options to handle layout.</p>
</blockquote>
<p>In <a href="https://brothercake.com/Ref/presentational-tables.html">Screen reader heuristics for presentational tables</a>, you’ll find some examples on how to use <code>role="presentation"</code> in the context of a layout table.</p>
<h2>Wrapping up</h2>
<p>Thanks to a detailed analysis of the specifications, we have learned what <code>role="presentation"</code> does and how few use cases there actually are for this attribute. We have also seen from real-life examples how misunderstood the functionality of this attribute is among developers.</p>
<p>The only real use cases would be tabbed interfaces, the menu pattern and email templates, but even here, one could (if possible) switch to plain text emails and avoid using <code>role="presentation"</code>.</p>
<hr />
<p>Many thanks to <a href="https://heydonworks.com/">Heydon Pickering</a> for their help checking over this article and lending us their endless accessibility wisdom.</p>
        
        ]]></description>
        
      </item>
    
      <item>
        <title>A guide to creating accessible PDFs using free tools</title>
        <link>https://piccalil.li/blog/a-guide-to-creating-accessible-pdfs-using-free-tools/?ref=accessibility-category-rss-feed</link>
        <dc:creator><![CDATA[Steve Frenzel]]></dc:creator>
        <pubDate>Thu, 02 Oct 2025 10:55:00 GMT</pubDate>
        <guid isPermaLink="true">https://piccalil.li/blog/a-guide-to-creating-accessible-pdfs-using-free-tools/?ref=accessibility-category-rss-feed</guid>
        <description><![CDATA[<p>Before we look at what free alternatives there are for creating and checking PDFs, you should ask yourself the following question: do I really need to create a PDF, or could I create a website or write an email instead?</p>
<p>If the answer to that is “no” or even “I don't know”, I recommend reading <em><a href="https://blog.pope.tech/2023/05/01/inaccessible-pdfs-how-to-know-when-to-use-html-webpages-instead-of-pdfs/">Inaccessible PDFs? How to know when to use HTML webpages instead of PDFs</a></em> by <em>Whitney Lewis</em>.</p>
<p>If the answer was “yes”, I’m going to show you how to do the following things using a practical example:</p>
<ul>
<li>Creating an accessible PDF using <a href="https://www.libreoffice.org/">LibreOffice</a></li>
<li>Doing a quick structure check with a text editor</li>
<li>Testing for PDF/UA and WCAG conformance on the <a href="https://check.axes4.com">axes4</a> website</li>
<li>Checking our documents with different screenreaders (JAWS, NVDA and VoiceOver)</li>
</ul>
<h2>Why I’m writing this</h2>
<p>As I write this, I am in the application phase of finding a new role. Every now and then, I am offered the option to have form fields filled in automatically by uploading my resume.</p>
<p>I created my resume in <a href="https://support.apple.com/en-gb/guide/pages/welcome/mac">Pages</a> and selected the “On” option under “Advanced Options” and “Accessibility” when exporting. I did this in the hope that it would be accessible and machine-readable from a technical point of view.</p>
<p>After uploading the resume, my first name was always displayed as “Mastodon” and many fields were filled in incorrectly, or not at all. Since “Mastodon” is not my first name, I suspected that there was some kind of technical problem. So, for the nth time, I researched how to create and test accessible PDFs, and for the nth time, I was told that this was only possible with Adobe Acrobat Reader Pro. I didn't feel like throwing my money at a big corporation, so I frantically continued searching for a way to make my wish come true.</p>
<p>I quickly found an answer <a href="https://mastodon.online/@stvfrnzl/114991699718172415">after asking on Mastodon</a>, thanks to Grant, who pointed me to the official accessibility documentation and <a href="https://mastodon.online/@yatil@yatil.social">Eric Eggert</a>, who showed me how to test it for <a href="https://www.digitalaccesstraining.com/pages/articles?p=an-introduction-to-the-pdfua-standard">PDF/UA</a> and <a href="https://www.w3.org/TR/WCAG20-TECHS/pdf">WCAG conformance</a>.</p>
<p></p>
<h2>Using LibreOffice to create and export accessible PDFs</h2>
<p>Often ridiculed by me and rarely needed, I wanted to give LibreOffice a <em>real</em> chance this time, so I transferred my resume manually and first got an overview of what the problems actually are.</p>
<h3>Requirements for accessible PDFs in LibreOffice</h3>
<p>PDFs are subject to very similar accessibility requirements as websites. Let's take a look at them (taken from the <a href="https://help.libreoffice.org/latest/en-US/text/shared/01/ref_pdf_export_universal_accessibility.html">Universal Accessibility (PDF/UA) documentation</a>):</p>
<blockquote>
<ul>
<li>The document title is set.</li>
</ul>
</blockquote>
<p>This is not the visible main heading, but the title of the document, think <em>metadata</em>.</p>
<blockquote>
<ul>
<li>The document language is set, or all styles in use have the language property set.</li>
</ul>
</blockquote>
<p>The language for the document is set automatically. However, if there are sections in other languages, these must be adjusted accordingly. Go to "Tools", "Languages" and select the appropriate option.</p>
<blockquote>
<ul>
<li>All images, graphics, OLE objects have an alternate (alt) text or a title.</li>
</ul>
</blockquote>
<p>Graphics must either have a meaningful description or be marked as decorative. Got to "Format", "Alt Text..." and either enter the text or tick the "Decorative" box. Check out <a href="https://design102.blog.gov.uk/2022/01/14/whats-the-alternative-how-to-write-good-alt-text/">What’s the alternative? How to write good alt text</a> if you need help writing alternative text.</p>
<blockquote>
<ul>
<li>Tables do not contain split or merged cells.</li>
<li>Only integrated numbering is used, no manual numbering. For example, do not type "1.", "2.", "3." at the beginning of paragraphs.</li>
</ul>
</blockquote>
<p>If numbers are generated, this should happen automatically and they should not be added manually. Example: Multiple lines of text are converted into a semantically correct element using “Ordered List” instead of adding the numbers yourself. Go to "Styles" and select "Numbering 123 List Style".</p>
<blockquote>
<ul>
<li>Hyperlink texts without the underlying hyperlinks.</li>
</ul>
</blockquote>
<p>Texts marked as hyperlinks should contain the corresponding path. This warning appears when you create a hyperlink and then remove the path it contains using “Remove Hyperlink,” which you shouldn't; just leave it be!</p>
<blockquote>
<ul>
<li>The contrast between text and the background meets the WCAG specification.</li>
</ul>
</blockquote>
<p>See <a href="https://www.section508.gov/test/color-contrast-in-nonweb-documents-images/">Testing Color Contrast in Non-Web Documents and Images</a>.</p>
<blockquote>
<ul>
<li>No blinking text.</li>
<li>No footnotes or endnotes.</li>
<li>Headings must increase sequentially with no skips, for example, you cannot have Heading 1, Heading 3, and no Heading 2.</li>
<li>Text does not convey additional meaning with (direct) formatting.</li>
</ul>
</blockquote>
<p>If the font or style for text is changed, this must not be applied to the text itself, but only to the semantic element itself representing this element. Example: All Heading 2 elements should be italic and in Comic Sans. Select the appropriate element either directly in the document or in the right-hand sidebar, go to "Styles" and select "Edit Style…" and change it accordingly.</p>
<p>Some of these points apply to our use case, as we will need headings, paragraphs, lists, hyperlinks, and a decorative image for the resume. If you work in web development and know a little about accessibility, these pain points should be very familiar to you.</p>
<p>Now that we know all the requirements, we can get started!</p>
<h3>Displaying accessibility problems and warnings</h3>
<p>On the right-hand side, you can click on “Accessibility Check” to display the corresponding warnings and notes. I have also selected “Entire page” under “Zoom” and “Formatting Marks” under “View.” This gives me an overview of the entire page and allows me to see where elements such as paragraphs, line breaks, or lists are located.</p>
<p><img src="https://piccalil.b-cdn.net/images/screenshots/Screenshot%202025-08-29%20at%2007.46.09.png" alt="Screenshot of the LibreOffice user interface showing a document with text and an Accessibility Check panel on the right hand side. Inside the panel are one error and multiple warnings shown." /></p>
<p>Not very pretty, but the good thing is that we only have one problem and a handful of warnings! The problem with the missing page title is quickly solved by clicking on the “Fix...” button and entering the title for the document, “Resume Steve Frenzel”:</p>
<p><img src="https://piccalil.b-cdn.net/images/screenshots/Screenshot%202025-08-29%20at%2007.53.29.png" alt="Screenshot of the LibreOffice user interface highlighting a dialog for the document title. The input field contains the words “Resume Steve Frenzel”." /></p>
<h3>Creating a heading structure</h3>
<p>Before we look at the warnings for links, I want to start by creating a hierarchy using headings. On the right-hand side, you can either select “Properties” or use the select element at the top left of the toolbar.</p>
<p><img src="https://piccalil.b-cdn.net/images/screenshots/Screenshot%202025-08-29%20at%2007.54.44.png" alt="Screenshot of the LibreOffice user interface with two big arrows. One points to a select element in the toolbar on top, one points to the same element inside the panel on the right hand side. Both of them have the option “Default Paragraph Style” selected." /></p>
<p>To do this, we highlight the relevant text and select, for example, “Heading 1,” “Heading 2,” and so on.</p>
<p><img src="https://piccalil.b-cdn.net/images/screenshots/Screenshot%202025-08-29%20at%2008.02.08.png" alt="Screenshot of the LibreOffice user interface highlighting two warnings inside the Accessibility Check panel, “Avoid new empty lines between numbered paragraphs.”." /></p>
<p>That looks much clearer already. However, there are now two warnings for “Avoid new empty lines between numbered paragraphs.”</p>
<p>Before we look at how to solve this, let's add the lists.</p>
<h3>Adding lists</h3>
<p>Lists can be added either via “Format,” “Lists,” and “Unordered List,” or via the toolbar and the button element with the list icon:</p>
<p><img src="https://piccalil.b-cdn.net/images/screenshots/Screenshot%202025-08-29%20at%2008.08.23.png" alt="Screenshot of the LibreOffice user interface highlighting the icon to create unordered lists with a big arrow. Below are multiple “Avoid new empty lines between numbered paragraphs.” Warnings highlighted." /></p>
<p>Our structure is coming along nicely, but what’s that: <em>more</em> warnings?! Let’s see how we can get rid of those.</p>
<h3>Avoiding empty lines between paragraphs</h3>
<p>By removing the empty paragraphs between headings, lists, and so on, we can significantly tidy up the “Accessibility Check” section:</p>
<p><img src="https://piccalil.b-cdn.net/images/screenshots/Screenshot%202025-08-29%20at%2008.11.39.png" alt="Screenshot of the LibreOffice user interface showing text with different kinds of headings, as well as unordered lists in-between. Inside the Accessibility check panel are multiple warnings for “Missing ‘name’ property of hyperlink.” and “Hyperlink text is the same as the link address”." /></p>
<p>The warnings have disappeared, but now the spacing between the “Heading 3” elements is virtually non-existent. “Heading 1” and “Heading 2” are fine for me.</p>
<p>To create a better visual hierarchy, we can go to “Styles” and “Edit styles...” and adjust the spacing under “Spacing” in “Indents &amp; Spacing.”</p>
<p>I chose a value of 0.20 and checked the box next to “Do not add space between paragraphs of the same style” so that these values are applied above and below the element.</p>
<p><img src="https://piccalil.b-cdn.net/images/screenshots/Screenshot%202025-08-29%20at%2008.16.00.png" alt="Screenshot of the LibreOffice user interface with a “Paragraph Style” dialog open. Inside, the “Spacing” section is highlighted, containing two options: “Above paragraph” and “Below paragraph”. Both values are 0.2." /></p>
<p>Now our document looks less squashed and we can take care of the warning about the links.</p>
<h3>Implementing links correctly</h3>
<p>There are two warnings, namely “Missing ‘name’ property of hyperlink.” and “Hyperlink text is the same as the link address [...]”. Here is our list of links:</p>
<ul>
<li>Email: <code>stvfrnzl@duck.com</code></li>
<li>Website: <a href="https://stevefrenzel.dev/">https://stevefrenzel.dev/</a>
<ul>
<li>Blog: <a href="https://stevefrenzel.dev/blog/">https://stevefrenzel.dev/blog/</a></li>
</ul>
</li>
<li>LinkedIn: <a href="https://linkedin.com/in/stevefrenzel/">https://linkedin.com/in/stevefrenzel/</a></li>
<li>GitHub: <a href="https://github.com/stevefrenzel/">https://github.com/stevefrenzel/</a></li>
<li>Mastodon: <a href="https://mastodon.online/@stvfrnzl/">https://mastodon.online/@stvfrnzl/</a></li>
</ul>
<p>What we need to do is give the link itself an accessible name and replace the URL with a different word. For example:</p>
<ul>
<li><a href="mailto:stvfrnzl@duck.com">Email</a></li>
<li><a href="https://stevefrenzel.dev/">Website</a>
<ul>
<li><a href="https://stevefrenzel.dev/blog/">Blog</a></li>
</ul>
</li>
<li><a href="https://linkedin.com/in/stevefrenzel/">LinkedIn</a></li>
<li><a href="https://github.com/stevefrenzel/">GitHub</a></li>
<li><a href="https://mastodon.online/@stvfrnzl/">Mastodon</a></li>
</ul>
<p>To do this, select the relevant word and open the context menu via “Insert” and “Hyperlink” in the toolbar (or <kbd>CMD</kbd> + <kbd>K</kbd> on macOS). For the email address, select “Mail” and enter the email address under “Recipient:”.</p>
<p>For hyperlinks, we select “Internet” and paste the URL under “Hyperlink settings” and “URL” (it is automatically pasted from the clipboard).</p>
<p><img src="https://piccalil.b-cdn.net/images/screenshots/Screenshot%202025-08-29%20at%2008.21.31.png" alt="Screenshot of the LibreOffice user interface with two big arrows pointing to the accessibility warning “Hyperlink test is too short.”. It also highlights a “Hyperlink” dialog, where one can enter values for websites, emails and documents." /></p>
<p>Although the warning about the hyperlink text has disappeared, two of the six links are now too short. It's “only” a warning, but my goal is to have zero errors or warnings, so we're going to fix that. “Email” becomes “Send email” and ‘Blog’ becomes “Read blog.”</p>
<div><h2>FYI</h2>
<p>To avoid issues with <a href="https://www.w3.org/TR/WCAG21/#label-in-name">WCAG success criterion 2.5.3 (Label in Name (Level A))</a>, the visible and accessible name are exactly the same here. This is very important for speech recognition users, because if these two are not, or only partially the same, users might have a hard time selecting this element.</p>
</div>
<p>Nice! All that's missing now is the accessible name for the links. To do this, we click the corresponding “Fix…” button and enter the appropriate name:</p>
<p><img src="https://piccalil.b-cdn.net/images/screenshots/Screenshot%202025-08-29%20at%2008.27.21.png" alt="Screenshot of the LibreOffice user interface highlighting a dialog titled “Enter a name of the hyperlink.”. It contains a text input with the value “Send email” in it." /></p>
<h3>Adding a different font</h3>
<p>This resume looks very plain, doesn't it? I'm not interested in winning a design award, but I would like to make it a little more appealing by using a different font. I've chosen “Graphik” for the headings and “Atkinson Hyperlegible Next” for the paragraphs.</p>
<p>Let's start by applying the style to the main heading:</p>
<p><img src="https://piccalil.b-cdn.net/images/screenshots/Screenshot%202025-08-29%20at%2008.36.33.png" alt="Screenshot of the LibreOffice user interface with a big arrow pointing to the accessibility warning “The text formatting conveys additional meaning.”" /></p>
<p>It looks better (in my opinion), but we got the warning “The text formatting conveys additional meaning.” This warning appears when we apply the new font <em>directly</em> to the text instead of using it <em>globally</em> for all main headings.</p>
<p>A better approach is to change the font under “Styles,” “Edit Style...,” “Font,” and “Family.” Alternatively, you can select the corresponding element, right-click, and access it in the context menu via ‘Paragraph’ and “Edit Style...”.</p>
<h3>Adding a decorative image</h3>
<p>Perfect, no more accessibility problems or warnings anymore! Now let's add a visual accent to the document with a visual separator. The toolbar has a button called “Insert line” (visualized by a diagonal line), which we can use to add the decorative image:</p>
<p><img src="https://piccalil.b-cdn.net/images/screenshots/Screenshot%202025-08-29%20at%2009.03.30.png" alt="Screenshot of the LibreOffice user interface with a big arrow pointing to a button inside the tool bar on top. The icon of the button shows a diagonal line." /></p>
<p>Interestingly, we do not receive a warning in the “Accessibility Check” section that this image has no alternative text or that it has not been marked as decorative. However, as we are aware of this issue, we will fix it immediately.</p>
<p>By right-clicking on the image (or selecting “Format” and “Alt Text...”), we can check the “Decorative” box. Done!</p>
<p><img src="https://piccalil.b-cdn.net/images/screenshots/Screenshot%202025-08-29%20at%2009.06.20.png" alt="Screenshot of the LibreOffice user interface showing a dialog called “Alt Text”. It contains input fields for “Text” and “Alt Text”, as well as a ticked checkbox labelled “Decorative”. A big arrow points to that checkbox." /></p>
<h3>Exporting it as accessible PDF</h3>
<p>Before exporting, we check whether we have implemented our elements correctly. To do this, we open the side panel under “Tools” and “Navigator,” which shows us semantic elements in the document. Although no paragraphs are displayed, all headings, hyperlinks, and images are shown as expected. Nice, moving on!</p>
<p><img src="https://piccalil.b-cdn.net/images/screenshots/Screenshot%202025-09-04%20at%2011.38.26.png" alt="Screenshot of the LibreOffice user interface showing eleven highlighted heading elements. The “Navigator” side panel visualises the hierarchy of these elements, as well as hyperlinks and images." /></p>
<p>Go to “File”, “Export As” and “Export as PDF...” and tick the box labelled “Universal Accessibility (PDF/UA)” to make sure it’s meeting the technical requirements for an accessible PDF:</p>
<p><img src="https://piccalil.b-cdn.net/images/screenshots/Screenshot%202025-08-29%20at%2009.09.21.png" alt="Screenshot of the LibreOffice user interface showing a dialog titled “PDF Options”. A big arrow is pointing to a ticked checkbox labelled “Universal Accessibility (PDF/UA)”." /></p>
<h2>Testing the PDF</h2>
<p>Let's start with a very simple test to make sure our document structure is correct. As I'm on MacOS, I'm using the native <a href="https://support.apple.com/en-gb/guide/preview/welcome/mac">Preview</a> and <a href="https://support.apple.com/en-gb/guide/textedit/welcome/mac">TextEdit</a> apps here but you can choose whatever is available to you.</p>
<p>After opening the PDF with Preview, we select all the text via <kbd>CMD</kbd> + <kbd>A</kbd> and copy it using <kbd>CMD</kbd> + <kbd>C</kbd>.</p>
<p><img src="https://piccalil.b-cdn.net/images/screenshots/Screenshot%202025-09-09%20at%2007.41.16.png" alt="Screenshot of the PDF opened in Preview on MacOS with all text highlighted in light blue." /></p>
<p>Now, we're going to paste it into an empty TextEdit document with <kbd>CMD</kbd> + <kbd>V</kbd>.</p>
<p><img src="https://piccalil.b-cdn.net/images/screenshots/Screenshot%202025-09-09%20at%2007.42.11.png" alt="Screenshot of TextEdit on MacOS showing all text of the PDF, including custom fonts, font sizes, formatting, lists and links." /></p>
<p>So, what are we looking for? We’re checking for:</p>
<ul>
<li>A logical reading order without mixed up content</li>
<li>Random text or characters</li>
</ul>
<p>As both are not the case, we can assume our document is fine. Let’s move on to check if it fulfils the PDF/UA and WCAG requirements on axes4.</p>
<h3>Checking PDF/UA and WCAG requirements on axes4</h3>
<p>Head over to the <a href="https://check.axes4.com/en/">axes4</a> website and either drag and drop your document where it says “Drag and drop your PDF here” or upload it by selecting the “select file” button.</p>
<p><img src="https://piccalil.b-cdn.net/images/screenshots/Screenshot%202025-08-29%20at%2009.20.28.png" alt="Screenshot of the axes4 website showing the drag and drop area for PDFs. A big arrow is pointing to the words “Drag and drop your PDF here”." /></p>
<p>Great, our document meets all requirements! In the “Document” and “Test Report” sections, you will find detailed information about the document and which criteria were checked.</p>
<p><img src="https://piccalil.b-cdn.net/images/screenshots/Screenshot%202025-08-29%20at%2009.21.53.png" alt="Screenshot of the axes4 website showing the results for the check. Both PDF/UA and WCAG are fulfilled. Below is more detailed information of the report." /></p>
<p>To be <em>really</em> sure that everything is as we intended, we can check our document with a screen reader to see how it interacts with this type of assistive technology.</p>
<h3>Testing it with different screen readers</h3>
<div><h2>FYI</h2>
<p>I'm neither dependent on a screen reader, nor am I an expert user. I use them mainly for checking the structure of a website, and to get a feeling how screen reader users <em>may</em> experience a website. Your screen reader experience might be very different than mine and the same goes for the setup of your preferred screen reader.</p>
</div>
<p>There are many screen reader apps out there and I chose to test with <a href="https://www.freedomscientific.com/products/software/jaws/">JAWS</a>, <a href="https://www.nvaccess.org/">NVDA</a> and <a href="https://support.apple.com/en-gb/guide/voiceover/welcome/mac">VoiceOver</a>, as these are the three most popular ones according to the <a href="https://webaim.org/projects/screenreadersurvey9/#primary">WebAIM Screen Reader User Survey</a>. A great resource on screen reader usage is <a href="https://adrianroselli.com/2022/11/your-accessibility-claims-are-wrong-unless.html#SRs">Your Accessibility Claims Are Wrong, Unless...</a> by <em>Adrian Roselli</em>.</p>
<p>I'm using MacOS Sequoia 15.6 and running Windows 11 on Mac with <a href="https://www.parallels.com/">Parallels</a>. Thanks to <a href="https://www.sarasoueidan.com/blog/testing-environment-setup/">this wonderful explainer by Sara Soueidan</a>, I was able to set it up quickly.</p>
<h4>Screen reader and browser combinations</h4>
<p>Regarding JAWS and NVDA: as I want to keep it as simple as possible, I open the PDF with Microsoft Edge, as it comes pre-installed with Windows 11.</p>
<p>However, some screen readers work better with certain browsers. These are some of the most popular combinations according to the <a href="https://webaim.org/projects/screenreadersurvey10/#browsercombos">WebAIM Screen Reader User Survey #10</a>, which are also recommended by the <a href="https://www.accessibilityassociation.org/sfsites/c/resource/WASBoK_PDF">IAAP (WAS Body of Knowledge, page 45)</a>:</p>
<ul>
<li>JAWS with Chrome</li>
<li>NVDA with Firefox (or Chrome)</li>
<li>VoiceOver with Safari</li>
</ul>
<h4>JAWS (Version 2025.2508.120) on Windows 11</h4>
<p>By pressing <kbd>H</kbd>, I’m moving through all the headings in the document, which worked as expected. We can also check the speech output by opening the <a href="https://www.freedomscientific.com/training/jaws/hotkeys/#:~:text=WINDOWS%20Key%2BC-,show%20speech%20history,-INSERT%2BSPACEBAR%20followed">Speech History</a> via <kbd>Insert</kbd> + <kbd>Spacebar</kbd> + <kbd>H</kbd>.</p>
<p><img src="https://piccalil.b-cdn.net/images/screenshots/Screenshot%202025-09-09%20at%2008.07.58.png" alt="Screenshot of the Speech History window of JAWS screen reader, with the announced headings highlighted. It shows eleven headings in total." /></p>
<p>Next, let’s check the lists by pressing <kbd>L</kbd>. It should announce seven lists:</p>
<ul>
<li>Five lists with three items</li>
<li>One list with two</li>
<li>One list with five items</li>
</ul>
<p><img src="https://piccalil.b-cdn.net/images/screenshots/Screenshot%202025-09-10%20at%2006.59.45.png" alt="Screenshot of the Speech History window of JAWS screen reader, with the announced lists highlighted. It shows seven lists in total." /></p>
<p>Sweet, this looks good as well! Lastly, let’s check if the links are working as expected by pressing <kbd>TAB</kbd> to traverse through the document:</p>
<p><img src="https://piccalil.b-cdn.net/images/screenshots/Screenshot%202025-09-09%20at%2008.10.17.png" alt="Screenshot of the Speech History window of JAWS screen reader, with the announced links highlighted. It shows six links in total." /></p>
<p>Looks like we’re good here! As we formatted our “Send email” hyperlink as a link to send an email straight away, JAWS announces “Send Mail Link” after the accessible name.</p>
<h4>NVDA (Version 2025.2) on Windows 11</h4>
<p>As before, I’m opening the PDF in Microsoft Edge and press <kbd>H</kbd> to traverse through the headings. All of them are announced correctly, let’s have a look at them in the <a href="https://download.nvaccess.org/documentation/en/userGuide.html#SpeechViewer">Speech Viewer</a>:</p>
<p><img src="https://piccalil.b-cdn.net/images/screenshots/Screenshot%202025-09-10%20at%2007.14.19.png" alt="Screenshot of the Speech Viewer window of NVDA screen reader, with the announced headings highlighted. It shows eleven headings in total." /></p>
<p>Moving on to the lists by pressing <kbd>L</kbd>, they are all recognised and announced correctly. However, NVDA also announces the bullet points here. Which is fine, as the most important thing are lists being announced as lists.</p>
<p><img src="https://piccalil.b-cdn.net/images/screenshots/Screenshot%202025-09-10%20at%2007.15.13.png" alt="Screenshot of the Speech Viewer window of NVDA screen reader, with the announced lists highlighted. It shows seven lists in total." /></p>
<p>When tabbing through the document using <kbd>TAB</kbd>, all links are announced as expected. Great, let’s check how this document behaves with VoiceOver.</p>
<p><img src="https://piccalil.b-cdn.net/images/screenshots/Screenshot%202025-09-10%20at%2007.15.57.png" alt="Screenshot of the Speech Viewer window of NVDA screen reader, with the announced links highlighted. It shows six links in total." /></p>
<h4>VoiceOver (Version 10) on MacOS Sequoia 15.6</h4>
<p>I am opening the document in <a href="https://support.apple.com/en-gb/guide/preview/welcome/mac">Preview</a> and use the so called <a href="https://support.apple.com/en-gb/guide/voiceover/mchlp2719/mac">Rotor</a> feature in VoiceOver to get an overview of elements like headings, links, images and many more. Let’s have a look at our heading structure:</p>
<p><img src="https://piccalil.b-cdn.net/images/screenshots/Screenshot%202025-09-04%20at%2011.44.41.png" alt="“Heading” section of the VoiceOver Rotor feature showing multiple heading levels from one to three." /></p>
<p>Everything looks as expected, layers and names are correct! Let's continue with the links:</p>
<p><img src="https://piccalil.b-cdn.net/images/screenshots/Screenshot%202025-09-04%20at%2011.44.47.png" alt="“Link” section of the VoiceOver Rotor feature showing six links." /></p>
<p>No surprises here either, wonderful. Let's take a look at the “Images” section:</p>
<p><img src="https://piccalil.b-cdn.net/images/screenshots/Screenshot%202025-09-04%20at%2011.44.55.png" alt="“Image” section of the VoiceOver Rotor feature showing nothing but the heading." /></p>
<p>Nothing is displayed here because we have marked the image as decorative.</p>
<p>Since the lists are not displayed here in Rotor, I navigated directly through the document using VoiceOver, and the lists were announced to me correctly.</p>
<p><img src="https://piccalil.b-cdn.net/images/screenshots/Screenshot%202025-09-04%20at%2012.02.00.png" alt="Text version of the VoiceOver output saying “content list 3 items”" /></p>
<h2>Wrapping up</h2>
<p>Anyone familiar with Microsoft Word or similar word processing programs should have no problem quickly finding their way around LibreOffice. It is also a small step toward digital sovereignty, moving away from the products of US tech giants.</p>
<p>The example with my resume may not be very complex, but it should contain enough examples for everyday use to quickly and easily create an accessible PDF.</p>
<p>Thanks to axes4, we can test our PDFs without ever having to think about the words “Adobe Acrobat Reader Pro”. If you wan't to make extra sure, you now know how to check the document with different screen readers too.</p>
        
        ]]></description>
        
      </item>
    
      <item>
        <title>Use transparent borders and outlines to assist with high contrast mode</title>
        <link>https://piccalil.li/blog/use-transparent-borders-and-outlines-to-assist-with-high-contrast-mode/?ref=accessibility-category-rss-feed</link>
        <dc:creator><![CDATA[Andy Bell]]></dc:creator>
        <pubDate>Thu, 11 Mar 2021 00:00:00 GMT</pubDate>
        <guid isPermaLink="true">https://piccalil.li/blog/use-transparent-borders-and-outlines-to-assist-with-high-contrast-mode/?ref=accessibility-category-rss-feed</guid>
        <description><![CDATA[<p>Say you’ve got this nice little button.</p>
<p></p><p>See the Pen <a href="https://codepen.io/piccalilli/pen/YzpdLRm">Button with shadow-based focus that’s not accessible in high contrast mode</a> by Andy Bell (<a href="https://codepen.io/piccalilli/">@piccalilli</a>) on <a href="https://codepen.io">CodePen</a>.</p><p></p>
<p>Because <code>outline</code> doesn’t clip to the shape of your button if you use <code>border-radius</code>, it can be tempting to use a sharp <code>box-shadow</code> for focus styles.</p>
<pre><code>button:focus {
  outline: none;
  box-shadow: 0px 0px 0px 3px #192a56;
}
</code></pre>
<p>With standard operating system and browser settings this looks fine. There’s plenty of contrast and the focus style is very clear. Job done, right? Unfortunately not because in <a href="https://support.microsoft.com/en-us/windows/use-high-contrast-mode-in-windows-10-fedc744c-90ac-69df-aed5-c8a90125e696">Windows High Contrast Mode</a>, both the background and focus styles probably won’t show up.</p>
<figure>
<video></video>
<figcaption><p>Because the background isn’t showing up in high contrast mode, the user has no visual indication of hover or focus events.</p></figcaption>
</figure>
<p>There is a solution to this: transparent borders and outlines! First, we add a transparent border to our button:</p>
<pre><code>button {
  border: 1px solid transparent;
  /* all the other CSS */
}
</code></pre>
<p>This border is completely invisible and you probably won’t even notice it, but the difference in Windows High Contrast Mode is huge.</p>
<p><img src="https://piccalil.b-cdn.net/images/quick-tips/high-contrast-button/good-button.jpg" alt="The much better button with styles as described in windows high contrast mode" /></p>
<p>This doesn’t fix the focus style though. It’s best to provide genuine contrast with focus styles so when a keyboard user <kbd>tab</kbd>s to your element, they can see that it is focused. To improve the initial focus style, we need to tweak it a bit:</p>
<pre><code>button:focus {
  outline: 2px solid transparent;
  outline-offset: 4px;
  box-shadow: 0px 0px 0px 3px #192a56;
}
</code></pre>
<p></p><p>See the Pen <a href="https://codepen.io/piccalilli/pen/VwmqXgd">Button with shadow-based focus that’s still accessible in high contrast mode</a> by Andy Bell (<a href="https://codepen.io/piccalilli/">@piccalilli</a>) on <a href="https://codepen.io">CodePen</a>.</p><p></p>
<p>We first set a 2 pixel <code>outline</code> and then using the ever-handy <code>outline-offset</code>, push it out by another 4 pixels. Now, when a user focuses our button, it looks great both in a standard operating system and browser configuration <strong>and</strong> it looks great in Windows High Contrast Mode.</p>
<figure>
<video></video>
<figcaption><p>The transparent border helps the button show up better to start with, then the outline adds an even better visual indicator that there has been a focus event.</p></figcaption>
</figure>
<p>Here’s all the CSS for the button:</p>
<pre><code>button {
  display: inline-block;
  padding: 0.5rem 2rem;
  font: inherit;
  font-weight: bold;
  border-radius: 2rem;
  border: 1px solid transparent;
  background: #3f25c4;
  color: #ffffff;
  min-width: 10rem;
  cursor: pointer;
}

button:hover,
button:focus {
  background: #8c7ae6;
  color: #000000;
}

button:focus {
  outline: 2px solid transparent;
  outline-offset: 4px;
  box-shadow: 0px 0px 0px 3px #192a56;
}
</code></pre>
<p>This is a quick win, for everyone: the visual design is left almost untouched <em>and</em> it’s accessible.</p>
        
        ]]></description>
        
      </item>
    
    </channel>
  </rss>
