Preprocessors
SCSS/Sass
Language Name:scss or sassFile Extensions:
.scss, .sassCompiler: Dart Sass (modern Sass compiler)
// Variables
$primary-color: #3b82f6;
$secondary-color: #8b5cf6;
$spacing: 1rem;
// Nesting
.card {
padding: $spacing;
background: white;
border-radius: 0.5rem;
&:hover {
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
.card-header {
color: $primary-color;
font-weight: bold;
margin-bottom: $spacing;
}
.card-body {
color: #333;
}
}
// Mixins
@mixin flex-center {
display: flex;
align-items: center;
justify-content: center;
}
@mixin responsive($breakpoint) {
@if $breakpoint == mobile {
@media (max-width: 768px) { @content; }
} @else if $breakpoint == tablet {
@media (max-width: 1024px) { @content; }
}
}
.container {
@include flex-center;
@include responsive(mobile) {
flex-direction: column;
}
}
// Functions
@function calculate-spacing($multiplier) {
@return $spacing * $multiplier;
}
.large-padding {
padding: calculate-spacing(2);
}
// Extend/Inheritance
%button-base {
padding: 0.5rem 1rem;
border: none;
border-radius: 0.25rem;
cursor: pointer;
}
.primary-button {
@extend %button-base;
background: $primary-color;
color: white;
}
.secondary-button {
@extend %button-base;
background: $secondary-color;
color: white;
}
// Partials and imports
// @import 'variables';
// @import 'mixins';
// Loops
@for $i from 1 through 5 {
.mt-#{$i} {
margin-top: #{$i * 0.25}rem;
}
}
// Each
$colors: (primary: $primary-color, secondary: $secondary-color);
@each $name, $color in $colors {
.text-#{$name} {
color: $color;
}
}
Less
Language Name:lessFile Extensions:
.lessCompiler: Less.js
// Variables
@primary: #3b82f6;
@secondary: #8b5cf6;
@spacing: 1rem;
// Nesting
.card {
padding: @spacing;
background: white;
&:hover {
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
.title {
color: @primary;
font-weight: bold;
}
}
// Mixins
.flex-center() {
display: flex;
align-items: center;
justify-content: center;
}
.button-style(@bg-color) {
background: @bg-color;
color: white;
padding: 0.5rem 1rem;
border: none;
border-radius: 0.25rem;
}
.container {
.flex-center();
}
.primary-button {
.button-style(@primary);
}
// Operations
.sidebar {
width: @spacing * 20;
padding: @spacing / 2;
}
// Functions
.header {
background: lighten(@primary, 10%);
border-bottom: 2px solid darken(@primary, 20%);
}
// Guards (conditional mixins)
.mixin(@a) when (@a > 10) {
font-size: 20px;
}
.mixin(@a) when (@a <= 10) {
font-size: 14px;
}
// Loops
.loop(@counter) when (@counter > 0) {
.mt-@{counter} {
margin-top: (@counter * 0.25rem);
}
.loop((@counter - 1));
}
.loop(5);
Stylus
Language Name:stylusFile Extensions:
.stylCompiler: Stylus
// Variables (no $ or @ needed)
primary = #3b82f6
secondary = #8b5cf6
spacing = 1rem
// Nesting (no braces or semicolons needed)
.card
padding spacing
background white
border-radius 0.5rem
&:hover
box-shadow 0 4px 6px rgba(0, 0, 0, 0.1)
.title
color primary
font-weight bold
// Mixins
flex-center()
display flex
align-items center
justify-content center
button-style(bg-color)
background bg-color
color white
padding 0.5rem 1rem
border none
border-radius 0.25rem
.container
flex-center()
.primary-button
button-style(primary)
// Conditionals
box(x, y, color = red)
if color == red
border 1px solid red
else
border 1px solid color
// Loops
for num in 1..5
.mt-{num}
margin-top (num * 0.25)rem
// Functions
add(a, b)
a + b
.sidebar
width add(100px, 50px)
Utility Frameworks
Tailwind CSS
Processor Name:tailwindcssType: PostCSS Plugin
Needs HTML: Yes (scans HTML for classes)
/* Your CSS file */
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer components {
.btn-primary {
@apply bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600;
}
}
@layer utilities {
.text-shadow {
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.1);
}
}
<!-- HTML with Tailwind classes -->
<div class="container mx-auto px-4">
<h1 class="text-4xl font-bold text-blue-600 mb-4">
Welcome to Tailwind
</h1>
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
<div class="bg-white p-6 rounded-lg shadow-md">
<h2 class="text-xl font-semibold mb-2">Card 1</h2>
<p class="text-gray-600">Content here</p>
</div>
<div class="bg-white p-6 rounded-lg shadow-md">
<h2 class="text-xl font-semibold mb-2">Card 2</h2>
<p class="text-gray-600">Content here</p>
</div>
<div class="bg-white p-6 rounded-lg shadow-md">
<h2 class="text-xl font-semibold mb-2">Card 3</h2>
<p class="text-gray-600">Content here</p>
</div>
</div>
<button class="btn-primary mt-4">
Click me
</button>
</div>
Tailwind Configuration
{
"processors": ["tailwindcss"],
"customSettings": {
"tailwindcss": {
"theme": {
"extend": {
"colors": {
"brand": "#3b82f6"
}
}
}
}
}
}
UnoCSS
Processor Name:unocssType: Instant atomic CSS engine
Needs HTML: Yes
<!-- UnoCSS uses similar utility classes to Tailwind -->
<div class="flex items-center justify-center min-h-screen">
<div class="p-8 bg-white rounded-lg shadow-xl">
<h1 class="text-3xl font-bold text-blue-500 mb-4">
UnoCSS Example
</h1>
<p class="text-gray-700 mb-4">
Instant on-demand atomic CSS
</p>
<button class="px-6 py-3 bg-purple-500 text-white rounded hover:bg-purple-600 transition">
Get Started
</button>
</div>
</div>
UnoCSS Configuration
{
"processors": ["unocss"],
"customSettings": {
"unocss": {
"presets": ["uno", "attributify", "icons"],
"theme": {
"colors": {
"brand": "#8b5cf6"
}
}
}
}
}
PostCSS
Processor Name:postcssType: CSS transformation tool
/* Modern CSS features via PostCSS plugins */
/* Nesting (via postcss-nesting) */
.card {
background: white;
& .title {
color: blue;
}
&:hover {
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
}
/* Custom properties */
:root {
--primary: #3b82f6;
--spacing: 1rem;
}
.button {
background: var(--primary);
padding: var(--spacing);
}
/* Autoprefixer automatically adds vendor prefixes */
.flex-container {
display: flex;
justify-content: center;
}
PostCSS Configuration
{
"processors": ["postcss"],
"customSettings": {
"postcss": {
"plugins": [
"autoprefixer",
"postcss-nesting",
"postcss-custom-properties"
]
}
}
}
Comparison
- SCSS
- Less
- Stylus
- Tailwind
- UnoCSS
Pros:
- Most popular preprocessor
- Powerful features (mixins, functions, loops)
- Large ecosystem
- Mature and stable
- Complex stylesheets
- Design systems
- Component libraries
Pros:
- Simple syntax
- Easy to learn
- Good tooling
- Simpler projects
- Bootstrap customization
- Quick prototypes
Pros:
- Minimal syntax
- Very flexible
- Powerful features
- Clean, minimal code
- Python-like syntax preference
Pros:
- Utility-first approach
- Rapid development
- Consistent design system
- No CSS file bloat
- Fast prototyping
- Component-based frameworks
- Design consistency
Pros:
- Instant compilation
- Smaller bundle size
- Highly customizable
- Icon support
- Performance-critical apps
- Modern frameworks
- Custom design systems
Using Processors
Select a processor in the project configuration:{
"processors": ["tailwindcss"],
"customSettings": {
"tailwindcss": {
"theme": {
"extend": {
"colors": {
"brand": "#3b82f6"
}
}
}
}
}
}
Example: Complete Card Component
- SCSS
- Tailwind
$primary: #3b82f6;
$shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
@mixin card-hover {
&:hover {
transform: translateY(-2px);
box-shadow: 0 8px 12px rgba(0, 0, 0, 0.15);
}
}
.card {
background: white;
border-radius: 0.5rem;
padding: 1.5rem;
box-shadow: $shadow;
transition: all 0.3s ease;
@include card-hover;
&__title {
color: $primary;
font-size: 1.5rem;
font-weight: bold;
margin-bottom: 1rem;
}
&__content {
color: #666;
line-height: 1.6;
}
&__button {
margin-top: 1rem;
padding: 0.5rem 1rem;
background: $primary;
color: white;
border: none;
border-radius: 0.25rem;
cursor: pointer;
&:hover {
background: darken($primary, 10%);
}
}
}
<div class="bg-white rounded-lg p-6 shadow-md hover:shadow-xl hover:-translate-y-0.5 transition-all">
<h2 class="text-blue-500 text-2xl font-bold mb-4">
Card Title
</h2>
<p class="text-gray-600 leading-relaxed">
Card content goes here with great typography.
</p>
<button class="mt-4 px-4 py-2 bg-blue-500 hover:bg-blue-600 text-white rounded transition">
Learn More
</button>
</div>
Best Practices
Use Variables/Utilities
Use Variables/Utilities
Keep values consistent:
// SCSS
$spacing-unit: 0.25rem;
$primary: #3b82f6;
// Tailwind
// Use theme values: p-4, text-blue-500
Organize Code
Organize Code
Structure your stylesheets:
// 1. Variables
// 2. Mixins
// 3. Base styles
// 4. Components
// 5. Utilities
Avoid Deep Nesting
Avoid Deep Nesting
Keep nesting shallow:
// Good
.card { }
.card__title { }
// Avoid
.card {
.inner {
.title { }
}
}
Related
React
Use CSS processors with React
Vue
SCSS/Less in Vue SFC styles
Svelte
Preprocessors in Svelte components
PostCSS
Modern CSS transformations