Skip to content

Commit eac03c9

Browse files
committed
Match Sphinx toggle button and Sphinx Design hover and focus styles
1 parent 25e01e2 commit eac03c9

File tree

3 files changed

+84
-26
lines changed

3 files changed

+84
-26
lines changed

src/pydata_sphinx_theme/assets/styles/abstracts/_mixins.scss

+12
Original file line numberDiff line numberDiff line change
@@ -68,3 +68,15 @@
6868
min-width: 24px;
6969
min-height: 24px;
7070
}
71+
72+
// Meant to darken the element on hover in light mode, or
73+
// lighten on hover in dark mode.
74+
@mixin hover-darken-lighten {
75+
&:hover {
76+
filter: brightness(0.9);
77+
78+
html[data-theme="dark"] & {
79+
filter: brightness(1.1);
80+
}
81+
}
82+
}

src/pydata_sphinx_theme/assets/styles/extensions/_sphinx_design.scss

+4-2
Original file line numberDiff line numberDiff line change
@@ -322,10 +322,12 @@ details.sd-dropdown {
322322
top: 0.7rem;
323323
}
324324

325+
@include hover-darken-lighten;
326+
325327
// Focus ring
326-
&:focus-visible {
328+
&:focus:focus-visible {
327329
outline: $focus-ring-outline;
328-
outline-offset: -$focus-ring-width;
330+
outline-offset: $focus-ring-width;
329331
}
330332
}
331333
}

src/pydata_sphinx_theme/assets/styles/extensions/_togglebutton.scss

+68-24
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
/**
22
* Sphinx togglebutton
3+
*
4+
* The rules in this style sheet are meant to tweak the
5+
* [sphinx-togglebutton](https://sphinx-togglebutton.readthedocs.io/en/latest/index.html)
6+
* extension so that it matches the look and feel of this theme.
37
*/
48

59
.bd-content {
@@ -17,8 +21,27 @@
1721
}
1822
}
1923

20-
// Admonition toggles
21-
.admonition {
24+
// Apply this mixin to the element that will be hovered. These styles are
25+
// intended to match what sphinx-design does for its dropdown admonitions.
26+
@mixin icon-hover-effects {
27+
&:hover .tb-icon {
28+
opacity: 1;
29+
scale: 1.1;
30+
}
31+
32+
.tb-icon {
33+
opacity: 0.6;
34+
}
35+
}
36+
37+
// Collapsible admonition, implemented as <div> + <button>
38+
.dropdown.admonition.toggle {
39+
// The title is visible when the admonition is collapsed and expanded
40+
.admonition-title {
41+
@include icon-hover-effects;
42+
@include hover-darken-lighten;
43+
}
44+
2245
button.toggle-button {
2346
color: inherit;
2447

@@ -34,49 +57,70 @@
3457
// Focus ring
3558
// ----------
3659
// Sphinx-togglebutton makes the entire admonition header clickable, but
37-
// only the button within the header is focusable. We want the entire
38-
// clickable area to be surrounded with a focus ring, so that's why we use
39-
// the :focus-within selector, rather than a :focus-visible selector on the
40-
// button.
41-
&:focus-within {
60+
// only the button within the header is focusable. But we want the entire
61+
// header and not just the button inside the header to be surrounded by a
62+
// a focus ring.
63+
&:has(:focus-visible) {
4264
overflow: visible;
4365

44-
// The complicated focus ring styles here are a consequence of the markup
45-
// and border styles for this particular admonition class. (For the other
46-
// type of admonition on this site, the focus ring style is achieved with
47-
// simple `outline` and `outline-offset` rules on the admonition's
48-
// header.) The problem is that Sphinx-togglebutton puts the admonition's
49-
// left border on the outermost container (rather than separately setting
50-
// the left border on the container's children). This makes it complicated
51-
// to get the focus ring to simultaneously cover the left border in the
52-
// header and align perfectly on the right with the body.
53-
.admonition-title:focus-within::before {
66+
/*
67+
Why not just do the following?
68+
69+
```
70+
.admonition-title {
71+
outline: $focus-ring-outline;
72+
}
73+
```
74+
75+
Why use ::before? If we put the focus ring on the ::before pseudo-element,
76+
we can reposition the focus ring by repositioning the pseudo-element.
77+
78+
Why reposition? The left edge of the admonition title box does not align
79+
with the left edge of the overall admonition box. There is a left border
80+
that belongs to the overall box. The border is outside of the admonition
81+
title, which means it is also outside of a focus ring around the title. We
82+
can make the focus ring bigger, with `outline-offset`, but this will
83+
result in a ring that looks off-centered. So we have to pull the ring left
84+
and stretch it right. That's what the pseudo-element allows us to do.
85+
86+
We do not have to do this with the other collapsible admonitions because
87+
those implementations put the left border and the title together so that a
88+
focus ring surrounds them both.
89+
*/
90+
.admonition-title::before {
5491
content: "";
55-
transform: translateX(
56-
-$admonition-left-border-width
57-
); // align left edges of admonition and ring
5892

59-
width: calc(100% + $admonition-left-border-width); // align right edges
93+
// pull the focus ring left and expand it right to be perfectly centered
94+
// between the left border and the right edge of the admonition title
95+
left: -$admonition-left-border-width;
96+
width: calc(100% + $admonition-left-border-width);
6097
height: 100%;
61-
border: $focus-ring-outline;
98+
outline: $focus-ring-outline;
99+
outline-offset: $focus-ring-width;
62100
border-radius: $focus-ring-width;
63101
}
64102

65103
// When expanded, sharpen the bottom left and right corners of the focus ring
66-
&:not(.toggle-hidden) .admonition-title:focus-within::before {
104+
&:not(.toggle-hidden) .admonition-title::before {
67105
border-bottom-left-radius: 0;
68106
border-bottom-right-radius: 0;
69107
}
70108
}
71109
}
72110

73-
// Details buttons
111+
// Collapsible component, implemented as <details> + <summary>
74112
details.toggle-details {
75113
// Over-ride border color to re-use our primary color
76114
summary {
77115
border-left: 3px solid var(--pst-color-primary);
78116

79117
@include chevron-down;
118+
@include icon-hover-effects;
119+
@include hover-darken-lighten;
120+
121+
&:focus-visible {
122+
outline-offset: $focus-ring-width;
123+
}
80124
}
81125

82126
// When expanded, sharpen the bottom left and right corners of the focus ring

0 commit comments

Comments
 (0)