Implementing an accessibility-focused design system in Drupal
Amy M. Drayer
jen neveau
Gabe Ormsby
University of Minnesota campus
Why is this statement important?
“This is how bad design makes it out into the world. Not due to malicious intent, but having no intent at all.”
-Mike Monteiro
Design with intent
Putting principles into action
Project goals and vision
(Universally) Accessible
Honest
Inclusive
Mindful
Private
Simple
Sustainable
(Universally) Accessible
Deliver content and services where barriers to access are removed for all people to use regardless of technology, format, or methods of delivery.
Avoid building to one way of doing or being. Build to be understandable, in a way that allows us to be human and make errors.
Honest
Be transparent.
Provide only accurate content written with non-biased language and clearly identify opinionated content. Fight disinformation, or the act of intentionally deceiving in content and algorithms.
Inclusive
Lead with person-first design, designing with people, not for them. Be aware of our own biases and assumptions, and recognize we are not the user.
Embrace people as complex beings, where average doesn’t exist.
Mindful
Make decisions that prioritize user wellbeing, don’t build to steal attention, and avoid deceptive and manipulative patterns.
Private
Promote and ensure privacy through security and personal data ownership. Provide these tenets in systems and services to the best of our ability and be transparent where we cannot.
Simple
Simple is challenging; it’s curating and cultivating the message concisely and clearly.
It’s discovering the most elegant semantic technical solution, and the intentional use of the resources available.
Sustainable
Factor in energy source and consumption for optimizations, from server to client side. Just as people do not deserve a reduced experience, our planet does not deserve to suffer the consequences of bad design and web delivery.
Sustainability is as much about our planet’s wellbeing as it is our own, as they are intertwined.
U Libraries Design System
(Universally) Accessible
Honest
Inclusive
Mindful
Private
Simple
Sustainable
Accessibility is aesthetic.
simplify code
simplify selectors #this-one #that-thing .this-button span�:not, ~, +, :first-child, :only-child, :nth-child(), :first-of-type, :last-of-type, :nth-of-type(), [att=value]
honor user settings to improve accessibility
mind high CPU styles for sustainability
Why is this statement important?
Making it work in Drupal
Why is this statement important?
The editing experience for content contributors
Why is this statement important?
Removing options...
Why is this statement important?
Setting constraints
Why is this statement important?
Keep the Design System in mind
Design System-to-Drupal
The Design System gives us web components and the canonical markup for them.
Why is this statement important?
Applying the abstract web components to Drupal
Why is this statement important?
Paragraphs as building blocks
Example paragraph types
Page body as Paragraphs
Content section
fields
The editing experience in summary
Theming (the Paragraphs) to fit the design system
Theme flow as a 3-step process
Theme flow
Step 1: Catch�
[...]�<!-- THEME DEBUG -->�<!-- THEME HOOK: 'paragraph' -->�<!-- FILE NAME SUGGESTIONS:� * paragraph--ds-content-section--default.html.twig� x paragraph--ds-content-section.html.twig� * paragraph--default.html.twig� * paragraph.html.twig�-->�<!-- BEGIN OUTPUT from 'sites/www.lib.umn.edu/themes/umnlib/templates/paragraphs/paragraph--ds-content-section.html.twig' -->
<section class="color-block hero" id="homepage">�[...]
Catch: Standard Drupal template behavior
"Catch" just means create a template where Drupal is going to look. For a specific example:
Our design system component: Content section
Implemented as: A paragraph of type ds-content-section
Catch the theming process at: our-theme/templates/paragraphs/� paragraph--ds-content-section.html.twig
Let's dig into that Twig file for the next two steps...
Excerpt 1: paragraph--ds-content-section.html.twig
{#�/**� * This template passes final rendering off to a design system pattern template� * in theme's templates/components/ directory. Here, we munge the data just� * enough to fit the expectations of the abstract DS pattern. That means:� [...]� * This approach will allow other Drupal Paragraphs, Block or Views, to also� * rely on the component templates, by ensuring a consistent 'inbound'� * vocabulary.� */�#}
Excerpt 2: paragraph--ds-content-section.html.twig
{% set section_classes = content.field_ds_section_classes|render|striptags|trim|split(' ') %}
{% set section_id = content.field_ds_section_id|render|striptags|trim|split(' ')|first ?: 's-' ~ paragraph.id() %}
This is Step 2...Tweak!
Why tweak? Paragraph data is not necessarily Component data
Part of the form for a content section paragraph
Excerpt 2 (again): paragraph--ds-content-section.html.twig
{% set section_classes = content.field_ds_section_classes|render|striptags|trim|split(' ') %}
{% set section_id = content.field_ds_section_id|render|striptags|trim|split(' ')|first ?: 's-' ~ paragraph.id() %}
Excerpt 3: paragraph--ds-content-section.html.twig
{% embed '@components/section/section.html.twig' with {� content: content.field_section_items,� heading: content.field_ds_section_heading,� heading_element: content.heading_element,� subtitle: content.field_section_subtitle,� section_classes: section_classes,� section_id: section_id,� classes: classes,� back_to_top: content.back_to_top,�} %}�{% endembed %}
...And here is Step 3: Redirect. What's going on here?
The "redirect" step relies on the Components module
Excerpt of umnlib.info.yml
...
components:� namespaces:� components: templates/components�...
What's in�templates/�components?
Excerpt 3 (again): paragraph--ds-content-section.html.twig
{% embed '@components/section/section.html.twig' with {� content: content.field_section_items,� heading: content.field_ds_section_heading,� heading_element: content.heading_element,� subtitle: content.field_section_subtitle,� section_classes: section_classes,� section_id: section_id,� classes: classes,� back_to_top: content.back_to_top,�} %}�{% endembed %}
That was the theme template for the content section paragraph type.
Let's go look at the theme template for the content section web component.
Excerpt 1: templates/components/section/section.html.twig
[...]�/**� * Available variables:� * - content: The content items within the article. Optional.� * - heading: The heading for the article. Required.� * - heading_element: The appropriate level heading. Required.� * - subtitle: Extension to heading, not included in side navigation. Optional.� * - back_to_top: Boolean flag indication whether to include a 'back to top' \� link. Optional.� * - section_classes: Array. Class options from paragraph type. Optional.� * - section_id: String. ID attribute value. Optional.� * - classes: Classes array passed by parent theme or module.�[...]
Excerpt 2: templates/components/section/section.html.twig
[...]�* This file may be used via twig 'embed' by any number of theme templates for�* Views, Blocks, or Paragraphs. The calling template is responsible for�* altering source data to fit the pattern's expected variables.�*�* See this theme's templates/paragraphs/paragraph--ds-content-section.html.twig�* for a sample implementation.�*/�[...]
Excerpt 3: templates/components/section/section.html.twig
<section{{ attributes.addClass(section_classes).setAttribute('id', section_id) }}>�{% if subtitle.0 %}� <{{heading_element}}>� {{ heading }} <span class="subtitle">{{ subtitle }}</span>� </{{heading_element}}>�{% else %}� <{{heading_element}}>{{ heading }}</{{heading_element}}>�{% endif %}�{% if content|render %}� {{ content }}�{% endif %}�{% if back_to_top %}� <p><a href="#top">Back to top</a></p>�{% endif %}�</section>
Recap: Implementing our Design System in a Drupal theme
Tweaking revisited: Fixing a thing that's bugged me since 2008
Remember this from our component template section.html.twig?
<{{heading_element}}>{{ heading }}</{{heading_element}}>�
umnlib_get_heading_level():
A helper function in our theme that finds the appropriate heading level for any heading-like field.
Why is this statement important?
Accessible content
Content strategy
“The University of Minnesota Libraries’ website prioritizes the support of users new to our site and services, and by doing so, supports all users in their goal to find and access our resources and apply them to their work, and our goal to engage and inspire our diverse community of users.”
Why is this statement important?
Content guidelines
Why is this statement important?
Content guidelines
Why is this statement important?
Content audit and remediation
Why is this statement important?
Content governance and workflow
Draft > Pending WCMC review > Published
Pending deletion or Archived
Lessons learned
Lessons learned
Thank you.