Das Anpassen von Standard-HTML-Formularelementen wie Kästchen und Optionsfeldern war bisher schwierig. Entwickler mussten sich oft entscheiden, ob sie die Standardeinstellungen des Browsers verwenden oder benutzerdefinierte Komponenten von Grund auf neu erstellen wollten. Das Erstellen benutzerdefinierter Steuerelemente ist zeitaufwendig und kann leicht zu Problemen mit der Barrierefreiheit oder fehlenden Zuständen führen (z. B. der unbestimmte Zustand für Kästchen).
Die CSS-Eigenschaft accent-color bietet eine einfache Möglichkeit, Ihre Markenfarbe mit einer einzigen Zeile CSS in integrierte HTML-Formulareingaben einzubringen, ohne die Barrierefreiheit oder integrierte Browserfunktionen zu beeinträchtigen.
Implementierung
So wenden Sie die Markenfarbe auf Formularsteuerelemente an:
- Markenfarbe festlegen: Wählen Sie eine Farbe aus, die Ihre Marke repräsentiert.
- Attribut
accent-coloranwenden: Fügen Sieaccent-colordem Element oder einem Container-Element (z. B.bodyoder einem bestimmten Formular) in Ihrem CSS hinzu. - Dunklen Modus unterstützen (optional, aber empfohlen): Verwende
color-scheme, um dem Browser mitzuteilen, dass deine Website den dunklen Modus unterstützt, und passe bei Bedarf dieaccent-colorfür einen besseren Kontrast an.
Beispielcode: Markenkonsistente Formularsteuerelemente
:root {
--brand-color: #6200ee;
}
/* Apply accent-color to the body or a specific container */
body {
accent-color: var(--brand-color);
}
/* Optional: Adjust for dark mode if needed */
@media (prefers-color-scheme: dark) {
:root {
--brand-color: #bb86fc; /* A lighter shade for dark mode */
}
}
<form>
<!-- Checkbox -->
<label for="subscribe">
<input type="checkbox" id="subscribe" checked>
Subscribe to newsletter
</label>
<!-- Radio Buttons -->
<label for="plan-monthly">
<input type="radio" id="plan-monthly" name="plan" value="monthly">
Monthly
</label>
<label for="plan-yearly">
<input type="radio" id="plan-yearly" name="plan" value="yearly" checked>
Yearly
</label>
<!-- Range Slider -->
<label for="volume">Volume:</label>
<input type="range" id="volume" min="0" max="100" value="70">
<!-- Progress Bar -->
<label for="file">Upload Progress:</label>
<progress id="file" max="100" value="70">70%</progress>
</form>
Strategische Implementierung und Best Practices
- DO use
accent-colorto easily theme form controls to match your brand. - Verlassen Sie sich NICHT blind darauf, dass der Browser den Kontrast richtig darstellt. Browser sollten zwar automatisch eine geeignete Kontrastfarbe bestimmen, aber bekannte Fehler in Implementierungen wie Safari (WebKit-Fehler 244233) und Android Chrome (Chromium-Fehler 343503163) können dazu führen, dass die Farben von Häkchen nicht invertiert werden. Das kann dazu führen, dass Steuerelemente unsichtbar oder schwer zu erkennen sind, wenn Farben verwendet werden, die keinen ausreichenden Kontrast zum Hintergrund haben (z. B. helle Farben im hellen Modus oder dunkle Farben im dunklen Modus).
- DO combine
accent-colorwithcolor-scheme: light darkto ensure form controls look good in both light and dark themes. - Verwenden Sie KEINE Farbe, die der Hintergrundfarbe zu ähnlich ist. Auch wenn Browser versuchen, einen Kontrast zu gewährleisten, ist es am besten, eine Farbe mit gutem Grundkontrast zu verwenden.
- Gehen Sie NICHT davon aus, dass
accent-colorfür alle Formularelemente funktioniert. Derzeit werden nurcheckbox-,radio-,range- undprogress-Elemente eingefärbt.
Fallback-Strategie
In Browsern, die accent-color nicht unterstützen, werden die Formularsteuerelemente auf die Standarddarstellung des Browsers zurückgesetzt. Um eine vollständige Markenkonsistenz und hohe Zuverlässigkeit in allen Umgebungen zu gewährleisten, MÜSSEN Sie eine benutzerdefinierte Fallback-Strategie mit der etablierten Technik „Visuell ausgeblendete Eingabe“ implementieren.
Progressive Verbesserung mit @supports not
Sie MÜSSEN die Regel @supports not verwenden, um benutzerdefinierte Fallback-Stile nur dann anzuwenden, wenn accent-color nicht unterstützt wird. So können Sie die Einfachheit von accent-color für moderne Browser nutzen und gleichzeitig ein einheitliches Branding für ältere Browser gewährleisten.
1. HTML-Struktur
Achten Sie darauf, dass der Text in Ihren Labels in ein <span>-Element eingeschlossen ist, um Geschwisterselektoren in CSS zu ermöglichen:
<label for="subscribe-fallback">
<input type="checkbox" id="subscribe-fallback" class="visually-hidden" checked>
<span>Subscribe to newsletter</span>
</label>
2. CSS-Fallback
Benutzerdefinierte Stile in einem @supports not-Block anwenden:
/* Fallback for older browsers without accent-color */
@supports not (accent-color: var(--brand-color)) {
/* Visually hide the native input using the canonical accessible recipe */
form input[type="checkbox"].visually-hidden {
position: absolute !important;
clip-path: inset(50%) !important;
overflow: hidden !important;
width: 1px !important;
height: 1px !important;
margin: -1px !important;
padding: 0 !important;
border: 0 !important;
white-space: nowrap !important;
}
/* Style the wrapper label */
label {
position: relative;
padding-left: 2rem;
cursor: pointer;
display: inline-flex;
align-items: center;
}
/* Custom box for checkbox */
input[type="checkbox"] + span::before {
content: "";
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
width: 1.2rem;
height: 1.2rem;
border: 2px solid #ccc;
background: white;
border-radius: 4px;
box-sizing: border-box;
transition: all 0.2s ease;
}
/* Ensure custom checkbox shows focus for keyboard users */
input[type="checkbox"]:focus-visible + span::before {
outline: 2px solid #000;
outline-offset: 2px;
}
/* Checked State */
input[type="checkbox"]:checked + span::before {
background-color: var(--brand-color, #6200ee);
border-color: var(--brand-color, #6200ee);
}
/* Checkmark (Unicode) */
input[type="checkbox"]:checked + span::after {
content: "✓";
position: absolute;
left: 0.25rem;
top: 50%;
transform: translateY(-50%);
color: white;
font-weight: bold;
font-size: 0.9rem;
}
/* Fallback for Range Slider */
input[type="range"] {
-webkit-appearance: none;
appearance: none;
background: transparent;
}
/* Webkit (Chrome, Safari, Edge) */
input[type="range"]::-webkit-slider-runnable-track {
width: 100%;
height: 8px;
/* Use gradient to show progress for a static value (e.g., 70%) or update with JS */
background: linear-gradient(to right, var(--brand-color, #6200ee) 70%, #ccc 70%);
border-radius: 4px;
}
input[type="range"]::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
height: 16px;
width: 16px;
border-radius: 50%;
background: var(--brand-color, #6200ee);
cursor: pointer;
margin-top: -4px; /* Center vertically */
}
/* Firefox */
input[type="range"]::-moz-range-track {
width: 100%;
height: 8px;
background: #ccc;
border-radius: 4px;
}
input[type="range"]::-moz-range-thumb {
height: 16px;
width: 16px;
border-radius: 50%;
background: var(--brand-color, #6200ee);
cursor: pointer;
}
/* Firefox specific progress bar */
input[type="range"]::-moz-range-progress {
background-color: var(--brand-color, #6200ee);
height: 8px;
border-radius: 4px;
}
/* Fallback for Progress Bar */
progress {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
border: none;
background: #ccc;
height: 8px;
border-radius: 4px;
}
progress::-webkit-progress-bar {
background-color: #ccc;
border-radius: 4px;
}
progress::-webkit-progress-value {
background-color: var(--brand-color, #6200ee);
border-radius: 4px;
}
progress::-moz-progress-bar {
background-color: var(--brand-color, #6200ee);
border-radius: 4px;
}
}
Fortschritt des Dynamikbereichs im Webkit-Fallback
Damit sich die Fortschrittsanzeige in Webkit-Browsern (ohne accent-color) mit dem Schieberegler bewegt, können Sie eine CSS-Variable und ein wenig JavaScript verwenden.
CSS aktualisieren: Verwenden Sie eine CSS-Variable für den Farbverlaufsstopp:
input[type="range"]::-webkit-slider-runnable-track { background: linear-gradient(to right, var(--brand-color) var(--progress, 0%), #ccc var(--progress, 0%)); }JavaScript hinzufügen: Aktualisieren Sie die Variable im Ereignis
input:
if (!CSS.supports('accent-color')) {
const slider = document.getElementById('volume');
slider.addEventListener('input', (e) => {
e.target.style.setProperty('--progress', `${e.target.value}%`);
});
}