@@ -164,114 +164,59 @@ $link-hover-decoration-thickness: string.unquote(
164
164
}
165
165
}
166
166
167
- // Navigation bar current page link styles
168
- // ---------------------------------------
169
- // Adds a bottom underline, this leaves enough space for the hover state without
170
- // cluttering the navbar.
171
- // We want the side box shadow to have the same thickness as the hover underline
172
- @mixin link-navbar-current {
173
- font-weight : 600 ;
174
- color : var (--pst-color-primary );
167
+ // Heaver navbar text and icon links
168
+ // ---------------------------------
169
+ // (includes light/dark mode button)
170
+
171
+ // This mixin makes it possible to show hover/underline and focus/ring styles at
172
+ // the same time. The trick is to use:
173
+ // - a pseudo-element with bottom border for the hover underline
174
+ // - a CSS outline for the focus ring.
175
+
176
+ // Normally we use box-shadow for underline and outline for focus ring. But we
177
+ // cannot apply box-shadow and outline together on the same element because the
178
+ // border-radius value that we use to round the outline will also round the
179
+ // box-shadow used for the underline. We also cannot use text-underline because
180
+ // it does not work on non-text links, nor do we want to use it on text links
181
+ // that we want to treat as blocks, such as the header nav links because the
182
+ // underline will wrap across two lines if the link text also wraps across two
183
+ // lines.
184
+ @mixin link-style-block {
185
+ color : var (--pst-color-text-muted );
175
186
176
- @if $link-hover-decoration-thickness {
177
- border-bottom : $link-hover-decoration-thickness
178
- solid
179
- var (--pst-color-primary );
180
- }
181
- }
187
+ // Set position relative so that the child ::before pseudo-element's absolute
188
+ // position is relative to this element.
189
+ position : relative ;
182
190
183
- // Navigation bar icon links hover styles
184
- // --------------------------------------
185
- // Adds a bottom box-shadow - since there is no text we cannot use text-decoration
186
- // We want the side box shadow to have the same thickness as the hover underline
187
- @mixin icon-navbar-hover {
188
- & :hover {
189
- color : var ( --pst-color-link-hover ) ;
191
+ // Set up pseudo-element used for hover underline styles
192
+ & ::before {
193
+ content : " " ;
194
+ display : block ;
195
+ position : absolute ;
196
+ inset : 0 ;
197
+ background- color : transparent ;
190
198
191
199
@if $link-hover-decoration-thickness {
192
- box-shadow : 0
193
- $link-hover-decoration-thickness
194
- 0
195
- var (--pst-color-link-hover );
200
+ bottom : calc (-1 * $link-hover-decoration-thickness );
201
+ margin : $link-hover-decoration-thickness 0 ;
196
202
}
197
203
}
198
- }
199
-
200
- // Mixin for links in the header (and the More dropdown toggle).
201
-
202
- // The mixin assumes it will be applied to some element X with a markup structure
203
- // like: X > .nav-link, or X > .dropdown-toggle.
204
-
205
- // It also assumes X.current is how the app annotates which item in the header nav
206
- // corresponds to the section in the docs that the user is currently reading.
207
- @mixin header-link {
208
- // Target the child and not the parent because we want the underline in the
209
- // mobile sidebar to only span the width of the text not the entire row/line.
210
- > .nav-link ,
211
- > .dropdown-toggle {
212
- border-radius : 2px ;
213
- color : var (--pst-color-text-muted );
214
- }
215
-
216
- > .nav-link {
217
- // Set up pseudo-element for hover and current states below.
218
- position : relative ;
219
204
205
+ & :hover {
206
+ color : var (--pst-color-secondary );
207
+ text-decoration : none ; // override the link-style-hover mixin
220
208
& ::before {
221
- content : " " ;
222
- display : block ;
223
- position : absolute ;
224
- inset : 0 ;
225
- background-color : transparent ;
226
- }
227
-
228
- // Underline on hover.
229
- // - Don't use text-decoration because it will wrap across two lines if
230
- // the link text also wraps across two lines.
231
- // - Use pseudo-element in order to avoid the border-radius values
232
- // rounding the edges of the underline. (And since a header link can be
233
- // both focused and hovered at the same time and we want the focus ring
234
- // but not the underline to be rounded, we cannot use a box shadow or
235
- // bottom border link element to create the underline, or else it will
236
- // be rounded and if we apply border-radius 0 then the hovered focus
237
- // ring would go from rounded to sharp. So we have to use the
238
- // pseudo-element.)
239
- & :hover {
240
- color : var (--pst-color-secondary );
241
- text-decoration : none ; // override the link-style-hover mixin
242
- & ::before {
243
- border-bottom : 3px solid var (--pst-color-secondary );
209
+ @if $link-hover-decoration-thickness {
210
+ border-bottom : $link-hover-decoration-thickness
211
+ solid
212
+ var (--pst-color-secondary );
244
213
}
245
214
}
246
-
247
- & :focus-visible {
248
- box-shadow : none ; // override Bootstrap
249
- outline : 3px solid var (--pst-color-accent );
250
- outline-offset : 3px ;
251
- }
252
- }
253
-
254
- > .dropdown-toggle {
255
- & :focus-visible {
256
- box-shadow : $focus-ring-box-shadow ;
257
- }
258
-
259
- & :hover {
260
- text-decoration : none ;
261
- box-shadow : 0 0 0 $focus-ring-width var (--pst-color-link-hover ); // purple focus ring
262
- // Brighten the text on hover (muted -> base)
263
- color : var (--pst-color-text-base );
264
- }
265
215
}
266
216
267
- & .current {
268
- > .nav-link {
269
- color : var (--pst-color-primary );
270
-
271
- // Underline the current navbar item
272
- & ::before {
273
- border-bottom : 3px solid var (--pst-color-primary );
274
- }
275
- }
217
+ & :focus-visible {
218
+ box-shadow : none ; // override Bootstrap
219
+ outline : 3px solid var (--pst-color-accent );
220
+ outline-offset : 3px ;
276
221
}
277
222
}
0 commit comments