Files
dickloads/PICO_CSS.md

96 lines
3.8 KiB
Markdown

# Pico CSS — Gotchas & Notes
## [role=button] clobbers --pico-color
Pico's stylesheet includes this rule:
```css
[role=button], [type=button], button, ... {
--pico-color: var(--pico-primary-inverse);
...
}
```
In light mode, `--pico-primary-inverse` is `#fff`. This means **any element with `role="button"` will have white text by default**, regardless of its background. Children inherit this, making text invisible on white/light card backgrounds.
**Fix:** On the element itself, reset the variable and set an explicit color:
```css
.your-element {
--pico-color: initial;
color: var(--pico-contrast); /* #181c25 light / #dfe3eb dark — always legible */
}
```
**Alternative:** Remove `role="button"` and use `tabindex="0"` + keyboard handlers only, avoiding the Pico button rule entirely. Only do this if button semantics aren't needed for accessibility.
## Plain/ghost buttons disappear on hover in light/Dan mode
Pico's button hover rule sets **both** CSS custom properties **and** computed values:
```css
button:is(:hover,:active,:focus) {
--pico-background-color: var(--pico-primary-hover-background);
--pico-border-color: var(--pico-primary-hover-border);
--pico-color: var(--pico-primary-inverse); /* #fff in light mode */
}
```
If your button has a transparent or white background — e.g. a ghost/plain-style button — the text becomes invisible because `--pico-primary-inverse` is `#fff` in light mode.
**Important:** Overriding only `color: ... !important` is **not enough**, because Pico sets `--pico-color` as a CSS variable that other rules may read. You must override all three custom properties *and* the corresponding computed properties simultaneously.
**Symptom:** ghost button text vanishes on hover in light or Dan mode (background goes blue, text goes white). Works fine in dark mode because the dark background makes white text readable.
**Fix:** Override all Pico button hover variables explicitly:
```css
.my-ghost-button:not(:disabled):hover {
--pico-color: var(--pico-contrast) !important; /* near-black in light, near-white in dark */
--pico-background-color: transparent !important;
--pico-border-color: var(--pico-contrast) !important;
color: var(--pico-contrast) !important;
background: transparent !important;
border-color: var(--pico-contrast) !important;
}
```
Use `--pico-contrast` (not `--pico-color`) as the hover text color — it's `#181c25` in light mode and `#dfe3eb` in dark mode, so it's always legible against the page background regardless of theme.
## Palette overrides must be scoped to light mode
Pico defines its palette twice: once for light (`:root:not([data-theme=dark])`) and once for dark (`@media (prefers-color-scheme: dark)` + `[data-theme=dark]`). If you override Pico vars at bare `:root`, you'll clobber the dark mode values.
**Wrong:**
```css
:root {
--pico-color: #2C2C2C; /* kills dark mode */
}
```
**Correct:**
```css
@media (prefers-color-scheme: light) {
:root:not([data-theme]) { --pico-color: #2C2C2C; }
}
[data-theme=light] { --pico-color: #2C2C2C; }
```
## Theme toggling pattern
Set `data-theme="light"` or `data-theme="dark"` on `<html>`. Pico reads this attribute for its palette selectors. Persist to `localStorage`. Read OS preference (`prefers-color-scheme`) on first visit when no stored value exists.
## --pico-card-background-color in light mode
In light mode, Pico sets:
```
--pico-card-background-color: var(--pico-background-color) → #fff
```
If you want custom card backgrounds, override `--pico-card-background-color` directly (scoped to light mode only — see above).
## CSS variables that Pico does NOT define
- `--color-label` (app-defined) — must be set for both light and dark explicitly
- Any `--shadow-*` vars — define at `:root` (theme-neutral)