Was macht Pixel HUD UI?
Ein UI-Framework, nicht nur ein Farbschema. Es hat drei Ebenen, und ein gutes Ergebnis nutzt alle drei:
- Grundlagen: ein 4px-Raster, eine auf 12px-Pixelfläche abgestimmte Schriftgrößen-Skala, Farb-Rollen (jede Farbe bedeutet eine Sache), 1px-Regeln anstelle von Schatten, schrittweise Bewegung.
- Steuerelemente: Panels und Titelleisten, Tasten (Buttons) mit Absichten, Symboltasten, Tabs, segmentierte Steuerelemente, Listenzeilen, Formularfelder, Eingaben, Selects, quadratische Checkboxen und Radios, Lampenschalter, Gauge-Schieberegler, Fortschrittsanzeigen, Lampen, Tags, Badges, Keycaps, Menüs, Tooltips, Dialoge, Toasts, Tabellen, Codeblöcke, Prosa, Ladezustände, leere Zustände. Jedes hat feste Größen und ein gemeinsames Zustandsmodell (hover, pressed, focus, selected, disabled, loading, error).
- Paletten:
--hud-*-Tokens, sodass das Framework auf beliebigen Farben sitzt, einschließlich der eigenen Markenfarben der App.
Dateien
| Datei | Was es ist |
|---|---|
references/design-system.md | Die Spezifikation. Prinzipien, Grundlagen und die Anatomie jedes Steuerelements, Größen, Zustände, wann es zu verwenden ist und Barrierefreiheit. Vor dem Design lesen. |
assets/pixel-hud.css | Die Implementierung: Tokens, globale Lichteinstellungen unter [data-skin="pixel"] und die hud-*-Steuerklassen |
assets/palettes.css | starward (Tiefraum, dunkel), terminal (Graugrün, dunkel), paper (warmer Sand, hell) |
assets/fonts.css | Fusion Pixel 12px (OFL), gehostet auf jsDelivr; oder selbst hosten via @fontsource |
assets/pixel-caret.js | Optionaler 3px-Block-Cursor für Textfelder (data-pixel-caret) |
assets/demo.html | Jedes Steuerelement in jedem Zustand, mit einem Paletten-Umschalter: die visuelle Referenz |
references/integration.md | Rezepte pro Stack: Zuordnung der App-Farben, Tailwind, shadcn/ui, React/Next, Vue, Scoping, No-Flash-Toggle, selbst gehostete Schriftarten |
scripts/check-contrast.mjs | WCAG-Prüfung für jede Palette: node scripts/check-contrast.mjs meine.css |
Arbeitsablauf
1. Spezifikation und Demo lesen
references/design-system.md lesen (zumindest Prinzipien, Grundlagen und die vom Task benötigten Steuerelemente) und assets/demo.html ansehen. Die Spezifikation erklärt, warum jedes Steuerelement so aussieht; ihr zu folgen ist, was einen Bildschirm als dieses Framework lesbar macht und nicht nur als „dunkles Theme mit Pixel-Schriftart".
2. Das Projekt ansehen
Bevor etwas kopiert wird, herausfinden:
- den Stack und wo globales CSS geladen wird (Layout-Datei,
main.ts,index.html, Tailwind-Eintrag); - wie Farben heute definiert sind (CSS-Custom-Properties, Tailwind-Theme, shadcn-HSL-Variablen, Hex in Komponenten);
- ob es sich um ein neues UI oder ein Restyling handelt, ob es der einzige Look der App oder ein umschaltbares Theme ist, ob die ganze Seite oder nur ein Bereich.
Diese entscheiden über die Farbzuordnung (Schritt 4) und verhindern, dass man gegen die Styles der App kämpft.
3. Das Kit hinzufügen
pixel-hud.css, fonts.css, palettes.css (falls eine gebündelte Palette verwendet wird) und pixel-caret.js (falls die App Texteingaben hat) in das Projekt kopieren. Ladenreihenfolge: Schriftarten → Paletten → pixel-hud.css, nach den eigenen Basis-Styles der App.
4. Farben auswählen
- Eine gebündelte Palette:
data-hud-palette="starward" | "terminal" | "paper". - Die eigenen Farben der App: Ein Block bildet seine Variablen auf
--hud-*ab (references/integration.md› Zuordnung der App-Farben). Behält die Marke, fügt das Framework hinzu. - Eine neue Palette: „新建一套配色" in der Spezifikation folgen.
Dann node scripts/check-contrast.mjs <datei> auf jeder Palette ausführen, die geschrieben oder zugeordnet wurde, und jedes FEHLER beheben: Die Steuerelemente sind darauf angewiesen, dass die Balken-, Text- und Grüntöne auf jeder Oberfläche lesbar sind.
5. Einschalten
<html data-skin="pixel" data-hud-palette="starward">
Ein umschaltbares Theme setzt diese vor dem ersten Paint (references/integration.md › No-Flash-Toggle). Um nur einen Bereich zu stylen, beide Attribute auf dessen Container setzen.
6. Mit den Steuerelementen bauen
Die globalen Styles kümmern sich bereits um Typografie, eckige Ecken, native Eingaben, Selects, Range-Slider, Checkboxen, Scrollbalken, Fokus-Ringe, Auswahl und Scanlines. Jedem Element seine Rolle mit einer Klasse geben, gemäß der Spezifikation für Größe und Zustand:
| Bedarf | Steuerelement (Klasse) |
|---|---|
| Zusammengehörige Informationen gruppieren | .hud-panel + .hud-titlebar (+ .hud-titlebar__actions), Body .hud-panel__body, Abschnitte .hud-subhead |
| Hauptaktion | .hud-btn.is-solid (Absicht: accent, go, warn, info, danger) |
| Sekundäraktion | .hud-btn |
| Nur-Symbol-Aktion | .hud-icon-btn + aria-label |
| Ansichten wechseln | .hud-tabs > .hud-tab[aria-selected] |
| Einen von 2–5 Werten auswählen | .hud-segmented > button[aria-pressed] |
| Navigierbare Liste | .hud-row[aria-current] |
| Ein beschriftetes Eingabefeld | .hud-field > .hud-label + input/select + .hud-help / .hud-error |
| Dropdown | .hud-select > select |
| Ja/Nein, einer von vielen | .hud-check, .hud-radio (quadratische Markierungen) |
| Sofortiges Ein/Aus | button.hud-switch[role=switch][aria-checked] > .hud-switch__knob |
| Pegel / Fortschritt | .hud-gauge + --value (data-state warn/alert) |
| Status | .hud-lamp[data-state] |
| Wert, ID, Parameter | .hud-tag; Zählungen .hud-badge; Tasten kbd |
| Menüs, Hinweise, Modal, Feedback | .hud-menu, .hud-tooltip, .hud-backdrop > .hud-dialog, .hud-toasts > .hud-toast |
| Daten, Code, Artikel | table.hud-table, .hud-code, .hud-prose |
| Befehls-/Chat-Eingabe | .hud-input + data-pixel-caret |
| Warten, nichts anzuzeigen | .hud-loader, aria-busy auf einer Taste, .hud-empty |
Klassen in den Komponenten-Quellcode (JSX, Templates) setzen, indem sie über die className/class-Prop einer Komponentenbibliothek übergeben werden, anstatt Selektoren gegen Framework-Interna zu schreiben: Sie überstehen Refactorings und lesen sich klar.
Beim Restyling einer bestehenden App zuerst jedes vorhandene Steuerelement der obigen Tabelle zuordnen (eine kurze Liste in der Antwort hilft dem Benutzer, zu folgen), dann anwenden.
7. Das Ergebnis prüfen
- Einen Screenshot der Seite machen (oder sie öffnen) und mit
assets/demo.htmlvergleichen. - Bestätigen, dass die Pixel-Schriftart geladen wurde (
document.fonts, Netzwerk-Tab); ein CSP könnte jsDelivr blockieren, dann selbst hosten. - Mit Tab durchgehen: jedes Steuerelement erreichbar, 1px grüne Fokus-Ringe sichtbar.
- Das Zustandsmodell an den Haupt-Steuerelementen durchgehen: hover, pressed, disabled, loading, error.
- Das Kontrast-Skript besteht für die verwendete Palette.
Die wichtigsten Regeln
Die Spezifikation enthält die vollständige Begründung; dies sind die am häufigsten verletzten:
- Quadratisch und flach. Keine Rundung, keine Weichzeichnungsschatten, keine Verläufe außer Scanlines. Nur Overlays erhalten den harten Offset-Schatten.
- Farben behalten ihre Aufgaben. Balken = Struktur und Auswahl; Grün = an, Hervorhebung, Fokus; Gelb = Werte; Orange = Notizen und Warnungen; Rot = Gefahr. Grün, das als Dekoration verwendet wird, hört auf, „an" zu bedeuten.
- Ausgewählt = invertiert. Balkenfüllung mit dunklem Text; Zeilen erhalten einen 3px grünen Rand. Auf einem balkenfarbigen Hintergrund invertieren Hover-Zustände in die andere Richtung.
- Eine solide Hauptaktion pro Bereich; nebeneinanderliegende Aktionen erhalten jeweils ihre eigene Absichtsfarbe und behalten diese, wenn deaktiviert (ausblenden, nicht umranden).
- Titelleisten nur für Panels. Tabellen- und Code-Köpfe verwenden den weichen Farbton
--hud-bar-soft. - Größen stammen aus der Skala: Steuerelemente 24/28/32px, Abstände auf dem 4px-Raster, Text 12/14/16/24/36px.
Fallstricke
- Das Framework erzwingt
border-radius: 0 !importantin seinem Gültigkeitsbereich. Behalte etwas Rundes (einen Avatar), indem das Skin auf einen Container beschränkt wird, der dieses ausschließt. color-mix()benötigt Chrome/Edge 111, Safari 16.2, Firefox 113; für ältere Browser--hud-bar-soft/--hud-bar-linemit einfachen Farben setzen.- Eine Klasse, die
displaysetzt, würdehidden-Elemente anzeigen; das Framework blendet[hidden]in seinem Gültigkeitsbereich wieder aus, also für das Umschalten dashidden-Attribut bevorzugen. - Frameworks, die den Wert eines Feldes aus Code setzen, lösen kein
inputaus; nach einer solchen Änderungfield.__pixelCaret.update()aufrufen, wenn der Cursor sofort springen muss. - Scanlines liegen auf einem sehr hohen z-index mit
pointer-events: none; schalte sie mit `data-hud-scanlines="off"" dort aus, wo sie stören (Screenshots, Canvas-Apps).