Skip to content

Commit

Permalink
Consistent focus ring (first pass) (#1549)
Browse files Browse the repository at this point in the history
* wip

* Style focus state in header nav

* update focus ring style on all focussable elements

* simplify

* fix links in mobile sidebar overlay

* put focus rings around a few more focusable elements

* polish

* update comment

* review

* better align focus ring on collapsible admonitions

* comment and simplify sphinx-togglebutton focus ring

* make css override more explicit

* Fix SD link-card focus ring and on homepage, bring links inside card

* Update docs/index.md

---------

Co-authored-by: Daniel McCloy <dan@mccloy.info>
  • Loading branch information
gabalafou and drammock committed Dec 8, 2023
1 parent 5e53589 commit 8495ba4
Show file tree
Hide file tree
Showing 17 changed files with 177 additions and 48 deletions.
2 changes: 1 addition & 1 deletion docs/examples/gallery.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ Thanks for your support!
link: https://fairlearn.org/main/about/
- title: Feature-engine
link: https://feature-engine.readthedocs.io/
- title: idtracker.ai
- title: idtracker&period;ai
link: https://idtracker.ai/
- title: MegEngine
link: https://www.megengine.org.cn/doc/stable/en/index.html
Expand Down
8 changes: 3 additions & 5 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,11 @@ A clean, Bootstrap-based Sphinx theme by and for [the PyData community](https://
- header: "{fas}`circle-half-stroke;pst-color-primary` Light / Dark theme"
content: "Users can toggle between light and dark themes interactively."
- header: "{fas}`palette;pst-color-primary` Customizable UI and themes"
content: "Customize colors and branding with CSS variables, and build custom UIs with [Sphinx Design](user_guide/web-components)."
content: "Customize colors and branding with CSS variables, and build custom UIs with [Sphinx Design components](user_guide/web-components)."
- header: "{fab}`python;pst-color-primary` Supports PyData and Jupyter"
content: "CSS and UI support for Jupyter extensions and PyData execution outputs."
link: "examples/pydata.html"
content: "CSS and UI support for [Jupyter extensions](examples/execution) and [PyData execution outputs](examples/pydata.ipynb)."
- header: "{fas}`lightbulb;pst-color-primary` Example Gallery"
content: "See our gallery of projects that use this theme."
link: "examples/gallery.html"
content: "See [our gallery](examples/gallery.md) of projects that use this theme."
```

```{seealso}
Expand Down
15 changes: 2 additions & 13 deletions src/pydata_sphinx_theme/assets/styles/abstracts/_links.scss
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,6 @@ $link-hover-decoration-thickness: unquote("max(3px, .1875rem, .12em)") !default;
color: var(--pst-color-link-hover);
}
}
@include focus-indicator;
}

// Text link styles
Expand All @@ -102,7 +101,6 @@ $link-hover-decoration-thickness: unquote("max(3px, .1875rem, .12em)") !default;
@include link-decoration;
@include link-decoration-hover;
}
@include focus-indicator;
}

// Sidebar and TOC links
Expand Down Expand Up @@ -137,10 +135,8 @@ $link-hover-decoration-thickness: unquote("max(3px, .1875rem, .12em)") !default;
font-weight: 600;
color: var(--pst-color-primary);
@if $link-hover-decoration-thickness {
box-shadow: inset
$link-hover-decoration-thickness
0px
0px
border-left: $link-hover-decoration-thickness
solid
var(--pst-color-primary);
}
}
Expand Down Expand Up @@ -175,10 +171,3 @@ $link-hover-decoration-thickness: unquote("max(3px, .1875rem, .12em)") !default;
}
}
}

// Focus indicator
@mixin focus-indicator {
&:focus-visible {
outline: 2px solid var(--pst-color-accent);
}
}
10 changes: 10 additions & 0 deletions src/pydata_sphinx_theme/assets/styles/base/_base.scss
Original file line number Diff line number Diff line change
Expand Up @@ -179,3 +179,13 @@ pre {
background-color: var(--pst-color-secondary);
border: none;
}

// Focus ring
//
// Note: The Bootstrap stylesheet provides the focus ring (customized via Sass
// variables in _bootstrap.scss) in some cases. This rules covers all other
// cases.
:focus-visible {
outline: $focus-ring-outline;
box-shadow: none; // override Bootstrap
}
19 changes: 12 additions & 7 deletions src/pydata_sphinx_theme/assets/styles/components/_search.scss
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,6 @@
&:focus,
&:focus-visible {
border: none;
box-shadow: none;
outline: 3px solid var(--pst-color-accent);
background-color: var(--pst-color-background);
color: var(--pst-color-text-muted);
}
Expand All @@ -75,11 +73,16 @@
align-items: center;
align-content: center;
color: var(--pst-color-text-muted);
// Needed to match other icons hover
padding: 0 0 0.25rem 0;
border-radius: 0;
border: none; // Override Bootstrap button border
font-size: 1rem; // Override Bootstrap button font size

// Override Bootstrap button padding-x. Whitespace in nav bar is controlled
// via column gap rule on the container.
padding-left: 0;
padding-right: 0;

@include icon-navbar-hover;
@include focus-indicator;

i {
font-size: 1.3rem;
Expand Down Expand Up @@ -136,19 +139,21 @@
* Lives at components/search-button-field.html
*/
.search-button-field {
$search-button-border-radius: 1.5em;
display: inline-flex;
align-items: center;
border: var(--pst-color-border) solid 1px;
border-radius: 1.5em;
border-radius: $search-button-border-radius;
color: var(--pst-color-text-muted);
padding: 0.5em;
background-color: var(--pst-color-surface);

&:hover {
border: 2px solid var(--pst-color-link-hover);
}

&:focus-visible {
border: 2px solid var(--pst-color-accent);
border-radius: $search-button-border-radius;
}

// The keyboard shotcut text
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,23 @@
*/

.theme-switch-button {
// overide bootstrap settings
margin: 0 -0.5rem;
padding: 0; // We pad the `span` not the container
color: var(--pst-color-text-muted);
border-radius: 0;
@include focus-indicator;
border: none; // Override Bootstrap button border
font-size: 1rem; // Override Bootstrap's button font size

// Override Bootstrap button padding-x. Whitespace in nav bar is controlled
// via column gap rule on the container.
padding-left: 0;
padding-right: 0;

&:hover {
@include icon-navbar-hover;
}

span {
display: none;
padding: 0.5em;

@include icon-navbar-hover;
&:active {
text-decoration: none;
color: var(--pst-color-link-hover);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ button.btn.version-switcher__button {
}

@include link-style-hover;
@include focus-indicator;
&:active {
color: var(--pst-color-text-base);
border-color: var(--pst-color-border);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,8 @@ nav.page-toc {
}
}
}

:focus-visible {
border-radius: 0.125rem;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@
* Admonitions CSS originally inspired by https://squidfunk.github.io/mkdocs-material/getting-started/
*/
$admonition-border-radius: 0.25rem;
$admonition-left-border-width: 0.2rem;
div.admonition,
.admonition {
margin: 1.5625em auto;
padding: 0 0.6rem 0.8rem 0.6rem;
overflow: hidden;
page-break-inside: avoid;
border-left: 0.2rem solid;
border-left: $admonition-left-border-width solid;
border-color: var(--pst-color-info);
border-radius: $admonition-border-radius;
background-color: var(--pst-color-on-background);
Expand Down Expand Up @@ -205,7 +206,7 @@ div.admonition,
margin-top: 0;

// Undo the .sidebar directive border
border-width: 0 0 0 0.2rem;
border-width: 0 0 0 $admonition-left-border-width;

// TODO: these semantic-color-names border-color rules might no longer be
// needed when we drop support for Sphinx 4 / docutils 0.17
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,13 @@ div.highlight button.copybtn {
color: var(--pst-color-text);
background-color: var(--pst-color-surface);
}

&:focus {
// For keyboard users, make the copy button visible when focussed.
opacity: 1;
}

&:focus-visible {
outline: $focus-ring-outline;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,22 @@ html[data-theme="light"] {
.sd-card-body {
background-color: var(--pst-color-panel-background);
}

// Focus ring for link-cards
.sd-stretched-link:focus-visible {
// Don't put the focus ring on the <a> element (it has zero height in Sphinx Design cards)
outline: none;

// Put the focus ring on the <a> element's ::after pseudo-element
&:after {
outline: $focus-ring-outline;
border-radius: 0.25rem; // copied from Sphinx Design CSS for .sd-card
}
}

&.sd-card-hover:hover {
border-color: var(--pst-color-link-hover);
}
}
/*******************************************************************************
* tabs
Expand Down Expand Up @@ -255,5 +271,11 @@ details.sd-dropdown {
.sd-summary-down {
top: 0.7rem;
}

// Focus ring
&:focus-visible {
outline: $focus-ring-outline;
outline-offset: -$focus-ring-width;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,43 @@
button.toggle-button {
color: inherit;
}

// Focus ring
//
// Sphinx-togglebutton makes the entire admonition header clickable, but
// only the button within the header is focusable. We want the entire
// clickable area to be surrounded with a focus ring, so that's why we use
// the :focus-within selector, rather than a :focus-visible selector on the
// button.
&:focus-within {
overflow: visible;

// The complicated focus ring styles here are a consequence of the markup
// and border styles for this particular admonition class. (For the other
// type of admonition on this site, the focus ring style is achieved with
// simple `outline` and `outline-offset` rules on the admonition's
// header.) The problem is that Sphinx-togglebutton puts the admonition's
// left border on the outermost container (rather than separately setting
// the left border on the container's children). This makes it complicated
// to get the focus ring to simultaneously cover the left border in the
// header and align perfectly on the right with the body.
.admonition-title:focus-within:before {
content: "";
transform: translateX(
-$admonition-left-border-width
); // align left edges of admonition and ring
width: calc(100% + $admonition-left-border-width); // align right edges
height: 100%;
border: $focus-ring-outline;
border-radius: $focus-ring-width;
}

// When expanded, sharpen the bottom left and right corners of the focus ring
&:not(.toggle-hidden) .admonition-title:focus-within:before {
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
}
}

// Details buttons
Expand All @@ -16,5 +53,11 @@
summary {
border-left: 3px solid var(--pst-color-primary);
}

// When expanded, sharpen the bottom left and right corners of the focus ring
&[open] :focus-visible {
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
}
}
6 changes: 4 additions & 2 deletions src/pydata_sphinx_theme/assets/styles/sections/_header.scss
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@
padding-right: 1rem;
}

:focus-visible {
border-radius: 0.125rem;
}

// These items will define the height of the header
.navbar-item {
height: var(--pst-header-height);
Expand Down Expand Up @@ -99,7 +103,6 @@
color: var(--pst-color-text-muted);
border: none;
@include link-style-hover;
@include focus-indicator;
}

.dropdown-menu {
Expand Down Expand Up @@ -190,7 +193,6 @@
}
}
@include icon-navbar-hover;
@include focus-indicator;
}

// Hide the navbar header items on mobile because they're in the sidebar
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@
font-size: var(--pst-sidebar-font-size);
}

// Focus styles
:focus-visible {
border-radius: 0.125rem;
}

// override bootstrap when navlink are displayed in the sidebar
.nav-link {
font-size: var(--pst-sidebar-font-size-mobile);
Expand Down Expand Up @@ -80,6 +85,26 @@
border: none;
background-color: inherit;
font-size: inherit;

.dropdown-item {
&:hover,
&:focus {
// In the mobile sidebar, the dropdown menu is inlined with the
// other links, which do not have background-color changes on hover
// and focus
background-color: unset;
}
}
}
}

.bd-navbar-elements {
.nav-link {
&:focus-visible {
box-shadow: none; // Override Bootstrap
outline: $focus-ring-outline;
outline-offset: $focus-ring-width;
}
}
}

Expand All @@ -93,7 +118,7 @@
.sidebar-header-items__end {
display: flex;
align-items: center;
gap: 0.5rem;
gap: 1rem;
}

@include media-breakpoint-up($breakpoint-sidebar-primary) {
Expand Down Expand Up @@ -171,8 +196,6 @@

/* Between-page links and captions */
nav.bd-links {
margin-right: -1rem;

@include media-breakpoint-up($breakpoint-sidebar-primary) {
display: block;
}
Expand Down
Loading

0 comments on commit 8495ba4

Please sign in to comment.