From 0cfd0d3aedfe0b0e255ae760ea36e865b058c341 Mon Sep 17 00:00:00 2001
From: Mark Otto
Date: Thu, 5 Mar 2026 11:18:59 -0800
Subject: [PATCH 1/2] Update placeholder sizing, docs, and animations
---
scss/_placeholder.scss | 28 ++++++++++++++-----
.../content/docs/components/placeholder.mdx | 24 ++++++++++------
2 files changed, 36 insertions(+), 16 deletions(-)
diff --git a/scss/_placeholder.scss b/scss/_placeholder.scss
index e05056396347..8987f44459eb 100644
--- a/scss/_placeholder.scss
+++ b/scss/_placeholder.scss
@@ -1,19 +1,30 @@
@use "colors" as *;
@use "config" as *;
@use "functions" as *;
+@use "mixins/border-radius" as *;
@use "mixins/tokens" as *;
$placeholder-tokens: () !default;
+$placeholder-wave-tokens: () !default;
// scss-docs-start placeholder-tokens
// stylelint-disable-next-line scss/dollar-variable-default
$placeholder-tokens: defaults(
(
- --placeholder-opacity-max: .5,
- --placeholder-opacity-min: .2,
+ --placeholder-opacity-max: .18,
+ --placeholder-opacity-min: .1,
),
$placeholder-tokens
);
+
+// stylelint-disable-next-line scss/dollar-variable-default
+$placeholder-wave-tokens: defaults(
+ (
+ --placeholder-opacity-max: .5,
+ --placeholder-opacity-min: .25,
+ ),
+ $placeholder-wave-tokens
+);
// scss-docs-end placeholder-tokens
@layer components {
@@ -21,10 +32,11 @@ $placeholder-tokens: defaults(
@include tokens($placeholder-tokens);
display: inline-block;
- min-height: 1em;
+ min-height: 1.25em;
vertical-align: middle;
cursor: wait;
background-color: currentcolor;
+ @include border-radius(var(--radius-3));
opacity: var(--placeholder-opacity-max);
&.btn::before {
@@ -35,15 +47,15 @@ $placeholder-tokens: defaults(
// Sizing
.placeholder-xs {
- min-height: .6em;
+ min-height: .75em;
}
.placeholder-sm {
- min-height: .8em;
+ min-height: 1em;
}
.placeholder-lg {
- min-height: 1.2em;
+ min-height: 1.75em;
}
// Animation
@@ -66,7 +78,9 @@ $placeholder-tokens: defaults(
}
.placeholder-wave {
- mask-image: linear-gradient(130deg, $black 55%, rgb(0 0 0 / calc(1 - var(--placeholder-opacity-min))) 75%, $black 95%);
+ @include tokens($placeholder-wave-tokens);
+
+ mask-image: linear-gradient(110deg, var(--black) 40%, rgb(0 0 0 / calc(1 - var(--placeholder-opacity-max))) 50%, var(--black) 60%);
mask-size: 200% 100%;
animation: placeholder-wave 2s linear infinite;
diff --git a/site/src/content/docs/components/placeholder.mdx b/site/src/content/docs/components/placeholder.mdx
index 0323beb56c3d..7da7fdc0e5fc 100644
--- a/site/src/content/docs/components/placeholder.mdx
+++ b/site/src/content/docs/components/placeholder.mdx
@@ -39,7 +39,7 @@ In the example below, we take a typical card component and recreate it with plac
-
+
`} />
@@ -82,13 +82,13 @@ We apply additional styling to `.btn`s via `::before` to ensure the `height` is
- `} />
+ `} />
The use of `aria-hidden="true"` only indicates that the element should be hidden to screen readers. The *loading* behavior of the placeholder depends on how authors will actually use the placeholder styles, how they plan to update things, etc. Some JavaScript code may be needed to *swap* the state of the placeholder and inform AT users of the update.
-### Width
+## Width
You can change the `width` through grid column classes, width utilities, or inline styles.
@@ -96,26 +96,26 @@ You can change the `width` through grid column classes, width utilities, or inli
`} />
-### Color
+## Color
By default, the `placeholder` uses `currentColor`. This can be overridden with a custom color or utility class.
+ `
`,
- ...getData('theme-colors').map((themeColor) => ``)
+ ...getData('theme-colors').map((themeColor) => ``)
]} />
-### Sizing
+## Sizing
The size of `.placeholder`s are based on the typographic style of the parent element. Customize them with sizing modifiers: `.placeholder-lg`, `.placeholder-sm`, or `.placeholder-xs`.
-
+
`} />
-### Animation
+## Animation
Animate placeholders with `.placeholder-glow` or `.placeholder-wave` to better convey the perception of something being *actively* loaded.
@@ -127,6 +127,12 @@ Animate placeholders with `.placeholder-glow` or `.placeholder-wave` to better c
`} />
+### Text
+
+Add `placeholder-wave` to an inline element with text to apply the placeholder animations to the text.
+
+Working on it…`} />
+
## CSS
### Variables
From 6a708d083b165a39ea42fef30acaf74d10476c6e Mon Sep 17 00:00:00 2001
From: Mark Otto
Date: Mon, 31 Aug 2026 12:03:31 -0700
Subject: [PATCH 2/2] fix(css): drop unused colors import from placeholder
The wave mask uses var(--black), so @use "colors" fails css-lint-imports.
---
scss/_placeholder.scss | 1 -
1 file changed, 1 deletion(-)
diff --git a/scss/_placeholder.scss b/scss/_placeholder.scss
index 8987f44459eb..bc70b41e6cf9 100644
--- a/scss/_placeholder.scss
+++ b/scss/_placeholder.scss
@@ -1,4 +1,3 @@
-@use "colors" as *;
@use "config" as *;
@use "functions" as *;
@use "mixins/border-radius" as *;