Files
dickloads/PICO_CSS.md

91 lines
3.3 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 buttons disappear on hover in light/Dan mode
Pico's button hover rule sets `--pico-color: var(--pico-primary-inverse)` (i.e. `#fff`) on hover, making the text white. If your button has a transparent or white background — e.g. a "plain" / ghost-style button — the text becomes invisible.
This affects any `<button>` element, not just `[role=button]`. The `plain` class (or similar resets) strips Pico's background/border, but **does not prevent Pico from overriding the text color on hover**.
**Symptom:** button text vanishes on hover in light or Dan mode, visible in dark mode (where the background is already dark).
**Fix:** Use `!important` on hover to override Pico's specificity, and also explicitly reset the background so you're sure nothing sneaks in:
```css
.my-plain-button:not(:disabled):hover {
color: var(--pico-color) !important;
background: transparent;
}
```
Or, if you want a specific non-body text color on hover:
```css
.my-plain-button:not(:disabled):hover {
color: var(--pico-contrast) !important; /* always legible */
background: transparent;
}
```
**Do not** rely on Pico's hover cascade for plain/ghost buttons — always override explicitly.
## 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)