coopdigital / coop-frontend

Co-op CSS Foundations and design system mono-repo
MIT License
0 stars 0 forks source link

feat: only show skipnav when focus-visible #516

Closed philwolstenholme closed 1 year ago

philwolstenholme commented 1 year ago

CookiePro uses JavaScript to programmatically focus the first focusable element on the page when the cookie consent modal is dismissed. This is causing the skiplink to appear for non-keyboard nav users, and causing site header content to be unnecessarily obscured until a user moved focus elsewhere on the page by clicking on something or using the keyboard to navigate.

Proposed solution

.coop-c-skip-nav__link:focus:not(:focus-visible) {
  left: var(--offscreen-position);
}

This will keep the skip link offscreen if it is focused programmatically (e.g. by CookiePro focusing the first focusable element on the page once the banner has been dismissed), but the rule will not apply if the skip link is focussed via the keyboard. If the browser does not have focus-visible support then the rule will also not apply, and the skip link will behave as it currently does.

This is a simplified version of an approach used on shop.coop.co.uk.

Existing approaches

www.coop.co.uk

This was my first suggestion but it's more complicated than it needs to be and doesn't use a custom property:

@supports selector(:focus-visible) { 
  .coop-c-skip-nav__link:focus {
    /* The browser supports focus-visible, so we can undo the default focus style from the shared component and keep the skip link hidden (off-screen) even if it is focused, e.g. via the CookiePro JavaScript */
    left: -9999px;
  }
}

.coop-c-skip-nav__link:focus-visible {
  /* If the user manually focuses the skip links then focus-visible will kick in and this should show the skip link. If it doesn't then try making this selector more specific, or use !important on the `left` declaration */
  left: var(--spacing-medium--1-4);
}

shop.coop.co.uk

Similar to the proposed approach for the shared component, more simple than the www.coop.co.uk approach, but without using a custom property.

.coop-c-skip-nav__link:focus:not(:focus-visible) {
  // The browser supports focus-visible, so we can undo the default focus style and keep the skip
  // link hidden (off-screen) even if it is focused programmatically via the CookiePro JavaScript.
  left: -9999px !important;
}