Styling contract
Headless checkbox styling is native-first. You own the label shell and can target state through data-state, data-focus-visible, data-invalid, and the other emitted attributes on the input itself.
CSS contracts
| Selector | Why it exists |
|---|---|
input[tngCheckbox] | Base selector for native sizing, accent color, and cursor policies. |
[data-state='checked' | 'unchecked' | 'mixed'] | Single source of truth for visual state changes. |
[data-focus-visible] | Keyboard-aware focus styling hook. |
[data-invalid], [data-readonly], [data-disabled] | State selectors for validation and interaction rules. |
State selectors
checkbox.states.css
css
input[tngCheckbox][data-state="checked"] {
accent-color: var(--tng-semantic-accent-brand, #2563eb);
}
input[tngCheckbox][data-mixed] {
accent-color: var(--tng-semantic-accent-brand, #2563eb);
}
input[tngCheckbox][data-invalid] {
outline: 2px solid color-mix(in srgb, var(--tng-semantic-accent-danger, #dc2626) 55%, white);
outline-offset: 2px;
}
input[tngCheckbox][data-focus-visible] {
outline: 2px solid color-mix(in srgb, var(--tng-semantic-accent-brand, #2563eb) 70%, white);
outline-offset: 2px;
}
Example shells
checkbox.shell.css
css
.checkbox-filter-card {
display: grid;
gap: 0.75rem;
inline-size: min(100%, 26rem);
margin-inline: auto;
padding: 1rem;
border: 1px solid var(--tng-semantic-border-subtle, #cbd5e1);
border-radius: 0.9rem;
background: var(--tng-semantic-background-base, #ffffff);
}
.checkbox-filter-card__row {
display: inline-flex;
align-items: center;
gap: 0.65rem;
color: var(--tng-semantic-foreground-primary, #0f172a);
}
Status filter shell
The primitive stays native while your wrapper card and label rows carry the visual language.