Design Engineering Tip:
Use tabular numbers for ticking timers. Proportional digits shift in width on every update.
.timer {
font-variant-numeric: tabular-nums;
}
css tip: 𝚌𝚘𝚕𝚘𝚛-𝚖𝚒𝚡() takes more than two colors now.
.𝚌𝚊𝚛𝚍 {
𝚋𝚊𝚌𝚔𝚐𝚛𝚘𝚞𝚗𝚍: 𝚌𝚘𝚕𝚘𝚛-𝚖𝚒𝚡(𝚒𝚗 𝚘𝚔𝚕𝚊𝚋, 𝚟𝚊𝚛(--𝚜𝚞𝚛𝚏𝚊𝚌𝚎), 𝚟𝚊𝚛(--𝚋𝚛𝚊𝚗𝚍) 𝟸𝟶%, 𝚟𝚊𝚛(--𝚊𝚌𝚌𝚎𝚗𝚝) 𝟷𝟶%);
}
each color keeps the share you give it. the one with no percentage takes the rest, here 70%.
wrapping a two-color mix in a second one scales the inner shares down: at 80% accent, the 20% brand drops to 4%.
CSS tip: Use the scroll-padding and scroll-margin properties to snap the elements to a comfortable distance away from the edges.
This is also useful when the scroll view has a sticky header and you want elements to snap below it.
CSS tip: animate elements in when they appear, even from display: none.
.toast {
transition: opacity .3s, translate .3s;
@starting-style {
opacity: 0;
translate: 0 12px;
}
}
No JS, no "add a class on the next frame" hack. Older browsers just show it instantly.
CSS tip: Enable scroll snapping with "scroll-snap-type" to make a scroll view snap to specific child points based on the defined rules.
Use "scroll-snap-align" on child elements to define the reference point the parent scroll view snaps to.
CSS tip: stop hand-picking a darker hex for every hover state.
.button:hover {
background: color-mix(in oklch, var(--brand), black 15%);
}
Change --brand and the hover shade follows. Works in every modern browser.
html tip 🖼️ - let the browser pick the srcset file for lazy images with sizes="auto".
<𝚒𝚖𝚐 𝚕𝚘𝚊𝚍𝚒𝚗𝚐="𝚕𝚊𝚣𝚢" 𝚜𝚒𝚣𝚎𝚜="𝚊𝚞𝚝𝚘" 𝚜𝚛𝚌𝚜𝚎𝚝="𝚊-𝟺𝟶𝟶.𝚓𝚙𝚐 𝟺𝟶𝟶𝚠, 𝚊-𝟾𝟶𝟶.𝚓𝚙𝚐 𝟾𝟶𝟶𝚠, 𝚊-𝟷𝟼𝟶𝟶.𝚓𝚙𝚐 𝟷𝟼𝟶𝟶𝚠" 𝚜𝚛𝚌="𝚊-𝟾𝟶𝟶.𝚓𝚙𝚐" 𝚠𝚒𝚍𝚝𝚑="𝟷𝟼𝟶𝟶" 𝚑𝚎𝚒𝚐𝚑𝚝="𝟷𝟶𝟼𝟽" 𝚊𝚕𝚝="">
👀 CSS margin-trim - Soon available in all browsers?
If you are a web dev, it's 100% sure you needed it at least once in your life 😅
Lets a container drop the margins of children that touch its edges
https://t.co/gQ0lKP1RbN
Finally coming in Firefox:
https://t.co/x6fBhVlozU
CSS tip: make a carousel snap to each card, no JS.
.carousel {
overflow-x: auto;
scroll-snap-type: x mandatory;
}
.card {
scroll-snap-align: start;
}
Every swipe lands on a full card instead of stopping halfway through one.
CSS tip: Use scrollbar-gutter to avoid layout shifts when a scrollbar appears.
The browser keeps room for the scrollbar even when there's nothing to scroll, so content doesn't shift when it shows up.
If only Chrome supported `color-mix()` with more than 2 `<color>` values 😭🐼
Bug 🪲 493736782 🪲
https://t.co/Y9nPaMSZKl
Firefox already does, supposedly Safari 27 does too (doesn't work in Epiphany for me).
#CSS
A reasonable question from Jens Oliver Meiert: Is the technique of using declarations just once, a lá chained selectors, still a relevant optimization strategy?
https://t.co/veZ4QyrVRz
Left to their own devices, AI coding agents will happily write 100 lines of custom JavaScript for something modern HTML and CSS can do natively in a few lines.
Today, in partnership with @FirefoxWebDevs, @MozDevNet, and @MSEdgeDev, we're releasing Modern Web Guidance 1.0 with 200+ expert guides and Baseline support → https://t.co/lQXQBxUcx1
𝚌𝚘𝚗𝚝𝚛𝚊𝚜𝚝-𝚌𝚘𝚕𝚘𝚛() - a newer color function worth experimenting with.
It automatically picks a contrasting color for a given background.
.𝚋𝚞𝚝𝚝𝚘𝚗 {
𝚋𝚊𝚌𝚔𝚐𝚛𝚘𝚞𝚗𝚍: 𝚟𝚊𝚛(--𝚋𝚛𝚊𝚗𝚍-𝚌𝚘𝚕𝚘𝚛);
𝚌𝚘𝚕𝚘𝚛: 𝚌𝚘𝚗𝚝𝚛𝚊𝚜𝚝-𝚌𝚘𝚕𝚘𝚛(𝚟𝚊𝚛(--𝚋𝚛𝚊𝚗𝚍-𝚌𝚘𝚕𝚘𝚛));
}
Useful for buttons, badges and dynamically themed components where the background color changes.
No manually maintaining light and dark text colors.
design tip 🌀 - delay a spinner, then hold it. show it after 200ms, and once it shows, keep it at least 400ms.
.𝚜𝚙𝚒𝚗𝚗𝚎𝚛 {
𝚘𝚙𝚊𝚌𝚒𝚝𝚢: 𝟶;
𝚊𝚗𝚒𝚖𝚊𝚝𝚒𝚘𝚗: 𝚜𝚑𝚘𝚠 𝟶𝚜 𝟸𝟶𝟶𝚖𝚜 𝚏𝚘𝚛𝚠𝚊𝚛𝚍𝚜, 𝚜𝚙𝚒𝚗 𝟶.𝟾𝚜 𝚕𝚒𝚗𝚎𝚊𝚛 𝚒𝚗𝚏𝚒𝚗𝚒𝚝𝚎;
}
@𝚔𝚎𝚢𝚏𝚛𝚊𝚖𝚎𝚜 𝚜𝚑𝚘𝚠 {
𝚝𝚘 { 𝚘𝚙𝚊𝚌𝚒𝚝𝚢: 𝟷; }
}
a save that takes 100ms never paints it. the hold is a few lines of js:
𝚌𝚘𝚗𝚜𝚝 𝚜𝚝𝚊𝚛𝚝 = 𝚙𝚎𝚛𝚏𝚘𝚛𝚖𝚊𝚗𝚌𝚎.𝚗𝚘𝚠();
𝚋𝚞𝚝𝚝𝚘𝚗.𝚊𝚙𝚙𝚎𝚗𝚍(𝚜𝚙𝚒𝚗𝚗𝚎𝚛);
𝚊𝚠𝚊𝚒𝚝 𝚜𝚊𝚟𝚎();
𝚌𝚘𝚗𝚜𝚝 𝚘𝚗 = 𝚙𝚎𝚛𝚏𝚘𝚛𝚖𝚊𝚗𝚌𝚎.𝚗𝚘𝚠() - 𝚜𝚝𝚊𝚛𝚝 - 𝟸𝟶𝟶;
𝚒𝚏 (𝚘𝚗 > 𝟶) 𝚊𝚠𝚊𝚒𝚝 𝚗𝚎𝚠 𝙿𝚛𝚘𝚖𝚒𝚜𝚎((𝚛) => 𝚜𝚎𝚝𝚃𝚒𝚖𝚎𝚘𝚞𝚝(𝚛, 𝟺𝟶𝟶 - 𝚘𝚗));
𝚜𝚙𝚒𝚗𝚗𝚎𝚛.𝚛𝚎𝚖𝚘𝚟𝚎();
CSS tip: stop paragraphs from leaving one lonely word on the last line.
p {
text-wrap: pretty;
}
The browser rebalances the last few lines so no word is left hanging alone. Browsers without support just wrap as usual.