<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Amira Chaabane</title>
    <description>The latest articles on DEV Community by Amira Chaabane (@amira_chaabane_ef95a1cc19).</description>
    <link>https://dev.to/amira_chaabane_ef95a1cc19</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3801147%2F4f721a99-de98-433e-bef4-19e2fb351c46.jpg</url>
      <title>DEV Community: Amira Chaabane</title>
      <link>https://dev.to/amira_chaabane_ef95a1cc19</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/amira_chaabane_ef95a1cc19"/>
    <language>en</language>
    <item>
      <title>How Don Norman's framework applies to sustainable UX and digital product design</title>
      <dc:creator>Amira Chaabane</dc:creator>
      <pubDate>Thu, 26 Mar 2026 07:20:35 +0000</pubDate>
      <link>https://dev.to/devly-digital/how-don-normans-circular-design-framework-applies-to-sustainable-ux-and-digital-product-design-2i3o</link>
      <guid>https://dev.to/devly-digital/how-don-normans-circular-design-framework-applies-to-sustainable-ux-and-digital-product-design-2i3o</guid>
      <description>&lt;p&gt;Don Norman coined the term "&lt;em&gt;User Experience&lt;/em&gt;."&lt;/p&gt;

&lt;p&gt;Then he spent his later career arguing that designers have been solving the wrong problems.&lt;/p&gt;

&lt;p&gt;In Design for a Better World (2023), he lays out a framework called Circular Design. Here's the core of it:&lt;/p&gt;

&lt;p&gt;The world runs on a linear model:&lt;br&gt;
Take raw materials → Make products → Discard as waste.&lt;/p&gt;

&lt;p&gt;Waste happens at every stage. Not just at the end.&lt;br&gt;
Half of all waste is produced before a product is even manufactured:  in mining, refining, and transportation alone.&lt;/p&gt;

&lt;p&gt;The materials we design with take 20 to 500 years to biodegrade.&lt;br&gt;
More than 1 million species are now threatened with extinction.&lt;br&gt;
84% of global energy still comes from fossil fuels.&lt;/p&gt;

&lt;p&gt;These are not environmental stats. These are &lt;strong&gt;design consequences&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Norman defines three types of planned obsolescence:&lt;br&gt;
→ Breakdown: components fused so repair is impossible&lt;br&gt;
→ Progress: new standards that make old products incompatible&lt;br&gt;
→ Fashion: cosmetic changes that make the old feel outdated&lt;/p&gt;

&lt;p&gt;And three principles of circular design to counter them:&lt;br&gt;
→ Treat waste and pollution as design flaws&lt;br&gt;
→ Design products to last, to be repaired, to be reused&lt;br&gt;
→ Design so end-of-life materials regenerate, not degrade&lt;/p&gt;

&lt;p&gt;These principles apply to digital products:&lt;/p&gt;

&lt;p&gt;An app that drops OS support to push upgrades ?&lt;br&gt;
That's planned obsolescence through progress.&lt;/p&gt;

&lt;p&gt;A redesign that forces users to relearn everything ?&lt;br&gt;
That's the digital equivalent of a glued-together coffee cup.&lt;/p&gt;

&lt;p&gt;Features that pile up until the only fix is a full rebuild ?&lt;br&gt;
That's take-make-waste applied to software.&lt;/p&gt;

&lt;p&gt;It is too late to stop the damage, but it is not too late to slow it down and reverse its progress.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://devly.digital/blog/how-don-normans-circular-design-framework-applies-to-sustainable-ux-and-digital-product-design" rel="noopener noreferrer"&gt;Full article&lt;/a&gt; covering the complete framework, the recycling myth, and how circular design applies to UX.&lt;/p&gt;

</description>
      <category>ux</category>
    </item>
    <item>
      <title>Your analytics script is the heaviest thing most visitors download</title>
      <dc:creator>Amira Chaabane</dc:creator>
      <pubDate>Thu, 12 Mar 2026 06:25:50 +0000</pubDate>
      <link>https://dev.to/devly-digital/your-analytics-script-is-the-heaviest-thing-most-visitors-download-cnp</link>
      <guid>https://dev.to/devly-digital/your-analytics-script-is-the-heaviest-thing-most-visitors-download-cnp</guid>
      <description>&lt;p&gt;Every time someone visits your website, their browser silently downloads a piece of JavaScript code called a tracking script. This is a small program that runs in the background, watches what the visitor does, which pages they view, where they came from, how long they stay and sends that information back to an analytics service like Google Analytics.&lt;/p&gt;

&lt;p&gt;The visitor never sees it. They never click on it. But their browser downloads and executes it on every single page, every single visit.&lt;/p&gt;

&lt;p&gt;Google Analytics loads roughly &lt;strong&gt;45 KB&lt;/strong&gt; of this tracking code onto every page of your website. Multiply that by your monthly traffic and the numbers stop being trivial.&lt;/p&gt;

&lt;p&gt;This article breaks down the environmental cost of analytics tracking scripts, compares Google Analytics to the lightweight open-source alternatives that have emerged in recent years, and makes the case that switching is one of the easiest &lt;strong&gt;Green IT wins&lt;/strong&gt; available to any website owner.&lt;/p&gt;




&lt;h2&gt;
  
  
  What your analytics script actually costs
&lt;/h2&gt;

&lt;p&gt;Before we talk about the cost, it helps to understand what actually happens when a visitor lands on a page that runs Google Analytics.&lt;/p&gt;

&lt;p&gt;When a visitor's browser loads your page, it encounters a &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tag in your HTML that points to &lt;strong&gt;Google Tag Manager&lt;/strong&gt;: a JavaScript file hosted on Google's servers at &lt;code&gt;googletagmanager.com&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The browser downloads this file (&lt;strong&gt;~28 KB&lt;/strong&gt;). Once executed, this script immediately fetches a second file: the &lt;strong&gt;Google Analytics tag&lt;/strong&gt; from &lt;code&gt;google-analytics.com&lt;/code&gt; (&lt;strong&gt;~17 KB&lt;/strong&gt;).&lt;/p&gt;

&lt;p&gt;Once both scripts are loaded and running, they begin collecting data:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;page URL
&lt;/li&gt;
&lt;li&gt;referrer
&lt;/li&gt;
&lt;li&gt;screen size
&lt;/li&gt;
&lt;li&gt;browser
&lt;/li&gt;
&lt;li&gt;device
&lt;/li&gt;
&lt;li&gt;location
&lt;/li&gt;
&lt;li&gt;scroll depth
&lt;/li&gt;
&lt;li&gt;engagement time
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;…and more.&lt;/p&gt;

&lt;p&gt;This data is then sent back to Google's servers as a series of HTTP requests. This happens on &lt;strong&gt;every page the visitor navigates to&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That’s roughly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;45 KB of JavaScript downloaded&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;two external server connections&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;tracking data sent back&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;for every page view.&lt;/p&gt;

&lt;p&gt;Each of these steps has an &lt;strong&gt;energy cost&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The files must be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;transferred over the network (routers, CDNs, cell towers)&lt;/li&gt;
&lt;li&gt;downloaded to the visitor's device&lt;/li&gt;
&lt;li&gt;parsed and executed by the browser&lt;/li&gt;
&lt;li&gt;followed by additional data sent back to external servers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All of this consumes &lt;strong&gt;electricity and computing resources&lt;/strong&gt;.&lt;/p&gt;




&lt;h4&gt;
  
  
  Note
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;DNS lookup&lt;/strong&gt; is how the browser translates a domain name (like &lt;code&gt;googletagmanager.com&lt;/code&gt;) into an IP address it can connect to.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TCP connection&lt;/strong&gt; is the handshake between the browser and the server that establishes a reliable communication channel.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TLS handshake&lt;/strong&gt; is the encryption negotiation that happens for HTTPS connections.&lt;/p&gt;

&lt;p&gt;Because Google Analytics uses &lt;strong&gt;two external domains&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;googletagmanager.com&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;google-analytics.com&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;the browser performs the full:DNS → TCP → TLS&lt;/p&gt;

&lt;p&gt;sequence &lt;strong&gt;twice&lt;/strong&gt;, before a single byte of analytics data has even been collected.&lt;/p&gt;




&lt;p&gt;For a site with &lt;strong&gt;100,000 monthly page views&lt;/strong&gt;, that's roughly &lt;strong&gt;4.5 GB of analytics JavaScript transferred per month&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For a site with &lt;strong&gt;1 million page views&lt;/strong&gt;, it's &lt;strong&gt;45 GB&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;And that's just the &lt;strong&gt;tracking script&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
It does &lt;strong&gt;not include the analytics data payloads&lt;/strong&gt; sent back to Google's servers.&lt;/p&gt;




&lt;h4&gt;
  
  
  Note
&lt;/h4&gt;

&lt;p&gt;These numbers assume the &lt;strong&gt;standard Google Tag Manager + GA4 integration&lt;/strong&gt;, which is how most sites implement Google Analytics.&lt;/p&gt;

&lt;p&gt;There are lighter implementations (minimal analytics scripts, self-hosted &lt;code&gt;gtag&lt;/code&gt;), but the vast majority of websites use the &lt;strong&gt;default setup&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  The lightweight alternatives
&lt;/h2&gt;

&lt;p&gt;A new generation of analytics tools has appeared.&lt;/p&gt;

&lt;p&gt;They share a common philosophy:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;collect only what you need
&lt;/li&gt;
&lt;li&gt;use the smallest possible tracking script
&lt;/li&gt;
&lt;li&gt;respect user privacy by design
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Well-known ones include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Umami&lt;/li&gt;
&lt;li&gt;Plausible&lt;/li&gt;
&lt;li&gt;Fathom&lt;/li&gt;
&lt;li&gt;Cabin&lt;/li&gt;
&lt;li&gt;Simple Analytics&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Several of these are &lt;strong&gt;fully open source&lt;/strong&gt;.&lt;/p&gt;




&lt;h4&gt;
  
  
  What they have in common (from a Green IT perspective)
&lt;/h4&gt;

&lt;h4&gt;
  
  
  Script size
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Umami:&lt;/strong&gt; &amp;lt; 2 KB
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Plausible:&lt;/strong&gt; &amp;lt; 1 KB
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cabin:&lt;/strong&gt; ~1.2 KB
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Google Analytics (via GTM):&lt;/strong&gt; ~45 KB
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That’s roughly a &lt;strong&gt;20× to 45× difference&lt;/strong&gt; in JavaScript payload on every page view.&lt;/p&gt;

&lt;h4&gt;
  
  
  No third-party requests
&lt;/h4&gt;

&lt;p&gt;Most lightweight alternatives either:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;self-host their script
&lt;/li&gt;
&lt;li&gt;serve it from a single domain
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Google Analytics requires connections to &lt;strong&gt;multiple Google-owned domains&lt;/strong&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  No cookies
&lt;/h4&gt;

&lt;p&gt;These tools &lt;strong&gt;don’t use cookies&lt;/strong&gt;, which means &lt;strong&gt;no cookie consent banners&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Consent banners themselves load additional:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JavaScript&lt;/li&gt;
&lt;li&gt;CSS&lt;/li&gt;
&lt;li&gt;modal overlays&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Removing the need for them &lt;strong&gt;reduces page weight further&lt;/strong&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Smaller data payloads
&lt;/h4&gt;

&lt;p&gt;Lightweight analytics collect fewer data points:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;page views&lt;/li&gt;
&lt;li&gt;referrers&lt;/li&gt;
&lt;li&gt;device type&lt;/li&gt;
&lt;li&gt;country&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Google Analytics collects &lt;strong&gt;hundreds of data points&lt;/strong&gt;, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;scroll depth&lt;/li&gt;
&lt;li&gt;engagement time&lt;/li&gt;
&lt;li&gt;user demographics&lt;/li&gt;
&lt;li&gt;session data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;More data means &lt;strong&gt;more bytes sent back to servers&lt;/strong&gt;.&lt;/p&gt;




&lt;h4&gt;
  
  
  Pro Tip
&lt;/h4&gt;

&lt;p&gt;Plausible calculated that replacing Google Analytics on a site with &lt;strong&gt;100,000 monthly visitors&lt;/strong&gt; saves approximately:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;7 GB of data transfer per month&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;84 GB per year&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At an estimated &lt;strong&gt;0.2 kWh per GB&lt;/strong&gt;, that’s roughly:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;16.8 kWh saved annually&lt;/strong&gt; from a single script change.&lt;/p&gt;




&lt;h2&gt;
  
  
  The privacy argument
&lt;/h2&gt;

&lt;p&gt;This article focuses on &lt;strong&gt;Green IT&lt;/strong&gt;, but privacy is closely related.&lt;/p&gt;

&lt;p&gt;Google Analytics:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;collects personal data&lt;/li&gt;
&lt;li&gt;uses cookies&lt;/li&gt;
&lt;li&gt;integrates with Google’s advertising ecosystem&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This requires &lt;strong&gt;cookie consent banners&lt;/strong&gt; under regulations such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;GDPR (EU)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CCPA (California)&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Lightweight alternatives:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;collect no personal data&lt;/li&gt;
&lt;li&gt;use no cookies&lt;/li&gt;
&lt;li&gt;require no consent banners&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;They are &lt;strong&gt;GDPR-compliant by design&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Devly uses
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Umami&lt;/strong&gt;, self-hosted on a VPS at &lt;strong&gt;OVHcloud&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Umami is open source and OVHcloud has committed to powering its data centers with &lt;strong&gt;100% renewable energy by 2025&lt;/strong&gt;, with &lt;strong&gt;77% already achieved&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;They have also:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;signed a solar power purchase agreement with EDF Renewables&lt;/li&gt;
&lt;li&gt;implemented proprietary liquid cooling systems&lt;/li&gt;
&lt;li&gt;reported a &lt;strong&gt;PUE between 1.1 and 1.3&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;signed the &lt;strong&gt;Climate Neutral Data Centre Pact&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Self-hosting matters for Green IT.&lt;/p&gt;

&lt;p&gt;When you self-host analytics:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;you control the infrastructure&lt;/li&gt;
&lt;li&gt;you choose the hosting provider&lt;/li&gt;
&lt;li&gt;you know where the data center is located&lt;/li&gt;
&lt;li&gt;you can verify its energy sourcing&lt;/li&gt;
&lt;/ul&gt;




&lt;h4&gt;
  
  
  Note
&lt;/h4&gt;

&lt;p&gt;If self-hosting isn’t an option, good managed alternatives include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Plausible&lt;/strong&gt; (open source, hosted on renewable-energy-powered Hetzner servers)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cabin&lt;/strong&gt; (100% renewable hosting with built-in carbon tracking)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The counter-argument: when Google Analytics is justified
&lt;/h2&gt;

&lt;p&gt;Google Analytics exists because it solves &lt;strong&gt;real problems&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;detailed conversion attribution&lt;/li&gt;
&lt;li&gt;e-commerce funnel analysis&lt;/li&gt;
&lt;li&gt;Google Ads integration&lt;/li&gt;
&lt;li&gt;advanced audience segmentation&lt;/li&gt;
&lt;li&gt;remarketing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Lightweight tools &lt;strong&gt;don’t fully replicate these capabilities&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;But most websites don’t need them.&lt;/p&gt;

&lt;p&gt;Typical sites like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;blogs&lt;/li&gt;
&lt;li&gt;documentation sites&lt;/li&gt;
&lt;li&gt;portfolios&lt;/li&gt;
&lt;li&gt;small business websites&lt;/li&gt;
&lt;li&gt;SaaS marketing pages&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;mostly need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;page views&lt;/li&gt;
&lt;li&gt;referrers&lt;/li&gt;
&lt;li&gt;top pages&lt;/li&gt;
&lt;li&gt;basic events&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For these use cases, Google Analytics is &lt;strong&gt;dramatically over-engineered&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  How to switch
&lt;/h2&gt;

&lt;p&gt;Migrating is simpler than most people expect.&lt;/p&gt;

&lt;p&gt;Typical process:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Add the analytics &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tag to your &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Verify data appears in the dashboard&lt;/li&gt;
&lt;li&gt;Remove the Google Analytics script&lt;/li&gt;
&lt;li&gt;Remove the cookie consent banner (if analytics was the only reason)&lt;/li&gt;
&lt;/ol&gt;




&lt;h4&gt;
  
  
  Pro Tip
&lt;/h4&gt;

&lt;p&gt;Before removing Google Analytics, export any historical data you want to keep.&lt;/p&gt;

&lt;p&gt;Some tools, such as &lt;strong&gt;Plausible Analytics&lt;/strong&gt;, offer a &lt;strong&gt;Google Analytics import feature&lt;/strong&gt; that allows you to migrate historical statistics into their dashboard.&lt;/p&gt;




&lt;p&gt;Analytics tracking scripts are only &lt;strong&gt;one piece of a website’s environmental footprint&lt;/strong&gt; but they are a uniquely wasteful one because many sites load far more analytics infrastructure than they actually need.&lt;/p&gt;

&lt;p&gt;For more: &lt;a href="https://devly.digital/?utm_source=devto&amp;amp;utm_campaign=green_web&amp;amp;utm_content=your_analytics_script_is_the_heaviest_thing_most_visitors_download" rel="noopener noreferrer"&gt;Devly digital&lt;/a&gt;&lt;/p&gt;

</description>
      <category>greenweb</category>
      <category>webperf</category>
    </item>
    <item>
      <title>A starting guide to web accessibility</title>
      <dc:creator>Amira Chaabane</dc:creator>
      <pubDate>Fri, 06 Mar 2026 04:39:54 +0000</pubDate>
      <link>https://dev.to/devly-digital/a-starting-guide-to-web-accessibility-42jh</link>
      <guid>https://dev.to/devly-digital/a-starting-guide-to-web-accessibility-42jh</guid>
      <description>&lt;h2&gt;
  
  
  What is web accessibility really?
&lt;/h2&gt;

&lt;p&gt;Web accessibility means that every person can use your website, regardless of ability, disability, device, or situation. That includes someone using a screen reader, someone navigating with only a keyboard, someone with low vision, or someone in bright sunlight trying to read their phone.&lt;/p&gt;

&lt;p&gt;It's not an extra feature you bolt on at the end. It's a fundamental part of how the web was designed to work in the first place. The inventor of the World Wide Web, Tim Berners-Lee, said it best:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The power of the Web is in its universality. Access by everyone, regardless of disability, is an essential aspect.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;Accessibility is often shortened to "a11y" in the developer community, the "11" represents the 11 letters between the "a" and the "y". You'll see this everywhere.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Who needs accessible websites?
&lt;/h2&gt;

&lt;p&gt;Most developers think of accessibility as helping "people with disabilities." But it's far broader than that.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A person who is blind and uses a screen reader to navigate the web.&lt;/li&gt;
&lt;li&gt;A person with a motor impairment who cannot use a mouse and relies entirely on a keyboard.&lt;/li&gt;
&lt;li&gt;A person with low vision who needs to zoom in to 400% to read content.&lt;/li&gt;
&lt;li&gt;A person with a cognitive disability who needs clear, simple language and structure.&lt;/li&gt;
&lt;li&gt;An elderly person whose vision or motor control has declined with age.&lt;/li&gt;
&lt;li&gt;A person in a bright environment where low-contrast text becomes unreadable.&lt;/li&gt;
&lt;li&gt;A person on a slow mobile connection where heavy pages take forever to load.&lt;/li&gt;
&lt;li&gt;A person temporarily injured — a broken arm means no mouse for weeks.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Accessibility features benefit everyone. Curb cuts on sidewalks were designed for wheelchair users but are also used daily by people with strollers, luggage, and bicycles. The web works the same way.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding WCAG
&lt;/h2&gt;

&lt;p&gt;WCAG stands for Web Content Accessibility Guidelines. It's the international standard for web accessibility, maintained by the World Wide Web Consortium (W3C). When someone says "accessible website," they almost always mean WCAG compliant.&lt;/p&gt;

&lt;p&gt;WCAG is organized into three levels of conformance:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Level A&lt;/strong&gt;: The minimum. Covers the most critical barriers that completely block access for some users.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Level AA&lt;/strong&gt;: The recommended standard. Most legal requirements around the world require at least AA compliance. This is your target.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Level AAA&lt;/strong&gt;: The gold standard. Nice to achieve where possible, but not required for most websites.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Many countries and regions have laws requiring websites to meet WCAG AA. In the EU, the European Accessibility Act applies. In the US, the Americans with Disabilities Act (ADA) has been interpreted to cover websites. Building accessibly isn't just good practice. In many cases, it's a legal requirement.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The 4 pillars of accessibility
&lt;/h2&gt;

&lt;p&gt;WCAG organizes all its guidelines around four core principles. Everything you'll ever do for accessibility traces back to one of these:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Perceivable&lt;/strong&gt;: Users must be able to perceive all information. If something is only communicated through color, or only through sound, some users will miss it entirely.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Operable&lt;/strong&gt;: Users must be able to operate the interface. If something can only be activated with a mouse click, keyboard users are locked out.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Understandable&lt;/strong&gt;: The content and interface must be understandable. Confusing navigation, inconsistent behavior, or unclear language creates barriers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Robust&lt;/strong&gt;: The content must be robust enough to be reliably interpreted by a wide variety of assistive technologies, both current and future.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Semantic HTML: the foundation
&lt;/h2&gt;

&lt;p&gt;This is the single most important thing you can do for accessibility. Semantic HTML means using the right HTML elements for their intended purpose, instead of using generic elements like divs for everything.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!-- Bad: No meaning, screen readers see nothing useful --&amp;gt;
&amp;lt;div class="header"&amp;gt;
  &amp;lt;div class="nav"&amp;gt;
    &amp;lt;div class="nav-link"&amp;gt;Home&amp;lt;/div&amp;gt;
    &amp;lt;div class="nav-link"&amp;gt;About&amp;lt;/div&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;div class="main"&amp;gt;
  &amp;lt;div class="title"&amp;gt;Welcome&amp;lt;/div&amp;gt;
  &amp;lt;div class="content"&amp;gt;This is my website.&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;!-- Good: Every element tells assistive tech what it is --&amp;gt;
&amp;lt;header&amp;gt;
  &amp;lt;nav&amp;gt;
    &amp;lt;a href="/"&amp;gt;Home&amp;lt;/a&amp;gt;
    &amp;lt;a href="/about"&amp;gt;About&amp;lt;/a&amp;gt;
  &amp;lt;/nav&amp;gt;
&amp;lt;/header&amp;gt;
&amp;lt;main&amp;gt;
  &amp;lt;h1&amp;gt;Welcome&amp;lt;/h1&amp;gt;
  &amp;lt;p&amp;gt;This is my website.&amp;lt;/p&amp;gt;
&amp;lt;/main&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Screen readers announce the role of elements to users. With semantic HTML, a user hears "navigation, list, 2 items" instead of just silence. This gives them a mental map of your page without ever seeing it.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Here are the key semantic elements you should know:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;/strong&gt; The top section of a page or article, usually containing branding and navigation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;/strong&gt; A block of navigation links.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;/strong&gt; The main content of the page. Only one per page.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;/strong&gt; A self-contained piece of content, like a blog post.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;/strong&gt; A thematic grouping of content&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;/strong&gt; Content that is tangentially related to the main content, like a sidebar.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;/strong&gt; The bottom section of a page or article.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;h1&lt;/strong&gt; through &lt;strong&gt;h6&lt;/strong&gt; Headings that create a hierarchy. Never skip levels.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;/strong&gt; For actions. Never use a div or span for a clickable action.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a&gt;&lt;/a&gt;&lt;/strong&gt; For navigation. Never use a button for navigating to a URL.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Never use a div with an onClick handler as a button, and never use a  to navigate to a different page. Screen readers announce these differently, and keyboard users expect specific behavior from each. Using them wrong breaks the experience entirely&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Keyboard navigation
&lt;/h2&gt;

&lt;p&gt;Every single interactive element on your website must be reachable and usable with only a keyboard. Many users; whether due to motor disabilities, power users, or assistive technology; rely entirely on the keyboard.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!-- Bad: Only works with a mouse click --&amp;gt;
&amp;lt;div class="btn" onclick="submitForm()"&amp;gt;Submit&amp;lt;/div&amp;gt;

&amp;lt;!-- Good: Keyboard accessible, correct semantics --&amp;gt;
&amp;lt;button type="submit"&amp;gt;Submit&amp;lt;/button&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The key rules:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;All interactive elements must be focusable: buttons, links, inputs, and custom components.&lt;/li&gt;
&lt;li&gt;Focus must follow a logical order: top to bottom, left to right.&lt;/li&gt;
&lt;li&gt;Focus must always be visible: the user must see which element is currently focused.&lt;/li&gt;
&lt;li&gt;No keyboard traps: the user must never get stuck somewhere they can't escape with the keyboard.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/* Bad: Removing focus styles entirely */
button:focus {
  outline: none;
}

/* Good: Custom but visible focus indicator */
button:focus-visible {
  outline: 2px solid #5de8e2;
  outline-offset: 2px;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Never remove focus styles with outline: none without providing an alternative. This makes your website completely unusable for keyboard-only users. If you don't like the default browser outline, style it, don't remove it.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Images and alt text
&lt;/h2&gt;

&lt;p&gt;Every image on your website needs an alt attribute. This is one of the most basic and most commonly violated accessibility rules.&lt;/p&gt;

&lt;p&gt;Alt text serves two purposes: it describes the image to screen readers, and it displays as fallback text if the image fails to load.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!-- Bad: No alt text at all --&amp;gt;
&amp;lt;img src="chart.png"&amp;gt;

&amp;lt;!-- Bad: Meaningless alt text --&amp;gt;
&amp;lt;img src="chart.png" alt="image"&amp;gt;
&amp;lt;img src="chart.png" alt="IMG_4732.png"&amp;gt;

&amp;lt;!-- Good: Descriptive alt text --&amp;gt;
&amp;lt;img src="chart.png" alt="Bar chart showing website carbon emissions dropping 60% after optimization"&amp;gt;

&amp;lt;!-- Good: Decorative images use empty alt --&amp;gt;
&amp;lt;img src="decorative-divider.png" alt=""&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Color contrast
&lt;/h2&gt;

&lt;p&gt;Color contrast is the difference in brightness between text and its background. If the contrast is too low, text becomes hard or impossible to read, especially for people with low vision, color blindness, or anyone in a bright environment.&lt;/p&gt;

&lt;p&gt;WCAG AA requires:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Normal text (under 18px or 14px bold): A contrast ratio of at least 4.5:1.&lt;/li&gt;
&lt;li&gt;Large text (18px+ or 14px+ bold): A contrast ratio of at least 3:1.&lt;/li&gt;
&lt;li&gt;UI components and icons: A contrast ratio of at least 3:1 against adjacent colors
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/* Bad: Low contrast — fails WCAG AA */
.text {
  color: #777777; /* gray text */
  background-color: #ffffff; /* white background */
}
/* Contrast ratio: 4.48:1 — just below the 4.5:1 requirement */

/* Good: Sufficient contrast — passes WCAG AA */
.text {
  color: #595959;
  background-color: #ffffff;
}
/* Contrast ratio: 7.0:1 — well above the requirement */
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Never rely on color alone to convey information. For example, don't show errors in red text only. Add an icon, a label, or a pattern so that colorblind users can also understand the message.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Forms and inputs
&lt;/h2&gt;

&lt;p&gt;Forms are one of the most common accessibility failure points on the web. A form that looks fine visually can be completely broken for assistive technology users.&lt;/p&gt;

&lt;p&gt;Every input needs a proper label. Every error needs to be clearly communicated. Every required field needs to be marked.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!-- Bad: No label, no error handling --&amp;gt;
&amp;lt;input type="email" placeholder="Enter your email"&amp;gt;

&amp;lt;!-- Good: Proper label, error handling, required marking --&amp;gt;
&amp;lt;div&amp;gt;
  &amp;lt;label for="email"&amp;gt;
    Email address
    &amp;lt;span aria-label="required"&amp;gt;*&amp;lt;/span&amp;gt;
  &amp;lt;/label&amp;gt;
  &amp;lt;input
    type="email"
    id="email"
    name="email"
    required
    aria-required="true"
    aria-describedby="email-error"
  &amp;gt;
  &amp;lt;p id="email-error" role="alert" aria-live="polite"&amp;gt;
    Please enter a valid email address.
  &amp;lt;/p&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  ARIA: when and why
&lt;/h2&gt;

&lt;p&gt;ARIA stands for Accessible Rich Internet Applications. It's a set of attributes you can add to HTML to give assistive technologies extra information about your content.&lt;/p&gt;

&lt;p&gt;But here's the critical rule: use native HTML first. ARIA is a last resort.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!-- Bad: Using ARIA when native HTML already works --&amp;gt;
&amp;lt;div role="button" tabindex="0" aria-pressed="false"&amp;gt;
  Submit
&amp;lt;/div&amp;gt;

&amp;lt;!-- Good: Native HTML does this automatically --&amp;gt;
&amp;lt;button type="submit"&amp;gt;Submit&amp;lt;/button&amp;gt;

&amp;lt;!-- Good: ARIA used correctly — native HTML can't do this --&amp;gt;
&amp;lt;div
  role="dialog"
  aria-modal="true"
  aria-label="Confirm deletion"
&amp;gt;
  &amp;lt;p&amp;gt;Are you sure you want to delete this item?&amp;lt;/p&amp;gt;
  &amp;lt;button&amp;gt;Cancel&amp;lt;/button&amp;gt;
  &amp;lt;button&amp;gt;Delete&amp;lt;/button&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;A good rule of thumb: if a native HTML element already does what you need, use it. ARIA is for cases where native HTML falls short: like custom modals, tooltips, live regions, and complex widgets that have no HTML equivalent.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing your work
&lt;/h2&gt;

&lt;p&gt;You cannot rely on visual inspection alone to find accessibility issues. You need a combination of automated tools and manual testing.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Automated tools&lt;/strong&gt;: They catch roughly 30-40% of issues. Use them as a starting point, not a guarantee.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keyboard testing&lt;/strong&gt;: Unplug your mouse. Navigate your entire site using only Tab, Enter, Space, and arrow keys. Can you reach everything? Can you use everything?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Screen reader testing&lt;/strong&gt;: Install a free screen reader and try using your site. NVDA (Windows) and VoiceOver (Mac/iOS) are both free and widely used.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Color contrast checkers&lt;/strong&gt;: Tools like the WebAIM Contrast Checker let you input two colors and see if they meet WCAG ratios.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Real user feedback&lt;/strong&gt;: If possible, ask people who use assistive technologies to test your site. Their feedback is irreplaceable.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Automated tools are helpful but limited. They cannot detect issues like confusing navigation, unclear language, or illogical reading order. Always combine automated testing with manual review.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources to keep learning
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;W3C WCAG 2.1 Guidelines&lt;/strong&gt;: &lt;a href="https://www.w3.org/WAI/WCAG21/Understanding/" rel="noopener noreferrer"&gt;w3.org/WAI/WCAG21/Understanding&lt;/a&gt; The official standard. Read the "Understanding" version, it's much more approachable than the raw spec.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;WebAIM&lt;/strong&gt;: &lt;a href="//webaim.org"&gt;webaim.org&lt;/a&gt; One of the best free resources. Guides, tools, and checklists all in one place.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MDN Web Docs (Accessibility)&lt;/strong&gt;: &lt;a href="https://developer.mozilla.org/en-US/docs/Web/Accessibility" rel="noopener noreferrer"&gt;developer.mozilla.org/en-US/docs/Web/Accessibility&lt;/a&gt; Solid technical reference for HTML, ARIA, and accessibility best practices.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;axe DevTools&lt;/strong&gt;: &lt;a href="https://chromewebstore.google.com/detail/axe-devtools-web-accessib/lhdoppojpmngadmnindnejefpokejbdd" rel="noopener noreferrer"&gt;axe devtools&lt;/a&gt; The most popular browser extension for automated accessibility testing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Google Lighthouse&lt;/strong&gt;: &lt;a href="//developers.google.com/web/tools/lighthouse"&gt;developers.google.com/web/tools/lighthouse&lt;/a&gt; Built into Chrome DevTools. Gives you an accessibility score and actionable recommendations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;WebAIM Contrast Checker&lt;/strong&gt;: &lt;a href="//webaim.org/resources/contrastchecker"&gt;webaim.org/resources/contrastchecker&lt;/a&gt; Instantly check if two colors meet WCAG contrast requirements.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>a11y</category>
      <category>frontend</category>
      <category>html</category>
    </item>
    <item>
      <title>The Skip Navigation feature makes your website more accessible</title>
      <dc:creator>Amira Chaabane</dc:creator>
      <pubDate>Mon, 02 Mar 2026 07:38:04 +0000</pubDate>
      <link>https://dev.to/devly-digital/the-skip-navigation-feature-makes-your-website-more-accessible-1i93</link>
      <guid>https://dev.to/devly-digital/the-skip-navigation-feature-makes-your-website-more-accessible-1i93</guid>
      <description>&lt;p&gt;Only 13.7% of the top million websites have a skip navigation link. Of those that do, 10% are broken. This is a feature that takes about 20 minutes to implement, costs nothing to maintain, and directly improves the experience for every keyboard user who visits your site.&lt;/p&gt;

&lt;p&gt;So what skip navigation actually does and why it matters beyond compliance checkboxes ?&lt;/p&gt;

&lt;h2&gt;
  
  
  What skip navigation actually solves
&lt;/h2&gt;

&lt;p&gt;Picture a typical website. There's a logo, a main navigation with 8–15 links, maybe a search bar, maybe a language switcher or a dark mode toggle. A sighted mouse user glances past all of it and clicks directly on the content they want. The whole process takes less than a second.&lt;/p&gt;

&lt;p&gt;Now picture navigating that same page with only a keyboard. Every one of those elements: logo, nav links, search input, toggles, requires a Tab keypress to move past. On a site with 20 interactive elements before the main content, that's 20 Tab presses. On every single page. For someone using a switch device by tapping their head, or operating a mouth stick to press keys, those 20 actions aren't a minor inconvenience. They're a physical barrier.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu6ewyze96c7apdxuwwbu.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu6ewyze96c7apdxuwwbu.jpg" alt=" " width="590" height="464"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;(image caption: A mouth stick: an assistive device gripped between the teeth to press keys and interact with a computer, used by people with limited or no use of their hands.)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A skip navigation link solves this by placing an anchor link as the very first focusable element on the page. When activated, it jumps the user directly to the main content. One Tab, one Enter, done.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: WCAG Success Criterion 2.4.1 (Bypass Blocks) requires that websites provide a mechanism to skip repeated content blocks. This is a Level A requirement, the most basic tier of accessibility compliance. It's referenced in the ADA (US) and the European Accessibility Act. It is not optional for any public-facing website that needs to meet accessibility standards.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why this isn't just a compliance box
&lt;/h2&gt;

&lt;p&gt;The practical argument for skip links goes beyond legal requirements.&lt;/p&gt;

&lt;p&gt;Screen reader users hear every element announced sequentially. Without a bypass mechanism, they hear the same navigation announced on every page they visit. Keyboard-only users, whether due to motor impairments, temporary injuries, or simply preference, must physically tab through every repeated element. Users with cognitive or attention differences benefit from reduced noise between them and the content they came for.&lt;/p&gt;

&lt;p&gt;And it's not a niche audience. WebAIM's 2025 analysis of the top million home pages found an average of 51 accessibility errors per page. The web is not built for these users by default, which means every correct implementation counts.&lt;/p&gt;
&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang="en"&amp;gt;
&amp;lt;head&amp;gt;
  &amp;lt;meta charset="UTF-8"&amp;gt;
  &amp;lt;title&amp;gt;Page Title&amp;lt;/title&amp;gt;
  &amp;lt;link rel="stylesheet" href="styles.css"&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;

  &amp;lt;!-- Skip link: first element inside &amp;lt;body&amp;gt; --&amp;gt;
  &amp;lt;a href="#main-content" class="skip-link"&amp;gt;
    Skip to content
  &amp;lt;/a&amp;gt;

  &amp;lt;header&amp;gt;
    &amp;lt;nav&amp;gt;
      &amp;lt;a href="/"&amp;gt;Home&amp;lt;/a&amp;gt;
      &amp;lt;a href="/about"&amp;gt;About&amp;lt;/a&amp;gt;
      &amp;lt;a href="/blog"&amp;gt;Blog&amp;lt;/a&amp;gt;
      &amp;lt;a href="/contact"&amp;gt;Contact&amp;lt;/a&amp;gt;
    &amp;lt;/nav&amp;gt;
  &amp;lt;/header&amp;gt;

  &amp;lt;!-- Target: the main content area --&amp;gt;
  &amp;lt;main id="main-content" tabindex="-1"&amp;gt;
    &amp;lt;h1&amp;gt;Page Heading&amp;lt;/h1&amp;gt;
    &amp;lt;p&amp;gt;Your actual content starts here.&amp;lt;/p&amp;gt;
  &amp;lt;/main&amp;gt;

  &amp;lt;footer&amp;gt;
    &amp;lt;p&amp;gt;&amp;amp;copy; 2025&amp;lt;/p&amp;gt;
  &amp;lt;/footer&amp;gt;

&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Three things make this work: the skip link is the first focusable element in the DOM (it can be after the logo also), it points to an id on the main content container, and the target has tabindex="-1" so it can receive focus programmatically.&lt;/p&gt;

&lt;p&gt;The tabindex="-1" part is critical. Without it, the  element isn't focusable, the browser will scroll to it when the link is activated, but focus won't actually move there. The next Tab press would jump back to wherever focus was before (usually somewhere in the header), completely defeating the purpose.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: Use the semantic  element as your target, not a random . This serves double duty: it's the skip link target and an ARIA landmark that screen readers can navigate to independently using their built-in landmark navigation.

&lt;/p&gt;
&lt;p&gt;The link is hidden off-screen by default and slides into view when it receives keyboard focus. When the user Tabs away, it slides back out. Mouse users never see it unless they're also using the keyboard.&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.skip-link {
  position: absolute;
  top: -100%;
  left: 16px;
  z-index: 9999;
  padding: 12px 24px;
  background-color: #0a0e17;
  color: #ffffff;
  font-size: 1rem;
  font-weight: 600;
  text-decoration: none;
  border-radius: 0 0 8px 8px;
  transition: top 0.2s ease-in-out;
}

.skip-link:focus {
  top: 0;
  outline: 2px solid #ffffff;
  outline-offset: 2px;
}
&lt;/code&gt;&lt;/pre&gt;



&lt;h2&gt;
  
  
  Common mistakes and how to avoid them
&lt;/h2&gt;

&lt;p&gt;The pattern above is simple, but there are several ways to break it. The WebAIM Million 2025 study found that 10% of existing skip links were non-functional. The following mistakes are among the most common causes of broken or ineffective skip links.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Hiding with display: none or visibility: hidden&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is the most widespread error. An element with display: none is removed from both the layout and the tab order, it cannot receive keyboard focus at all. That means you can't pair it with a :focus rule to make it appear when the user Tabs to it, because the user can never Tab to it in the first place. visibility: hidden has the same practical effect: the element takes up layout space but is removed from the tab order and invisible to assistive technology.&lt;/p&gt;

&lt;p&gt;It is technically possible to use JavaScript to toggle display: none on and off in response to some external trigger (a keypress event, a :focus-within on a parent wrapper, etc.). But this adds unnecessary complexity for a problem that CSS positioning solves cleanly without scripting.&lt;/p&gt;

&lt;p&gt;The same problem applies to subtler hiding techniques: setting the link to 0px width or height, making it fully transparent, or matching its color to the background. Automated testing tools flag all of these as failures.&lt;/p&gt;

&lt;p&gt;Fix: Hide the link with CSS positioning (top: -100% or left: -9999px) so it stays in the DOM and the tab order. Bring it back into view on :focus. No JavaScript needed.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The target element isn't focusable&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If the skip link points to an id on a &lt;/p&gt; or  without tabindex="-1", activating the link scrolls the page to that element, but focus doesn't move there. The user sees the content scroll into view, presses Tab, and focus jumps back to the header. From their perspective, the skip link did nothing.

&lt;p&gt;Fix: Always add tabindex="-1" to the target element. This makes it programmatically focusable without adding it to the natural tab order.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Buried under a sticky header:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Sites often have a fixed or sticky header with position: fixed and a high z-index. When the skip link appears on focus, it renders behind the header, present in the DOM, technically visible in the layout, but completely obscured on screen. This one is particularly frustrating because the skip link works perfectly in terms of functionality (focus moves, keyboard interaction works), but sighted keyboard users can't see it.&lt;/p&gt;

&lt;p&gt;Fix: Give the skip link a z-index value higher than your header. If your header uses z-index: 100, the skip link needs at least z-index: 101. The example CSS above uses 9999 to avoid this issue entirely.&lt;/p&gt;
&lt;h2&gt;
  
  
  When you might not need one
&lt;/h2&gt;

&lt;p&gt;Skip links are strongly recommended, but there are contexts where they add less value. A page with very minimal navigation: a landing page with two links in the header, doesn't force keyboard users through a burdensome number of Tab stops. Adding a skip link is still good practice, but the impact is smaller.&lt;/p&gt;

&lt;p&gt;Single-purpose pages with no repeated navigation (a login form for example) may not have content blocks to skip in the first place.&lt;/p&gt;

&lt;p&gt;Skip navigation is one of the simplest accessibility features to implement. It's a single component, a few lines of CSS, and a tabIndex attribute. The fact that 86% of the top million websites still don't have one isn't a technical problem, it's an awareness problem.&lt;/p&gt;

&lt;p&gt;If you're reading this and your site doesn't have a skip link yet: add one. It will take you less time than reading this article did.&lt;/p&gt;
&lt;h2&gt;
  
  
  Further reading
&lt;/h2&gt;

&lt;p&gt;WebAIM: &lt;a href="https://webaim.org/techniques/skipnav/" rel="noopener noreferrer"&gt;Skip Navigation Links&lt;/a&gt;&lt;br&gt;
WCAG 2.1 SC 2.4.1: &lt;a href="https://www.w3.org/WAI/WCAG21/Understanding/bypass-blocks.html" rel="noopener noreferrer"&gt;Bypass Blocks&lt;/a&gt;&lt;br&gt;
&lt;a href="https://webaim.org/projects/million/" rel="noopener noreferrer"&gt;WebAIM Million 2025&lt;/a&gt;: annual report on the state of web accessibility&lt;/p&gt;

&lt;p&gt;For more content like this, check &lt;a href="https://www.devly.digital/?utm_source=dev.to"&gt;devly.digital&lt;/a&gt;&lt;/p&gt;


</description>
      <category>frontend</category>
      <category>a11y</category>
    </item>
  </channel>
</rss>
