Skip to content

Commit f7d19db

Browse files
[ci skip] Improve accessibility (rails#51499)
* Add label and accessible content Having a select element without a label outside a form isn't directly problematic, but the text Version is the label of the select and should act as such. Because the select element is set up to browse to a different page which loses the current focus position, users must be instructed about this context change. It would be much better to display this content to everyone, but having this for screenreaders only is better than not having it at all. * Fix accessible text for voice commands Using the title attribute means some screenreaders will not be able to show the expanded accessible text at all, but using aria-label loses the hover text currently available. If the title attribute is still used, the accessible label should start with the same content as the visible label. This is necessary for most voice operated tooling which only match starting text. Having "Return" as the start of the accessible label and "Guides" as the start of the visible label means in most cases users that rely on voice commands will not be able to browse here. * Add utilities for screen readers This enables hiding content visually whilst still enabling it for assisistive technologies. * Feature detection for JavaScript functionalities * Add landmarks to all guide pages Landmarks such as header, section, footer, article, and the main content landmark help navigating when using assistive tooling. Since each guide is a self-contained article, a header section with the guide introduction and navigation, a footer section which is not part of the content but a call to action, and the rest can be clearly separated, landmarks here are appropiate. * Make back-to-top work without JavaScript By doing feature detection on animation timeline CSS, the graceful degradation can take care of the visiblity of the back-to-top button. In case no JavaScript is available, it should always be shown. * Enable back-to-top without JavaScript And add an accessible label to the button. It would be better to just show the text back to top underneath the arrow, but this change is again better than not having it at all. * Consistent scrolling behaviour respecting pref Use the preference to detect if a user wants reduced motion and if not enable smooth scrolling. This takes care of the back-to-top smooth scrolling, and also adds it to anchor links. If this is unwanted, the change can be reverted and a matchmedia check should be done in JavaScript instead before smooth scrolling * Add skip links to quickly navigate past navs Skip links are a common practice to allow keyboard and other users to skip past large blocks of content that are present on every page, which in this case are the secondary navigation at the top, the version selector, and the chapter navigation. The skip links only show when focused. * Wrap tables to make them responsive * Make back-to-top link to skip link This allow screen readers to announce something, because linking to an empty fragment or the body element doesn't announce anything usefull. * Fix false positive for broken (skip) link anchor * Add branded selectable color Fixes selecting text in dark mode and brands it for both modes. * Make more info and guides index accessible * Adds aria-controls, which binds the control to the content. * Adds aria-expanded, which signals the current expansion state. * Adds focus handling, which focuses the first link or the button depending on the expansion state. * Adds keyboard closing for the more info button. * Adds outside click tracking to close the expanded content. * Fixes the more info button to not be focusable. * Fix CSS for more info button * Fix dark mode for guide selector * Add accessible label for guide navigator * Only use nav on sub-column if it's actually a nav On the index page the sub-column is not a navigational element and does not contain content that needs to be skipped over. Therefore it should not be a <nav> and not contain a skiplink. Furthermore, the definition list doesn't contain any definitions, thus its role should be removed. * Ignore turbo for in-page skiplinks This ensures the JavaScript doesn't overridde any screenreader behaviour and the resulting fragment is correctly focused as expected. * Use keydown for escape detection When an action should be perceived as fast, or no pause is required before the interaction, keydown should be used and not keyup, which can add (the feeling of a) significant delay. * Fix heading levels It is important that the heading structure (all hx elements) are properly closed, and make sense. They can only ever increment by 1 since the previous heading (and decrement by many). * Presentational picture needs aria-hidden="true" The picture here adds a visual gimmic, but doesn't provide information to the user and thus should be removed from the accessibility tree. * JS-enabled link-as-button should have correct role When JavaScript is enabled, this link turns into a button that expands an element. The change ensures that screenreaders only announce it as such if JavaScript is enabled and applied. * Accessible regions, focusable anchors, cleanup Applied requested changes from review. See PR for discussion about explicitly adding a role="region" rails#51499 * Apply requested changes from review and re-apply after rebase * Adapt the highlight in the navigation side column for the new page structure. Additionally, replace the active class with aria-current="true", which is meant to keep track of what is currently active in a set. Finally, update the implementation of the intersection observer to: * not rely on the viewport height (-95%) * not rely on fixing the highlighted item after click * support both scrolling up and scrolling down * support fast scrolling * Apply review commentary * Fix issues with scrolling behaviour To "restore" the current behaviour on main, a solution was needed for browser-OS combinations that do not allow for two concurrent scrolling elements. Current code on main breaks completely when using scroll-behaviour: smooth (in CSS), and breaks when scrolling back-to-top from the bottom of the page (highlight no longer correct). This commit works around the limitation whilst also enabling the non-smooth scrolled solution for those who want reduced motion. Additionally it has a workaround for a bug on Android, and some defaults for those without JavaScript enabled. * Ensure chapters list is always scrolled after scroll-end Co-authored-by: Rafael Mendonça França <[email protected]>
1 parent 1932359 commit f7d19db

File tree

9 files changed

+880
-404
lines changed

9 files changed

+880
-404
lines changed

guides/assets/javascripts/guides.js

Lines changed: 396 additions & 110 deletions
Large diffs are not rendered by default.

guides/assets/stylesrc/_dark.scss

Lines changed: 40 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// ----------------------------------------------------------------------------
44
//
55
// @include-media does not handle prefers-color-scheme so we are declaring this
6-
// as an independent file with the overrides for dark mode.
6+
// as an independent file with the overrides for dark mode.
77

88
@media (prefers-color-scheme: dark) {
99
body.guide {
@@ -15,17 +15,17 @@
1515
width: 12px;
1616
background-color: transparent;
1717
}
18-
18+
1919
&::-webkit-scrollbar-track {
20-
-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3);
20+
-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3);
2121
border-radius: 10px;
2222
background-color: $gray-900;
2323
}
24-
24+
2525
&::-webkit-scrollbar-thumb {
2626
background-color: $gray-500;
2727
border-radius: 10px;
28-
-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.5);
28+
-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.5);
2929
}
3030

3131
h1, h2, h3 {
@@ -45,20 +45,24 @@
4545
} // &:visited
4646
} // a
4747

48+
a.skip-link {
49+
background-color: $gray-900;
50+
}
51+
4852
h2 a, h3 a {
4953
&:link,
5054
&:visited {
5155
color: inherit;
52-
}
56+
}
5357
} // h2 a
54-
58+
5559
table {
5660
th {
5761
background-color: $gray-900;
5862
border-bottom: 2px solid $gray-700;
5963
color: $text-on-darker-bg;
6064
} // th
61-
65+
6266
tr {
6367
&:nth-child(even) {
6468
background-color: $gray-900;
@@ -101,9 +105,10 @@
101105
color: #fff;
102106
}
103107

104-
nav#topNav { background-color: $gray-900;
108+
#mobile-navigation-bar {
109+
background-color: $gray-900;
105110
color: $gray-400;
106-
111+
107112

108113
.more-info-links {
109114
background: $gray-1000;
@@ -112,22 +117,22 @@
112117
li {
113118
border-bottom: 1px solid $gray-800;
114119
} // li
115-
} // nav#topNav
120+
} // #mobile-navigation-bar
116121

117-
header#page_header {
118-
nav#feature_nav {
122+
header#page-header {
123+
nav#feature-nav {
119124
.header-logo {
120125
a, a:link, a:visited {
121126
color: #fff;
122127
}
123-
span#version_switcher {
128+
span#version-switcher {
124129
color: $gray-400;
125130

126131
select {
127132
background-color: $gray-900;
128133
color: $gray-400;
129134
} // select
130-
} // span#version_switcher
135+
} // span#version-switcher
131136
} // .header-logo
132137

133138
ul.nav {
@@ -146,10 +151,19 @@
146151
background-image: url("../images/icon_house-chimney-wht.svg");
147152
}
148153
} // @include media('>desktop')
154+
155+
&:last-child {
156+
// the drop down
157+
158+
select {
159+
background-color: $gray-900;
160+
color: $gray-400;
161+
} // select
162+
}
149163
} // li
150164
} // ul.nav
151-
} // nav#feature_nav
152-
} // header#page_header
165+
} // nav#feature-nav
166+
} // header#page-header
153167

154168
#guides {
155169
background: $gray-800;
@@ -179,43 +193,43 @@
179193
background-color: $gray-1000;
180194
}
181195

182-
#subCol {
183-
background-color: $gray-900;
196+
#column-side {
197+
background-color: $gray-900;
184198

185199
ol.chapters {
186200
&::-webkit-scrollbar {
187201
background-color: $gray-800;
188202
}
189-
203+
190204
&::-webkit-scrollbar-track {
191205
background-color: $gray-700;
192206
border-radius: 5px;
193-
box-shadow: inset 0 0 6px rgba(0,0,0,0.3);
207+
box-shadow: inset 0 0 6px rgba(0,0,0,0.3);
194208
}
195-
209+
196210
&::-webkit-scrollbar-thumb {
197211
background-image: -webkit-gradient(linear,
198212
left bottom,
199213
left top,
200214
color-stop(0.44, $rf-brand-lightest),
201215
color-stop(0.86, $rf-brand-lighter));
202216
border-radius: 5px;
203-
box-shadow: inset 0 0 6px rgba(0,0,0,0.5);
217+
box-shadow: inset 0 0 6px rgba(0,0,0,0.5);
204218
}
205219
li {
206220
a,
207221
a:link,
208222
a:visited {
209223
color: inherit;
210224
}
211-
225+
212226
a:hover,
213227
a:active {
214228
color: $rf-brand-lighter;
215229
} // a
216230
} // li
217231
} // ol
218-
} // #subCol
232+
} // #column-side
219233
} // #feature
220234

221235
.interstitial {
@@ -247,4 +261,4 @@
247261
}
248262
}
249263
} // body.guide
250-
} // @media (prefers-color-scheme: dark
264+
} // @media (prefers-color-scheme: dark

0 commit comments

Comments
 (0)