Back to all posts
CSS

5 Common CSS Mistakes and How to Fix Them

By Huzi
5 Common CSS Mistakes and How to Fix Them

CSS is a powerful language, but its deceptive simplicity can lead developers down a path of frustration. Writing CSS that is scalable, maintainable, and easy to debug is a skill that takes practice. Many developers, especially those new to the language, fall into the same common traps. This article covers five of the most frequent CSS mistakes and how you can avoid them to write cleaner, more professional code.

1. Abusing the !important Rule

This is perhaps the most notorious mistake. You have a style that isn't applying, and after minutes of frustration, you add !important to force it to work. Problem solved, right? Wrong.

The Problem: !important is a sledgehammer. It breaks the natural cascade and specificity rules of CSS, making your stylesheet incredibly difficult to debug and manage in the long run. When you start using !important to override other !important rules, you've entered a battle you can't win.

The Fix: Instead of reaching for !important, understand why your style isn't applying. It's almost always a specificity issue.

  • Increase Specificity: Make your selector more specific. For example, div.card p is more specific than just p.
  • Selector Order: If two selectors have the same specificity, the one that appears later in the stylesheet wins.
  • Use Browser DevTools: The "Styles" tab in your browser's developer tools is your best friend. It shows you which styles are being applied and which are being overridden, and by what selectors.

When is !important okay? Very rarely. The most common acceptable use is in utility classes that must override any other style, for example, a hidden class:

.hidden {
  display: none !important;
}

2. Using "Magic Numbers"

Magic numbers are arbitrary pixel values used for widths, heights, margins, and padding without a clear reason.

The Problem: Layouts built with magic numbers are brittle. A small change in content, like a longer title or an extra line of text, can break the entire design. They are also terrible for responsive design, as a margin-left: 342px; that looks good on your monitor will be a disaster on a mobile screen.

The Fix: Use a system and relative units.

  • Use Relative Units: Prefer %, rem, em, vw, and vh over px for layout and typography. rem is excellent for creating scalable UIs.
  • Embrace Flexbox and Grid: Modern layout tools like Flexbox and CSS Grid are designed to create fluid, responsive layouts without magic numbers. Use properties like gap, justify-content, and align-items to manage spacing.
  • Use CSS Custom Properties (Variables): Define a spacing scale for your application. This creates consistency and makes global changes easy.
    :root {
      --spacing-sm: 0.5rem;
      --spacing-md: 1rem;
      --spacing-lg: 2rem;
    }
    
    .card {
      padding: var(--spacing-md);
    }
    

3. Overly Specific Selectors

Long, complex selectors are a sign of fragile CSS.

The Problem: A selector like div#main-content .container > ul.item-list li a.link is extremely hard to override. To change the style of that link, you'd need an even more specific selector. This leads to a specificity war and bloated CSS. It also tightly couples your CSS to your HTML structure; if you change a div to a section, the style breaks.

The Fix: Keep selectors short and use classes.

  • Prefer Classes: Instead of relying on a chain of HTML tags, give the element you want to style a meaningful class name.
  • Follow a Naming Convention: Methodologies like BEM (Block, Element, Modifier) help you write modular, decoupled CSS. A BEM selector might look like .card__title or .button--primary. These have low specificity and are easy to understand.

Bad:

#sidebar div.user-profile ul > li.active a {
  color: red;
}

Good:

.user-profile__link--active {
  color: red;
}

4. Not Using a CSS Reset

Every browser has its own default stylesheet (the "user agent stylesheet"). This is why an <h1> has a certain size and margin by default. The problem is that these defaults are inconsistent across different browsers.

The Problem: Without a reset, your website will look slightly different in Chrome, Firefox, and Safari. You'll spend time writing CSS to "undo" browser-specific styles, leading to inconsistent results.

The Fix: Use a modern CSS reset. A reset neutralizes default browser styling, giving you a clean, consistent base to build upon.

A simple reset might start like this:

/* Box-sizing reset */
*, *::before, *::after {
  box-sizing: border-box;
}

/* Remove default margin */
body, h1, h2, p, ul, li {
  margin: 0;
}

5. Writing Non-Responsive CSS

In today's multi-device world, failing to write responsive CSS is not an option.

The Problem: A site designed with fixed widths will be unusable on mobile devices, requiring users to zoom and pan horizontally, which is a terrible user experience.

The Fix: Adopt a mobile-first mindset and use responsive units and media queries.

  • Mobile-First: Design for the smallest screen first, then use min-width media queries to add complexity for larger screens. This approach is generally simpler and results in less CSS.
  • Use Fluid Layouts: Use max-width on containers to prevent them from becoming too wide on large screens, while allowing them to shrink on small ones.
  • Responsive Units: Use rem for font sizes and vw for elements that should scale with the viewport width.

Example of a Mobile-First Approach:

/* Base styles (for mobile) */
.container {
  padding: 1rem;
}

.grid {
  display: grid;
  grid-template-columns: 1fr; /* 1 column on mobile */
  gap: 1rem;
}

/* Tablet and up */
@media (min-width: 768px) {
  .grid {
    grid-template-columns: 1fr 1fr; /* 2 columns */
  }
}

/* Desktop and up */
@media (min-width: 1024px) {
  .grid {
    grid-template-columns: repeat(4, 1fr); /* 4 columns */
  }
}

By avoiding these common mistakes, you'll write CSS that is not only more effective but also a pleasure to work with.