CSS Tricks I Actually Use Every Day
There are two kinds of CSS articles. The first shows you jaw-dropping things that are theoretically possible but that you’ll use approximately never. The second covers the unglamorous stuff that solves real problems every single day.
This is the second kind.
The stack with gap
Before flexbox, vertical spacing between elements was a margin-bottom nightmare. Now:
.stack {
display: flex;
flex-direction: column;
gap: 1rem;
}
One class. Everything inside gets consistent vertical spacing. No margin-bottom on the last child. No specificity fights. Stack it.
clamp() for fluid typography
Stop writing three breakpoints to change a font size. clamp() handles it:
h1 {
font-size: clamp(2rem, 5vw, 4rem);
}
Minimum 2rem. Maximum 4rem. Scales fluidly between. The middle value is the “ideal” size at a given viewport. Works for padding too.
aspect-ratio
Used to be a padding-top hack. Now it’s one line:
.thumbnail {
aspect-ratio: 16 / 9;
width: 100%;
object-fit: cover;
}
Every image, every video, every card thumbnail. Set it once.
CSS custom properties for themes
I stopped writing #5b5bd6 directly in my stylesheets. Everything goes through a variable:
:root {
--color-accent: #5b5bd6;
--color-text: #0a0a0a;
--color-muted: #888888;
--radius-card: 16px;
--space-section: clamp(3rem, 8vw, 7rem);
}
When a client says “can we change the blue to green,” it’s one line. When I want to add dark mode, it’s a [data-theme="dark"] override. Variables are the cheapest design system you can build.
:where() for zero-specificity resets
Base styles that don’t fight with everything else:
:where(h1, h2, h3, h4) {
line-height: 1.2;
text-wrap: balance;
}
:where(p, li) {
max-width: 65ch;
}
:where() has zero specificity. Any other selector overrides it without a fight. Perfect for resets and base styles you never want to debug.
text-wrap: balance
Speaking of which:
h1, h2, h3 {
text-wrap: balance;
}
This tells the browser to balance line lengths in headings. No more two-line heading where the second line has one orphaned word. Browser support is good enough to use now.
inset shorthand
top: 0; right: 0; bottom: 0; left: 0 is four lines. This is one:
.overlay {
position: absolute;
inset: 0;
}
inset accepts the same shorthand as margin and padding. inset: 1rem is 1rem on all sides. inset: 0 1rem is top/bottom 0, left/right 1rem.
The focusable ring
The default browser focus ring is ugly. Removing it is an accessibility violation. The correct move:
:focus-visible {
outline: 2px solid var(--color-accent);
outline-offset: 3px;
border-radius: 4px;
}
:focus:not(:focus-visible) {
outline: none;
}
:focus-visible only shows the ring when the user is navigating with keyboard, not mouse. You get clean mouse interactions AND accessible keyboard navigation.
None of these are new. None of them will get you retweets for being clever. But they’re in every project I build, and they make everything a little less annoying.
That’s the only bar that matters.