Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Menu accessibility keyboard access using tab and screen reader #590

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
File renamed without changes.
4 changes: 4 additions & 0 deletions dist/spectre.css
Original file line number Diff line number Diff line change
Expand Up @@ -2422,6 +2422,10 @@ summary.accordion-header::-webkit-details-marker {
border-top-right-radius: .1rem;
}

[aria-haspopup="true"]:focus-within .menu {
display: block;
}

.empty {
background: #f7f8f9;
border-radius: .1rem;
Expand Down
2 changes: 1 addition & 1 deletion dist/spectre.min.css

Large diffs are not rendered by default.

24 changes: 12 additions & 12 deletions docs/components/menu.html
Original file line number Diff line number Diff line change
Expand Up @@ -271,18 +271,18 @@ <h3 class="s-title">Menu<a class="anchor" href="#menu" aria-hidden="true">#</a><
Spectre.css does not include JavaScript code, you will need to implement your JS to interact with the menus.
</p>
<p>Menus also have <a href="../elements/forms.html" target="_blank">Form controls</a> (checkbox, radio and checkbox) support.</p>
<pre class="code" data-lang="HTML"><code><span class="hljs-tag">&lt;<span class="hljs-name">ul</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"menu"</span>&gt;</span>
<pre class="code" data-lang="HTML"><code><span class="hljs-tag">&lt;<span class="hljs-name">ul</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"menu"</span> <span class="hljs-attr">role</span>=<span class="hljs-string">"menu"</span>&gt;</span>
<span class="hljs-comment">&lt;!-- menu header text --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"divider"</span> <span class="hljs-attr">data-content</span>=<span class="hljs-string">"LINKS"</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
<span class="hljs-comment">&lt;!-- menu item standard --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"menu-item"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"menu-item"</span> <span class="hljs-attr">role</span>=<span class="hljs-string">"menuitem"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">i</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"icon icon-link"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">i</span>&gt;</span> Slack
<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
<span class="hljs-comment">&lt;!-- menu item with form control --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"menu-item"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"menu-item"</span> <span class="hljs-attr">role</span>=<span class="hljs-string">"menuitem"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-checkbox"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"checkbox"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">i</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-icon"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">i</span>&gt;</span> form-checkbox
Expand All @@ -291,7 +291,7 @@ <h3 class="s-title">Menu<a class="anchor" href="#menu" aria-hidden="true">#</a><
<span class="hljs-comment">&lt;!-- menu divider --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"divider"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
<span class="hljs-comment">&lt;!-- menu item with badge --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"menu-item"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"menu-item"</span> <span class="hljs-attr">role</span>=<span class="hljs-string">"menuitem"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">i</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"icon icon-link"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">i</span>&gt;</span> Settings
<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
Expand All @@ -300,7 +300,7 @@ <h3 class="s-title">Menu<a class="anchor" href="#menu" aria-hidden="true">#</a><
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"menu-item"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"menu-item"</span> <span class="hljs-attr">role</span>=<span class="hljs-string">"menuitem"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#"</span>&gt;</span>My profile<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"menu-badge"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-checkbox"</span>&gt;</span>
Expand All @@ -315,7 +315,7 @@ <h4 class="s-subtitle" id="menu-dropdown">Dropdown menu<a class="anchor" href="#
<p>The dropdown is a combination of buttons and menus.</p>
<div class="docs-demo columns">
<div class="column col-xs-12">
<div class="dropdown">
<div class="dropdown" role="menu" aria-haspopup="true" aria-label="Dropdown menu example with button style">
<div class="btn-group"><a class="btn btn-primary">dropdown button</a><a class="btn btn-primary dropdown-toggle" tabindex="0"><i class="icon icon-caret"></i></a>
<ul class="menu">
<li class="menu-item"><a href="#dropdowns">Slack</a></li>
Expand All @@ -326,7 +326,7 @@ <h4 class="s-subtitle" id="menu-dropdown">Dropdown menu<a class="anchor" href="#
</div>
</div>
<div class="column col-xs-12">
<div class="dropdown"><a class="btn btn-link dropdown-toggle" tabindex="0">dropdown button <i class="icon icon-caret"></i></a>
<div class="dropdown" role="menu" aria-haspopup="true" aria-label="Dropdown menu example with link style"><a class="btn btn-link dropdown-toggle" tabindex="0">dropdown button <i class="icon icon-caret"></i></a>
<ul class="menu">
<li class="menu-item"><a href="#dropdowns">Slack</a></li>
<li class="menu-item"><a href="#dropdowns">Hipchat</a></li>
Expand All @@ -343,7 +343,7 @@ <h4 class="s-subtitle" id="menu-dropdown">Dropdown menu<a class="anchor" href="#
<p>If the dropdown is close to the right edge of the browser, you can add the <code>dropdown-right</code> class to the container to prevent it appearing off screen.</p>
<div class="docs-demo columns">
<div class="column col-xs-12 text-right">
<div class="dropdown dropdown-right"><a class="btn btn-primary dropdown-toggle" tabindex="0">dropdown button <i class="icon icon-caret"></i></a>
<div class="dropdown dropdown-right" role="menu" aria-haspopup="true" aria-label="Dropdown menu example positioned right"><a class="btn btn-primary dropdown-toggle" tabindex="0">dropdown button <i class="icon icon-caret"></i></a>
<ul class="menu text-left">
<li class="menu-item"><a href="#dropdowns">Slack</a></li>
<li class="menu-item"><a href="#dropdowns">Hipchat</a></li>
Expand All @@ -354,18 +354,18 @@ <h4 class="s-subtitle" id="menu-dropdown">Dropdown menu<a class="anchor" href="#
</div>
<p>Also, you can implement your JS to interact with the dropdown menus by adding the <code>active</code> class to the <code>dropdown</code> container.</p>
<pre class="code" data-lang="HTML"><code><span class="hljs-comment">&lt;!-- basic dropdown button --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"dropdown"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"dropdown"</span> <span class="hljs-attr">role</span>=<span class="hljs-string">"menu"</span> <span class="hljs-attr">aria-haspopup</span>=<span class="hljs-string">"true"</span> <span class="hljs-attr">aria-label</span>=<span class="hljs-string">"Dropdown menu example with button style"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"btn btn-link dropdown-toggle"</span> <span class="hljs-attr">tabindex</span>=<span class="hljs-string">"0"</span>&gt;</span>
dropdown menu <span class="hljs-tag">&lt;<span class="hljs-name">i</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"icon icon-caret"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">i</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
<span class="hljs-comment">&lt;!-- menu component --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">ul</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"menu"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">ul</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"menu"</span> <span class="hljs-attr">role</span>=<span class="hljs-string">"menu"</span>&gt;</span>
...
<span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>

<span class="hljs-comment">&lt;!-- dropdown button group --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"dropdown"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"dropdown"</span> <span class="hljs-attr">role</span>=<span class="hljs-string">"menu"</span> <span class="hljs-attr">aria-haspopup</span>=<span class="hljs-string">"true"</span> <span class="hljs-attr">aria-label</span>=<span class="hljs-string">"Dropdown menu example with link style"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"btn-group"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"btn"</span>&gt;</span>
dropdown button
Expand All @@ -375,7 +375,7 @@ <h4 class="s-subtitle" id="menu-dropdown">Dropdown menu<a class="anchor" href="#
<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>

<span class="hljs-comment">&lt;!-- menu component --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">ul</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"menu"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">ul</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"menu"</span> <span class="hljs-attr">role</span>=<span class="hljs-string">"menu"</span>&gt;</span>
...
<span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
Expand Down
4 changes: 4 additions & 0 deletions docs/dist/spectre-rtl.css
Original file line number Diff line number Diff line change
Expand Up @@ -2423,6 +2423,10 @@ summary.accordion-header::-webkit-details-marker {
border-top-right-radius: .1rem;
}

[aria-haspopup="true"]:focus-within .menu {
display: block;
}

.empty {
background: #f7f8f9;
border-radius: .1rem;
Expand Down
2 changes: 1 addition & 1 deletion docs/dist/spectre-rtl.min.css

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions docs/dist/spectre.css
Original file line number Diff line number Diff line change
Expand Up @@ -2422,6 +2422,10 @@ summary.accordion-header::-webkit-details-marker {
border-top-right-radius: .1rem;
}

[aria-haspopup="true"]:focus-within .menu {
display: block;
}

.empty {
background: #f7f8f9;
border-radius: .1rem;
Expand Down
2 changes: 1 addition & 1 deletion docs/dist/spectre.min.css

Large diffs are not rendered by default.

24 changes: 12 additions & 12 deletions docs/src/components/menu.pug
Original file line number Diff line number Diff line change
Expand Up @@ -76,18 +76,18 @@ block docs-content
pre.code(data-lang='HTML')
code
:highlight(lang="html")
<ul class="menu">
<ul class="menu" role="menu">
<!-- menu header text -->
<li class="divider" data-content="LINKS">
</li>
<!-- menu item standard -->
<li class="menu-item">
<li class="menu-item" role="menuitem">
<a href="#">
<i class="icon icon-link"></i> Slack
</a>
</li>
<!-- menu item with form control -->
<li class="menu-item">
<li class="menu-item" role="menuitem">
<label class="form-checkbox">
<input type="checkbox">
<i class="form-icon"></i> form-checkbox
Expand All @@ -96,7 +96,7 @@ block docs-content
<!-- menu divider -->
<li class="divider"></li>
<!-- menu item with badge -->
<li class="menu-item">
<li class="menu-item" role="menuitem">
<a href="#">
<i class="icon icon-link"></i> Settings
</a>
Expand All @@ -105,7 +105,7 @@ block docs-content
</div>
</li>

<li class="menu-item">
<li class="menu-item" role="menuitem">
<a href="#">My profile</a>
<div class="menu-badge">
<label class="form-checkbox">
Expand All @@ -122,7 +122,7 @@ block docs-content

.docs-demo.columns
.column.col-xs-12
.dropdown
.dropdown(role="menu" aria-haspopup="true" aria-label="Dropdown menu example with button style")
.btn-group
a.btn.btn-primary dropdown button
a.btn.btn-primary.dropdown-toggle(tabindex="0")
Expand All @@ -138,7 +138,7 @@ block docs-content
a(href="#dropdowns")
| Skype
.column.col-xs-12
.dropdown
.dropdown(role="menu" aria-haspopup="true" aria-label="Dropdown menu example with link style")
a.btn.btn-link.dropdown-toggle(tabindex="0")
| dropdown button
i.icon.icon-caret
Expand All @@ -164,7 +164,7 @@ block docs-content

.docs-demo.columns
.column.col-xs-12.text-right
.dropdown.dropdown-right
.dropdown.dropdown-right(role="menu" aria-haspopup="true" aria-label="Dropdown menu example positioned right")
a.btn.btn-primary.dropdown-toggle(tabindex="0")
| dropdown button
i.icon.icon-caret
Expand All @@ -183,18 +183,18 @@ block docs-content
code
:highlight(lang="html")
<!-- basic dropdown button -->
<div class="dropdown">
<div class="dropdown" role="menu" aria-haspopup="true" aria-label="Dropdown menu example with button style">
<a href="#" class="btn btn-link dropdown-toggle" tabindex="0">
dropdown menu <i class="icon icon-caret"></i>
</a>
<!-- menu component -->
<ul class="menu">
<ul class="menu" role="menu">
...
</ul>
</div>

<!-- dropdown button group -->
<div class="dropdown">
<div class="dropdown" role="menu" aria-haspopup="true" aria-label="Dropdown menu example with link style">
<div class="btn-group">
<a href="#" class="btn">
dropdown button
Expand All @@ -204,7 +204,7 @@ block docs-content
</a>

<!-- menu component -->
<ul class="menu">
<ul class="menu" role="menu">
...
</ul>
</div>
Expand Down
Loading