Skip to content

fix: WCAG AA accessibility pass — landmarks, nav, alt text, headings, accordion#625

Open
thostetler wants to merge 23 commits intomasterfrom
a11y-updates-2
Open

fix: WCAG AA accessibility pass — landmarks, nav, alt text, headings, accordion#625
thostetler wants to merge 23 commits intomasterfrom
a11y-updates-2

Conversation

@thostetler
Copy link
Member

WCAG 2.1 AA accessibility pass over non-blog pages. Total findings reduced from 26,212 to 10,843 (-58.6%).

Builds on #622 — should be merged after that one lands.

Rule Issue Before After
sia-r57 Content outside landmark regions 13,024 569
sia-r90 Accordion triggers not keyboard-accessible 710 0
sia-r56 Duplicate/unnamed nav landmarks 256 0
sia-r55 (resolved as side-effect) 256 0
sia-r2 Missing alt text on images 187 0
sia-r4 Missing html[lang] 176 43
sia-r68 Invalid ul list markup (a>li) 109 0
sia-r53 Heading level skips 94 58
sia-r64 Empty h2.post-title emitted 17 0
sia-r13 iframes without accessible names 12 0
sia-r111 Tap target size (bonus side-effect) 3,452 1,896

- Add alt text to thumbnail images in news, general, and technical-posts listing pages
- Fix contrast and layout issues in blog layout and post templates
- Fix shared navbar dropdown role attribute and footer link target sizes
- Add alt text to results chart image in nasa-open-access post
- Add docker-based local dev config
- Fix fallback logo alt text to "ADS/SciX logo" on all listing pages
- Convert darkSwitch div to button with aria-label; sync aria-label on toggle
- Replace line-height: 44px with padding-block on list links
- Update .press-coverage-header CSS selector from h4 to h3
- Remove redundant role="banner" from semantic <header>
- Update newsletter signup links from http to https
…r13, sia-r64)

- sia-r4: add lang="en" to all layout html elements and static api docs
- sia-r13: add descriptive title attributes to all YouTube iframes
- sia-r64: guard h2.post-title with if page.title to prevent empty headings
…-r13, sia-r64)

- Trim whitespace from dynamically derived iframe title in scixhelp
- Add if page.title guard to blog_page_scix.html h1.post-title
- Invert <a><li> to <li><a> in all list-group sections of both left-nav
  include files (left-nav.html and left-nav_scix.html)
- Update _sidebar.scss: zero out li.list-group-item padding and move it
  to the child anchor, making the anchor block-level and full-row
  clickable with a 44px minimum tap target
- Preserve active state styling and hover background on the anchor
- Add > a { color } nested rule inside li.active.list-group-item in
  _sidebar.scss so the anchor inherits the active blue (#2169DA)
  reliably, not just from cascade on the li
- Same fix in _darkmode.scss for dark mode active link color
- Replace :hover/:focus grouping with separate :hover and :focus-visible
  rules on li.list-group-item > a; add explicit outline (2px solid
  #4073dd, offset -2px) on :focus-visible for keyboard nav visibility
  (outline: none is not globally set for anchors; only .btn-link:focus
  and Bootstrap component-scoped rules suppress it)
Add <main> to layouts that were serving page content outside any
landmark region. Fixes 6 root layouts across ADS and SciX sections.

- default_layout.html: .page-content div → <main>
- help_layout.html: .page-content div → <main>
- blog_layout.html: .page-content div → <main>
- home.html: .home-page-content div → <main>
- ads_to_scix.html: bare content div → <main>
- ads_to_scix_quick_start.html: .page-content div → <main>

Layouts skipped (already have <main>):
- help_layout_scix.html (existing <main> on line 14)
- blog_layout_scix.html (existing <main> on line 28)

Layouts skipped (nesting risk — child layout emits <main>):
- about_layout.html (about.html child emits <main>)
- about_layout_scix.html (about_scix.html child emits <main>)
Replace <a role="button"> collapse triggers with native <button> elements
across both left-nav includes (ADS and SciX variants). Switches Bootstrap 3
collapse binding from href to data-target. Also fixes two pre-existing
aria-labelledby mismatches in left-nav.html (troubleshooting and videos
sections pointed to wrong or nonexistent ids). Updates _sidebar.scss to
target button instead of a within .panel-heading.
Remove invalid tablist/tab/tabpanel roles from left-nav.html — those roles
require strict ownership rules not met by this markup structure. Remove
aria-multiselectable from left-nav_scix.html panel-group div which had no
role to host it. Replace flow-content <div> inside each <button> with <span>
(valid phrasing content per HTML spec) across both nav includes. Add
aria-hidden="true" to all decorative Font Awesome caret icons. Extend dark
mode .left-nav color rule in _darkmode.scss to cover button elements alongside
the existing anchor rule.
- Blog listing templates (blog/index.md and subcategory pages): add
  alt="{{ post.title }}" for post thumbnails and alt="ADS logo" for
  the fallback logo image; fixes ~50 missing alts on /blog and
  subcategory listing pages
- help/actions/visualize.md: add descriptive alt to scatter-plot,
  word-cloud, and svg-crowbar screenshots
- help/userpreferences/myads.md: add descriptive alt to 6 myADS
  setup screenshots (setup_blank x2, arxiv, citations, keywords,
  general, begin_import)
- help/gettingstarted/build-library.md: add descriptive alt to 6
  library screenshots (export, citation-helper, metrics, author_network
  and their SciX gif counterparts)
- help/gettingstarted/searching-for-paper.md: add descriptive alt to
  filter-facet screenshot and its SciX counterpart
- help/api/api-docs*.html: add alt="ADS logo" to the nav logo image
  in all three API docs pages
- faqs.md: h5 questions promoted to h3 under h2 section headings (21 headings)
- data-faq.md: h5 questions promoted to h3 under h2 section headings (15 headings)
- export.md: h6 format category headings promoted to h4 under h3 parent (3 headings)
- terms-of-use.md: h3 Acknowledgements promoted to h2 under h1 page title (1 heading)
- help/orcid, libraries, userpreferences: h1 page titles demoted to h2 so h3 post titles no longer skip
- scixhelp/orcid-scix, libraries-scix, userpreferences-scix: same h1 to h2 correction
- help/api, scixhelp/api-scix: h3 page title promoted to h2, h4 sub-section to h3
@thostetler thostetler marked this pull request as ready for review March 5, 2026 20:47
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

WCAG 2.1 AA accessibility pass across the site (landmarks, headings, nav/accordion semantics, media accessible names, tap target sizes), plus a Docker-based dev workflow.

Changes:

  • Reworked navigation/accordion markup to be keyboard-accessible and fixed invalid list markup.
  • Added accessible names (alt text, iframe titles) and improved heading/landmark structure across layouts and content.
  • Introduced Docker Compose + helper script for local development/builds.

Reviewed changes

Copilot reviewed 111 out of 111 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
scixhelp/userpreferences-scix/index.html Adjust heading level for help landing page content
scixhelp/orcid-scix/index.html Adjust heading level for help landing page content
scixhelp/libraries-scix/index.html Adjust heading level for help landing page content
scixhelp/index.md Add accessible iframe title for dynamically created video embeds
scixhelp/api-scix/index.html Adjust heading levels on API help page
scixblog/technical-posts/index.md Add page title + thumbnail alt text
scixblog/news/index.md Add page title + thumbnail alt text
scixblog/index.md Add page title, switch signup link to HTTPS, add thumbnail alt text
scixblog/general/index.md Add page title + thumbnail alt text
run Add Docker Compose wrapper script for common dev/build tasks
help/userpreferences/index.html Adjust heading level for help landing page content
help/orcid/index.html Adjust heading level for help landing page content
help/libraries/index.html Adjust heading level for help landing page content
help/common/js/dark-mode-switch.js Improve dark mode toggle accessibility labeling
help/api/index.html Adjust heading levels on API help page
help/api/api-docs.html Add lang + logo alt text
help/api/api-docs-internal.html Add lang + logo alt text
help/api/api-docs-all.html Add lang + logo alt text
docker-compose.yml Add Docker Compose services/profiles for Jekyll workflows
blog/technical-posts/index.md Add thumbnail alt text
blog/news/index.md Add thumbnail alt text
blog/index.md Add thumbnail alt text
blog/general/index.md Add thumbnail alt text
_sass/_sidebar.scss Style accordion triggers as buttons; improve focus styles; enlarge tap targets
_sass/_layout.scss Improve tap target sizing, line-height, footer link targets, and label contrast
_sass/_darkmode.scss Improve dark mode toggle contrast/size; ensure nav items remain readable
_layouts/post_scix.html Avoid emitting empty post title heading
_layouts/post.html Avoid emitting empty post title heading
_layouts/home.html Add lang; wrap content in <main> for landmark coverage
_layouts/help_layout.html Add lang; wrap content in <main> for landmark coverage
_layouts/default_layout.html Add lang; wrap content in <main> for landmark coverage
_layouts/blog_post_scix.html Reduce heading misuse by rendering author/date as paragraphs
_layouts/blog_page_scix.html Promote page title to <h1> when present
_layouts/blog_page.html Avoid emitting empty page title heading
_layouts/blog_layout_scix.html Add lang, add nav landmark label, convert dark switch to <button>, add <main>
_layouts/blog_layout.html Add lang; wrap content in <main> for landmark coverage
_layouts/ads_to_scix_quick_start.html Add lang; wrap content in <main> for landmark coverage
_layouts/ads_to_scix.html Add lang; wrap content in <main> for landmark coverage
_layouts/about_scix.html Avoid nested nav landmarks; avoid emitting empty post title heading
_layouts/about.html Avoid nested nav landmarks; avoid emitting empty post title heading
_includes/left-nav_scix.html Convert accordion triggers to <button>; fix invalid list markup; add aria-labels
_includes/left-nav.html Convert accordion triggers to <button>; fix invalid list markup; add aria-labels
_includes/header_default_scix.html Remove redundant role="menu" attribute
_includes/about-left-nav_scix.html Add aria-label to about nav landmark
_includes/about-left-nav.html Add aria-label to about nav landmark
_includes/_help/videos/_posts/welcome.md Add iframe title
_includes/_help/videos/_posts/personalization.md Add iframe title
_includes/_help/videos/_posts/libraries.md Add iframe title
_includes/_help/videos/_posts/intro.md Add iframe title
_includes/_help/videos/_posts/infrastructure.md Add iframe title
_includes/_help/videos/_posts/fulltext.md Add iframe title
_includes/_help/videos/_posts/experts.md Add iframe title
_includes/_help/videos/_posts/api.md Add iframe title
_includes/_help/videos/_posts/affiliations.md Add iframe title
_includes/_help/videos/_posts/advanced-search.md Add iframe title
_includes/_help/userpreferences/_posts/myads.md Add iframe title + image alt text
_includes/_help/terms/_posts/terms-of-use.md Adjust heading level to avoid heading skips
_includes/_help/index.md Add iframe title
_includes/_help/gettingstarted/_posts/searching-for-paper.md Add image alt text
_includes/_help/gettingstarted/_posts/build-library.md Add image alt text
_includes/_help/faq/_posts/faqs.md Normalize question headings to reduce heading skips
_includes/_help/data_faq/_posts/data-faq.md Normalize question headings to reduce heading skips
_includes/_help/actions/_posts/visualize.md Add image alt text
_includes/_help/actions/_posts/export.md Normalize heading levels
_includes/_blogcontent/2025-09-29-scix-launch.md Add alt text; adjust press coverage heading level
_includes/_blogcontent/2025-08-25-scix-data-collections.md Add alt text; normalize section headings
_includes/_blogcontent/2025-07-01-scix-visualizations.md Add alt text; normalize section headings
_includes/_blogcontent/2025-03-25-what-i-wish-i-knew-about-ads-scix-during-my-phd.md Add alt text
_includes/_blogcontent/2025-02-27-scix-earth-science-literature-review.md Add alt text
_includes/_blogcontent/2025-02-27-scix-ambassador-workshop.md Add alt text
_includes/_blogcontent/2024-08-01-data-linking-III.md Add alt text
_includes/_blogcontent/2024-07-01-data-linking-II.md Add alt text
_includes/_blogcontent/2024-06-13-data-linking-I.md Add alt text
_includes/_blogcontent/2024-06-04-HistoricLit.md Add alt text
_includes/_blogcontent/2024-03-06-introducing-scix-ambassador-program.md Normalize headings; add alt text
_includes/_blogcontent/2024-02-26-userfeedback-2024.md Normalize headings; add alt text
_includes/_blogcontent/2024-01-03-aas-2024.md Add alt text
_includes/_blogcontent/2023-10-23-ads-models-and-datasets.md Normalize headings; add alt text
_includes/_blogcontent/2023-04-19-scix.md Add alt text
_includes/_blogcontent/2023-03-20-curation-model.md Add alt text
_includes/_blogcontent/2022-12-29-uat-integration.md Replace footnote structure for clarity
_includes/_blogcontent/2022-09-06-ads-object-search.md Inline prior footnote content; add alt text
_includes/_blogcontent/2021-11-12-arc-ssad-project.md Normalize headings
_includes/_blogcontent/2021-08-04-openapi-docs.md Add alt text
_includes/_blogcontent/2021-04-15-affils-update.md Normalize headings; add alt text
_includes/_blogcontent/2020-08-10-the_new_myADS.md Add alt text
_includes/_blogcontent/2020-05-29-ui-updates.md Add alt text
_includes/_blogcontent/2020-04-06-nasa-open-access.md Add alt text
_includes/_blogcontent/2020-01-15-affiliations-feature.md Normalize headings; add alt text
_includes/_blogcontent/2019-05-30-ave-atque-vale.md Add alt text
_includes/_blogcontent/2019-04-11-transition-reminder.md Normalize headings; add alt text
_includes/_blogcontent/2019-03-26-citations-journals-3.md Add alt text
_includes/_blogcontent/2019-02-13-updates2.md Switch newsletter link to HTTPS; normalize headings; add alt text
_includes/_blogcontent/2018-10-22-citations-journals-2.md Normalize headings; add alt text
_includes/_blogcontent/2018-08-20-citations-journals.md Add alt text
_includes/_blogcontent/2018-07-17-concepts-at-work.md Add alt text
_includes/_blogcontent/2018-05-24-transition.md Normalize headings
_includes/_blogcontent/2018-04-11-updates.md Normalize headings
_includes/_blogcontent/2018-02-05-asclepias.md Replace markdown tables with semantic HTML tables; add alt text
_includes/_blogcontent/2017-12-12-adsug.md Normalize headings
_includes/_blogcontent/2017-10-05-100M-citations.md Add alt text to images
_includes/_blogcontent/2016-03-16-open-access-and-nasa-data.md Add alt text
_includes/_blogcontent/2016-02-17-building-an-app.md Normalize headings; add alt text
_includes/_blogcontent/2015-11-17-discovering-long-fuse-papers.md Add alt text
_includes/_blogcontent/2015-11-03-ads-private-libraries.md Add alt text
_includes/_blogcontent/2015-10-21-visualising-metrics-with-bbb.md Add alt text
_includes/_blogcontent/2015-07-15-introducing-bumblebee.md Add alt text
_config.yml Exclude Docker/dev artifacts from the Jekyll build
README.md Document Docker-based dev workflow
Dockerfile Add container image for consistent Jekyll builds
.dockerignore Reduce Docker build context and avoid copying build artifacts

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Comment on lines +10 to +26
serve:
extends: jekyll
ports:
- "127.0.0.1:${JEKYLL_PORT:-4000}:4000"
- "127.0.0.1:35729:35729"
command: bundle exec jekyll serve --host 0.0.0.0 --livereload
profiles: [serve]

dev:
extends: jekyll
command: bundle exec jekyll build --watch --incremental --force_polling
profiles: [dev]

build:
extends: jekyll
command: bundle exec jekyll build
profiles: [build]
Copy link

Copilot AI Mar 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

extends: jekyll is not valid Compose syntax. extends must be a mapping (e.g., extends: { service: jekyll }), or you can replace this with YAML anchors/aliases (or x- extension fields) to share the base service config. As-is, docker compose will fail to parse the file.

Copilot uses AI. Check for mistakes.
run

usage() {
cat <<EOF
Usage: ./site <command>
Copy link

Copilot AI Mar 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The usage text references ./site, but the provided script is named run and the README examples use ./run .... Update the usage string to match the actual entrypoint so users don’t get misdirected.

Suggested change
Usage: ./site <command>
Usage: ./run <command>

Copilot uses AI. Check for mistakes.
Comment on lines 1464 to +1467
const iframe = document.createElement('iframe');
// Add enablejsapi=1 to enable YouTube API control
iframe.src = 'https://www.youtube.com/embed/' + videoYoutubeId + '?autoplay=1&enablejsapi=1';
iframe.setAttribute('title', videoTitle);
Copy link

Copilot AI Mar 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

iframe.title is set from an <h3> lookup that can resolve to an empty string; an empty title typically still fails 'iframe has an accessible name' checks. Provide a non-empty fallback (e.g., a generic 'Video' label or use another attribute like data-title) before setting the attribute.

Suggested change
const iframe = document.createElement('iframe');
// Add enablejsapi=1 to enable YouTube API control
iframe.src = 'https://www.youtube.com/embed/' + videoYoutubeId + '?autoplay=1&enablejsapi=1';
iframe.setAttribute('title', videoTitle);
const effectiveTitle = videoTitle || 'Video';
const iframe = document.createElement('iframe');
// Add enablejsapi=1 to enable YouTube API control
iframe.src = 'https://www.youtube.com/embed/' + videoYoutubeId + '?autoplay=1&enablejsapi=1';
iframe.setAttribute('title', effectiveTitle);

Copilot uses AI. Check for mistakes.
Comment on lines 10 to 11
{% include footer_default.html %}
<div id="darkSwitch" class="darkmode-toggle" title="Turn on dark mode">
Copy link

Copilot AI Mar 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The dark mode control is still a <div> in this layout, which is not keyboard-operable by default (and won’t behave like a button for assistive tech). Since _layouts/blog_layout_scix.html already converts this to a real <button type=\"button\"> with aria-label, consider updating the remaining layouts to use <button> as well for consistent keyboard accessibility.

Copilot uses AI. Check for mistakes.
---

<h1> User Preferences </h1>
<h2> User Preferences </h2>
Copy link

Copilot AI Mar 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change demotes a top-level page heading from <h1> to <h2>. If the surrounding layout does not provide an <h1>, the page may end up without a top-level heading, which is problematic for screen reader navigation and expected document outline. Consider keeping this as <h1> (or ensure the layout emits exactly one <h1> and content starts at <h2>).

Suggested change
<h2> User Preferences </h2>
<h1> User Preferences </h1>

Copilot uses AI. Check for mistakes.
- Convert all dark mode toggle divs to semantic buttons with aria-label
  across all 10 layouts and 3 API docs pages
- Restore h1 page headings in help index pages (userpreferences, orcid,
  libraries, api) and promote sub-section h3 to h2 for proper hierarchy
- Add fallback title for dynamically created video iframes in scixhelp
- Add border/padding reset to .darkmode-toggle for button element
Incorporate upstream's post.hidden filter while keeping h1/h2
heading hierarchy from a11y fixes.
Add min-height to .search-bar-container in both _layout.scss and
help/common/css/styles.scss so the Google CSE widget has allocated
space before it loads, eliminating CLS on page navigation. Remove
the slideInDown animation that caused a visible fade-in on every
page load.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants