Skip to content

Commit 026aa2a

Browse files
authored
Clean up theme styling and improve accessibility of theme toggle (#4005)
- Utilize SCSS nesting in theme styles - Hide the IDs of internal icons of theme toggle from screen readers - Enable a focus style for theme toggle by switching to a button - Properly center theme toggle --- **Focused while in light mode:** <img width="185" alt="Screenshot of toggle focused while in light mode" src="https://github.com/user-attachments/assets/a6aedde6-b53c-4a50-a161-f0fb939853ad" /> **Focused while in dark mode:** <img width="215" alt="Screenshot of toggle focused while in dark mode" src="https://github.com/user-attachments/assets/cc23bab5-1a64-489b-97f1-dcb96f6045f2" /> **Hovered while in dark mode:** <img width="201" alt="Screenshot of toggle hovered while in dark mode" src="https://github.com/user-attachments/assets/8e3e8413-ac8f-4dae-95f4-f5c85ff5f9e1" />
1 parent 766f61e commit 026aa2a

File tree

9 files changed

+1811
-1842
lines changed

9 files changed

+1811
-1842
lines changed

lib/resources/docs.dart.js

+1,733-1,759
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/resources/docs.dart.js.map

+6-6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/resources/styles.css

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/src/generator/templates.aot_renderers_for_html.dart

+8-11
Original file line numberDiff line numberDiff line change
@@ -2478,17 +2478,14 @@ String _deduplicated__head(TemplateDataBase context0) {
24782478
<form class="search navbar-right" role="search">
24792479
<input type="text" id="search-box" autocomplete="off" disabled class="form-control typeahead" placeholder="Loading search...">
24802480
</form>
2481-
<div class="toggle" id="theme-button" title="Toggle brightness">
2482-
<label for="theme">
2483-
<input type="checkbox" id="theme" value="light-theme">
2484-
<span id="dark-theme-button" class="material-symbols-outlined">
2485-
dark_mode
2486-
</span>
2487-
<span id="light-theme-button" class="material-symbols-outlined">
2488-
light_mode
2489-
</span>
2490-
</label>
2491-
</div>
2481+
<button class="toggle" id="theme-button" title="Toggle between light and dark mode" aria-label="Light and dark mode toggle">
2482+
<span id="dark-theme-button" class="material-symbols-outlined" aria-hidden="true">
2483+
dark_mode
2484+
</span>
2485+
<span id="light-theme-button" class="material-symbols-outlined" aria-hidden="true">
2486+
light_mode
2487+
</span>
2488+
</button>
24922489
</header>
24932490
<main>''');
24942491

lib/templates/_head.html

+8-11
Original file line numberDiff line numberDiff line change
@@ -54,16 +54,13 @@
5454
<form class="search navbar-right" role="search">
5555
<input type="text" id="search-box" autocomplete="off" disabled class="form-control typeahead" placeholder="Loading search...">
5656
</form>
57-
<div class="toggle" id="theme-button" title="Toggle brightness">
58-
<label for="theme">
59-
<input type="checkbox" id="theme" value="light-theme">
60-
<span id="dark-theme-button" class="material-symbols-outlined">
61-
dark_mode
62-
</span>
63-
<span id="light-theme-button" class="material-symbols-outlined">
64-
light_mode
65-
</span>
66-
</label>
67-
</div>
57+
<button class="toggle" id="theme-button" title="Toggle between light and dark mode" aria-label="Light and dark mode toggle">
58+
<span id="dark-theme-button" class="material-symbols-outlined" aria-hidden="true">
59+
dark_mode
60+
</span>
61+
<span id="light-theme-button" class="material-symbols-outlined" aria-hidden="true">
62+
light_mode
63+
</span>
64+
</button>
6865
</header>
6966
<main>

web/sig.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
6AD77EE4737CB53C3F7994D7BCC1E463
1+
318ACAF85024D323F3F60B8D63B1EC23

web/styles/_theme.scss

+30-40
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,15 @@
4545
--alert-important-fgColor: #7953bf;
4646
--alert-warning-fgColor: #955d00;
4747
--alert-error-fgColor: #c43131;
48+
49+
#light-theme-button {
50+
display: none;
51+
}
52+
53+
// Hide dark-mode only images from GitHub's themable image support.
54+
img[src$="#gh-dark-mode-only"] {
55+
display: none;
56+
}
4857
}
4958

5059
.dark-theme {
@@ -88,53 +97,34 @@
8897
--alert-important-fgColor: #ad81ff;
8998
--alert-warning-fgColor: #cea11f;
9099
--alert-error-fgColor: #ff6666;
91-
}
92100

93-
#theme {
94-
display: none;
101+
#dark-theme-button {
102+
display: none;
103+
}
104+
105+
// Hide light-mode only images from GitHub's themable image support.
106+
img[src$="#gh-light-mode-only"] {
107+
display: none;
108+
}
95109
}
96110

97111
#theme-button {
112+
// Reset button appearance.
113+
appearance: none;
114+
border: none;
115+
background: none;
116+
cursor: pointer;
117+
98118
position: absolute;
99119
right: 30px;
100-
height: 24px;
101-
}
120+
display: flex;
121+
align-items: center;
122+
justify-content: center;
123+
padding: 4px;
102124

103-
#theme-button .material-symbols-outlined {
104125
color: var(--main-icon-color);
105-
user-select: none;
106-
cursor: pointer;
107-
}
108-
109-
#theme-button .material-symbols-outlined:hover {
110-
color: var(--main-hyperlinks-color);
111-
}
112-
113-
li .material-symbols-outlined, dt .material-symbols-outlined {
114-
font-size: 1em;
115-
vertical-align: text-bottom;
116-
}
117-
118-
dt .material-symbols-outlined {
119-
text-indent: 0;
120-
}
121-
122-
.light-theme #light-theme-button {
123-
display: none;
124-
}
125-
126-
.dark-theme #dark-theme-button {
127-
display: none;
128-
}
129-
130-
/*
131-
Only show images that fit their theme using GitHub's syntax, see:
132-
https://github.blog/changelog/2021-11-24-specify-theme-context-for-images-in-markdown/
133-
*/
134-
.dark-theme img[src$="#gh-light-mode-only"] {
135-
display: none;
136-
}
137126

138-
.light-theme img[src$="#gh-dark-mode-only"] {
139-
display: none;
127+
&:hover {
128+
color: var(--main-hyperlinks-color);
129+
}
140130
}

web/styles/dartdoc/_misc.scss

+9
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,12 @@
3434
display: none !important;
3535
}
3636
}
37+
38+
li .material-symbols-outlined, dt .material-symbols-outlined {
39+
font-size: 1em;
40+
vertical-align: text-bottom;
41+
}
42+
43+
dt .material-symbols-outlined {
44+
text-indent: 0;
45+
}

web/theme.dart

+15-13
Original file line numberDiff line numberDiff line change
@@ -8,34 +8,36 @@ import 'package:web/web.dart';
88

99
void init() {
1010
var bodyElement = document.body;
11-
1211
if (bodyElement == null) {
1312
return;
1413
}
1514

16-
var theme = document.getElementById('theme') as HTMLInputElement;
15+
var themeButton =
16+
document.getElementById('theme-button') as HTMLButtonElement;
17+
18+
void switchThemes(bool toDarkMode) {
19+
if (toDarkMode) {
20+
bodyElement.classList.remove('light-theme');
21+
bodyElement.classList.add('dark-theme');
1722

18-
void switchThemes() {
19-
if (theme.checked) {
20-
bodyElement.setAttribute('class', 'dark-theme');
21-
theme.setAttribute('value', 'dark-theme');
2223
window.localStorage.setItem('colorTheme', 'true');
2324
} else {
24-
bodyElement.setAttribute('class', 'light-theme');
25-
theme.setAttribute('value', 'light-theme');
25+
bodyElement.classList.remove('dark-theme');
26+
bodyElement.classList.add('light-theme');
27+
2628
window.localStorage.setItem('colorTheme', 'false');
2729
}
2830
}
2931

30-
theme.addEventListener(
31-
'change',
32+
themeButton.addEventListener(
33+
'click',
3234
(Event _) {
33-
switchThemes();
35+
final currentlyDarkMode = bodyElement.classList.contains('dark-theme');
36+
switchThemes(!currentlyDarkMode);
3437
}.toJS,
3538
);
3639

3740
if (window.localStorage.getItem('colorTheme') case var colorTheme?) {
38-
theme.checked = colorTheme == 'true';
39-
switchThemes();
41+
switchThemes(colorTheme == 'true');
4042
}
4143
}

0 commit comments

Comments
 (0)