10 CSS Tips and Tricks to Write Less Code in 2026
Master these practical CSS tips and tricks to write cleaner, shorter stylesheets. Learn modern shorthand, one-liners, and techniques that cut your code in half.

10 CSS Tips and Tricks to Write Less Code in 2026
Every line of CSS you write is a line you have to maintain. Whether you are building production interfaces or battling it out in a CSS challenge on StyleWars, the ability to express more with less code is what separates a competent developer from a truly efficient one. These CSS tips and tricks will help you slash your stylesheet size while actually improving readability.
This guide covers ten practical techniques -- from classic shorthand properties to cutting-edge features like native CSS nesting and the :has() selector. Each tip includes a before-and-after comparison so you can see exactly how much code you are saving. Whether you are optimizing a design system at work or competing for the top spot on a CSS challenge platform, these patterns will make your code tighter and more expressive.
1. Collapse Properties With CSS Shorthand
The most immediate way to write less CSS is to use shorthand properties. Many developers still write out individual declarations when a single line would do the job.
Before:
.card {
margin-top: 1rem;
margin-right: 2rem;
margin-bottom: 1rem;
margin-left: 2rem;
background-color: #1a1a2e;
background-image: url("bg.webp");
background-repeat: no-repeat;
background-position: center;
background-size: cover;
}
After:
.card {
margin: 1rem 2rem;
background: #1a1a2e url("bg.webp") no-repeat center / cover;
}
That is nine lines reduced to two. The CSS shorthand for margin accepts one to four values (top, right, bottom, left), and the background shorthand can pack color, image, repeat, position, and size into a single declaration. The / before cover separates background-position from background-size.
Other shorthand properties worth memorizing: font, border, flex, grid, place-items, inset, and gap. Mastering these is essential for anyone serious about CSS battles and competitive coding.
2. Use the inset Property Instead of Four Offsets
Positioning an element to fill its container used to require four separate properties. The inset shorthand replaces all of them.
Before:
.overlay {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
After:
.overlay {
position: absolute;
inset: 0;
}
inset follows the same one-to-four value pattern as margin and padding. Need different values? Use inset: 10px 20px 30px 40px for top, right, bottom, left respectively. This is one of the most effective CSS one-liners for layout work.
3. Replace Media Queries With Container Queries
Media queries have served us well, but they respond to the viewport rather than the component's actual container. Container queries let components own their responsive behavior, which often means fewer breakpoints and less duplicated code.
Before (media queries):
.card-title {
font-size: 1rem;
}
@media (min-width: 600px) {
.card-title {
font-size: 1.25rem;
}
}
@media (min-width: 900px) {
.card-title {
font-size: 1.5rem;
}
}
After (container queries):
.card {
container-type: inline-size;
}
.card-title {
font-size: 1rem;
@container (min-width: 300px) {
font-size: 1.25rem;
}
@container (min-width: 500px) {
font-size: 1.5rem;
}
}
The real savings come at scale. When a component adapts to its own container width, you can drop it anywhere in any layout without writing new media queries. The code stays co-located with the component instead of scattered across breakpoints. This is especially powerful in component-driven architectures where a card might appear in a three-column grid on one page and a single-column stack on another -- the same CSS handles both contexts without any additional rules.
4. Simplify Selectors With CSS Nesting
Native CSS nesting -- no preprocessor required -- landed in all major browsers in 2024. It reduces repetition and keeps related styles grouped together.
Before:
.nav {
display: flex;
gap: 1rem;
}
.nav a {
color: #ccc;
text-decoration: none;
}
.nav a:hover {
color: #fff;
}
.nav a.active {
color: #00d4ff;
border-bottom: 2px solid #00d4ff;
}
After:
.nav {
display: flex;
gap: 1rem;
a {
color: #ccc;
text-decoration: none;
&:hover {
color: #fff;
}
&.active {
color: #00d4ff;
border-bottom: 2px solid #00d4ff;
}
}
}
You no longer need to repeat .nav in every selector. The & symbol references the parent selector, just like in Sass or Less, except now it is native CSS. This is one of those CSS tips and tricks that immediately makes your stylesheets more scannable.
5. Replace JavaScript Logic With the :has() Selector
The :has() relational pseudo-class lets you style a parent based on its children -- something that previously required JavaScript. It eliminates entire categories of toggle classes and DOM manipulation.
Before (requires JS to add a class):
.form-group.has-error .label {
color: red;
}
// JavaScript needed to toggle .has-error
input.addEventListener("invalid", () => {
input.closest(".form-group").classList.add("has-error");
});
After (pure CSS):
.form-group:has(input:invalid) .label {
color: red;
}
No JavaScript needed. The browser watches the DOM and applies the style reactively. The :has() selector is widely supported in all modern browsers and has become one of the most transformative additions to CSS in years. Other powerful CSS hacks using :has() include styling a card differently when it contains an image (.card:has(img)), changing a grid layout when a sidebar is present, highlighting a table row on checkbox selection, or even building entire form validation UIs without a single line of scripting.
If you enjoy finding creative pure-CSS solutions to visual problems, you will love creating CSS art without any images.
6. Center Anything With place-items
The classic "how do I center a div" question has a one-line answer that every developer should have memorized.
Before:
.container {
display: grid;
justify-items: center;
align-items: center;
}
After:
.container {
display: grid;
place-items: center;
}
place-items is shorthand for align-items and justify-items. Its sibling, place-content, does the same for align-content and justify-content. And place-self combines align-self and justify-self. These three properties are among the most useful CSS one-liners for layout work.
For a deeper comparison of when to reach for Flexbox versus Grid, see our breakdown of CSS Flexbox vs. Grid.
7. Use aspect-ratio Instead of the Padding Hack
For years, developers used the padding-bottom percentage trick to maintain aspect ratios on responsive elements. That hack is officially retired.
Before:
.video-wrapper {
position: relative;
width: 100%;
padding-bottom: 56.25%; /* 16:9 */
height: 0;
}
.video-wrapper iframe {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
}
After:
.video-wrapper {
width: 100%;
aspect-ratio: 16 / 9;
}
Seven lines become two. The aspect-ratio property works on any element and accepts any ratio. Use 1 for a perfect square, 4 / 3 for classic screen proportions, or any custom value you need. This is cleaner, more readable, and does not require absolute positioning gymnastics.
8. Eliminate Repetition With Custom Properties and calc()
CSS custom properties (variables) combined with calc() let you define a value once and derive everything else from it. This drastically cuts repetition across your stylesheet.
Before:
.btn-sm {
padding: 4px 8px;
font-size: 12px;
border-radius: 4px;
}
.btn-md {
padding: 8px 16px;
font-size: 16px;
border-radius: 6px;
}
.btn-lg {
padding: 12px 24px;
font-size: 20px;
border-radius: 8px;
}
After:
.btn {
--size: 1;
padding: calc(var(--size) * 4px) calc(var(--size) * 8px);
font-size: calc(12px + var(--size) * 4px);
border-radius: calc(2px + var(--size) * 2px);
}
.btn-sm { --size: 1; }
.btn-md { --size: 2; }
.btn-lg { --size: 3; }
Fifteen lines become ten, and more importantly, the scaling logic is defined in one place. Change the formula once, and every size variant updates automatically. This pattern scales beautifully when you have five or six size variants. You can also override custom properties inline via the style attribute, which makes this approach work well with utility-class systems and JavaScript-driven theming without extra stylesheet rules.
9. Use color-mix() for Dynamic Color Variants
Generating hover states, disabled states, and color variations used to mean hardcoding hex values or pulling in a preprocessor. The color-mix() function handles this natively.
Before:
.btn-primary {
background: #3b82f6;
}
.btn-primary:hover {
background: #2563eb; /* manually picked darker shade */
}
.btn-primary:disabled {
background: #93bbfd; /* manually picked lighter shade */
}
After:
.btn-primary {
--accent: #3b82f6;
background: var(--accent);
}
.btn-primary:hover {
background: color-mix(in oklch, var(--accent), black 20%);
}
.btn-primary:disabled {
background: color-mix(in oklch, var(--accent), white 40%);
}
Change --accent to any color and the hover and disabled states adapt automatically. The in oklch color space produces perceptually uniform mixes, so the results look natural regardless of the base hue. This is one of the more underappreciated CSS hacks for design systems.
10. Scope Styles With @scope for Zero-Conflict Components
The @scope rule lets you limit where styles apply without relying on naming conventions like BEM or CSS Modules. It defines both where a style starts and where it stops.
Before (BEM-style scoping):
.card__header {
font-weight: bold;
}
.card__header .card__title {
font-size: 1.25rem;
}
.card__body {
padding: 1rem;
}
.card__body .card__title {
font-size: 1rem;
}
After:
@scope (.card-header) {
:scope {
font-weight: bold;
}
.title {
font-size: 1.25rem;
}
}
@scope (.card-body) {
:scope {
padding: 1rem;
}
.title {
font-size: 1rem;
}
}
You can use simple, semantic class names like .title without worrying about collisions, because @scope restricts the selector's reach. You can also add a "scope limit" -- @scope (.card) to (.nested-card) -- to prevent styles from leaking into deeply nested components with similar structures.
Putting It All Together
These ten CSS tips and tricks share a common thread: they let the language do the heavy lifting so you do not have to. Here is a quick reference of what each technique replaces:
| Tip | Replaces |
| --- | --- |
| Shorthand properties | Multiple individual declarations |
| inset | Four offset properties |
| Container queries | Redundant media queries |
| Native nesting | Repeated parent selectors |
| :has() | JavaScript class toggling |
| place-items | Separate alignment properties |
| aspect-ratio | Padding-bottom hack |
| Custom properties + calc() | Hardcoded size variants |
| color-mix() | Manually picked color shades |
| @scope | BEM or CSS Modules naming |
The best way to internalize these patterns is to practice them under constraints. On StyleWars, every character counts -- shorter code earns higher scores, which pushes you to discover exactly these kinds of optimizations. If you want to see how you stack up, check the leaderboard or challenge someone directly in 1v1 mode.
Start Writing Less CSS Today
Modern CSS is more expressive than it has ever been. Features that once required preprocessors, JavaScript, or verbose workarounds are now one-liners baked into the language. The ten techniques in this guide are not theoretical -- they are practical, production-ready patterns you can start using in your next project or your next battle.
Pick one tip from this list, refactor a piece of your existing code, and see how much cleaner the result is. Then pick another. Before long, writing concise CSS will be second nature, and your stylesheets will be shorter, more maintainable, and easier to reason about.
If you want a fun, low-stakes environment to drill these techniques, try recreating targets on StyleWars where character count directly impacts your score. There is no faster feedback loop for learning to write less CSS that does more.
Sharpen Your CSS Skills
Put what you learned into practice. Try a CSS battle and see how you compare against other developers on the leaderboard.


