Improve CSS writing with newer features and best practices
Let’s explore how to improve CSS writing with newer features and best practices, including the use of CSS Variables, Grid Layout, Flexbox, logical properties, and clamp().
1. CSS Variables (Custom Properties)
CSS variables allow you to define reusable values across your styles, which reduces repetition and makes updates easier.
/* Define Variables */
:root {
--main-bg-color: #f4f4f4;
--primary-color: #3498db;
--secondary-color: #2ecc71;
--font-size-base: 16px;
}
/* Use Variables */
body {
background-color: var(--main-bg-color);
color: var(--primary-color);
font-size: var(--font-size-base);
}
h1 {
color: var(--secondary-color);
}
Benefit: You only need to change values in one place instead of across multiple rules.
2. CSS Grid Layout
Grid simplifies complex layouts and reduces the need for multiple wrapper divs.
/* Before: Old Method using Floats or Flexbox */
.container {
display: flex;
flex-wrap: wrap;
}
.item {
flex: 1 1 50%;
}
/* After: Using CSS Grid */
.container {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 10px;
}
/* Add responsiveness easily */
@media (max-width: 768px) {
.container {
grid-template-columns: 1fr;
}
}
Benefit: Grid simplifies complex layouts with less code, especially for responsive designs.
3. Clamp() Function for Responsive Typography
The clamp()
function helps create responsive typography by defining a range between minimum, ideal, and maximum values.
/* Responsive font size */
h1 {
font-size: clamp(1.5rem, 2vw + 1rem, 3rem);
}
Benefit: You can scale typography smoothly between different screen sizes without needing media queries.
4. Logical Properties for Internationalization
CSS logical properties adapt to different writing modes and make layouts more flexible for various languages.
/* Before */
.container {
padding-left: 10px;
padding-right: 10px;
}
/* After: Using Logical Properties */
.container {
padding-inline: 10px;
}
Benefit: Logical properties automatically adapt based on the reading direction (LTR or RTL) without requiring changes in CSS.
5. Aspect-ratio for Consistent Sizing
The aspect-ratio
property allows you to maintain the aspect ratio of elements, simplifying responsive layouts.
/* Before */
.img-container {
width: 100%;
height: auto;
padding-bottom: 56.25%; /* for 16:9 aspect ratio */
position: relative;
}
/* After: Using aspect-ratio */
.img-container {
aspect-ratio: 16 / 9;
width: 100%;
}
Benefit: This drastically simplifies code for maintaining aspect ratios across responsive designs.
6. Min(), Max(), and Clamp() for Flexible Sizing
The min()
, max()
, and clamp()
functions help create more flexible, dynamic layouts without media queries.
/* Before */
.container {
width: 50%;
max-width: 1200px;
min-width: 300px;
}
/* After: Using clamp() */
.container {
width: clamp(300px, 50%, 1200px);
}
Benefit: This reduces the need for complex media queries and provides a smoother resizing experience.
7. @supports for Progressive Enhancement
The @supports
rule lets you target newer browsers with specific features, allowing for more modern CSS without breaking older browsers.
/* Only apply styles if grid is supported */
@supports (display: grid) {
.container {
display: grid;
grid-template-columns: 1fr 1fr;
}
}
Benefit: You can use cutting-edge CSS features while still ensuring compatibility with older browsers.
8. Content Visibility for Performance
The content-visibility
property can improve performance by skipping rendering of off-screen content.
/* Before: No control over rendering */
.container {
overflow: hidden;
}
/* After: Using content-visibility */
.container {
content-visibility: auto;
}
Benefit: It boosts performance by allowing the browser to skip rendering content that is off-screen, especially in long pages.
9. Layering CSS with @layer
The @layer
feature in CSS allows you to manage the cascade by defining layers, ensuring critical styles take precedence without relying on !important
.
/* Define layers */
@layer reset, base, components, utilities;
/* Example use */
@layer base {
body {
margin: 0;
font-family: sans-serif;
}
}
@layer components {
.button {
background-color: blue;
color: white;
}
}
Benefit: This helps organize styles in a way that ensures priority and avoids specificity wars.
10. Modern Color Functions (hsl, rgba)
Using modern color functions like hsl()
and rgba()
makes it easier to adjust colors dynamically.
/* Before */
background-color: #3498db;
/* After: Using hsl */
background-color: hsl(204, 70%, 53%);
Benefit: Easier to adjust color values such as hue, saturation, and lightness without needing to convert from hex.
11. Use CSS Modules (For Scoped Styles)
CSS Modules automatically scope styles locally to the component, reducing the need for long class names or IDs to prevent conflicts.
/* Before: Global CSS */
.button {
background: blue;
color: white;
}
/* After: CSS Modules */
.button {
composes: base-button from './base.module.css';
background: blue;
color: white;
}
Benefit: No more global class conflicts, making styles more modular and reusable.
12. Cascade Layers with Variables
Using variables in conjunction with cascade layers to maintain a balance between global and component-specific styling.
@layer global {
:root {
--primary-color: #3498db;
}
}
@layer components {
.btn {
color: var(--primary-color);
}
}
Benefit: Variables remain consistent across layers, while specific components can still maintain their own hierarchy of styles.
13. is()
and where()
Pseudo-Class Functions
These functions allow for more concise targeting of multiple elements without repeating selectors.
/* Before */
h1, h2, h3 {
font-family: sans-serif;
}
/* After: Using is() */
:is(h1, h2, h3) {
font-family: sans-serif;
}
Benefit: This reduces repetition and improves code clarity when applying the same styles to multiple elements.
14. Scroll Snap for Smooth Scroll Behavior
The scroll-snap
properties help create smooth scrolling sections with minimal CSS.
/* Scroll snapping behavior */
.container {
scroll-snap-type: y mandatory;
}
.section {
scroll-snap-align: start;
}
Benefit: Makes scroll-based layouts smoother with less JavaScript and more CSS.
15. Grid auto-fill
and auto-fit
for Responsive Grids
Make grids more flexible with automatic filling and fitting.
/* Responsive grid with auto-fill */
.grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
gap: 10px;
}
Benefit: Automatically adapts grid layout based on available space without media queries.
These newer CSS features streamline code, improve maintainability, and reduce the need for complex workarounds, resulting in cleaner, more performant, and future-proof designs.