style(next): fall back to the user agent's default check boxes and radio buttons if the ":has" selector is not supported

This commit is contained in:
Adorian Doran 2025-01-24 22:45:58 +02:00
parent 41ef47576d
commit 97295e959b

View File

@ -183,135 +183,141 @@ optgroup {
line-height: 40px; line-height: 40px;
} }
/* Check box & radio button commons */ /* Check boxes and radio buttons */
/* The parent label */ @supports selector(label:has(*)) {
label.tn-radio,
label.tn-checkbox {
--box-size: 1em;
--box-label-gap: .5em;
position: relative; /* Check box & radio button commons */
padding-left: calc(var(--box-size) + var(--box-label-gap)) !important;
user-select: none;
} /* The parent label */
label.tn-radio,
label.tn-checkbox {
--box-size: 1em;
--box-label-gap: .5em;
/* The original input */ position: relative;
label.tn-radio > input[type="radio"], padding-left: calc(var(--box-size) + var(--box-label-gap)) !important;
label.tn-checkbox > input[type="checkbox"] { user-select: none;
position: absolute;
top: 0;
left: 0;
width: var(--box-size);
height: 100%;
opacity: 0 !important;
}
label.tn-radio::before, }
label.tn-radio::after,
label.tn-checkbox::before,
label.tn-checkbox::after {
content: "";
position: absolute;
top: 50%;
left: 0;
translate: 0 -50%;
width: var(--box-size);
height: var(--box-size);
}
label.tn-radio:has(>input[type="radio"]:focus-visible)::before, /* The original input */
label.tn-checkbox:has(>input[type="checkbox"]:focus-visible)::before { label.tn-radio > input[type="radio"],
outline: 2px solid var(--input-focus-outline-color); label.tn-checkbox > input[type="checkbox"] {
} position: absolute;
top: 0;
left: 0;
width: var(--box-size);
height: 100%;
opacity: 0 !important;
}
/* Check boxes */ label.tn-radio::before,
label.tn-radio::after,
label.tn-checkbox::before,
label.tn-checkbox::after {
content: "";
position: absolute;
top: 50%;
left: 0;
translate: 0 -50%;
width: var(--box-size);
height: var(--box-size);
}
/* The check box background */ label.tn-radio:has(>input[type="radio"]:focus-visible)::before,
label.tn-checkbox::before { label.tn-checkbox:has(>input[type="checkbox"]:focus-visible)::before {
border-radius: 3px; outline: 2px solid var(--input-focus-outline-color);
background: var(--radio-checkbox-background); }
}
label.tn-checkbox:has(>input[type="checkbox"]:not(:disabled)):hover:before { /* Check boxes */
background: var(--radio-checkbox-hover-background);
}
@keyframes checkbox-checked { /* The check box background */
from { label.tn-checkbox::before {
transform: scale(2); border-radius: 3px;
} to { background: var(--radio-checkbox-background);
}
label.tn-checkbox:has(>input[type="checkbox"]:not(:disabled)):hover:before {
background: var(--radio-checkbox-hover-background);
}
@keyframes checkbox-checked {
from {
transform: scale(2);
} to {
transform: scale(1);
}
}
/* The tick mark */
label.tn-checkbox::after {
mask-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3e%3ctitle%3echeck-bold%3c/title%3e%3cpath d='M9%2c20.42L2.79%2c14.21L5.62%2c11.38L9%2c14.77L18.88%2c4.88L21.71%2c7.71L9%2c20.42Z' /%3e%3c/svg%3e");
mask-position: center center;
mask-size: .95em;
background-color: var(--radio-checkbox-indicator-color);
transform: scale(0);
opacity: 0;
transition: transform 300ms ease-out,
opacity 300ms linear;
}
label.tn-checkbox:has(>input[type="checkbox"]:checked)::after {
opacity: 1;
transform: scale(1); transform: scale(1);
transition: opacity 100ms ease-in-out;
animation: checkbox-checked 150ms ease-out;
} }
}
/* The tick mark */ /* Radio buttons */
label.tn-checkbox::after {
mask-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3e%3ctitle%3echeck-bold%3c/title%3e%3cpath d='M9%2c20.42L2.79%2c14.21L5.62%2c11.38L9%2c14.77L18.88%2c4.88L21.71%2c7.71L9%2c20.42Z' /%3e%3c/svg%3e");
mask-position: center center;
mask-size: .95em;
background-color: var(--radio-checkbox-indicator-color);
transform: scale(0);
opacity: 0;
transition: transform 300ms ease-out,
opacity 300ms linear;
}
label.tn-checkbox:has(>input[type="checkbox"]:checked)::after { label.tn-radio::before,
opacity: 1; label.tn-radio::after {
transform: scale(1); border-radius: 50%;
transition: opacity 100ms ease-in-out; }
animation: checkbox-checked 150ms ease-out;
}
/* Radio buttons */ /* The outer circle */
label.tn-radio::before {
background: var(--radio-checkbox-background);
}
label.tn-radio::before, label.tn-radio:has(>input[type="radio"]:not(:disabled)):hover::before {
label.tn-radio::after { background: var(--radio-checkbox-hover-background);
border-radius: 50%; }
}
/* The outer circle */ @keyframes radio-checked {
label.tn-radio::before { from {
background: var(--radio-checkbox-background); transform: scale(1.5);
} } to {
transform: scale(.5);
}
}
label.tn-radio:has(>input[type="radio"]:not(:disabled)):hover::before { /* The inner circle */
background: var(--radio-checkbox-hover-background); label.tn-radio::after {
} background: var(--radio-checkbox-indicator-color);
transform: scale(0);
opacity: 0;
transition: opacity 300ms linear,
transform 300ms ease-in;
}
@keyframes radio-checked { label.tn-radio:has(>input[type="radio"]:checked)::after {
from {
transform: scale(1.5);
} to {
transform: scale(.5); transform: scale(.5);
opacity: 1;
transition: opacity 150ms linear;
animation: radio-checked 200ms ease-out;
} }
}
/* The inner circle */ /* Disabled check boxes and radio buttons */
label.tn-radio::after {
background: var(--radio-checkbox-indicator-color);
transform: scale(0);
opacity: 0;
transition: opacity 300ms linear,
transform 300ms ease-in;
}
label.tn-radio:has(>input[type="radio"]:checked)::after { label.tn-radio:has(> input[type="radio"]:disabled)::before,
transform: scale(.5); label.tn-radio:has(> input[type="radio"]:disabled)::after,
opacity: 1; label.tn-checkbox:has(> input[type="checkbox"]:disabled)::before,
transition: opacity 150ms linear; label.tn-checkbox:has(> input[type="checkbox"]:disabled)::after {
animation: radio-checked 200ms ease-out; opacity: .5;
} }
/* Disabled check boxes and radio buttons */
label.tn-radio:has(> input[type="radio"]:disabled)::before,
label.tn-radio:has(> input[type="radio"]:disabled)::after,
label.tn-checkbox:has(> input[type="checkbox"]:disabled)::before,
label.tn-checkbox:has(> input[type="checkbox"]:disabled)::after {
opacity: .5;
} }
/* Links */ /* Links */