Refactoring our cookie banner for better accessibility – Part 1

Our cookie banner worked, but accessibility wasn’t part of the original design. In this first article of a two-part series, we look at several improvements that made the banner and preferences modal more inclusive and easier to use.
João Rosa

Once upon a time, Cocomore used a Drupal contrib module to handle its cookies notice and selector. But as the deadline for the General Data Protection Regulation (GDPR) approached, the need to more strictly enforce when cookies were set and which scripts got loaded became unavoidable, and the module we used was no longer suitable for our needs.

Given that our existing solution was working well, and that it’s often more efficient to adapt an existing implementation than to develop one from scratch, we decided to build our own solution based on the one we had been using until then. At the time, speed and compliance were the goal. We wanted to get the new cookie management solution live as soon as possible, so we focused on adapting only what was strictly necessary and developing anew what was missing.

Fast forward a few years, and we took a fresh look at what we had on our hands and found a solution that was functionally sane but was dearly lacking in accessibility. There were multiple <div> elements posing as buttons, a notorious lack of visual cues when using keyboard navigation, and the most complex issue of all: proper focus management inside modals.

This article is the first of a two-part series where we share how we rebuilt our cookie banner and cookie preference modal with accessibility in mind. In this first part, we’ll focus on foundational improvements, from skip links to proper use of <button> elements that instantly made the interface more user-friendly for everyone. In Part 2, we’ll go further by discussing visual focus indicators, focus management inside modals, and how modern features like the <dialog> element made a real difference.

Actually, since we were modifying these components, we took the chance to do many more improvements than the ones described in this article, such as removing jQuery as a dependency and instead implement everything in pure JavaScript, or refactoring some animations to use only CSS, but on this article we will focus on accessibility. Specifically, how using modern browser features and a little care can significantly improve the experience for all users, even those who don't rely on assistive technologies.

Skip links for keyboard navigation

Skip links are hidden navigation aids on websites that let keyboard and screen reader users quickly "skip" repetitive content (like menus or sliders) and jump directly into some important section of a page. While these can be placed anywhere on a website for skipping any kind of content, when they are implemented it’s common to find at least one such link high up in the page’s hierarchy, typically before anything else, and pointing to the main content section of the page. These are also known as a "skip navigation links" or "skip to main content links".

Given that the button which effectively brings up the cookie preferences selector is located all the way down in the website's footer, we decided to add a skip link – in this case a button – to do the same thing. This allows users who prefer to use the keyboard to much more easily set their cookie preferences at any time without having to navigate all through the page only to reach the footer.

<a href="#main-content" class="visually-hidden focusable skip-link"> 
  {{ 'Skip to main content'|t }} 
</a> 
<button class="open-cookie-preferences visually-hidden focusable skip-link"> 
  {{ 'Cookie preferences'|t }} 
</button>
Right after the standard "Skip to main content link" is a button to open the cookie settings

Why a button and not an anchor? Although anchors are often used as a replacement for buttons, both serve different purposes, and have different semantics and accessibility features.

Anchors are for navigation – going somewhere – even if it is within the same page. Buttons are for actions – doing something. For example, if you want to navigate to a different page, or point to a specific section within any page, you should use anchors, and ideally the anchor’s "href" attribute should point to the destination. However, if you want to do things like seeing the next slide in a carousel, or opening a collapsible section, you should use a button.  
Additionally, the difference in semantics leads to different behaviours when using screen readers or simply the keyboard. While anchors are usually only activated when using the "Enter" key, buttons activate both with the "Enter" and the "Space" key. This is a subtle but crucial distinction for people who rely on the keyboard to navigate a website. On top of that, assistive technologies like screen readers announce each element as "button" and "link", respectively, and therefore expect certain behaviours when either of the elements is used. 

Using <div> as buttons

One of the most common accessibility pitfalls we encountered was the use of <div> elements as buttons. While it might seem harmless to make any element clickable by attaching a "click” event handler to it, this is actually very troublesome for a variety of reasons. Just to list a few:

  • Screen readers won't announce the element as a button
  • It's not focusable by default
  • It won't be "clickable" when using the keyboard
  • It lacks default button semantics and general interactivity styles

We replaced all such elements with proper <button> elements, which instantly solved most of the issues above. Native HTML elements come with built-in accessibility features that we often don't even have to consider, so, in many cases, simply choosing the proper element eliminates the need for extra code and offers users accessibility features for free. For instance, by using a proper button, we did not need to add new event listeners for keyboard navigation; using a keyboard's "Enter" or "Space" keys will trigger the same effect as a mouse click, or a tap on the screen, without extra JavaScript.

Below is one example of the button fixes we made. The <div> with the "close” class served as the effective "close" button of the modal.

<div id="cookie-customization-wrapper-backdrop"> 
  <div id="cookie-customization-wrapper"> 
    <div class="close"></div> 
    <div class="text-wrapper"> 
      <p class="banner-title">{{ 'This website uses cookies'|t }}</p>
<!-- (...) -->

And below is the corrected version:

<div id="cookie-customization-wrapper-backdrop"> 
  <div id="cookie-customization-wrapper"> 
    <button class="cookie-compliance-banner--button--cancel"> 
      <span class="sr-only">{{ 'Cancel'|t }}</span> 
    </button> 

    <div class="text-wrapper"> 
      <p class="banner-title">{{ 'This website uses cookies'|t }}</p> 
<!-- (...) -->

Very plainly, the <div> got replaced with a <button>. Since the element uses only an image of a cross instead of any actual text to indicate the button's purpose, there is no non-visual hint of what the button is supposed to do, so we added a translatable "Cancel" text inside the button element, wrapping it in a <span> holding the "sr-only" class, which is a CSS utility class whose styles visually hide any text within, but since the text is effectively there, it will still be accessible to screen readers.

To be continued...

With just this small change – replacing <div> elements with actual <button> elements – we unlocked a whole set of built-in accessibility benefits for free. But this was just the beginning.
In Part 2, we’ll dive into visual focus indicators, focus management within modals, and how modern browser features like the <dialog> element helped us take accessibility to the next level. Stay tuned!

Unser Experte

João Rosa

João Rosa arbeitet seit Oktober 2015 bei Cocomore. Egal, ob jemand Hilfe bei CSS oder JavaScript, beim Bugfixing oder Programmieren in PHP braucht – als Backend- und Frontend-Entwickler ist João der Allrounder in unserem IT-Team. An Cocomore gefällt ihm besonders die Arbeitsatmosphäre, denn alle Kollegen sind super nett und hilfsbereit. Auch wenn es mal etwas stressiger wird, kommt der Spaß trotzdem nie zu kurz. Drei Worte die den jungen Portugiesen beschreiben: vielseitig, hartnäckig, witzig.

Haben Sie Fragen oder Input? Kontaktieren Sie unsere Expert:innen!

E-Mail senden!