aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorGeoffrey B. Eisenbarth <geoffrey-eisenbarth@users.noreply.github.com>2025-07-12 14:24:43 -0500
committerGitHub <noreply@github.com>2025-07-12 14:24:43 -0500
commit21da7467229b216cace748572db734390c398d6e (patch)
tree5118a417d8bd5b6fa021b9d7f10e231aaa7021e7
parent973ae69c45c364241e5a58ca0b15b123ad8343dd (diff)
parentcee6da722f7ffc509dd5513527c3652eaa202b22 (diff)
downloadmissing-dev.tar.gz
missing-dev.zip
Merge pull request #119 from geoffrey-eisenbarth/devHEADdev
Style scrollbars, fix tab color, and add meter / progress elements
-rw-r--r--src/aria.css4
-rw-r--r--src/components.css30
-rw-r--r--src/core/sanitize.css2
-rw-r--r--src/layout.css14
-rw-r--r--src/main.css190
-rw-r--r--src/utils.css6
-rw-r--r--www/demos/meter.html89
-rw-r--r--www/docs/20-forms.md147
-rw-r--r--www/docs/30-components.md8
-rw-r--r--www/docs/70-layout.md22
-rw-r--r--www/docs/B0-js.md2
-rw-r--r--www/js/pagefind.js4
12 files changed, 473 insertions, 45 deletions
diff --git a/src/aria.css b/src/aria.css
index 126fb67..6aa708b 100644
--- a/src/aria.css
+++ b/src/aria.css
@@ -2,11 +2,11 @@
[role="tablist"] {
display: flex;
gap: .5ch;
- scrollbar-width: thin;
}
-[role="tab"][role="tab"] {
+[role="tab"]:not([specificity-hack]) {
all: initial;
+ color-scheme: light dark;
font-family: var(--secondary-font);
diff --git a/src/components.css b/src/components.css
index 3dd1833..dca9a39 100644
--- a/src/components.css
+++ b/src/components.css
@@ -20,19 +20,27 @@ details,
}
.titlebar {
- margin-inline: calc(0px - var(--gap));
- margin-block-end: calc(0px - var(--gap));
- padding-inline: var(--gap);
+ display: block;
- font: inherit;
+ margin-inline: calc(0px - var(--gap));
+ margin-block-end: var(--gap);
+ padding-inline: var(--gap);
+
+ font: inherit;
font-family: var(--secondary-font);
- font-weight: bold;
-
- translate: 0 calc(0px - var(--gap));
-
- background: var(--graphical-fg);
- color: var(--bg);
+ font-weight: bold;
+
+ background: var(--graphical-fg);
+ color: var(--bg);
text-shadow: 0 .1em .2em var(--fg);
+ overflow-y: clip;
+
+ & a {
+ color: var(--bg);
+ }
+}
+:is(.box, dialog):has( > .titlebar ) {
+ padding-block-start: 0;
}
.sub-title, sub-title {
@@ -91,6 +99,7 @@ details,
& > :nth-child(2) {
overflow: auto;
+ scrollbar-width: auto;
--full-width: calc(100vw - 25ch);
padding-top: var(--gap);
}
@@ -146,7 +155,6 @@ details,
border-block-end: var(--border-block-end-width) var(--border-block-end-style) var(--accent);
overflow-x: auto;
- scrollbar-width: thin;
position: sticky;
z-index: 5;
diff --git a/src/core/sanitize.css b/src/core/sanitize.css
index 9906d65..bb7ba5c 100644
--- a/src/core/sanitize.css
+++ b/src/core/sanitize.css
@@ -199,7 +199,7 @@ textarea {
:focus-visible {
outline: .2em solid var(--accent);
- z-index: 32;
+ z-index: 2;
}
iframe:focus-visible,
diff --git a/src/layout.css b/src/layout.css
index d45f685..22b36cc 100644
--- a/src/layout.css
+++ b/src/layout.css
@@ -228,10 +228,10 @@
.float\:left { float: left }
.float\:right { float: right }
-.overflow\:auto { overflow: auto }
-.overflow\:scroll { overflow: scroll }
-.overflow-x\:scroll { overflow-x: scroll }
-.overflow-y\:scroll { overflow-y: scroll }
-.overflow\:clip { overflow: clip }
-.overflow-x\:clip { overflow-x: clip }
-.overflow-y\:clip { overflow-y: clip }
+.overflow\:auto { overflow: auto; }
+.overflow\:scroll { overflow: scroll; }
+.overflow-x\:scroll { overflow-x: scroll; }
+.overflow-y\:scroll { overflow-y: scroll; }
+.overflow\:clip { overflow: clip; }
+.overflow-x\:clip { overflow-x: clip; }
+.overflow-y\:clip { overflow-y: clip; }
diff --git a/src/main.css b/src/main.css
index 1ccb036..9ad33de 100644
--- a/src/main.css
+++ b/src/main.css
@@ -13,7 +13,19 @@ html {
background: var(--bg);
color: var(--fg);
+
scroll-padding-block-start: calc(4 * var(--gap));
+ @supports selector(::-webkit-scrollbar-thumb) {
+ ::-webkit-scrollbar-thumb { background-color: var(--accent); }
+ ::-webkit-scrollbar-track { background-color: transparent; }
+ }
+ @supports (scrollbar-color: gray transparent) {
+ scrollbar-color: var(--accent) transparent;
+ }
+}
+html, body {
+ scrollbar-width: auto;
+ & * { scrollbar-width: thin; }
}
body {
@@ -172,7 +184,7 @@ hr {
color: inherit;
margin-inline: 0;
margin-block: var(--gap);
-
+
flex: 0 1 0px;
border-inline-start: var(--border-inline-start-width) var(--border-inline-start-style) var(--accent);
block-size: auto;
@@ -190,15 +202,13 @@ pre {
margin: var(--gap) 0;
overflow-x: auto;
- scrollbar-width: thin;
- scrollbar-color: var(--accent) transparent;
}
blockquote {
margin-inline: 0 var(--gap);
padding-inline: var(--gap) 0;
margin-block: var(--gap);
-
+
font-size: 1.1em;
line-height: var(--rhythm, 1rlh);
font-style: italic;
@@ -473,7 +483,7 @@ tr {
td, th {
vertical-align: top;
-
+
&:not(:last-child) {
padding-inline-end: var(--rhythm, 1rlh);
}
@@ -700,7 +710,7 @@ select,
textarea {
padding: calc(var(--rhythm, 1rlh) / 4);
vertical-align: top;
-
+
font-size: 1rem;
line-height: inherit;
font-family: var(--main-font);
@@ -756,12 +766,168 @@ optgroup::before {
font-style: normal;
}
-progress {
- /* TODO */
+meter, progress {
+ --border-width: var(--interactive-border-width);
+ --border-style: var(--interactive-border-style);
+ --border-radius: var(--tab-border-radius);
+
+ @supports (
+ selector(::-moz-meter-bar) or
+ selector(::-webkit-meter-bar) or
+ selector(::-moz-progress-bar) or
+ selector(::-webkit-progress-bar)
+ ) {
+ appearance: none;
+
+ box-sizing: border-box;
+ display: inline-block;
+ position: relative;
+
+ background: var(--box-bg);
+ border: var(--border-width) var(--border-style) var(--graphical-fg);
+ border-radius: var(--border-radius);
+
+ overflow: clip;
+ block-size: 1em;
+ inline-size: unset;
+ min-inline-size: 5em; /* cf: -webkit UA */
+ vertical-align: -0.2em; /* cf: -moz and -webkit UA */
+
+ transition: all .1s ease-in-out;
+ }
}
meter {
- /* TODO */
+ @supports selector(::-webkit-meter-bar) {
+ &::-webkit-meter-inner-element {
+ /* Wrapper element */
+ grid-template-rows: unset;
+ }
+
+ &::-webkit-meter-bar {
+ /* Outer bar */
+ background: var(--box-bg);
+ border-radius: 0;
+ }
+
+ &::-webkit-meter-even-less-good-value,
+ &::-webkit-meter-suboptimum-value,
+ &::-webkit-meter-optimum-value {
+ /* Inner bar */
+ background: var(--accent);
+ border-radius: 0;
+ }
+
+ /* Partial colorway support */
+ background: var(--plain-bg);
+ border-color: var(--interactive-bg);
+ &::-webkit-meter-optimum-value {
+ --accent: var(--ok-fg);
+ }
+ &::-webkit-meter-suboptimum-value {
+ --accent: var(--warn-fg);
+ }
+ &::-webkit-meter-even-less-good-value {
+ --accent: var(--bad-fg);
+ }
+ }
+ @supports selector(::-moz-meter-bar) {
+ /* Pseudo-classes allow us to fully implement colorways */
+ background: var(--box-bg);
+ border-color: var(--graphical-fg);
+
+ &::-moz-meter-bar {
+ /* Inner bar */
+ background: var(--accent);
+ border-radius: 0;
+ }
+ &:-moz-meter-optimum {
+ --box-bg: var(--ok-bg);
+ --accent: var(--ok-fg);
+ --graphical-fg: var(--ok-graphical-fg);
+ }
+ &:-moz-meter-sub-optimum {
+ --box-bg: var(--warn-bg);
+ --accent: var(--warn-fg);
+ --graphical-fg: var(--warn-graphical-fg);
+ }
+ &:-moz-meter-sub-sub-optimum {
+ --box-bg: var(--bad-bg);
+ --accent: var(--bad-fg);
+ --graphical-fg: var(--bad-graphical-fg);
+ }
+ }
+}
+
+progress {
+ @supports selector(::-moz-progress-bar) {
+ &::-moz-progress-bar {
+ /* Inner bar */
+ background: var(--accent);
+ border-radius: 0;
+ transition: all .1s ease-in-out;
+ }
+ }
+ @supports selector(::-webkit-progress-bar) {
+ &::-webkit-progress-bar {
+ /* Outer bar */
+ background: var(--box-bg);
+ border-radius: 0;
+ }
+ &::-webkit-progress-value {
+ /* Inner bar */
+ background: var(--accent);
+ border-radius: 0;
+ }
+ }
+ &:not([value]) {
+ /* Indeterminate state */
+ --track-bg-color: linear-gradient(to right,
+ var(--box-bg) 45%,
+ var(--accent) 0%,
+ var(--accent) 55%,
+ var(--box-bg) 0%
+ );
+ --track-size: 225% 100%;
+ --track-bg-position: right;
+ --track-animation: progress-loading 4s infinite ease-in-out;
+ @media (prefers-reduced-motion) {
+ --track-bg-position: center;
+ --track-animation: none;
+ }
+
+ @supports selector(progress::after) {
+ /* Chromium only */
+ &::after {
+ content: "";
+ inset: 0;
+ position: absolute;
+ background: var(--track-bg-color);
+ background-size: var(--track-size);
+ background-position: var(--track-bg-position);
+ animation: var(--track-animation);
+ }
+ }
+ @supports selector(::-webkit-progress-bar) {
+ &::-webkit-progress-bar {
+ background: var(--track-bg-color);
+ background-size: var(--track-size);
+ background-position: var(--track-bg-position);
+ animation: var(--track-animation);
+ }
+ }
+ @supports selector(::-moz-progress-bar) {
+ &::-moz-progress-bar {
+ background: var(--track-bg-color);
+ background-size: var(--track-size);
+ background-position: var(--track-bg-position);
+ animation: var(--track-animation);
+ }
+ }
+ }
+}
+@keyframes progress-loading {
+ 50% { background-position: left; }
}
label[for] {
@@ -817,12 +983,12 @@ summary {
dialog {
/* SEE components/box.css */
-
+
inset-inline: 0;
-
+
block-size: fit-content;
inline-size: fit-content;
-
+
margin: auto !important;
background-color: var(--bg);
diff --git a/src/utils.css b/src/utils.css
index 36d5295..427d354 100644
--- a/src/utils.css
+++ b/src/utils.css
@@ -5,6 +5,12 @@
.crowded { --density: .5; }
.packed { --density: 0; }
+.airy-inside > * { --density: 3; }
+.spacious-inside > * { --density: 2; }
+.dense-inside > * { --density: 1; }
+.crowded-inside > * { --density: .5; }
+.packed-inside > * { --density: 0; }
+
.autodensity {
--density: 1;
@media (min-width: 768px) { --density: 2 }
diff --git a/www/demos/meter.html b/www/demos/meter.html
new file mode 100644
index 0000000..f6b8053
--- /dev/null
+++ b/www/demos/meter.html
@@ -0,0 +1,89 @@
+---
+layout: layout.vto
+name: Meter
+---
+
+<main>
+ <nav class=breadcrumbs aria-label="Breadcrumbs">
+ <ol><li><a href="/">Home</a>
+ <li><a href="/demos/">Demos</a>
+ <li><a href="/demos/" aria-current=page>Progress &amp; Meter</a>
+ </ol>
+ </nav>
+
+ <h1>Progress &amp; Meters</h1>
+
+ <h2>Progress element</h2>
+ <p>
+ The <code>&lt;progress&gt;</code> element can be put into an indeterminate state by removing the <code>value</code> attribute.
+ <a href="/docs/colorways/">Colorways</a> are supported.
+
+ <div class=flex-column>
+ <h3>Determinate</h3>
+ <progress value=0.5></progress>
+ <progress class=info value=0.75></progress>
+ <progress class=ok value=0.25></progress>
+ <progress class=warn value=0.33></progress>
+ <progress class=bad value=0.66></progress>
+ <h3>Indeterminate</h3>
+ <progress>Indeterminate</progress>
+ </div>
+
+ <h2>Meter element</h2>
+ <p>
+ The <code>&lt;meter&gt;</code> element derives its colors from the <code>.ok</code>, <code>.warn</code>, and <code>.bad</code> colorways.
+
+ <figure>
+ <figcaption><sub-title class=allcaps>Example</sub-title>Value in optimum range</figcaption>
+
+ <pre><code>
+&lt;meter min=0 max=100 value=60 low=30 high=70 optimum=50&gt;
+&lt;meter min=0 max=100 value=85 low=20 high=70 optimum=100&gt;
+&lt;meter min=0 max=50 value=15 low=10 high=30 optimum=0&gt;
+ </code></pre>
+
+ <hr>
+
+ <h3>Disk usage (optimum is a medium amount of usage)</h3>
+ <label for=disk1>60GB Used:</label>
+ <meter id=disk1 min=0 max=100 value=60 low=30 high=70 optimum=50>60GB of 100GB</meter>
+
+ <h3>Battery level (optimum is full)</h3>
+ <label for=battery1>85% Charged:</label>
+ <meter id=battery1 min=0 max=100 value=85 low=20 high=70 optimum=100>85% charged</meter>
+
+ <h3>Temperature (optimum is low)</h3>
+ <label for=temp1>15°C:</label>
+ <meter id=temp1 min=0 max=50 value=15 low=20 high=30 optimum=0>15°C</meter>
+
+ </figure>
+
+ <figure>
+ <figcaption><sub-title class=allcaps>Example</sub-title>Value in sub-optimum range</figcaption>
+
+ <pre><code>
+&lt;meter min=0 max=100 value=80 low=30 high=70 optimum=50&gt;
+&lt;meter min=0 max=100 value=25 low=20 high=70 optimum=100&gt;
+&lt;meter min=0 max=50 value=40 low=10 high=30 optimum=0&gt;
+&lt;meter min=0 max=100 value=20 low=40 high=80 optimum=100&gt;
+ </code></pre>
+
+ <hr>
+
+ <h3>Disk usage (getting full)</h3>
+ <label for=disk2>80GB Used:</label>
+ <meter id=disk2 min=0 max=100 value=80 low=30 high=70 optimum=50>80GB of 100GB</meter>
+
+ <h3>Battery level (getting low)</h3>
+ <label for=battery2>25% Charged:</label>
+ <meter id=battery2 min=0 max=100 value=25 low=20 high=70 optimum=100>15% charged</meter>
+
+ <h3>Temperature (overheating)</h3>
+ <label for=temp2>40°C:</label>
+ <meter id=temp2 min=0 max=50 value=40 low=10 high=30 optimum=0>40°C</meter>
+
+ <h3>Exam score (failing)</h3>
+ <label for=exam1>20% Score:</label>
+ <meter id=exam1 min=0 max=100 value=20 low=40 high=80 optimum=100>20% score</meter>
+
+</main>
diff --git a/www/docs/20-forms.md b/www/docs/20-forms.md
index ce15222..eeda4a6 100644
--- a/www/docs/20-forms.md
+++ b/www/docs/20-forms.md
@@ -256,5 +256,152 @@ the label itself.
</figure>
+## Progress bar
+
+Create a progress bar using the `<progress>` element.
+This element should be used to represent how much of a specific, ongoing process has been completed.
+Be sure to add a `<label>` for accessibility (in conjunction with `.vh` or `<v-h>` if you like).
+
+The element can be put in an indeterminate state by not including the `value` attribute.
+Indeterminate `<progress>` elements will show a pending animation if the user does not have `@prefers-reduced-motion` set.
+
+The element can be styled by setting `--border-width`, `--border-style`, and `--border-radius` variables directly on the `<progress>` element.
+When not explicitly set, the element inherits from `--interactive-border-width`, `--interactive-border-style`, and `--tab-border-radius`.
+For full-width progress bars, use the `.width:100%` utility class.
+[Colorways](colorways) are supported.
+
+
+<figure>
+<figcaption><sub-title class="allcaps">Example<v-h>:</v-h></sub-title>Progress bar markup</figcaption>
+
+ ~~~ html
+ <div class=flex-column>
+
+ <label for=p1 class="vh">Upload progress...</label>
+ <progress id=p1 value=0.5 class="width:100%"></progress>
+
+ <label for=p2>LCARS Scan...</label>
+ <progress id=p2 class="ok width:100%" value=0.25 style="height: 1.5em; --border-width: 6px; --border-style: double; --border-radius: 0 .5em"></progress>
+
+ <label for=p3>Virus progress...</label>
+ <progress id=p3 class="warn width:100%" value=0.75 style="--border-width: 3px; --border-style: inset; --border-radius: 0 .5rem .5rem .5rem"></progress>
+
+ <label for=p4>Indeterminate Cylon</label>
+ <progress id=p4 class="bad" style="width: 3em;">Indeterminate Cylon</progress>
+
+ </div>
+ ~~~
+
+ <hr>
+
+ <div class=flex-column>
+
+ <label for=p1 class="vh">Upload progress...</label>
+ <progress id=p1 value=0.5 class="width:100%"></progress>
+
+ <label for=p2>LCARS Scan...</label>
+ <progress id=p2 class="ok width:100%" value=0.25 style="height: 1.5em; --border-width: 6px; --border-style: double; --border-radius: 0 .5em"></progress>
+
+ <label for=p3>Virus progress...</label>
+ <progress id=p3 class="warn width:100%" value=0.75 style="--border-width: 3px; --border-style: inset; --border-radius: 0 .5rem .5rem .5rem"></progress>
+
+ <label for=p4>Indeterminate Cylon</label>
+ <progress id=p4 class="bad" style="width: 3em;">Indeterminate Cylon</progress>
+
+ </div>
+
+</figure>
+
+## Meter
+
+Use the `<meter>` element to create a meter guage.
+This element is used to indicate a measurement within a known range and is semantically differen from the `<progress>` element.
+
+Similar to the `<progress>` element, you can style a `<meter>` by setting `--border-width`, `--border-style`, and `--border-radius` directly on the element.
+The `<meter>` element derives its colors from the <code>.ok</code>, <code>.warn</code>, and <code>.bad</code> [colorways]().
+
+<div class="box warn">
+
+**Warning**:&emsp;Due to cross-browser implementation differences, colorways are only fully supported in browsers that pass the `@supports (selector(:-moz-meter-optimum))` check.
+The color of the meter bar is correctly set in all browsers according to the values of `--ok-fg`, `--warn-fg`, and `--bad-fg`. However, only browsers passing the `@supports` rule will also have the appropriate colorway background and border colors.
+
+A suitable fallback choice has been made for these colors (`--plain-bg` for the background and `--interactive-bg` for the border) until browser support improves.
+
+</div>
+
+<figure>
+<figcaption><sub-title class=allcaps>Example</sub-title>Value in optimum range</figcaption>
+
+ ~~~html
+ <strong>Disk usage (optimum is a medium amount of usage)</strong>
+ <label for=disk1>60GB Used:</label>
+ <meter id=disk1 min=0 max=100 value=60 low=30 high=70 optimum=50>60GB of 100GB</meter>
+
+ <strong>Battery level (optimum is full)</strong>
+ <label for=battery1>85% Charged:</label>
+ <meter id=battery1 min=0 max=100 value=85 low=20 high=70 optimum=100>85% charged</meter>
+
+ <strong>Temperature (optimum is low)</strong>
+ <label for=temp1>15°C:</label>
+ <meter id=temp1 min=0 max=50 value=15 low=20 high=30 optimum=0>15°C</meter>
+ ~~~
+
+ <hr>
+
+ <strong>Disk usage (optimum is a medium amount of usage)</strong>
+ <label for=disk1>60GB Used:</label>
+ <meter id=disk1 min=0 max=100 value=60 low=30 high=70 optimum=50>60GB of 100GB</meter>
+
+ <strong>Battery level (optimum is full)</strong>
+ <label for=battery1>85% Charged:</label>
+ <meter id=battery1 min=0 max=100 value=85 low=20 high=70 optimum=100>85% charged</meter>
+
+ <strong>Temperature (optimum is low)</strong>
+ <label for=temp1>15°C:</label>
+ <meter id=temp1 min=0 max=50 value=15 low=20 high=30 optimum=0>15°C</meter>
+
+</figure>
+
+<figure>
+<figcaption><sub-title class=allcaps>Example</sub-title>Value in sub-optimum range</figcaption>
+
+ ~~~html
+ <strong>Disk usage (getting full)</strong>
+ <label for=disk2>80GB Used:</label>
+ <meter id=disk2 min=0 max=100 value=80 low=30 high=70 optimum=50>80GB of 100GB</meter>
+
+ <strong>Battery level (getting low)</strong>
+ <label for=battery2>25% Charged:</label>
+ <meter id=battery2 min=0 max=100 value=25 low=20 high=70 optimum=100>15% charged</meter>
+
+ <strong>Temperature (overheating)</strong>
+ <label for=temp2>40°C:</label>
+ <meter id=temp2 min=0 max=50 value=40 low=10 high=30 optimum=0>40°C</meter>
+
+ <strong>Exam score (failing)</strong>
+ <label for=exam1>20% Score:</label>
+ <meter id=exam1 min=0 max=100 value=20 low=40 high=80 optimum=100>20% score</meter>
+ ~~~
+
+ <hr>
+
+ <strong>Disk usage (getting full)</strong>
+ <label for=disk2>80GB Used:</label>
+ <meter id=disk2 min=0 max=100 value=80 low=30 high=70 optimum=50>80GB of 100GB</meter>
+
+ <strong>Battery level (getting low)</strong>
+ <label for=battery2>25% Charged:</label>
+ <meter id=battery2 min=0 max=100 value=25 low=20 high=70 optimum=100>15% charged</meter>
+
+ <strong>Temperature (overheating)</strong>
+ <label for=temp2>40°C:</label>
+ <meter id=temp2 min=0 max=50 value=40 low=10 high=30 optimum=0>40°C</meter>
+
+ <strong>Exam score (failing)</strong>
+ <label for=exam1>20% Score:</label>
+ <meter id=exam1 min=0 max=100 value=20 low=40 high=80 optimum=100>20% score</meter>
+
+</figure>
+
[masquerades]: /docs/utils/#masquerades
[colorways]: /docs/colorways
diff --git a/www/docs/30-components.md b/www/docs/30-components.md
index 0ae79c7..0c0565f 100644
--- a/www/docs/30-components.md
+++ b/www/docs/30-components.md
@@ -50,16 +50,16 @@ appearance with the `.box` class.
~~~ html
<div class="box bad">
- <strong class="block titlebar">Error</strong>
- Task failed successfully
+ <strong class="titlebar">Error</strong>
+ <p>Task failed successfully
</div>
~~~
<hr>
<div class="box bad">
- <strong class="block titlebar">Error</strong>
- Task failed successfully
+ <strong class="titlebar">Error</strong>
+ <p>Task failed successfully
</div>
</figure>
diff --git a/www/docs/70-layout.md b/www/docs/70-layout.md
index fc2a571..0390abc 100644
--- a/www/docs/70-layout.md
+++ b/www/docs/70-layout.md
@@ -135,7 +135,10 @@ Borders can be removed by using <dfn>`.border:none`</dfn> or one of the followin
***
-The <dfn>`.nested-list`</dfn> class removes extraneous margins in nested lists.
+~~The <dfn>`.nested-list`</dfn> class removes extraneous margins in nested lists.~~
+**Deprecated:**{.bad .color} Will be removed in version 2.0.
+In the future, nested lists will not have margins by default.
+You can add them back in using `<li><p>` as needed.
<figure>
<figcaption><sub-title class="allcaps">Example<v-h>:</v-h></sub-title>Nested lists</figcaption>
@@ -229,16 +232,25 @@ To set the aspect ratio of an element, use the `aspect-ratio` CSS property:
## Scrolling
-Set the `overflow` property with these utility classes:
+Set the `overflow` property with these utility classes.
<dfn>`.overflow:auto`</dfn>
-: Show scrollbars if needed
+: Show scrollbars if needed.
<dfn>`.overflow:scroll`</dfn>
-: Always show scrollbars
+: Always show scrollbars (use <dfn>`.overflow-x:scroll`</dfn> or <dfn>`.overflow-y:scroll`</dfn> to set on a specific axis).
<dfn>`.overflow:clip`</dfn>
-: Overflow content is clipped at the element's padding box. Can be extended using the `overflow-clip-margin` property.
+: Overflow content is clipped at the element's padding box.
+ Can be set per axis using <dfn>`.overflow-x:clip`</dfn> or <dfn>`.overflow-y:clip`</dfn>, and the clip margin can be extended using the `overflow-clip-margin` CSS property.
+
+<div class="box info">
+
+**Info**:&emsp;When using the `.overflow:scroll` utilities, it is recommended to add
+the element to the tabbing order (e.g., `<div tabindex=0 class=overflow-x:scroll>`)
+so that the container can be scrolled using the keyboard.
+
+</div>
## Pseudo-tables
diff --git a/www/docs/B0-js.md b/www/docs/B0-js.md
index b8ac476..45aa197 100644
--- a/www/docs/B0-js.md
+++ b/www/docs/B0-js.md
@@ -46,7 +46,7 @@ The tabs behavior emits these custom events:
**Info**:&emsp;For dynamically inserted content, initialize it as such:
-<figure>
+<figure class="plain">
~~~ js
import tabs from "https://unpkg.com/missing.css@{{ version }}/dist/js/tabs.js";
diff --git a/www/js/pagefind.js b/www/js/pagefind.js
index ea2a7aa..2b933d3 100644
--- a/www/js/pagefind.js
+++ b/www/js/pagefind.js
@@ -28,10 +28,10 @@ updateResultItem = (item, result) => {
searchDialog = () => {
const markup = (html`
<dialog class="margin flex-col" style="max-width: 100%; width: 30em; max-height: 100%; height: 40em; padding-bottom: 0;">
- <label for="search-input" class="titlebar" style="margin-inline: calc(-1*var(--gap))">
+ <label for="search-input" class="titlebar">
Search
</label>
- <div class="flex-row">
+ <div class="flex-row margin-block">
<input autofocus id="search-input" class="block width:100%">
<button class="float:right" onclick="this.closest('dialog').close();">Close</button>
</div>