CSS has evolved dramatically over the past decade. Where once we needed preprocessors like Sass and Less for variables and nesting, modern CSS now includes many of these features natively. At the same time, tooling like PostCSS and utility frameworks (Tailwind) have changed how developers write styles.
Classic Preprocessors: Sass and Less
Sass (SCSS syntax)
Sass (using the .scss syntax) remains the most widely adopted classic preprocessor, thanks to its mature ecosystem and feature-rich design.
Features:
- Variables
- Mixins
- Nesting
- Partials and imports
Example:
// variables.scss
$primary-color: #3498db;
.button {
background-color: $primary-color;
color: white;
padding: 0.5rem 1rem;
border-radius: 4px;
&:hover {
background-color: darken($primary-color, 10%);
}
}
When to use:
– If you work on a legacy project or a team that relies on classic CSS separation.
Less
Less has largely fallen out of favor compared to Sass, but still appears in some legacy projects, especially Bootstrap 3/4 themes.
Example:
@primary-color: #3498db;
.button {
background-color: @primary-color;
color: white;
&:hover {
background-color: darken(@primary-color, 10%);
}
}
When to use:
– Maintaining old Bootstrap-based projects.
Postprocessors: PostCSS
PostCSS is not a preprocessor like Sass; instead, it transforms your CSS after you write it, with plugins that add features or optimize the code.
Key plugins:
- Autoprefixer
- postcss-nested
- cssnano (for minification)
Example:
/* styles.css */
:root {
--primary-color: #3498db;
}
.button {
color: white;
background-color: var(--primary-color);
&:hover {
background-color: darken(var(--primary-color), 10%);
}
}
With postcss-nested, the nesting syntax above will work, even though vanilla CSS doesn’t fully support all nested structures yet.
postcss.config.js
module.exports = {
plugins: [
require('postcss-nested'),
require('autoprefixer')
]
}
When to use:
– If you want to use modern vanilla CSS, but still need features like autoprefixing and nesting.
Modern CSS: Native features
Modern browsers now support many features that once required preprocessors:
- CSS Variables
- Native Nesting (increasingly supported)
- :has() (parent selector)
- Container Queries
- Subgrid
Example: native variables + native nesting
:root {
--primary-color: #3498db;
}
.button {
background-color: var(--primary-color);
color: white;
&:hover {
background-color: color-mix(in srgb, var(--primary-color), black 10%);
}
}
Native Nesting
.card {
color: black;
& .title {
font-weight: bold;
}
}
- Supported in modern Chromium / Safari (2025)
- Firefox stable in progress
When to use:
– Modern projects where you can control browser support.
CSS-in-JS
In frameworks like React, CSS-in-JS has become a standard. Instead of separate .css
or .scss
files, you write your styles directly inside your JavaScript.
Example: styled-components
import styled from "styled-components";
const Button = styled.button`
background-color: #3498db;
color: white;
padding: 0.5rem 1rem;
border-radius: 4px;
&:hover {
background-color: #2980b9;
}
`;
When to use:
– React / Vue / component-driven apps, co-locating styles with logic.
Utility-First CSS: Tailwind CSS
Tailwind is huge in 2025. It eliminates much of the need for traditional CSS by providing atomic utility classes.
Example:
<button class="bg-blue-500 hover:bg-blue-600 text-white px-4 py-2 rounded">
Click me
</button>
- Consistent
- Easy to scale
- Plays well with design systems
Tailwind also supports:
- Dark mode
- Responsive utilities
- Composition with
@apply
Tailwind with @apply
:
/* custom.css */
.btn {
@apply bg-blue-500 hover:bg-blue-600 text-white px-4 py-2 rounded;
}
Where is it going?
- Modern CSS is catching up to Sass features (nesting, variables, etc.)
- PostCSS fills in remaining gaps (like autoprefixer, advanced nesting)
- Tailwind and other utilities dominate new apps
- CSS-in-JS rules in React/Next.js world
- Native CSS keeps improving every month (e.g., container queries, parent selectors)
Which should you use?
- New app with React/Next.js? → Tailwind + CSS Modules or styled-components
- Vanilla project with modern browsers? → Modern CSS + PostCSS
- Legacy codebase? → Sass (SCSS)
- Component libraries or design systems? → CSS-in-JS or Tailwind
- Don’t want to learn a framework? → Modern CSS with native features is honestly very good in 2025.
Summary
Preprocessors like Sass are still relevant, but PostCSS, utility frameworks, and modern native CSS are driving the industry forward.
Modern CSS has never been more powerful — and you have more choices than ever. Pick the one that fits your team, your project, and your goals.