CSS Highlights – 2020

In an attempt to keep up with the fast paced changes in CSS here are the most significant updates over the past few years. Starting with 2020.

JUMP TO:



1. CSS GRID


HTML

<div class="grid">
  <header>Header</header>
  <nav>Nav</nav>
  <main>Main content</main>
  <aside>Sidebar</aside>
  <footer>Footer</footer>
</div>

CSS

.grid {
  display: grid;

  /* 1️⃣ Define columns and rows */
  grid-template-columns: 200px 1fr 150px;
  grid-template-rows: auto 1fr auto;

  /* 2️⃣ Name layout areas */
  grid-template-areas:
    "header header header"
    "nav    main   aside"
    "footer footer footer";

  /* 3️⃣ Spacing between items */
  gap: 1rem;

  min-height: 100vh;
}

/* 4️⃣ Assign elements to areas */
header { grid-area: header; }
nav    { grid-area: nav; }
main   { grid-area: main; }
aside  { grid-area: aside; }
footer { grid-area: footer; }

/* Just styling so it’s visible */
.grid > * {
  padding: 1rem;
  background: #eaeaea;
  border: 1px solid #ccc;
}

/* Responsive Design */
@media (max-width: 600px) {
  .grid {
    grid-template-areas:
      "header"
      "nav"
      "main"
      "aside"
      "footer";
    grid-template-columns: 1fr;
  }
}

What this example shows (important features)

1️⃣ Grid container

display: grid;

Turns the .grid div into a grid layout.


2️⃣ Columns & rows

grid-template-columns: 200px 1fr 150px;
grid-template-rows: auto 1fr auto;
  • px → fixed width
  • fr → “take remaining space”
  • auto → size to content

3️⃣ Named grid areas (very powerful)

grid-template-areas:
  "header header header"
  "nav    main   aside"
  "footer footer footer";

This visually describes the layout in CSS.
You can rearrange the whole layout just by changing these lines.


4️⃣ Placing items by name

header { grid-area: header; }

No row/column numbers needed — much more readable.


5️⃣ Gaps

gap: 1rem;

Replaces old hacks like margins for spacing grid items.


Why Grid is useful (vs Flexbox)

  • Grid → 2-dimensional (rows and columns)
  • Flexbox → 1-dimensional (row or column)

This example would be awkward in Flexbox but clean in Grid.


2. prefers-color-scheme


prefers-color-scheme is a media query that lets your CSS respond to the user’s OS or browser theme preference:

  • light
  • dark

The browser decides this based on system settings (macOS, Windows, iOS, Android).


HTML (unchanged for both themes)

<div class="card">
  <h1>Hello</h1>
  <p>This page adapts to your system theme.</p>
  <button>Click me</button>
</div>

CSS

/* 1️⃣ Default (light theme fallback) */
:root {
  --bg: #ffffff;
  --text: #222222;
  --card: #f4f4f4;
  --accent: #0066cc;
}

body {
  background: var(--bg);
  color: var(--text);
  font-family: system-ui, sans-serif;
  padding: 2rem;
}

.card {
  background: var(--card);
  padding: 2rem;
  border-radius: 8px;
  max-width: 400px;
}

button {
  background: var(--accent);
  color: white;
  border: none;
  padding: 0.6rem 1rem;
  border-radius: 4px;
}

/* 2️⃣ Dark mode overrides */
@media (prefers-color-scheme: dark) {
  :root {
    --bg: #0f172a;
    --text: #e5e7eb;
    --card: #1e293b;
    --accent: #60a5fa;
  }
}

What this example demonstrates

1️⃣ Media query, not a class

@media (prefers-color-scheme: dark)
  • No JavaScript
  • No .dark class
  • Automatically responds to system setting changes

2️⃣ CSS variables (best practice)

:root {
  --bg: #ffffff;
}

Instead of duplicating all styles, we:

  • define variables once
  • override them in dark mode

This keeps CSS clean and scalable.


3️⃣ Light mode as a fallback

/* default styles first */

If a browser doesn’t support prefers-color-scheme, users still get light mode.


4️⃣ Instant theme switching

Try changing:

  • macOS → System Settings → Appearance
  • Windows → Personalization → Colors

The page updates without reload.


Common patterns in real projects

Combine with color-scheme

html {
  color-scheme: light dark;
}

This tells the browser to:

  • theme form controls
  • scrollbars
  • built-in UI correctly

Support only dark mode users

@media (prefers-color-scheme: dark) {
  body {
    background: black;
  }
}

Force a theme (overrides system)

body.force-light {
  --bg: white;
}

Useful if you later add a user toggle.


Other user-preference media queries.


All of these belong to the same family:

Media queryWhat it respects
prefers-color-schemeLight / dark theme
prefers-reduced-motionLess animation
prefers-contrastMore / less contrast
prefers-reduced-transparencyLess transparency

They:

  • read OS / browser accessibility settings
  • require no JavaScript
  • update live when the system setting changes

3. The popularity of Tailwind


Tailwind CSS is a utility-first CSS framework.

Instead of writing custom CSS classes, you compose your UI directly in HTML using small, single-purpose classes.

<button class="bg-blue-600 text-white px-4 py-2 rounded">
  Save
</button>

Each class maps to one CSS rule:

  • bg-blue-600 → background color
  • px-4 → horizontal padding
  • rounded → border radius

You rarely write traditional CSS at all.


How does this differ from the BEM approach?

What BEM is:

BEM (Block-Element-Modifier) is not a framework.
It’s a naming convention and architecture for writing CSS.

<button class="button button--primary">
  Save
</button>
.button {
  padding: 1rem;
  border-radius: 6px;
}

.button--primary {
  background: blue;
  color: white;
}

BEM helps you:

  • structure large CSS codebases
  • avoid selector conflicts
  • understand relationships between components

Core difference

Tailwind replaces most custom CSS.
BEM organizes custom CSS.

They’re solving different layers of the problem.


Side-by-side comparison

AspectTailwind CSSBEM
TypeCSS frameworkNaming methodology
Where styles liveMostly in HTMLMostly in CSS
CSS you writeMinimalPrimary
Naming responsibilityTailwind handles namingYou design names
Learning curveMedium (many utilities)Low–medium
File sizeGenerated & purgedGrows with project
Best forRapid UI developmentLong-term CSS architecture

Example: same button, different approach

Tailwind

<button class="bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded transition">
  Save
</button>

No CSS file needed.


BEM

<button class="btn btn--primary">
  Save
</button>
.btn {
  padding: 0.5rem 1rem;
  border-radius: 0.5rem;
  transition: background 200ms;
}

.btn--primary {
  background: blue;
  color: white;
}

.btn--primary:hover {
  background: darkblue;
}

How they scale

Tailwind scaling model

  • Reuse comes from copying patterns
  • Consistency comes from design tokens
  • Changes are fast and local
<div class="max-w-md mx-auto p-6 bg-white shadow-lg rounded-lg">

BEM scaling model

  • Reuse comes from shared components
  • Consistency comes from discipline
  • Changes are centralized but slower
.card {}
.card__header {}
.card__body {}
.card--featured {}

Mental model difference

Tailwind

“Describe how it looks, right here, right now.”

BEM

“Describe what this thing is, and style it elsewhere.”


Common criticisms

Tailwind critics say:

  • HTML becomes cluttered
  • Harder to read at first
  • Requires a build step

BEM critics say:

  • Boilerplate-heavy
  • Lots of class names
  • CSS files grow large over time

Both are valid — it depends on context.


Can they be used together?

Yes — and often they are.

Example:

<button class="btn bg-blue-600 text-white px-4 py-2">
  • btn → semantic hook (BEM-ish)
  • Tailwind → actual styling

This is common in WordPress and React projects.


When Tailwind is a good fit

  • Component-based apps (React, Vue)
  • Design systems
  • Teams that want speed + consistency
  • You want fewer CSS files

When BEM is a good fit

  • Traditional multi-page sites
  • CMS-driven sites (WordPress, Drupal)
  • Teams that prefer semantic HTML
  • Long-lived projects with lots of CSS

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *