UI Hub 是一个每日更新的免费 UI 资源目录,给设计师、前端开发者和做界面的 AI Agent 用:共 2,395 条资源,其中 133 个组件库、1,929 个带明暗预览的组件样式示例,另有设计 skill 与 AI 设计技巧文章。UI Hub 是一個每日更新的免費 UI 資源目錄,給設計師、前端開發者和做介面的 AI Agent 用:共 2,395 條資源,其中 133 個元件庫、1,929 個附明暗預覽的元件樣式示例,另有設計 skill 與 AI 設計技巧文章。UI Hub is a free, daily-updated directory of UI resources for designers, front-end developers and AI agents that build interfaces: 2,395 resources, including 133 component libraries and 1,929 component style demos with light/dark previews, plus design skills and AI design articles.UI Hub は、デザイナー・フロントエンド開発者・UI を作る AI エージェント向けの、毎日更新される無料の UI リソース集です。全 2,395 件(コンポーネントライブラリ 133 件、ライト/ダーク対応のスタイルデモ 1,929 件)に加え、デザインスキルと AI デザイン記事を掲載しています。UI Hub는 디자이너, 프론트엔드 개발자, 인터페이스를 만드는 AI 에이전트를 위한 매일 업데이트되는 무료 UI 리소스 디렉터리입니다. 총 2,395개 리소스(컴포넌트 라이브러리 133개, 라이트/다크 미리보기가 있는 스타일 데모 1,929개)와 디자인 스킬, AI 디자인 글을 제공합니다.UI Hub ialah direktori sumber UI percuma yang dikemas kini setiap hari untuk pereka, pembangun front-end dan ejen AI yang membina antara muka: 2,395 sumber, termasuk 133 pustaka komponen dan 1,929 demo gaya komponen dengan pratonton terang/gelap, serta kemahiran reka bentuk dan artikel reka bentuk AI.UI Hub là danh mục tài nguyên UI miễn phí, cập nhật hằng ngày, dành cho nhà thiết kế, lập trình viên front-end và AI agent dựng giao diện: 2,395 tài nguyên, gồm 133 thư viện component và 1,929 mẫu phong cách component có xem trước sáng/tối, cùng skill thiết kế và bài viết về thiết kế với AI.UI Hub est un annuaire gratuit de ressources UI, mis à jour chaque jour, pour designers, développeurs front-end et agents IA qui construisent des interfaces : 2,395 ressources, dont 133 bibliothèques de composants et 1,929 démos de styles avec aperçus clair/sombre, plus des skills de design et des articles sur le design avec l’IA.UI Hub es un directorio gratuito de recursos de UI, actualizado a diario, para diseñadores, desarrolladores front-end y agentes de IA que construyen interfaces: 2,395 recursos, incluidas 133 bibliotecas de componentes y 1,929 demos de estilos con vista clara/oscura, además de skills de diseño y artículos de diseño con IA.UI Hub ist ein kostenloses, täglich aktualisiertes Verzeichnis von UI-Ressourcen für Designer, Frontend-Entwickler und KI-Agents, die Oberflächen bauen: 2,395 Ressourcen, darunter 133 Komponentenbibliotheken und 1,929 Komponenten-Stildemos mit Hell/Dunkel-Vorschau, dazu Design-Skills und Artikel zu KI-Design.

← 百科百科Encyclopedia百科백과EnsiklopediaBách khoaEncyclopédieEnciclopediaEnzyklopädie · 笔记筆記Noteノート노트NotaGhi chúNoteNotaNotiz · blog · dark mode · tokens

Dark mode done right: tokens, elevation and contrast

阅读博客原文閱讀部落格原文Read the blog postブログ記事を読む블로그 글 읽기Baca artikel blogĐọc bài blogLire l’articleLeer el artículoBlogbeitrag lesen →原始 Markdown原始 MarkdownRaw Markdown生Markdown원본 MarkdownMarkdown mentahMarkdown gốcMarkdown brutMarkdown en brutoRohes Markdown

本条目正文为英文,作为 AI Agent 上下文使用。

本條目正文為英文,作為 AI Agent 上下文使用。

この項目の本文は英語です(AIエージェントの文脈用)。

이 항목의 본문은 영어입니다(AI 에이전트 컨텍스트용).

Kandungan entri ini dalam bahasa Inggeris (untuk konteks ejen AI).

Nội dung mục này bằng tiếng Anh (dùng làm ngữ cảnh cho AI agent).

Le contenu de cette entrée est en anglais (contexte pour agents IA).

El contenido de esta entrada está en inglés (contexto para agentes de IA).

Der Inhalt dieses Eintrags ist auf Englisch (Kontext für KI-Agents).

Dark mode is a second palette, not an inverted one. Use semantic tokens, lighter surfaces for elevation, and desaturated accents.

Inverting colours is the fastest way to ship a bad dark mode: pure black backgrounds, glowing saturated blues, borders that vanish and shadows nobody can see. Apple's Human Interface Guidelines and web.dev both treat dark mode as its own design pass, not a filter. This post covers the token structure that makes two themes cheap, the rules for surfaces, colour and contrast, a step-by-step implementation without the white flash, and what to check before you ship.

Start from semantic tokens

The single decision that makes dark mode manageable is naming colours by role, not by value. Components use --bg, --surface, --ink, --muted, --line and --accent. Each theme assigns values to those roles. A component never knows which theme it is in.

:root, [data-theme="light"] { color-scheme: light; --bg: #f5f6fa; --surface: #ffffff; --raised: #ffffff; --ink: #0a0c14; --muted: #4a5164; --line: rgb(10 12 20 / .10); --accent: #2563eb; } [data-theme="dark"] { color-scheme: dark; --bg: #06070b; --surface: #0d0f15; --raised: #151924; --ink: #f3f5fb; --muted: #a6adbf; --line: rgb(255 255 255 / .10); --accent: #67e8f9; } .card { background: var(--surface); color: var(--ink); border: 1px solid var(--line); }

If your codebase has #fff and text-gray-900 scattered through components, the first step of a dark mode project is replacing them with roles. Agents are good at this mechanical refactor when you give them the role table.

Rules for surfaces and colour

Contrast in both themes

WCAG asks for at least 4.5:1 contrast for normal text and 3:1 for large text and UI components. Check muted text, placeholder text, disabled states and links in both themes. The usual failure is muted grey that passes on white and fails on near-black, or the reverse.

Step by step: implementing the switch

Step 1: respect the system, remember the choice. Default to prefers-color-scheme, let the user override it, and store the override.

Step 2: set the theme before first paint. A tiny inline script in <head> avoids the white flash on load:

Step 3: set color-scheme. It tells the browser to render form controls, scrollbars and the default canvas in the right theme. Without it you get light scrollbars on a dark page.

Step 4: consider light-dark(). Modern browsers support the CSS light-dark() function, which picks a value based on the active color-scheme. It is handy for one-off values: border-color: light-dark(#e5e7eb, #262a35);.

Step 5: wire the toggle. Update data-theme, save the choice, and update aria-pressed or the label so screen-reader users know the current state.

A five-minute dark-mode review

Open the page in dark mode on a real phone at low brightness and on a laptop at full brightness. Look for four things: text that glows or blurs at the edges (too much contrast, often pure white on pure black), cards that disappear into the background (missing border or lightness step), accent colours that vibrate, and any white rectangle (an image, embed or code block that was never themed). Then switch themes with the toggle and reload: the page should come back in the theme you chose, without a flash.

Pitfalls

Questions we get

Should dark mode be the default? Follow the system setting by default. Users who prefer dark have usually already said so at the operating-system level, and the same goes for light. A manual toggle covers everyone else.

Do we need a separate dark design in Figma? You need dark values for every role token and a review of key screens in dark. You do not need to redraw every screen if components use role tokens; the theme swap does the work.

What about charts and data visualisation? Chart palettes need their own dark variants. Colours that are distinguishable on white can merge on near-black, so check categorical colours side by side in both themes, and never rely on colour alone to distinguish series.

How do we keep the two themes from drifting? Run visual regression screenshots in both themes and fail the build on unexpected changes. Treat a component that looks wrong in one theme as a bug, not a polish item.

Is "dim" or high-contrast a third theme? If users need it, yes, and the role-token structure makes it a third column of values. Respect prefers-contrast before inventing a custom option.

Our take

NN/g's research shows preference between dark and light is split and situational, so ship both and remember the choice. The cost of the second theme is almost entirely in the token structure: get roles right and dark mode is a second column of values. UI Hub stores light and dark preview screenshots for each component for exactly this reason; a component that only looks good in one theme is half finished.

Checklist

References