diff --git a/.changeset/adaptive-bone-colors.md b/.changeset/adaptive-bone-colors.md new file mode 100644 index 0000000..a6223ef --- /dev/null +++ b/.changeset/adaptive-bone-colors.md @@ -0,0 +1,5 @@ +--- +"@camp.dev/bones": minor +--- + +Bone colors derive from the inherited text color instead of the OS color scheme. `--bone-base` defaults to the text color at 12% opacity and `--bone-highlight` at 6%, and the `prefers-color-scheme` media query is gone. Bones are now visible on any background the surrounding text is readable on. Before this, a dark-mode OS over a page that kept a light canvas painted white bones on white (BON-13). Overriding the custom properties works unchanged. Internally, bones hide their content by zeroing the alpha of `color` so the channels survive into the derivation, and the measured overlay's no-stylesheet fallbacks derive the same way. The stylesheets now use relative color syntax, which is Baseline 2024 (Chrome 119, Safari 18, Firefox 128). diff --git a/apps/docs/content/docs/styling.mdx b/apps/docs/content/docs/styling.mdx index b9ff02f..5728df5 100644 --- a/apps/docs/content/docs/styling.mdx +++ b/apps/docs/content/docs/styling.mdx @@ -7,12 +7,14 @@ All skeleton visuals are controlled by CSS custom properties. Override them glob ## CSS custom properties -| Property | Default (light) | Default (dark) | Description | -| ------------------ | --------------------- | --------------------------- | ------------------------------ | -| `--bone-base` | `rgba(0, 0, 0, 0.12)` | `rgba(255, 255, 255, 0.12)` | Skeleton background color | -| `--bone-highlight` | `rgba(0, 0, 0, 0.06)` | `rgba(255, 255, 255, 0.06)` | Highlight color (for shimmer) | -| `--bone-radius` | `4px` | `4px` | Border radius of skeleton bars | -| `--bone-duration` | `1.5s` | `1.5s` | Animation duration | +| Property | Default | Description | +| ------------------ | ----------------------------- | ------------------------------ | +| `--bone-base` | the text color at 12% opacity | Skeleton background color | +| `--bone-highlight` | the text color at 6% opacity | Highlight color (for shimmer) | +| `--bone-radius` | `4px` | Border radius of skeleton bars | +| `--bone-duration` | `1.5s` | Animation duration | + +The color defaults derive from the text color in effect at the skeleton, so bones contrast with whatever background the text around them is readable on. A `#333`-on-white article gets translucent dark bars. The same markup inside a dark card with light text gets translucent light bars. ## Theming @@ -41,18 +43,18 @@ Or use a CSS class: ## Dark mode -Dark mode works via `prefers-color-scheme`: +Dark mode needs no configuration. Because bones derive from the text color, a dark theme's light text produces light bones, whether the theme comes from `prefers-color-scheme` or a class-based toggle. + +To give dark mode different bones anyway, override the properties in your dark styles: ```css -@media (prefers-color-scheme: dark) { - :root { - --bone-base: rgba(255, 255, 255, 0.12); - --bone-highlight: rgba(255, 255, 255, 0.06); - } +.dark { + --bone-base: rgba(255, 255, 255, 0.2); + --bone-highlight: rgba(255, 255, 255, 0.1); } ``` -Override these in your own dark mode styles if your app uses a class-based dark mode toggle. +One case needs a manual override: text that depends on its background for contrast, such as white text over a hero image. If the image is part of what loads, the derived white bone can vanish against the page behind it. Set `--bone-base` on that section to a color that works without the image. ## Animations diff --git a/packages/bones/sandbox/auto.html b/packages/bones/sandbox/auto.html index c469a37..15d89c6 100644 --- a/packages/bones/sandbox/auto.html +++ b/packages/bones/sandbox/auto.html @@ -6,6 +6,12 @@