$30 off During Our Annual Pro Sale. View Details »

Building Olivero’s hyper-accessible (and beautiful) navigation from the ground up

Michael Herchel
May 03, 2022
33

Building Olivero’s hyper-accessible (and beautiful) navigation from the ground up

Olivero is the brand new look and feel for the Drupal CMS. Developing this theme carried with it lofty requirements, knowing that it will be used with millions of people and devices during its lifetime.

During its development, Olivero’s seemingly simplistic primary navigation incorporated reams of various accessibility, usability, and bug fixes. It was tested on various devices and assistive technologies to ensure that it is extremely usable, robust, and accessible no matter the environment.

In this highly entertaining and informative talk, we will walk attendees through the evolution of Olivero’s primary navigation from its inception to reaching stability. Attendees will learn about

- Various accessible navigation patterns
- The challenges of designing a primary navigational bar for a theme in an open source content management system
- Proper use of aria roles and attributes within this context
- Issues (and solutions) to specific accessibility issues
- Real-world accessibility and usability testing on various assistive devices and environments.

While this presentation delves heavily into accessibility, attendees will also learn about testing, usability, and even squashing an errant XSS security vulnerability.

Michael Herchel

May 03, 2022
Tweet

Transcript

  1. Mike Herchel
    @mikeherchel
    [email protected]
    The evolution of Drupal’s primary menu
    Robustness in chaos

    View Slide

  2. View Slide

  3. View Slide

  4. 1. Developing websites since 2001 (spacer.gif 💯)
    2. Doing Drupal development since 2007.
    3. Developing Olivero since 2019.
    A bit more about me

    View Slide

  5. 1. Learn to evaluate website navigation for accessibility
    2. Understand common navigation problems (and solutions)
    3. Discover recommended navigation patterns
    4. Dispel the myth that websites can’t be beautiful as well as highly
    accessible
    Presentation Goals

    View Slide

  6. Problem space
    Why a new theme and
    navigation?

    View Slide

  7. View Slide

  8. View Slide

  9. View Slide

  10. View Slide

  11. • Usable

    • Accessible

    • Robust
    Navigation Goals

    View Slide

  12. • Make it gorgeous

    • Submenus open on hover

    • Submenus open on click/touch
    Goal: Make it usable

    View Slide

  13. • Keyboard and switch navigable

    • Screen reader (or any other AT)
    navigable

    • Forced color (high contrast)
    friendly
    Goal: Make it
    Accessible

    View Slide

  14. • Mobile friendly

    • Pointer, tap, and hybrid devices

    • Support large number of
    navigation items

    • Multilingual and Support RTL

    • Support non-JS environments
    (both mobile and desktop)

    • Support IE11 😭
    Goal: Make it
    Robust

    View Slide

  15. How did we get here?

    View Slide

  16. https://github.com/Lullabot/olivero-poc

    View Slide

  17. • Menu open on hover

    • focus-within to navigate to
    submenus

    • Click buttons for mobile
    First work

    View Slide

  18. How will the user
    know if there’s a
    submenu?

    View Slide

  19. What if there are
    many submenus, and
    a keyboard user
    wants to quickly
    navigate to the end?

    View Slide

  20. • Enabled plus (+) button at wide
    widths

    • aria-controls and aria-
    expanded attributes control
    state

    • Removed menu open on focus-
    within (for those users that have
    JS)
    Added button

    View Slide

  21. Several features:
    Link Disclosure Pattern
    https://adrianroselli.com/2019/06/link-disclosure-widget-navigation.html
    • Disclosure button next to links to show submenu
    • Submenu is hidden (visually and from accessibility
    tree)
    • aria-controls attribute on button to point to ID
    of nested submenu
    • aria-expanded attribute on button set to either
    true or false and toggles submenu visibility
    • Escape key press closes menu
    • Clicking or tapping outside of menu closes menu


    View Slide

  22. View Slide

  23. View Slide

  24. • Makes it impossible to tab
    outside of the contained area
    (navigation)

    • Ensures that all focused
    elements are always in the
    viewport (WCAG 2.0 SC 2.4.7
    Focus Visible)
    Focus trap for mobile
    navigation

    View Slide

  25. Created Drupal Contributed Theme

    View Slide

  26. Support
    and
    Within Drupal's menu system, you
    can type in to generate a
    instead of an tag. You
    can also type in to
    generate a element
    drupal.org/i/3123836

    View Slide

  27. Button Disclosure Pattern
    • Same as Link Disclosure Pattern, but entire text is
    button
    • Submenu is hidden (visually and from
    accessibility tree)
    • aria-controls attribute on button to point to
    ID of nested submenu
    • aria-expanded attribute on button set to either
    true or false and toggles submenu visibility
    • Escape key press closes menu
    • Clicking or tapping outside of menu closes menu

    View Slide

  28. Collapsible nav
    button text should be
    more descriptive
    Depending on the assistive tech
    used, the toggle may not be
    associated by the user with the
    menu item that is next to it. Only
    sighted users are assured to know
    that the toggle is associated with
    "articles" in some capacity
    drupal.org/i/3190140

    View Slide

  29. Collapsible nav
    button text should be
    more descriptive
    Depending on the assistive tech
    used, the toggle may not be
    associated by the user with the
    menu item that is next to it. Only
    sighted users are assured to know
    that the toggle is associated with
    "articles" in some capacity
    drupal.org/i/3190140

    View Slide

  30. Initialize dynamic
    ARIA attributes and
    states in Javascript,
    not HTML source
    Don't initialize ARIA roles, states,
    and properties relating to dynamic
    behavior (e.g. aria-controls, aria-
    expanded, etc.) in the HTML
    source. These are only relevant
    when Javascript runs, so they are
    best initialized in Javascript.
    drupal.org/i/3153796

    View Slide

  31. In content no loss of content or functionality
    should occur when setting:
    Ensure text spacing
    compliance
    drupal.org/i/3110487
    • Line height (line spacing) to at least 1.5 times
    the font size

    • Spacing following paragraphs to at least 2
    times the font size

    • Letter spacing (tracking) to at least 0.12 times
    the font size

    • Word spacing to at least 0.16 times the font
    size.
    WCAG SC 1.4.10: Re
    fl
    ow

    View Slide

  32. Testing steps for
    WCAG 2.0 SC 1.4.12
    Text Spacing
    1. Bookmarklet that automatically
    sets styles:

    https://dylanb.github.io/
    bookmarklets.html

    2. Zoom in to 400% on
    representative pages (and
    various breakpoints)

    3. Ensure no horizontal scrolling
    drupal.org/i/3190262

    View Slide

  33. Ensure works property in
    forced color (high contrast)
    mode
    drupal.org/i/3191716
    • Windows High Contrast (forced color)

    • Not just black on white

    • white on black

    • custom color schemes

    • Not just IE, and Edge, but test with
    Firefox and Chrome too

    View Slide

  34. Not all CSS properties
    work in forced color
    mode
    drupal.org/i/3191716
    • Does not work in forced contrast:
    • box-shadow

    • background-color

    • Problematic
    • background-image

    • SVG

    • Good resource: https://blogs.windows.com/
    msedgedev/2020/09/17/styling-for-windows-high-
    contrast-with-new-standards-for-forced-colors/

    View Slide

  35. Olivero XSS Vulnerability (simpli
    fi
    ed)
    Drupal’s Twig templating engine automatically escapes string
    variables. This prevents Twig from outputting tags that<br/>might exist in database content.<br/>drupal.org/i/3174065<br/>

    View Slide

  36. View Slide

  37. View Slide

  38. Olivero XSS Vulnerability (simpli
    fi
    ed)
    Drupal’s Twig templating engine automatically escapes string
    variables. This prevents Twig from outputting tags that<br/>might exist in database content.<br/>drupal.org/i/3174065<br/>Solution: Don’t use “raw”<br/>fi<br/>lter<br/>

    View Slide

  39. View Slide

  40. Moved into Drupal core

    View Slide

  41. • If focus is inside of a sub-menu,
    do not close the menu on
    mouseout.

    • WCAG 2.0 SC 2.4.7 Focus
    Visible
    Mouseout event should not
    trigger sub-menu closing if
    sub-menu contains focus
    drupal.org/i/3192903

    View Slide

  42. Mouseout event
    should not trigger
    sub-menu closing if
    sub-menu contains
    focus
    • If focus is inside of a sub-
    menu, do not close the
    menu on mouseout.

    drupal.org/i/3192903

    View Slide

  43. • When focus moves from within the
    parent menu item’s , close the
    menu.

    • Prevents the menu from overlapping
    other focused elements.

    • WCAG 2.0 SC 2.4.7 Focus Visible
    Have sub-navigation
    menus close on blur
    drupal.org/i/3180086, drupal.org/i/3206211

    View Slide

  44. Have secondary
    menus close on blur
    • When focus moves from
    within the parent menu item’s
    , close the menu.

    • Prevents the menu from
    overlapping other focused
    elements.

    • WCAG 2.0 SC 2.4.7 Focus
    Visible
    drupal.org/i/3180086

    View Slide

  45. Problem: It takes
    two taps to open
    up desktop
    submenu

    View Slide

  46. • Tapping triggers mouseover event,
    which activates the sub-menu.

    • Then immediately triggers click event
    which then deactivates the sub-
    menu.

    • Tapping again re-triggers the click
    event which reactivates the menu.
    Touch events take two taps
    to open desktop submenu
    drupal.org/i/3191716

    View Slide

  47. First attempt
    1. MDN article, “Supporting both
    TouchEvent and MouseEvent”

    2. Listen for touch event, and
    then call preventDefault(),
    which prevents additional
    mouse events from being
    dispatched

    3. Failure of WCAG SC 2.5.2
    Pointer Cancellation

    https://knowbility.org/blog/2018/WCAG21-252PointerCancellation
    https://developer.mozilla.org/en-US/docs/Web/API/Touch_events/
    Supporting_both_TouchEvent_and_MouseEvent
    drupal.org/i/3191716

    View Slide

  48. Second attempt
    1. Listen for touch event.

    2. If touch event was triggered,
    do nothing on the mouseover
    event.

    3. click event
    fi
    res as normal

    drupal.org/i/3191716

    View Slide

  49. Not just touch and
    mouse devices
    drupal.org/i/3191716
    • A hover-capable stylus

    • Samsung Galaxy S-pen

    • Pointer emulation by
    assistive tech

    • MacOS point scanning,
    etc

    View Slide

  50. Submenu Solution
    1. If touch event:

    1. Add “is-touch-event” CSS class

    2. If mouseover event:

    1. Do nothing if “is-touch-event”
    CSS class is present.

    2. Add “is-active-mouseover” CSS
    class and open submenu.

    3. Set timeout for 500ms and then
    remove “is-active-mouseover”
    CSS class.

    3. If click event:

    1. Do nothing if “is-active-
    mouseover” class is present.

    2. Toggle menu as normal

    drupal.org/i/3191716

    View Slide

  51. Focused sub-menu item
    should always be in viewport
    drupal.org/i/3190120
    • Combination can force focused sub-menu items
    to be outside of viewport


    fi
    xed header

    • long sub-menus

    • short viewport height

    • Violation of WCAG 2.0 SC 2.4.7 Focus Visible

    View Slide

  52. Sub-menu item should
    always be in viewport when
    in focus
    drupal.org/i/3190120
    Fixable with combination of

    • max-height:

    calc(100vh - var(--header-height));


    • overflow: auto;

    View Slide

  53. Problem: Mobile menu
    obscures page after
    clicking anchor link
    drupal.org/i/3221871
    • If navigation contains anchor link the
    mobile menu stays open and
    obscures the content.

    • Example of us not controlling
    content.

    View Slide

  54. Anchor link solution
    If the clicked link starts with a hash, or contains the current
    page followed by a hash, then close the menu.
    drupal.org/i/3221871

    View Slide

  55. Problem: Mobile focus trap
    constrains focus when
    tabbing in only one direction
    drupal.org/i/3190120
    • Users expect to be able to SHIFT + TAB to
    shift the focus backwards

    • This allowed users to escape the focus trap

    • Violation of WCAG 2.0 SC 2.4.7 Focus Visible

    • Remember to thoroughly test!

    View Slide

  56. Problem: Menu items can
    overflow outside of container
    drupal.org/i/3186992
    • Content editor can insert large amount of menu
    items

    • Can we accommodate?

    View Slide

  57. Problem: The wrapping is ugly
    drupal.org/i/3246755
    • Content editor can insert large amount of menu
    items

    • Can we accommodate?

    View Slide

  58. Wrapping solution
    If resize observer detects a height change, evaluate and
    possibly shift to mobile menu
    drupal.org/i/3246755

    View Slide

  59. Test on real
    devices!
    drupal.org/i/3208116
    • Mobile Safari only: Menu brie
    fl
    y
    appears and slides out on every page
    load.

    • Easy CSS
    fi
    x. The hardest part was
    fi
    nding the bug.

    View Slide


  60. – Anil Lewis, Executive Director for the National Federation of the Blind
    Olivero is very well done and low-vision accessible. I
    am not
    fi
    nding any issues with contrast, focus, or
    scaling, the forms are very well done, and the content
    is easy to
    fi
    nd and navigate.

    View Slide

  61. lb.cm/olivero
    https://

    View Slide

  62. • Support color changing
    variables / dark modes / etc

    • Default theme

    • Support for secondary
    color?
    What’s next for
    Olivero?

    View Slide

  63. Thanks!
    Mike Herchel

    @mikeherchel

    [email protected]

    View Slide