算法艺术创作
algorithmic-art
通过代码和可调参数创作生成艺术与交互式视觉效果。
elevation-and-depth【设计与创意】Shadows and layering that lift elements above the surface. Use when designing cards, dropdowns, modals, tooltips or any floating element.
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
Elevation uses shadow and layering to communicate that an element sits above the base surface — giving UI a sense of physical depth. Combined with border-radius, it creates the tactile quality that makes cards graspable, modals clearly floating, and dropdowns feel like they've appeared on top of content.
Define a small set of elevation levels as tokens. Each level maps to a specific UI role.
| Level | Token | Shadow | Role |
|---|---|---|---|
| 0 | --shadow-none | none | Flat surface, inline elements |
| 1 | --shadow-xs | 0 1px 2px rgba(0,0,0,0.06) | Subtle card, table row hover |
| 2 | --shadow-sm | 0 1px 3px rgba(0,0,0,0.10), 0 1px 2px rgba(0,0,0,0.06) | Card, input focus ring area |
| 3 | --shadow-md | 0 4px 6px rgba(0,0,0,0.08), 0 2px 4px rgba(0,0,0,0.06) | Dropdown, popover |
| 4 | --shadow-lg | 0 10px 15px rgba(0,0,0,0.08), 0 4px 6px rgba(0,0,0,0.05) | Modal, dialog, side drawer |
| 5 | --shadow-xl | 0 20px 25px rgba(0,0,0,0.08), 0 8px 10px rgba(0,0,0,0.04) | Command palette, full-screen overlay |
Keep shadows subtle. Dark, heavy shadows feel dated and visually aggressive. Light, diffuse shadows feel modern and material.
A subtle shadow on a white surface can sometimes "wash out," making the edge of a card feel fuzzy or indistinct.
#E2E8F0 or grey-200).A card that shifts background colour on hover must have a defined edge — a border, shadow, or clear radius boundary. Without one, the shift has no shape and reads as a stray fill, not a highlighted card. On a borderless, flat card, a background-change hover is forbidden — use a border or a shadow (elevation) on hover instead.
Gradients can be used to bring "liveliness" to an interface and reinforce the sense of elevation.
Border-radius and shadow work together to define the character of a surface. The combination signals the element's role and the product's visual tone.
| Surface | Shadow | Border-Radius | Tone |
|---|---|---|---|
| Inline chip / tag | none | --radius-full (pill) | Flat, lightweight |
| Card | --shadow-sm | --radius-md (8–12px) | Graspable, contained |
| Dropdown / popover | --shadow-md | --radius-md (8px) | Floating, contextual |
| Modal / dialog | --shadow-lg | --radius-lg (12–16px) | Prominent, focused |
| Toast / notification | --shadow-md | --radius-md | Ephemeral, above content |
| Button | none or --shadow-xs | consistent across all buttons — see below |
Do not run a heavy coloured border along one side of a rounded box. Borders miter: where the accent meets its neighbours the renderer cuts a diagonal seam, and the radius bends that seam into a curve, so the accent visibly narrows and peels away before the corner ends. A 4px edge on an 8px radius spends most of its length tapering. Give the accent its own filled element instead, a bar or a wash that the container's radius clips cleanly, or keep the box square where the accent runs. A fill has no miter and no taper.
Button border-radius must not vary within a product. All buttons — primary, secondary, destructive, ghost — use the same radius token. Varying radius between button types breaks visual consistency and implies a semantic difference that does not exist.
/* Correct: one radius for all buttons */
.btn { border-radius: var(--radius-button); }
/* Wrong: different radii for different button variants */
.btn-primary { border-radius: 8px; }
.btn-secondary { border-radius: 4px; } /* ← breaks consistency */
The button radius token is a brand decision — set it once, apply it everywhere.
text-shadow can lift text off a background without changing colours — useful when contrast is marginal or text sits on a photograph, gradient, or complex background.
The effect must be imperceptible as a shadow. If the user notices the shadow, it is too strong.
/* On images or complex backgrounds */
.hero-title {
text-shadow: 0 1px 3px rgba(0, 0, 0, 0.25);
}
/* Very subtle separation from a near-matching background */
.label-on-tinted-surface {
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.12);
}
/* White text on light background — use a dark shadow, not white */
.inverted-text {
text-shadow: 0 1px 4px rgba(0, 0, 0, 0.30);
}
Rules:
0.30 — above that it reads as a design choice rather than a refinement2–4px maximum — higher values make text feel dirty0 1px or 0 0 — directional offsets above 2px look like retro Web 2.0text-shadow to compensate for a contrast failure — fix the colour first. Use it only when colours are already close to passing and a nudge is needed, or when text sits on unpredictable imageryShadows are less visible on dark backgrounds. On dark surfaces, compensate with:
1px solid rgba(255,255,255,0.08)) to define card edges| Anti-pattern | Problem | Fix |
|---|---|---|
| Different border-radius on primary vs secondary buttons | Implies semantic difference that doesn't exist | Single --radius-button token for all buttons |
Heavy box-shadow: 0 8px 16px rgba(0,0,0,0.4) | Feels dated and visually aggressive | Use low-opacity, multi-layer diffuse shadows |
| Shadow on every element regardless of role | Elevation loses meaning when everything is elevated | Reserve shadow for genuinely floating elements |
| Flat cards with no elevation on a white background | Card edge disappears into the page | Use --shadow-sm or a 1px border to define the card boundary |