Skip to content

Commit

Permalink
Merge branch 'main' into accessible-load-more
Browse files Browse the repository at this point in the history
  • Loading branch information
zoltan-dulac authored Jan 28, 2025
2 parents 169bac9 + 11b8024 commit a1255b5
Show file tree
Hide file tree
Showing 15 changed files with 263 additions and 70 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/push-actions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ jobs:
# https://mirror.cs.uchicago.edu/google-chrome/pool/main/g/google-chrome-stable/
run: |
apt search '^google-chrome.*' \
&& wget -q -O /tmp/chrome.deb http://dl.google.com/linux/chrome/deb/pool/main/g/google-chrome-stable/google-chrome-stable_130.0.6723.58-1_amd64.deb \
&& wget -q -O /tmp/chrome.deb https://mirror.cs.uchicago.edu/google-chrome/pool/main/g/google-chrome-stable/google-chrome-stable_132.0.6834.110-1_amd64.deb \
&& sudo apt install -y /tmp/chrome.deb --allow-downgrades \
&& rm /tmp/chrome.deb
- name: Log system details
Expand Down
6 changes: 6 additions & 0 deletions bin/checkHTML.sh
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,12 @@ If that does not work, you may need to do a global update of @axe-core/cli:
sudo npm update -g @axe-core/cli
********************************************************************************
* NOTE: If you are seeing this message in GitHub Automated Tests, you need to
* update push-actions.yml to ensure the version of Chrome being downloaded there
* matches the one in your package.json
********************************************************************************
' 1>&2
exit 1;
Expand Down
41 changes: 33 additions & 8 deletions content/body/accessible-pdf-generation.php
Original file line number Diff line number Diff line change
Expand Up @@ -324,13 +324,38 @@ function saveByteArray(reportName, byte) {


<h2>Feedback from a Screen Reader User</h2>
<p>Vishnu Ramchandani, an experienced screen reader user, was kind enough to help us test the PDFs that we generated with Open HTML to PDF. He confirmed that he was able to read the information in the generated PDFs, but added some UX feedback to see if we can incorporate them in our PDF reports. Here is his feedback, along with what actions we took.</p>
<p>Vishnu Ramchandani, an experienced screen reader user, was kind enough to help us test the PDFs that we generated with Open HTML to PDF. Vishnu confirmed that the generated PDFs were accessible for screen reader users but provided valuable UX feedback to improve the user experience. Below is his feedback and the actions we took to address the issues:</p>

<ol>
<li>Page title: To ensure consistency and clarity, the document title and the filename should both be same and should be meaningful.
<ul><li>We remedied this issue by changing the title to be the same as the filename. This is definitely something you should think about when implenting your own solution, since it is not default behavior for the library.</li></ul></li>
<li>Reading behavior of lengthy paragraphs in tables: Screen reader users experience line breaks when reading lengthy paragraphs in table columns using arrow keys. A paragraph is read in a broken manner, making it hard to follow. It is best to ensure that lengthy paragraphs are presented in a linear, single-column format when possible. This helps screen readers read the content in a logical order without breaking lines.
<ul><li>Unfortunately, this seems to be a limitation of PDF technology. We recommend keeping lines short in table rows to remedy this situation. If you know of any other work arounds for this, <a href="mailto:[email protected]">please contact us</a> with the details and we'll update our recommendations here.</li></ul></li>
<li>Issue with Splitting URLs/Links: A single URL or link splits into multiple lines, making screen reader users think there are multiple links instead of a single one. To prevent links from splitting across multiple lines, consider the following approaches: Use non-breaking spaces (&amp;nbsp;) between words in the link text to prevent line breaks. Apply CSS to ensure the link text does not break into multiple lines. For example, using white-space: nowrap; can help keep the link text on a single line.
<ul><li>This also seems like a limitation in PDFs, as many PDF authoring tools like <a href="https://acrobat.uservoice.com/forums/590923-acrobat-for-windows-and-mac/suggestions/40781203-hyperlinks-spanning-multiple-lines">InDesign seem to have this multiline link issue as well</a>. We recommend keeping link labels short (while still having appropriate and descriptive link text). Again, if you know of any other workarounds for this, <a href="mailto:[email protected]">email us</a>. We'd love to hear from you.</li></ul></li>
<li>Page Title Consistency
<dl>
<dt>Feedback:</dt>
<dd>The document title and filename should be consistent and meaningful to ensure clarity for users.</dd>
<dt>Action Taken:</dt>
<dd>We updated the title of the PDF to match the filename. This adjustment improves consistency and makes the document more user-friendly. When implementing your own solution, remember that this is not a default behavior in the Open HTML to PDF library and should be explicitly configured.</dd>
</dl>
</li>
<li>Reading Behavior of Lengthy Paragraphs in Tables

<dl>
<dt>Feedback:</dt>
<dd>Screen readers encounter issues when lengthy paragraphs within table columns are broken into lines. This disrupts the reading flow, making it difficult for users to follow the content. To address this, lengthy paragraphs should ideally be displayed in a linear, single-column format.</dd>
<dt>Action Taken:</dt>
<dd>Unfortunately, this behavior seems to be a limitation of PDF technology. While we cannot fully resolve this issue, we recommend keeping table row text concise and avoiding lengthy paragraphs. If you are aware of any workaround to mitigate this issue, <a href="mailto:[email protected]">please share your insights with us</a>, and we will update our recommendations accordingly.</dd>
</dl>
</li>
<li>Issues with Splitting URLs and Links

<dl>
<dt>Feedback:</dt>
<dd>When URLs or links break across multiple lines in the PDF, screen readers interpret them as multiple links, leading to confusion. To prevent this:
<ol>
<li>Use non-breaking spaces (&nbsp;) in link text to avoid line breaks.</li>
<li>Apply CSS styles such as white-space: nowrap; to keep links on a single line.</li>
</ol>
</dd>
<dt>Action Taken:</dt>
<dd>This issue also appears to be a limitation inherent to PDF technology, as <a href="https://acrobat.uservoice.com/forums/590923-acrobat-for-windows-and-mac/suggestions/40781203-hyperlinks-spanning-multiple-lines">even advanced tools like Adobe InDesign exhibit this behavior</a>. As a best practice, we recommend keeping link labels concise but descriptive to minimize splitting. If you have additional solutions or tools to address this, <a href="mailto:[email protected]">please reach out to us</a> &mdash; we are eager to incorporate any new strategies.</dd>
</dl>
</li>
</ol>

45 changes: 27 additions & 18 deletions content/body/tooltip.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@
This solution can be styled exactly as wanted and uses the maximum value of a z-index in the document.
We show different types of tooltips below, based on how they are triggered.
It will disappear when keyboard users press the Escape key.
<strong>It doesn't work in mobile,</strong> which while consistent with other tooltip solutions,
is something that we are still looking to fix. If anyone has any ideas, please feel free to <a href="https://twitter.com/zoltandulac">reach out to me on Twitter</a>.
</p>

<h3> Clickable tooltip </h3>
Expand All @@ -39,21 +37,21 @@
<legend>Vehicle Inspection Form</legend>
<div class="enable-form-example__fieldset-inner-container">
<div class="field-block">
<label for="clickable_example_1" class="form-label">
<label id="vin-label" for="vin" class="form-label">
<span>VIN</span>
</label>
<input id="clickable_example_1" size="25" type="text">
<button id="tooltip_button_1" type="button" class="tooltip__text-button" aria-label="Clickable tooltip information"
<input id="vin" size="25" type="text">
<button id="tooltip_button_1" type="button" class="tooltip__text-button" aria-describedby="vin-label"
data-tooltip="VIN (Vehicle Identification Number) is a 17 character (digits/capital letters) unique identifier for a vehicle.">
<span>What's this?</span>
<span>More info</span>
</button>
</div>
<div class="field-block">
<label for="clickable_example_2" class="form-label">
<label id="body-style-label" for="body-style" class="form-label">
<span>Body style</span>
</label>
<input id="clickable_example_2" size="25" type="text">
<button id="tooltip_button_2" type="button" class="tooltip__icon-button" aria-label="Clickable tooltip information"
<input id="body-style" size="25" type="text">
<button id="tooltip_button_2" type="button" class="tooltip__icon-button" aria-label="More Information" aria-describedby="body-style-label"
data-tooltip="Categorization of a car based on its shape, style, and space. Examples include sedan, SUV, convertible, etc.">
<span class="icon" aria-hidden="true">i</span>
</button>
Expand All @@ -69,24 +67,35 @@
<script type="application/json" id="example1-props">
{
"replaceHtmlRules": {},
"steps": [{
"label": "Create markup",
"highlight": "data-tooltip",
"steps": [
{
"label": "Create markup for the button that opens the tooltip",
"highlight": "[\\s]*data-tooltip",
"notes": "Our script uses the <code>data-tooltip</code> attribute instead of the <code>title</code> attribute, since <strong>title</strong> is rendered by user agents by default and cannot be styled."
},
{
"label": "Give button context on what it is giving information on",
"highlight": "aria-describedby",
"notes": "When screen reader users tab into this control, they will not just hear the label of the button that opens the tooptip (e.g. \"More Info\"), but also the context of what the context of the what information will be given when clicking the button via the <code>aria-describedby</code> (e.g. \"VIN\")"
},
{
"label": "Create HTML for the tooltip",
"highlight": "%OUTERHTML%tooltip ||| role=\"tooltip ||| aria-live=\"assertive\"",
"notes": "Note the role of tooltip. It is an aria-live region so that the content is announced by screen readers. The content is dynamically changed in JS when any of the buttons that open up the tooltip are pressed."
},
{
"label": "Create JavaScript events for tooltip script",
"highlight": "%JS% tooltip.create; tooltip.init",
"highlight": "%JS% tooltip.create; tooltip.init ||| (this.create|this.init)[^=]*=",
"notes": "When the page is loaded, create the tooltip DOM object and initialize the mouse and keyboard events that will display the tooltips. <strong>Note the role of tooltip being added to the tooltip DOM object</strong>."
},
{
"label": "Create the show and hide methods for the tooltip",
"highlight": "%JS% tooltip.show; tooltip.hide",
"highlight": "%JS% tooltip.show; tooltip.hide ||| (this.hide|this.show)\\s=\\s",
"notes": "We make sure the element that triggered the tooltip's <code>show</code> method will be connected to it with the aria-describedby attribute, which points to the tooltip. This ensures screen readers announce the tooltip on focus."
},
{
"label": "Ensure tooltip disappears when Escape key is pressed",
"highlight": "%JS% tooltip.onKeyup",
"highlight": "%JS% tooltip.onKeyup ||| (this.onKeyup)\\s=\\s",
"notes": "This is to ensure keyboard users can make the tooltip disappear without tabbing out of the component."
},
{
Expand All @@ -101,7 +110,7 @@
<h3> Focusable tooltip </h3>
<p> This type of tooltip can be triggered when the user either clicks on it or navigates to it by keyboard.</p>
<p>
The form example below demonstrates a tooltip that can be triggered via input field click.
The form example below demonstrates a tooltip that can be triggered via input field click.
</p>
<div id="example2" class="enable-example">
<form class="enable-form-example">
Expand Down Expand Up @@ -130,12 +139,12 @@
"replaceHtmlRules": {},
"steps": [{
"label": "Create markup",
"highlight": "data-tooltip",
"highlight": "[\\s]*data-tooltip",
"notes": "Our script uses the <code>data-tooltip</code> attribute instead of the <code>title</code> attribute, since <strong>title</strong> is rendered by user agents by default and cannot be styled."
},
{
"label": "Create JavaScript events for tooltip script",
"highlight": "%JS% tooltip.create; tooltip.init",
"highlight": "%JS% tooltip.create; tooltip.init ||| (this.create|this.init)[^=]*=",
"notes": "When the page is loaded, create the tooltip DOM object and initialize the mouse and keyboard events that will display the tooltips. <strong>Note the role of tooltip being added to the tooltip DOM object</strong>."
},
{
Expand Down
1 change: 1 addition & 0 deletions content/head/accessible-pdf-generation.php
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<link rel="stylesheet" type="text/css" href="css/definition-term.css" >
3 changes: 3 additions & 0 deletions css/definition-term.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

86 changes: 86 additions & 0 deletions css/tooltip.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

30 changes: 13 additions & 17 deletions js/modules/es4/tooltip.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
/*******************************************************************************
* tooltip.js - Accessible Tooltip Module
*
* Written by Zoltan Hawryluk <[email protected]>
* Written by Zoltan Hawryluk <[email protected]> and Jessie Cai.
* Part of the Enable accessible component library.
* Version 1.0 released Dec. 27, 2021
*
Expand All @@ -20,8 +20,6 @@ const tooltip = new (function() {
const tooltipStyle = tooltipEl.style;
const escapeKey = 'Escape';
const tabKey = 'Tab';
const buttonName = 'BUTTON';
const inputName = 'INPUT';
let tooltipTarget = null;
let isTooltipVisible = false;
let tooltipBelongsTo = null;
Expand Down Expand Up @@ -67,7 +65,7 @@ const tooltip = new (function() {
tooltipEl.id = 'tooltip';
tooltipEl.setAttribute('role', 'tooltip');
tooltipEl.classList.add('tooltip--hidden');
tooltipEl.innerHTML = '<div class="tooltip__content">Loading ...</div>';
tooltipEl.innerHTML = '<div class="tooltip__content">Loading</div>';
tooltipEl.setAttribute('aria-live', 'assertive');
body.appendChild(tooltipEl);
}
Expand All @@ -94,7 +92,7 @@ const tooltip = new (function() {
tooltipTarget = e.target;

//Hide tooltip on initial focus if tabbed in
if (tooltipTarget.tagName === buttonName && tabbedIn) {
if (tooltipTarget.tagName === 'BUTTON' && tabbedIn) {
if (tooltipBelongsTo !== tooltipTarget){
return;
}
Expand All @@ -106,8 +104,10 @@ const tooltip = new (function() {
this.show = (e) => {
tooltipTarget = e.target;

if (tooltipTarget.tagName === 'SPAN'){
tooltipTarget = e.target.parentNode;
const closestTooltipEl = tooltipTarget.closest('[data-tooltip]');

if (closestTooltipEl !== null) {
tooltipTarget = closestTooltipEl;
}

const text = tooltipTarget.dataset.tooltip;
Expand All @@ -116,15 +116,16 @@ const tooltip = new (function() {
}

//Set aria attribute only for onFocus (input) elements
if (tooltipTarget.tagName === inputName){
if (tooltipTarget.tagName === 'INPUT'){
tooltipTarget.setAttribute('aria-describedby', 'tooltip');
}

const tooltipTargetRect = tooltipTarget.getBoundingClientRect();
tooltipEl.innerHTML = text;
tooltipEl.classList.remove('tooltip--hidden');

tooltipEl.innerHTML = text;
tooltipStyle.top = `calc(${tooltipTargetRect.bottom + window.scrollY}px + 1em)`
tooltipStyle.left = `${tooltipTargetRect.left + window.pageXOffset}px`;
tooltipStyle.left = `${tooltipTargetRect.left + window.scrollX}px`;
tooltipEl.classList.remove('tooltip--bottom');
tooltipEl.classList.add('tooltip--top');

Expand All @@ -140,9 +141,6 @@ const tooltip = new (function() {
tooltipStyle.top = `calc(${tooltipTargetRect.top + window.scrollY - tooltipHeight}px - 1em)`
}

tooltipTarget.addEventListener('mouseleave', this.hide);
tooltipEl.addEventListener('mouseleave', this.hide);

tooltipEl.dispatchEvent(
new CustomEvent('enable-show', { bubbles: true })
);
Expand All @@ -151,7 +149,7 @@ const tooltip = new (function() {
this.handleClick = (e) => {
tooltipTarget = e.target;

if (tooltipTarget.tagName === buttonName && tabbedIn) {
if (tooltipTarget.tagName === 'BUTTON' && tabbedIn) {
if (!isTooltipVisible) {
this.show(e);
} else {
Expand All @@ -175,9 +173,7 @@ const tooltip = new (function() {
}

if (tooltipTarget) {
tooltipTarget.removeEventListener('mouseleave', this.hide);
tooltipEl.removeEventListener('mouseleave', this.hide);
if (tooltipTarget.tagName === inputName){
if (tooltipTarget.tagName === 'INPUT'){
tooltipTarget.removeAttribute('aria-describedby');
}
tooltipTarget = null;
Expand Down
Loading

0 comments on commit a1255b5

Please sign in to comment.