Bunch of structural improvements. (#3488)

- Make better use of html semantic elements to help
search & screen readers.

- Add or improve ARIA annotations for accessibility

- Improve print-time formatting.
This commit is contained in:
Martin Taillefer 2019-03-04 07:26:48 -08:00 committed by GitHub
parent 1e24115604
commit d093f22d0c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
29 changed files with 189 additions and 123 deletions

View File

@ -1,5 +1,6 @@
---
title: Istio
description: Connect, secure, control, and observe services.
---
<!-- these script blocks are only for the primary English home page -->
<script type="application/ld+json">

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -141,11 +141,13 @@
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" defer></script>
{{ end }}
<div id="scroll-to-top-container">
<button id="scroll-to-top" aria-hidden="true" title='{{ i18n "button_top"}}'>
{{ partial "icon.html" "top" }}
</button>
</div>
<nav>
<div id="scroll-to-top-container">
<button id="scroll-to-top" aria-hidden="true" title='{{ i18n "button_top"}}'>
{{ partial "icon.html" "top" }}
</button>
</div>
</nav>
{{ if .Site.Data.args.preliminary }}
<div id="switch-lang-container">

View File

@ -4,20 +4,23 @@
{{ if $page }}
{{ $.Scratch.Add "urls" (slice $page.Permalink) }}
{{ $.Scratch.Add "titles" (slice $page.LinkTitle) }}
{{ $.Scratch.Add "descriptions" (slice $page.Description) }}
{{ $page = $page.Parent }}
{{ end }}
{{ end }}
{{ $len := len ($.Scratch.Get "titles") }}
{{ range $index, $element := $.Scratch.Get "titles" }}
{{ $i := sub (sub $len $index) 1 }}
{{ $title := index ($.Scratch.Get "titles") $i }}
{{ $url := index ($.Scratch.Get "urls") $i }}
<ol>
{{ $len := len ($.Scratch.Get "titles") }}
{{ range $index, $element := $.Scratch.Get "titles" }}
{{ $i := sub (sub $len $index) 1 }}
{{ $title := index ($.Scratch.Get "titles") $i }}
{{ $description := index ($.Scratch.Get "descriptions") $i }}
{{ $url := index ($.Scratch.Get "urls") $i }}
{{ if ne $i 0 }}
<a href="{{- $url -}}">{{- $title -}}</a>
<span>/</span>
{{ else }}
{{ $title }}
{{ if ne $i 0 }}
<li><a href="{{- $url -}}" title="{{- $description -}}">{{- $title -}}</a></li>
{{ else }}
<li>{{- $title -}}</li>
{{ end }}
{{ end }}
{{ end }}
</ol>

View File

@ -4,22 +4,24 @@
{{ if .Scratch.Get "seeAlso" }}
{{ $related := .Site.RegularPages.Related . | first 6 }}
{{ with $related }}
<h2 id="see-also">{{ i18n "see_also" }}</h2>
<nav id="see-also">
<h2>{{ i18n "see_also" }}</h2>
<div class="see-also">
{{ range . }}
<div class="entry">
<p class="link"><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></p>
<p class="desc">{{ .Description }}</p>
</div>
{{ end }}
</div>
<div class="see-also">
{{ range . }}
<div class="entry">
<p class="link"><a class="not-for-endnotes" href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></p>
<p class="desc">{{ .Description }}</p>
</div>
{{ end }}
</div>
</nav>
{{ end }}
{{ end }}
</main>
</article>
{{ if or .NextInSection .PrevInSection }}
<div class="pagenav">
<nav class="pagenav">
<div class="left">
{{ if .NextInSection }}
<p>
@ -34,7 +36,7 @@
</p>
{{ end }}
</div>
</div>
</nav>
{{ end }}
<div id="endnotes-container" aria-hidden="true">
@ -52,4 +54,4 @@
</nav>
</div>
{{ end }}
</div>
</main>

View File

@ -2,9 +2,9 @@
{{ $needTOC := .Scratch.Get "needTOC" }}
{{ if and $needTOC (ne .Params.force_inline_toc true) }}
<div class="primary">
<main class="primary">
{{ else }}
<div class="primary notoc">
<main class="primary notoc">
{{ end }}
<div id="sidebar-container" class="sidebar-container sidebar-offcanvas">
@ -19,16 +19,16 @@
<div class="article-container">
{{ if or $section.Params.sidebar_singlecard $section.Params.sidebar_multicard }}
<label id="sidebar-toggler" title='{{ i18n "button_sidenav" }}'>
<button id="sidebar-toggler" title='{{ i18n "button_sidenav" }}'>
{{ partial "icon.html" "pull" }}
</label>
</button>
{{ end }}
<div class="pagenav">
<p>{{- partial "breadcrumbs.html" . -}}</p>
</div>
<nav class="breadcrumbs" aria-label="Breadcrumb">
{{- partial "breadcrumbs.html" . -}}
</nav>
<main aria-labelledby="title">
<article aria-labelledby="title">
<div class="title-area">
{{- if .Params.icon -}}
<div>

View File

@ -2,6 +2,8 @@
{{ $parent := .parent }}
{{ $current := .current }}
{{ $collapse := .collapse }}
{{ $top := .top }}
{{ $labelledby := .labelledby }}
{{ $leafSection := true }}
{{ range $pages }}
@ -12,24 +14,26 @@
{{ end }}
{{ end }}
<ul class="{{ if not $collapse }}show{{ end }}{{ if $leafSection }} leaf-section{{ end }}">
<ul role="{{ if $top }}tree{{ else }}group{{ end }}" aria-expanded="{{ if $collapse }}false{{ else }}true{{ end }}"{{ if $leafSection }} class="leaf-section"{{ end }} {{ if $labelledby}}aria-labelledby="{{ $labelledby }}"{{ end }}>
{{ range $pages }}
{{ if eq .Parent $parent }}
<li>
{{ if not .IsPage }}
{{ if not .IsPage }}
<li role="treeitem" aria-label="{{ .LinkTitle}}">
{{ $collapse := not (.IsAncestor $current) }}
<button{{ if not $collapse }} class="show"{{ end }}></button><a {{ if eq $current.Permalink .Permalink }}class="current"{{ end }} title="{{ .Description }}" href="{{ .Permalink }}">{{ .LinkTitle}}</a>
<button{{ if not $collapse }} class="show"{{ end }} aria-hidden="true"></button><a {{ if eq $current.Permalink .Permalink }}class="current"{{ end }} title="{{ .Description }}" href="{{ .Permalink }}">{{ .LinkTitle}}</a>
{{ partial "sidebar_level.html" (dict "pages" $pages "parent" . "current" $current "collapse" $collapse) }}
{{ else }}
{{ partial "sidebar_level.html" (dict "pages" $pages "parent" . "current" $current "collapse" $collapse "top" false "labelledby" "" ) }}
</li>
{{ else }}
<li role="none">
{{ if eq $current.Permalink .Permalink }}
<span class="current" title="{{ .Description }}">{{ .LinkTitle }}</span>
<span role="treeitem" class="current" title="{{ .Description }}">{{ .LinkTitle }}</span>
{{ else }}
<a title="{{ .Description }}" href="{{ .Permalink }}">{{ .LinkTitle }}</a>
<a role="treeitem" title="{{ .Description }}" href="{{ .Permalink }}">{{ .LinkTitle }}</a>
{{ end }}
{{ end }}
</li>
</li>
{{ end }}
{{ end }}
{{ end }}
</ul>

View File

@ -1,4 +1,4 @@
<nav id="sidebar">
<nav id="sidebar" aria-label="Section Navigation">
<div class="directory" role="tablist">
{{ $section := .Site.GetPage "section" .Section }}
@ -8,16 +8,17 @@
{{ range $count, $page := $pages }}
{{ if eq .Parent $section }}
<div class="card">
<div class="header" role="tab" id="header{{ $count }}" title="{{ $page.Description }}">
{{ $id := printf "header%d" $count }}
<div class="card" role="tabpanel" aria-labelledby="{{ $id }}">
<div class="header" role="tab" id="{{ $id }}" title="{{ $page.Description }}">
{{- if $page.Params.icon -}}
{{- partial "icon.html" .Params.icon -}}
{{- end -}}
{{- $page.Title -}}
</div>
<div class="body{{if .IsAncestor $current}} default{{end}}" role="tabpanel" aria-labelledby="header{{ $count }}">
{{ partial "sidebar_level.html" (dict "pages" $pages "parent" $page "current" $current "collapse" false) }}
<div class="body{{if .IsAncestor $current}} default{{end}}">
{{ partial "sidebar_level.html" (dict "pages" $pages "parent" $page "current" $current "collapse" false "top" true "labelledby" $id ) }}
</div>
</div>
{{ end }}

View File

@ -1,9 +1,10 @@
<nav id="sidebar">
<nav id="sidebar" aria-label="Section Navigation">
<div class="directory" role="tablist">
{{ $section := .Site.GetPage "section" .Section }}
<div class="card">
<div id="header0" class="header" role="tab" title="{{ $section.Description }}">
{{ $id := "header0" }}
<div class="card" role="tabpanel" aria-labelledby="{{ $id }}">
<div id="{{ $id }}" class="header" role="tab" title="{{ $section.Description }}">
{{- if $section.Params.icon -}}
{{- partial "icon.html" $section.Params.icon -}}
{{- end -}}
@ -13,7 +14,7 @@
{{ $pages := (where .Site.Pages "Section" .Section).ByWeight }}
<div class="body default" role="tabpanel" aria-labelledby="header0">
{{ partial "sidebar_level.html" (dict "pages" $pages "parent" $section "current" . "collapse" false) }}
{{ partial "sidebar_level.html" (dict "pages" $pages "parent" $section "current" . "collapse" false "top" true "labelledby" $id ) }}
</div>
</div>
</div>

View File

@ -21,8 +21,8 @@
{{ if or (gt $len 0) ($page.Scratch.Get "seeAlso") }}
{{ $page.Scratch.Set "needTOC" true }}
<nav id="TableOfContents">
<ul>
<nav id="TableOfContents" aria-label="Table of Contents">
<ul role="tree">
{{ $page.Scratch.Set "level" 50 }}
{{ range $h := $headers }}
{{ $level := index (index (findRE "<h[23456].*?" $h) 0) 2 | int }}
@ -33,16 +33,17 @@
{{ if gt $level $current }}
{{ $delta := sub $level $current }}
{{ range $index, $num := (seq $delta) }}
<ul>
<ul role="group">
{{ end }}
{{ else if lt $level $current }}
{{ $delta := sub $current $level }}
{{ range $index, $num := (seq $delta) }}
</ul>
</li>
{{ end }}
{{ end }}
<li><a href="#{{ $id }}">{{ $title | safeHTML }}</a></li>
<li role="none" aria-label="{{ $title | safeHTML }}"><a role="treeitem" href="#{{ $id }}">{{ $title | safeHTML }}</a>
{{ $page.Scratch.Set "level" $level }}
{{ end }}
@ -50,6 +51,7 @@
{{ $delta := sub ($page.Scratch.Get "level") 50 }}
{{ range $index, $num := (seq $delta) }}
</ul>
</li>
{{ end }}
{{ if $page.Scratch.Get "seeAlso" }}

View File

@ -1,4 +1,4 @@
<div class="callout idea">
<aside class="callout idea">
<div class="type">
<svg class="large-icon"><use xlink:href="/img/icons.svg#callout-idea"/></svg>
</div>
@ -6,4 +6,4 @@
{{ $trimmed := trim .Inner " \n" }}
{{ markdownify $trimmed }}
</div>
</div>
</aside>

View File

@ -1,4 +1,4 @@
<div class="callout quote">
<aside class="callout quote">
<div class="type">
<svg class="large-icon"><use xlink:href="/img/icons.svg#callout-quote"/></svg>
</div>
@ -6,4 +6,4 @@
{{ $trimmed := trim .Inner " \n" }}
{{ markdownify $trimmed }}
</div>
</div>
</aside>

View File

@ -6,13 +6,13 @@
{{- /* We don't use the inner content, but Hugo will complain if we don't reference it. */}}
{{- end -}}
<div class="tabset" id="{{ $tab_set_id }}">
<div id="{{ $tab_set_id }}" role="tablist">
<div class="tab-strip" data-cookie-name="{{ $cookie_name }}">
{{- range $i, $e := $tabs -}}
{{- $id := printf "%s-%d" $tab_set_id $i -}}
<a class="not-for-endnotes{{ if eq $i 0 }} active{{ end }}" data-cookie-value="{{ .cookie_value }}"
data-tab="{{ $id }}"><span>{{ trim .name " " }}</span>
</a>
<button {{ if eq $i 0 }}class="active"{{ end }} data-cookie-value="{{ .cookie_value }}"
data-tab="{{ $id }}-panel" id="{{ $id }}-tab" role="tab"><span>{{ trim .name " " }}</span>
</button>
{{- end -}}
</div>
@ -20,7 +20,7 @@
{{- range $i, $e := $tabs -}}
{{- $id := printf "%s-%d" $tab_set_id $i -}}
<div {{ if eq $i 0 }}class="active"{{ end }} id="{{ $id }}">
<div {{ if eq $i 0 }}class="active"{{ end }} id="{{ $id }}-panel" role="tabpanel" aria-labelledby="{{ $id }}-tab">
{{- with .content -}}
{{- . -}}
{{- end -}}

View File

@ -1,4 +1,4 @@
<div class="callout tip">
<aside class="callout tip">
<div class="type">
<svg class="large-icon"><use xlink:href="/img/icons.svg#callout-tip"/></svg>
</div>
@ -6,4 +6,4 @@
{{ $trimmed := trim .Inner " \n" }}
{{ markdownify $trimmed }}
</div>
</div>
</aside>

View File

@ -1,4 +1,4 @@
<div class="callout warning">
<aside class="callout warning">
<div class="type">
<svg class="large-icon"><use xlink:href="/img/icons.svg#callout-warning"/></svg>
</div>
@ -6,4 +6,4 @@
{{ $trimmed := trim .Inner " \n" }}
{{ markdownify $trimmed }}
</div>
</div>
</aside>

View File

@ -2,9 +2,9 @@
function handleLinks() {
function attachLink(node) {
function attachSelfLink(node) {
const anchor = document.createElement("a");
anchor.className = "header-link";
anchor.className = "self-link";
anchor.href = "#" + node.id;
anchor.setAttribute("aria-hidden", "true");
anchor.innerHTML = "<svg class='icon'><use xlink:href='" + iconFile + "#links'/></svg>";
@ -17,7 +17,7 @@ function handleLinks() {
for (let level = 2; level <= 6; level++) {
queryAll(document, "h" + level.toString()).forEach(hdr => {
if (hdr.id !== "") {
attachLink(hdr);
attachSelfLink(hdr);
}
});
}
@ -27,7 +27,7 @@ function handleLinks() {
function attachLinksToDefinedTerms() {
queryAll(document, 'dt').forEach(dt => {
if (dt.id !== "") {
attachLink(dt);
attachSelfLink(dt);
}
});
}
@ -49,11 +49,11 @@ function handleLinks() {
return;
}
// look for anchors in the main section of the doc only (skip headers, footers, tocs, nav bars, etc)
const main = document.getElementsByTagName("main")[0];
// look for anchors in the main section of the main article only (skip headers, footers, tocs, nav bars, etc)
const article = document.getElementsByTagName("article")[0];
const map = new Map(null);
let numLinks = 0;
queryAll(main, 'a').forEach(link => {
queryAll(article, 'a').forEach(link => {
if (link.pathname === location.pathname) {
// skip links pointing to the current page
return;

View File

@ -10,10 +10,16 @@ function handleSidebar() {
// toggle subtree in sidebar
queryAll(sidebar, 'button').forEach(o => {
listen(o, click, e => {
let el = e.currentTarget;
el.classList.toggle("show");
el.nextElementSibling.nextElementSibling.classList.toggle("show");
let button = e.currentTarget;
button.classList.toggle("show");
const ul = button.nextElementSibling.nextElementSibling;
if (ul.getAttribute("aria-expanded") === "true") {
ul.setAttribute("aria-expanded", "false");
} else {
ul.setAttribute("aria-expanded", "true");
}
let el = ul;
do {
el = el.parentElement;
} while (!el.classList.contains('body'));

View File

@ -1,7 +1,7 @@
"use strict";
function handleTabs() {
queryAll(document, ".tabset").forEach(tabset => {
queryAll(document, "[role=tablist]").forEach(tabset => {
queryAll(tabset, ".tab-strip").forEach(strip => {
const cookieName = strip.dataset.cookieName;
@ -22,17 +22,17 @@ function handleTabs() {
}
// attach the event handlers to support tab sets
queryAll(strip, "a").forEach(anchor => {
listen(anchor, click, () => {
queryAll(strip, "a").forEach(anchor2 => {
anchor2.classList.remove(active);
getById(anchor2.dataset.tab).classList.remove(active);
queryAll(strip, "button").forEach(button => {
listen(button, click, () => {
queryAll(strip, "button").forEach(button2 => {
button2.classList.remove(active);
getById(button2.dataset.tab).classList.remove(active);
});
anchor.classList.add(active);
getById(anchor.dataset.tab).classList.add(active);
button.classList.add(active);
getById(button.dataset.tab).classList.add(active);
if (cookieName !== null) {
createCookie(cookieName, anchor.dataset.cookieValue);
createCookie(cookieName, button.dataset.cookieValue);
}
});
});

View File

@ -10,6 +10,7 @@
@import "base/base";
@import "misc/blog";
@import "misc/_breadcrumbs";
@import "misc/button";
@import "misc/callout";
@import "misc/community";

View File

@ -372,30 +372,31 @@ h6 {
font-weight: $h6Weight;
}
.header-link {
.self-link {
position: relative;
left: 0.5em;
top: -.1em;
opacity: 0;
font-size: 0.6em;
display: none;
}
h2:hover .header-link,
h3:hover .header-link,
h4:hover .header-link,
h5:hover .header-link,
h6:hover .header-link,
dt:hover .header-link {
@media screen {
.self-link {
display: unset;
}
}
h2:hover .self-link,
h3:hover .self-link,
h4:hover .self-link,
h5:hover .self-link,
h6:hover .self-link,
dt:hover .self-link {
transition: opacity .4s ease-in-out;
opacity: 1;
}
@media print {
.header-link {
display: none;
}
}
em {
font-style: italic;
}

View File

@ -0,0 +1,29 @@
.breadcrumbs {
text-transform: uppercase;
margin: 1.1em 0;
@media print {
display: none;
}
ol {
margin: 0;
padding: 0;
list-style: none;
}
li {
display: inline;
font-size: 80%;
margin: 0;
}
li + li::before {
display: inline-block;
margin: 0 0.55em;
transform: rotate(15deg);
border-right: 0.1em solid currentColor;
height: 0.8em;
content: '';
}
}

View File

@ -58,8 +58,10 @@
}
#switch-lang-container, #edit-this-page-container, #report-site-bugs-container {
@media print {
display: none;
display: none;
@media screen {
display: block;
}
#switch-lang, #edit-this-page, #report-site-bugs {

View File

@ -9,6 +9,10 @@ header {
left: 0;
z-index: $header-z;
@media print {
display: none;
}
#brand {
display: inline-block;
font-size: 1.25rem;

View File

@ -20,6 +20,11 @@
padding-left: .5rem;
padding-right: .5rem;
@media print {
padding-left: 0;
padding-right: 0;
}
@media screen AND (min-width: $bp-md) {
grid-template-columns: [sidebar] 20% [article] calc(80% - 1rem);
padding-left: 1rem;
@ -39,4 +44,10 @@
grid-template-columns: [sidebar] 16% [article] calc(84% - 1rem);
}
}
#see-also {
@media print {
display: none;
}
}
}

View File

@ -63,7 +63,7 @@
margin: 0;
display: none;
&.show {
&[aria-expanded=true] {
display: block;
}
}

View File

@ -1,12 +1,9 @@
.tabset {
border: none;
[role=tablist] {
margin: 0 0 0 4px;
padding: 0;
.tab-strip {
margin-bottom: -2px;
a {
button {
display: inline-block;
margin: 0 3px;
border: 1px solid $mainBrandColor;
@ -16,19 +13,18 @@
padding: 0 1rem;
transform: skewX(-30deg);
transform-origin: left bottom;
text-decoration: none;
cursor: pointer;
outline: 0;
font: inherit;
span {
display: block;
transform: skewX(10deg);
font-size: 80%;
color: $textColor;
font-size: 80%;
}
&:hover {
background-color: $textBrandHighlightColor;
text-decoration: none;
}
&.active {