51 CSS Buttons38 / 51
CSS Chalkboard Menu Button
Slate with real chalk behaviour: a dusty, slightly uneven board, a hand-drawn double border, letterforms that sit in the tooth of the surface via a soft light shadow, and a puff of chalk dust when you press. The hover wipes a faint smudge across the board.
Published Updated
The code
<div class="cb-38">
<div class="cb-38__stage">
<button class="cb-38__btn" type="button">
<span class="cb-38__smudge" aria-hidden="true"></span>
<span class="cb-38__dust" aria-hidden="true"></span>
<span class="cb-38__label">Today's special</span>
</button>
</div>
</div><div class="cb-38">
<div class="cb-38__stage">
<button class="cb-38__btn" type="button">
<span class="cb-38__smudge" aria-hidden="true"></span>
<span class="cb-38__dust" aria-hidden="true"></span>
<span class="cb-38__label">Today's special</span>
</button>
</div>
</div>@import url('https://fonts.googleapis.com/css2?family=Patrick+Hand&display=swap');
.cb-38 {
--bg: #20242b;
--slate: #26302f;
--slate-2: #1b2322;
--chalk: #f4f1e6;
--frame: .35rem;
--hand: "Patrick Hand",ui-rounded,"Comic Sans MS",cursive;
width: 100%;
min-height: 100vh;
min-height: 100svh;
display: block;
background: repeating-linear-gradient(92deg, rgba(0,0,0,.05) 0 2px, transparent 2px 9px), var(--bg);
font-family: var(--hand);
}
@supports (color: oklch(50% 0 0)) {
.cb-38 {
--slate: oklch(30% .015 175);
--slate-2: oklch(23% .015 175);
--chalk: oklch(96% .01 90);
}
}
@media (prefers-color-scheme: light) {
.cb-38:not([data-theme="dark"]) {
--bg: #2c3238;
}
}
.cb-38[data-theme="light"] {
--bg: #2c3238;
}
.cb-38,
.cb-38 *,
.cb-38 *::before,
.cb-38 *::after {
box-sizing: border-box;
}
.cb-38__stage {
min-height: 100vh;
min-height: 100svh;
display: grid;
place-items: center;
padding: clamp(1.5rem,6vw,4rem);
}
.cb-38__btn {
position: relative;
cursor: pointer;
display: grid;
place-items: center;
min-height: 4.25rem;
padding: 0 2.75rem;
border: 2px dashed color-mix(in oklab,var(--chalk) 52%,transparent);
border-radius: .5rem;
font: inherit;
font-size: 1.5rem;
letter-spacing: .02em;
background-color: var(--slate);
background-image: radial-gradient(.08rem .08rem at 24% 36%, rgba(244,241,230,.2) 99%, transparent), radial-gradient(.06rem .06rem at 68% 72%, rgba(244,241,230,.16) 99%, transparent), radial-gradient(8rem 5rem at 20% 15%, rgba(255,255,255,.05), transparent 70%), radial-gradient(9rem 6rem at 82% 88%, rgba(255,255,255,.04), transparent 72%), linear-gradient(160deg, var(--slate), var(--slate-2));
background-size: 9px 9px, 13px 13px, 100% 100%, 100% 100%, 100% 100%;
box-shadow: 0 16px 26px -16px rgba(0,0,0,.8), inset 0 0 30px rgba(0,0,0,.35);
transition: translate .22s cubic-bezier(.16,1,.3,1), box-shadow .25s ease;
-webkit-tap-highlight-color: transparent;
}
.cb-38__btn::before {
content: '';
position: absolute;
inset: var(--frame);
pointer-events: none;
border: 1px dashed color-mix(in oklab,var(--chalk) 28%,transparent);
border-radius: .35rem;
rotate: .25deg;
}
.cb-38__label {
position: relative;
z-index: 3;
color: color-mix(in oklab,var(--chalk) 92%,transparent);
text-shadow: 0 0 1px color-mix(in oklab,var(--chalk) 55%,transparent), 0 0 7px color-mix(in oklab,var(--chalk) 20%,transparent), 0 1px 0 rgba(0,0,0,.35);
}
.cb-38__smudge {
position: absolute;
inset: 0;
z-index: 2;
pointer-events: none;
opacity: 0;
background: linear-gradient(104deg, transparent 30%, rgba(244,241,230,.1) 50%, transparent 70%);
transition: opacity .4s ease;
}
.cb-38__btn:is(:hover,:focus-visible) {
translate: 0 -2px;
}
.cb-38__btn:is(:hover,:focus-visible) .cb-38__smudge {
opacity: 1;
}
.cb-38__btn:focus-visible {
outline: 2px solid var(--chalk);
outline-offset: 5px;
}
.cb-38__btn:active {
translate: 0 1px;
box-shadow: 0 6px 12px -10px rgba(0,0,0,.8), inset 0 0 36px rgba(0,0,0,.45);
}
.cb-38__dust {
position: absolute;
left: 50%;
bottom: -.5rem;
width: 8rem;
height: 1.2rem;
margin-left: -4rem;
border-radius: 50%;
pointer-events: none;
opacity: 0;
background: radial-gradient(closest-side, rgba(244,241,230,.6), transparent 74%);
filter: blur(4px);
}
.cb-38__btn:active .cb-38__dust {
animation: cb-38-dust .6s ease-out;
}
@keyframes cb-38-dust {
0% {
opacity: .75;
scale: .4 .5;
}
100% {
opacity: 0;
scale: 1.6 1.4;
}
}
.cb-38__btn:disabled {
cursor: not-allowed;
opacity: .55;
}
@media (prefers-reduced-motion: reduce) {
.cb-38__btn,
.cb-38__smudge {
transition: none;
}
.cb-38__dust {
display: none;
}
}
@media (forced-colors: active) {
.cb-38__btn {
background: ButtonFace;
border: 2px solid ButtonText;
box-shadow: none;
}
.cb-38__label {
color: ButtonText;
text-shadow: none;
}
.cb-38__smudge,
.cb-38__dust {
display: none;
}
.cb-38__btn::before {
display: none;
}
}@import url('https://fonts.googleapis.com/css2?family=Patrick+Hand&display=swap');
.cb-38 {
--bg: #20242b;
--slate: #26302f;
--slate-2: #1b2322;
--chalk: #f4f1e6;
--frame: .35rem;
--hand: "Patrick Hand",ui-rounded,"Comic Sans MS",cursive;
width: 100%;
min-height: 100vh;
min-height: 100svh;
display: block;
background: repeating-linear-gradient(92deg, rgba(0,0,0,.05) 0 2px, transparent 2px 9px), var(--bg);
font-family: var(--hand);
}
@supports (color: oklch(50% 0 0)) {
.cb-38 {
--slate: oklch(30% .015 175);
--slate-2: oklch(23% .015 175);
--chalk: oklch(96% .01 90);
}
}
@media (prefers-color-scheme: light) {
.cb-38:not([data-theme="dark"]) {
--bg: #2c3238;
}
}
.cb-38[data-theme="light"] {
--bg: #2c3238;
}
.cb-38,
.cb-38 *,
.cb-38 *::before,
.cb-38 *::after {
box-sizing: border-box;
}
.cb-38__stage {
min-height: 100vh;
min-height: 100svh;
display: grid;
place-items: center;
padding: clamp(1.5rem,6vw,4rem);
}
.cb-38__btn {
position: relative;
cursor: pointer;
display: grid;
place-items: center;
min-height: 4.25rem;
padding: 0 2.75rem;
border: 2px dashed color-mix(in oklab,var(--chalk) 52%,transparent);
border-radius: .5rem;
font: inherit;
font-size: 1.5rem;
letter-spacing: .02em;
background-color: var(--slate);
background-image: radial-gradient(.08rem .08rem at 24% 36%, rgba(244,241,230,.2) 99%, transparent), radial-gradient(.06rem .06rem at 68% 72%, rgba(244,241,230,.16) 99%, transparent), radial-gradient(8rem 5rem at 20% 15%, rgba(255,255,255,.05), transparent 70%), radial-gradient(9rem 6rem at 82% 88%, rgba(255,255,255,.04), transparent 72%), linear-gradient(160deg, var(--slate), var(--slate-2));
background-size: 9px 9px, 13px 13px, 100% 100%, 100% 100%, 100% 100%;
box-shadow: 0 16px 26px -16px rgba(0,0,0,.8), inset 0 0 30px rgba(0,0,0,.35);
transition: translate .22s cubic-bezier(.16,1,.3,1), box-shadow .25s ease;
-webkit-tap-highlight-color: transparent;
}
.cb-38__btn::before {
content: '';
position: absolute;
inset: var(--frame);
pointer-events: none;
border: 1px dashed color-mix(in oklab,var(--chalk) 28%,transparent);
border-radius: .35rem;
rotate: .25deg;
}
.cb-38__label {
position: relative;
z-index: 3;
color: color-mix(in oklab,var(--chalk) 92%,transparent);
text-shadow: 0 0 1px color-mix(in oklab,var(--chalk) 55%,transparent), 0 0 7px color-mix(in oklab,var(--chalk) 20%,transparent), 0 1px 0 rgba(0,0,0,.35);
}
.cb-38__smudge {
position: absolute;
inset: 0;
z-index: 2;
pointer-events: none;
opacity: 0;
background: linear-gradient(104deg, transparent 30%, rgba(244,241,230,.1) 50%, transparent 70%);
transition: opacity .4s ease;
}
.cb-38__btn:is(:hover,:focus-visible) {
translate: 0 -2px;
}
.cb-38__btn:is(:hover,:focus-visible) .cb-38__smudge {
opacity: 1;
}
.cb-38__btn:focus-visible {
outline: 2px solid var(--chalk);
outline-offset: 5px;
}
.cb-38__btn:active {
translate: 0 1px;
box-shadow: 0 6px 12px -10px rgba(0,0,0,.8), inset 0 0 36px rgba(0,0,0,.45);
}
.cb-38__dust {
position: absolute;
left: 50%;
bottom: -.5rem;
width: 8rem;
height: 1.2rem;
margin-left: -4rem;
border-radius: 50%;
pointer-events: none;
opacity: 0;
background: radial-gradient(closest-side, rgba(244,241,230,.6), transparent 74%);
filter: blur(4px);
}
.cb-38__btn:active .cb-38__dust {
animation: cb-38-dust .6s ease-out;
}
@keyframes cb-38-dust {
0% {
opacity: .75;
scale: .4 .5;
}
100% {
opacity: 0;
scale: 1.6 1.4;
}
}
.cb-38__btn:disabled {
cursor: not-allowed;
opacity: .55;
}
@media (prefers-reduced-motion: reduce) {
.cb-38__btn,
.cb-38__smudge {
transition: none;
}
.cb-38__dust {
display: none;
}
}
@media (forced-colors: active) {
.cb-38__btn {
background: ButtonFace;
border: 2px solid ButtonText;
box-shadow: none;
}
.cb-38__label {
color: ButtonText;
text-shadow: none;
}
.cb-38__smudge,
.cb-38__dust {
display: none;
}
.cb-38__btn::before {
display: none;
}
}Here's a working CSS Button from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: CSS Chalkboard Menu Button
Source: https://codefronts.com/components/css-buttons/css-chalkboard-menu-button/
Slate with real chalk behaviour: a dusty, slightly uneven board, a hand-drawn double border, letterforms that sit in the tooth of the surface via a soft light shadow, and a puff of chalk dust when you press. The hover wipes a faint smudge across the board.
## HTML
```html
<div class="cb-38">
<div class="cb-38__stage">
<button class="cb-38__btn" type="button">
<span class="cb-38__smudge" aria-hidden="true"></span>
<span class="cb-38__dust" aria-hidden="true"></span>
<span class="cb-38__label">Today's special</span>
</button>
</div>
</div>
```
## CSS
```css
@import url('https://fonts.googleapis.com/css2?family=Patrick+Hand&display=swap');
.cb-38 {
--bg: #20242b;
--slate: #26302f;
--slate-2: #1b2322;
--chalk: #f4f1e6;
--frame: .35rem;
--hand: "Patrick Hand",ui-rounded,"Comic Sans MS",cursive;
width: 100%;
min-height: 100vh;
min-height: 100svh;
display: block;
background: repeating-linear-gradient(92deg, rgba(0,0,0,.05) 0 2px, transparent 2px 9px), var(--bg);
font-family: var(--hand);
}
@supports (color: oklch(50% 0 0)) {
.cb-38 {
--slate: oklch(30% .015 175);
--slate-2: oklch(23% .015 175);
--chalk: oklch(96% .01 90);
}
}
@media (prefers-color-scheme: light) {
.cb-38:not([data-theme="dark"]) {
--bg: #2c3238;
}
}
.cb-38[data-theme="light"] {
--bg: #2c3238;
}
.cb-38,
.cb-38 *,
.cb-38 *::before,
.cb-38 *::after {
box-sizing: border-box;
}
.cb-38__stage {
min-height: 100vh;
min-height: 100svh;
display: grid;
place-items: center;
padding: clamp(1.5rem,6vw,4rem);
}
.cb-38__btn {
position: relative;
cursor: pointer;
display: grid;
place-items: center;
min-height: 4.25rem;
padding: 0 2.75rem;
border: 2px dashed color-mix(in oklab,var(--chalk) 52%,transparent);
border-radius: .5rem;
font: inherit;
font-size: 1.5rem;
letter-spacing: .02em;
background-color: var(--slate);
background-image: radial-gradient(.08rem .08rem at 24% 36%, rgba(244,241,230,.2) 99%, transparent), radial-gradient(.06rem .06rem at 68% 72%, rgba(244,241,230,.16) 99%, transparent), radial-gradient(8rem 5rem at 20% 15%, rgba(255,255,255,.05), transparent 70%), radial-gradient(9rem 6rem at 82% 88%, rgba(255,255,255,.04), transparent 72%), linear-gradient(160deg, var(--slate), var(--slate-2));
background-size: 9px 9px, 13px 13px, 100% 100%, 100% 100%, 100% 100%;
box-shadow: 0 16px 26px -16px rgba(0,0,0,.8), inset 0 0 30px rgba(0,0,0,.35);
transition: translate .22s cubic-bezier(.16,1,.3,1), box-shadow .25s ease;
-webkit-tap-highlight-color: transparent;
}
.cb-38__btn::before {
content: '';
position: absolute;
inset: var(--frame);
pointer-events: none;
border: 1px dashed color-mix(in oklab,var(--chalk) 28%,transparent);
border-radius: .35rem;
rotate: .25deg;
}
.cb-38__label {
position: relative;
z-index: 3;
color: color-mix(in oklab,var(--chalk) 92%,transparent);
text-shadow: 0 0 1px color-mix(in oklab,var(--chalk) 55%,transparent), 0 0 7px color-mix(in oklab,var(--chalk) 20%,transparent), 0 1px 0 rgba(0,0,0,.35);
}
.cb-38__smudge {
position: absolute;
inset: 0;
z-index: 2;
pointer-events: none;
opacity: 0;
background: linear-gradient(104deg, transparent 30%, rgba(244,241,230,.1) 50%, transparent 70%);
transition: opacity .4s ease;
}
.cb-38__btn:is(:hover,:focus-visible) {
translate: 0 -2px;
}
.cb-38__btn:is(:hover,:focus-visible) .cb-38__smudge {
opacity: 1;
}
.cb-38__btn:focus-visible {
outline: 2px solid var(--chalk);
outline-offset: 5px;
}
.cb-38__btn:active {
translate: 0 1px;
box-shadow: 0 6px 12px -10px rgba(0,0,0,.8), inset 0 0 36px rgba(0,0,0,.45);
}
.cb-38__dust {
position: absolute;
left: 50%;
bottom: -.5rem;
width: 8rem;
height: 1.2rem;
margin-left: -4rem;
border-radius: 50%;
pointer-events: none;
opacity: 0;
background: radial-gradient(closest-side, rgba(244,241,230,.6), transparent 74%);
filter: blur(4px);
}
.cb-38__btn:active .cb-38__dust {
animation: cb-38-dust .6s ease-out;
}
@keyframes cb-38-dust {
0% {
opacity: .75;
scale: .4 .5;
}
100% {
opacity: 0;
scale: 1.6 1.4;
}
}
.cb-38__btn:disabled {
cursor: not-allowed;
opacity: .55;
}
@media (prefers-reduced-motion: reduce) {
.cb-38__btn,
.cb-38__smudge {
transition: none;
}
.cb-38__dust {
display: none;
}
}
@media (forced-colors: active) {
.cb-38__btn {
background: ButtonFace;
border: 2px solid ButtonText;
box-shadow: none;
}
.cb-38__label {
color: ButtonText;
text-shadow: none;
}
.cb-38__smudge,
.cb-38__dust {
display: none;
}
.cb-38__btn::before {
display: none;
}
}
```Here's a working CSS Button from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: CSS Chalkboard Menu Button
Source: https://codefronts.com/components/css-buttons/css-chalkboard-menu-button/
Slate with real chalk behaviour: a dusty, slightly uneven board, a hand-drawn double border, letterforms that sit in the tooth of the surface via a soft light shadow, and a puff of chalk dust when you press. The hover wipes a faint smudge across the board.
## HTML
```html
<div class="cb-38">
<div class="cb-38__stage">
<button class="cb-38__btn" type="button">
<span class="cb-38__smudge" aria-hidden="true"></span>
<span class="cb-38__dust" aria-hidden="true"></span>
<span class="cb-38__label">Today's special</span>
</button>
</div>
</div>
```
## CSS
```css
@import url('https://fonts.googleapis.com/css2?family=Patrick+Hand&display=swap');
.cb-38 {
--bg: #20242b;
--slate: #26302f;
--slate-2: #1b2322;
--chalk: #f4f1e6;
--frame: .35rem;
--hand: "Patrick Hand",ui-rounded,"Comic Sans MS",cursive;
width: 100%;
min-height: 100vh;
min-height: 100svh;
display: block;
background: repeating-linear-gradient(92deg, rgba(0,0,0,.05) 0 2px, transparent 2px 9px), var(--bg);
font-family: var(--hand);
}
@supports (color: oklch(50% 0 0)) {
.cb-38 {
--slate: oklch(30% .015 175);
--slate-2: oklch(23% .015 175);
--chalk: oklch(96% .01 90);
}
}
@media (prefers-color-scheme: light) {
.cb-38:not([data-theme="dark"]) {
--bg: #2c3238;
}
}
.cb-38[data-theme="light"] {
--bg: #2c3238;
}
.cb-38,
.cb-38 *,
.cb-38 *::before,
.cb-38 *::after {
box-sizing: border-box;
}
.cb-38__stage {
min-height: 100vh;
min-height: 100svh;
display: grid;
place-items: center;
padding: clamp(1.5rem,6vw,4rem);
}
.cb-38__btn {
position: relative;
cursor: pointer;
display: grid;
place-items: center;
min-height: 4.25rem;
padding: 0 2.75rem;
border: 2px dashed color-mix(in oklab,var(--chalk) 52%,transparent);
border-radius: .5rem;
font: inherit;
font-size: 1.5rem;
letter-spacing: .02em;
background-color: var(--slate);
background-image: radial-gradient(.08rem .08rem at 24% 36%, rgba(244,241,230,.2) 99%, transparent), radial-gradient(.06rem .06rem at 68% 72%, rgba(244,241,230,.16) 99%, transparent), radial-gradient(8rem 5rem at 20% 15%, rgba(255,255,255,.05), transparent 70%), radial-gradient(9rem 6rem at 82% 88%, rgba(255,255,255,.04), transparent 72%), linear-gradient(160deg, var(--slate), var(--slate-2));
background-size: 9px 9px, 13px 13px, 100% 100%, 100% 100%, 100% 100%;
box-shadow: 0 16px 26px -16px rgba(0,0,0,.8), inset 0 0 30px rgba(0,0,0,.35);
transition: translate .22s cubic-bezier(.16,1,.3,1), box-shadow .25s ease;
-webkit-tap-highlight-color: transparent;
}
.cb-38__btn::before {
content: '';
position: absolute;
inset: var(--frame);
pointer-events: none;
border: 1px dashed color-mix(in oklab,var(--chalk) 28%,transparent);
border-radius: .35rem;
rotate: .25deg;
}
.cb-38__label {
position: relative;
z-index: 3;
color: color-mix(in oklab,var(--chalk) 92%,transparent);
text-shadow: 0 0 1px color-mix(in oklab,var(--chalk) 55%,transparent), 0 0 7px color-mix(in oklab,var(--chalk) 20%,transparent), 0 1px 0 rgba(0,0,0,.35);
}
.cb-38__smudge {
position: absolute;
inset: 0;
z-index: 2;
pointer-events: none;
opacity: 0;
background: linear-gradient(104deg, transparent 30%, rgba(244,241,230,.1) 50%, transparent 70%);
transition: opacity .4s ease;
}
.cb-38__btn:is(:hover,:focus-visible) {
translate: 0 -2px;
}
.cb-38__btn:is(:hover,:focus-visible) .cb-38__smudge {
opacity: 1;
}
.cb-38__btn:focus-visible {
outline: 2px solid var(--chalk);
outline-offset: 5px;
}
.cb-38__btn:active {
translate: 0 1px;
box-shadow: 0 6px 12px -10px rgba(0,0,0,.8), inset 0 0 36px rgba(0,0,0,.45);
}
.cb-38__dust {
position: absolute;
left: 50%;
bottom: -.5rem;
width: 8rem;
height: 1.2rem;
margin-left: -4rem;
border-radius: 50%;
pointer-events: none;
opacity: 0;
background: radial-gradient(closest-side, rgba(244,241,230,.6), transparent 74%);
filter: blur(4px);
}
.cb-38__btn:active .cb-38__dust {
animation: cb-38-dust .6s ease-out;
}
@keyframes cb-38-dust {
0% {
opacity: .75;
scale: .4 .5;
}
100% {
opacity: 0;
scale: 1.6 1.4;
}
}
.cb-38__btn:disabled {
cursor: not-allowed;
opacity: .55;
}
@media (prefers-reduced-motion: reduce) {
.cb-38__btn,
.cb-38__smudge {
transition: none;
}
.cb-38__dust {
display: none;
}
}
@media (forced-colors: active) {
.cb-38__btn {
background: ButtonFace;
border: 2px solid ButtonText;
box-shadow: none;
}
.cb-38__label {
color: ButtonText;
text-shadow: none;
}
.cb-38__smudge,
.cb-38__dust {
display: none;
}
.cb-38__btn::before {
display: none;
}
}
```How this works
Chalk type is not white text — it is a slightly transparent off-white with a soft light bloom and a very faint dark offset, which is how pigment sits in a rough surface:
.cb-38__label{
color:color-mix(in oklab,var(--chalk) 92%,transparent);
text-shadow:
0 0 1px color-mix(in oklab,var(--chalk) 55%,transparent),
0 0 6px color-mix(in oklab,var(--chalk) 22%,transparent),
0 1px 0 rgba(0,0,0,.35);
}The slate is three layers: a dark base, a broad uneven wash from two offset radial gradients, and a fine dust speckle. The hand-drawn frame is two dashed borders at slightly different insets and dash rhythms, so it reads as drawn rather than printed:
.cb-38__btn{ border:2px dashed color-mix(in oklab,var(--chalk) 55%,transparent); }
.cb-38__btn::before{ content:''; position:absolute; inset:.28rem;
border:1px dashed color-mix(in oklab,var(--chalk) 30%,transparent);
border-radius:.35rem; rotate:.25deg; }The dust is a blurred ellipse under the button, scaled and faded on :active; the smudge is a wide, very low-alpha gradient that sweeps on hover.
Make it yours
- Change
--chalkfor coloured chalk; pastel yellow and pink are period-correct for café boards. - Vary the dash pattern with
border-style:dashedplus different border widths on the two frames. - Add a second smudge layer at a different angle for a heavily-reused board.
- Swap the slate tone via
--slate; a green board reads as a classroom rather than a café.
Gotchas — read before shipping
- Chalk type on slate is genuinely low-contrast. Keep the label at 1.25rem+ and verify contrast with the transparency applied, not the raw token.
- Soft-glow text shadows blur edges; never use them under 1rem or the label turns to fuzz.
- Rotating a decorative frame by a fraction of a degree looks hand-drawn; rotating the button itself makes the hit area unpredictable.
- Speckle plus two dashed borders is a lot of paint — no transitions on those layers.
- In forced-colors mode all texture drops; keep a solid border so the button still reads as one.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 111+ | 16.2+ | 113+ | 111+ |
Layered gradients, dashed borders and text-shadow are baseline. color-mix() needs Chrome 111 / Safari 16.2 / Firefox 113 and falls back to the hex tokens declared first.