Skip to content

Commit 458e721

Browse files
committed
Rustdoc accessibility: use real headers for doc items
This is a pretty annoying workaround: the specifications literally contradict each other on the matter of whether headers may be nested inside of summaries. We need the headers for people who use outline mode to browse rustdoc, mostly in screen readers, and the headers need to be inside the summary tag so that they're visible when the details tag is collapsed. HTML5 says it's okay, but the ordinary button semantics in ARIA say that headers nested in buttons are ignored, and summary is a button. Which means some screen readers, like NVDA, work, while others, like JAWS, don't.
1 parent e742158 commit 458e721

File tree

4 files changed

+26
-18
lines changed

4 files changed

+26
-18
lines changed

src/librustdoc/html/render/mod.rs

+10-10
Original file line numberDiff line numberDiff line change
@@ -1350,15 +1350,15 @@ fn render_impl(
13501350
);
13511351
render_rightside(w, cx, item, containing_item);
13521352
write!(w, "<a href=\"#{}\" class=\"anchor\"></a>", id);
1353-
w.write_str("<code>");
1353+
w.write_str("<h4 class=\"code-header\">");
13541354
render_assoc_item(
13551355
w,
13561356
item,
13571357
link.anchor(source_id.as_ref().unwrap_or(&id)),
13581358
ItemType::Impl,
13591359
cx,
13601360
);
1361-
w.write_str("</code>");
1361+
w.write_str("</h4>");
13621362
w.write_str("</div>");
13631363
}
13641364
}
@@ -1371,7 +1371,7 @@ fn render_impl(
13711371
id, item_type, in_trait_class
13721372
);
13731373
write!(w, "<a href=\"#{}\" class=\"anchor\"></a>", id);
1374-
w.write_str("<code>");
1374+
w.write_str("<h4 class=\"code-header\">");
13751375
assoc_type(
13761376
w,
13771377
item,
@@ -1381,7 +1381,7 @@ fn render_impl(
13811381
"",
13821382
cx,
13831383
);
1384-
w.write_str("</code>");
1384+
w.write_str("</h4>");
13851385
w.write_str("</div>");
13861386
}
13871387
clean::AssocConstItem(ref ty, ref default) => {
@@ -1394,7 +1394,7 @@ fn render_impl(
13941394
);
13951395
render_rightside(w, cx, item, containing_item);
13961396
write!(w, "<a href=\"#{}\" class=\"anchor\"></a>", id);
1397-
w.write_str("<code>");
1397+
w.write_str("<h4 class=\"code-header\">");
13981398
assoc_const(
13991399
w,
14001400
item,
@@ -1404,15 +1404,15 @@ fn render_impl(
14041404
"",
14051405
cx,
14061406
);
1407-
w.write_str("</code>");
1407+
w.write_str("</h4>");
14081408
w.write_str("</div>");
14091409
}
14101410
clean::AssocTypeItem(ref bounds, ref default) => {
14111411
let source_id = format!("{}.{}", item_type, name);
14121412
let id = cx.derive_id(source_id.clone());
14131413
write!(w, "<div id=\"{}\" class=\"{}{}\">", id, item_type, in_trait_class,);
14141414
write!(w, "<a href=\"#{}\" class=\"anchor\"></a>", id);
1415-
w.write_str("<code>");
1415+
w.write_str("<h4 class=\"code-header\">");
14161416
assoc_type(
14171417
w,
14181418
item,
@@ -1422,7 +1422,7 @@ fn render_impl(
14221422
"",
14231423
cx,
14241424
);
1425-
w.write_str("</code>");
1425+
w.write_str("</h4>");
14261426
w.write_str("</div>");
14271427
}
14281428
clean::StrippedItem(..) => return,
@@ -1613,7 +1613,7 @@ pub(crate) fn render_impl_summary(
16131613
write!(w, "<div id=\"{}\" class=\"impl has-srclink\"{}>", id, aliases);
16141614
render_rightside(w, cx, &i.impl_item, containing_item);
16151615
write!(w, "<a href=\"#{}\" class=\"anchor\"></a>", id);
1616-
write!(w, "<code class=\"in-band\">");
1616+
write!(w, "<h3 class=\"code-header in-band\">");
16171617

16181618
if let Some(use_absolute) = use_absolute {
16191619
write!(w, "{}", i.inner_impl().print(use_absolute, cx));
@@ -1629,7 +1629,7 @@ pub(crate) fn render_impl_summary(
16291629
} else {
16301630
write!(w, "{}", i.inner_impl().print(false, cx));
16311631
}
1632-
write!(w, "</code>");
1632+
write!(w, "</h3>");
16331633

16341634
let is_trait = i.inner_impl().trait_.is_some();
16351635
if is_trait {

src/librustdoc/html/render/print_item.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -621,9 +621,9 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra
621621
render_stability_since(w, m, t, cx.tcx());
622622
write_srclink(cx, m, w);
623623
write!(w, "</div>");
624-
write!(w, "<code>");
624+
write!(w, "<h4 class=\"code-header\">");
625625
render_assoc_item(w, m, AssocItemLink::Anchor(Some(&id)), ItemType::Impl, cx);
626-
w.write_str("</code>");
626+
w.write_str("</h4>");
627627
w.write_str("</div>");
628628
if toggled {
629629
write!(w, "</summary>");

src/librustdoc/html/static/css/rustdoc.css

+12-5
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,13 @@ h1.fqn > .in-band > a:hover {
146146
h2, h3, h4 {
147147
border-bottom: 1px solid;
148148
}
149+
h3.code-header, h4.code-header {
150+
font-size: 1em;
151+
font-weight: 600;
152+
border: none;
153+
padding: 0;
154+
margin: 0;
155+
}
149156
.impl,
150157
.impl-items .method,
151158
.methods .method,
@@ -233,7 +240,7 @@ details:not(.rustdoc-toggle) summary {
233240
margin-bottom: .6em;
234241
}
235242

236-
code, pre, a.test-arrow {
243+
code, pre, a.test-arrow, .code-header {
237244
font-family: "Source Code Pro", monospace;
238245
}
239246
.docblock code, .docblock-short code {
@@ -520,7 +527,7 @@ nav.sub {
520527
font-weight: normal;
521528
}
522529

523-
.method > code, .trait-impl > code, .invisible > code {
530+
.method > .code-header, .trait-impl > .code-header, .invisible > .code-header {
524531
max-width: calc(100% - 41px);
525532
display: block;
526533
}
@@ -536,7 +543,7 @@ nav.sub {
536543
padding: 0px;
537544
}
538545

539-
.in-band > code {
546+
.in-band > code, .in-band > .code-header {
540547
display: inline-block;
541548
}
542549

@@ -742,7 +749,7 @@ a {
742749
}
743750

744751
.invisible > .srclink,
745-
.method > code + .srclink {
752+
.method > .code-header + .srclink {
746753
position: absolute;
747754
top: 0;
748755
right: 0;
@@ -1103,7 +1110,7 @@ a.test-arrow:hover{
11031110
left: -10px;
11041111
}
11051112

1106-
:target > code {
1113+
:target > code, :target > .code-header {
11071114
opacity: 1;
11081115
}
11091116

src/librustdoc/html/static/js/main.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -706,8 +706,9 @@ function hideThemeButtonState() {
706706
}
707707
}
708708

709-
var code = document.createElement("code");
709+
var code = document.createElement("h3");
710710
code.innerHTML = struct.text;
711+
addClass(code, "code-header");
711712
addClass(code, "in-band");
712713

713714
onEachLazy(code.getElementsByTagName("a"), function(elem) {

0 commit comments

Comments
 (0)