Skip to content

Commit a606758

Browse files
authored
Merge pull request #6592 from WoltLab/63-toc-a11y
Improve A11y of the table of contents block
2 parents d58f8dd + 6d47293 commit a606758

3 files changed

Lines changed: 65 additions & 71 deletions

File tree

Lines changed: 37 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,47 @@
1-
<div class="tableOfContentsWrapper">
2-
<div class="tableOfContentsContainer open mobileForceHide" id="tocContainer-{$idPrefix}">
3-
<div class="tableOfContentsHeader">
4-
<span class="tableOfContentsTitle">{lang}wcf.message.toc{/lang}</span>
5-
<span class="jsOnly">[<a href="#" class="jsTableOfContentsHide">{lang}wcf.message.toc.hide{/lang}</a><a href="#" class="jsTableOfContentsShow">{lang}wcf.message.toc.show{/lang}</a>]</span>
1+
<div class="tableOfContents__wrapper">
2+
<nav class="tableOfContents__container" aria-labelledby="tocTitle-{$idPrefix}">
3+
<div class="tableOfContents__header">
4+
<h2 class="tableOfContents__title" id="tocTitle-{$idPrefix}">{lang}wcf.message.toc{/lang}</h2>
5+
6+
<button type="button"
7+
aria-expanded="true"
8+
aria-controls="toc-{$idPrefix}"
9+
class="tableOfContents__toggle button small"
10+
id="tocToggle-{$idPrefix}"
11+
>
12+
{lang}wcf.message.toc.hide{/lang}
13+
</button>
614
</div>
7-
<ol class="tableOfContents tocLevel1">
15+
<ul class="tableOfContents tableOfContents--level1" id="toc-{$idPrefix}">
816
{foreach from=$items item=item}
917
<li>
10-
<span class="tocItemTitle"><a href="#{$item->getID()}">{$item->getTitle()}</a></span>
18+
<a class="tableOfContents__item" href="#{$item->getID()}">{$item->getTitle()}</a>
1119

12-
{if $item->hasChildren()}<ol class="tableOfContents tocLevel{$item->getDepth() + 1}">{else}</li>{/if}
20+
{if $item->hasChildren()}<ul class="tableOfContents tableOfContents--level{$item->getDepth() + 1}">{else}</li>{/if}
1321

1422
{if !$item->hasChildren() && $item->isLastSibling()}
15-
{unsafe:"</ol></li>"|str_repeat:$item->getOpenParentNodes()}
23+
{unsafe:"</ul></li>"|str_repeat:$item->getOpenParentNodes()}
1624
{/if}
1725
{/foreach}
18-
</ol>
19-
</div>
20-
</div>
21-
<script data-relocate="true">
22-
require(['Ui/Screen'], function(UiScreen) {
23-
var container = elById('tocContainer-{$idPrefix}');
24-
elBySelAll('.jsTableOfContentsHide, .jsTableOfContentsShow', container, function(button) {
25-
button.addEventListener('click', function(event) {
26-
event.preventDefault();
27-
28-
container.classList.toggle('open');
26+
</ul>
27+
</nav>
28+
<script>
29+
{
30+
const button = document.getElementById('tocToggle-{$idPrefix}');
31+
button.addEventListener('click', () => {
32+
toggle();
2933
});
30-
});
31-
32-
if (UiScreen.is('screen-sm-down')) {
33-
container.classList.remove('open');
34+
35+
function toggle() {
36+
const hidden = button.getAttribute('aria-expanded') === 'true';
37+
button.setAttribute('aria-expanded', hidden ? 'false' : 'true');
38+
button.textContent = hidden ? '{jslang}wcf.message.toc.show{/jslang}' : '{jslang}wcf.message.toc.hide{/jslang}';
39+
document.getElementById(button.getAttribute('aria-controls')).hidden = hidden;
40+
}
41+
42+
if (window.matchMedia('(max-width: 768px)').matches) {
43+
toggle();
44+
}
3445
}
35-
36-
container.classList.remove('mobileForceHide');
37-
});
38-
</script>
46+
</script>
47+
</div>
Lines changed: 25 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,72 +1,57 @@
1-
.tableOfContentsContainer {
1+
.tableOfContents__container {
22
border: 1px solid var(--wcfContentBorderInner);
33
/* The list numbers extend into the horizontal padding, 10px is not enough for double digit numbers. */
4-
padding: 10px 20px;
5-
6-
&.open .jsTableOfContentsShow {
7-
display: none;
8-
}
4+
padding: 20px;
5+
}
96

10-
&:not(.open) {
11-
.jsTableOfContentsHide,
12-
.tableOfContents {
13-
display: none;
14-
}
7+
@include screen-sm-down {
8+
.tableOfContents__container {
9+
padding: 10px 20px;
1510
}
1611
}
1712

1813
@include screen-md-up {
19-
.tableOfContentsWrapper {
14+
.tableOfContents__wrapper {
2015
float: right;
2116
margin: 0 0 10px 10px;
2217
max-width: 50%;
2318
}
2419

25-
.htmlContent > .tableOfContentsWrapper + * {
20+
.htmlContent > .tableOfContents__wrapper + * {
2621
margin-top: 0 !important;
2722
}
2823
}
2924

30-
@include screen-sm-down {
31-
.tableOfContentsWrapper {
32-
margin-bottom: 10px;
25+
@include screen-lg {
26+
.tableOfContents__wrapper {
27+
max-width: 40%;
3328
}
29+
}
3430

35-
.tableOfContentsContainer {
36-
display: inline-block;
37-
38-
&.mobileForceHide {
39-
.jsTableOfContentsShow {
40-
display: initial !important;
41-
}
42-
43-
.jsTableOfContentsHide,
44-
.tableOfContents {
45-
display: none;
46-
}
47-
}
31+
@include screen-sm-down {
32+
.tableOfContents__wrapper {
33+
margin-bottom: 10px;
4834
}
4935
}
5036

51-
.tableOfContentsHeader {
52-
text-align: center;
37+
.tableOfContents__header {
38+
align-items: center;
39+
display: flex;
40+
gap: 10px;
41+
justify-content: center;
5342
}
5443

55-
.tableOfContentsTitle {
44+
h2.tableOfContents__title {
45+
@include wcfFontHeadline;
5646
@include wcfFontBold;
47+
48+
margin: 0;
5749
}
5850

5951
.htmlContent,
6052
.messageBody > .messageText {
6153
.tableOfContents {
6254
margin-left: 15px;
63-
64-
&.tocLevel2 {
65-
list-style-type: lower-alpha;
66-
}
67-
68-
&.tocLevel3 {
69-
list-style-type: lower-roman;
70-
}
55+
margin-bottom: 0;
7156
}
7257
}

wcfsetup/install/lang/en.xml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4287,9 +4287,9 @@ Allowed extensions: gif, jpg, jpeg, png, webp]]></item>
42874287
<item name="wcf.message.error.tooLong"><![CDATA[The message is too long, must be under {#$maxTextLength} characters.]]></item>
42884288
<item name="wcf.message.status.deleted"><![CDATA[Deleted]]></item>
42894289
<item name="wcf.message.status.disabled"><![CDATA[Disabled]]></item>
4290-
<item name="wcf.message.toc"><![CDATA[Contents]]></item>
4291-
<item name="wcf.message.toc.hide"><![CDATA[hide]]></item>
4292-
<item name="wcf.message.toc.show"><![CDATA[show]]></item>
4290+
<item name="wcf.message.toc"><![CDATA[Table of Contents]]></item>
4291+
<item name="wcf.message.toc.hide"><![CDATA[Hide]]></item>
4292+
<item name="wcf.message.toc.show"><![CDATA[Show]]></item>
42934293
<item name="wcf.message.user.consent.button.enable"><![CDATA[Display all external content]]></item>
42944294
<item name="wcf.message.user.consent.button.enableOnce"><![CDATA[Display content once]]></item>
42954295
<item name="wcf.message.user.consent.description"><![CDATA[Content embedded from external sources will not be displayed without your consent.]]></item>

0 commit comments

Comments
 (0)