CSS Rules That Will Make Your Life Easier

As a full-stack developer, I‘ve spent countless hours writing and maintaining CSS across projects large and small. I‘ve experimented with different architectures, naming conventions, and approaches. Over time, I‘ve converged on a set of CSS rules and best practices that have made my life much easier.

In this post, I‘ll share some of the most impactful rules I follow, explain the rationale behind them, and provide examples. Whether you‘re a beginner or a battle-hardened veteran, my hope is you‘ll come away with some new tricks for your repertoire.

Let‘s dive in!

Use Variables for Colors

It‘s easy for color palettes to get out of hand, especially on long-lived projects with many contributors. I once worked on an app that had over 300 unique color values littered throughout the stylesheets, with a third of them being slightly different shades of gray. What a nightmare!

The solution is to define all your colors as variables, either using a preprocessor like Sass or native CSS custom properties. Then ONLY reference those variables.

Not only does this keep your color usage consistent, it also makes it trivial to ensure proper color contrast ratios. You can vet each color pair for accessibility ahead of time.

Another common pitfall is using semi-transparent rgba() or hsla() colors. Because the final color changes based on what‘s underneath, this can cause unintended issues. Instead, use opaque hex codes or variables. If you need transparency, use opacity.

Standardize Typography Upfront

Similar to colors, it‘s easy for font styles to become inconsistent if not controlled. My approach is to define typography as a distinct section in the stylesheet, separate from component styles.

I start by defining any @font-face declarations to load web fonts. Then I create a set of single-purpose classes for each font family, weight, size, line height, and letter spacing combination in my design system. For example:

.text-xl {
  font-family: ‘Helvetica Neue‘, sans-serif;
  font-weight: 800;
  font-size: 2.4rem;
  line-height: 1.2;
  letter-spacing: 0.5px;
}

The goal is to predefine every typographic style, then ONLY set text styles using those classes. No more fiddling with individual properties like font-size or line-height in random places!

This approach keeps your type consistent and makes it easy to make global adjustments. It also prevents bugs like unintended faux bold or italic text when the font file doesn‘t include those weights/styles.

Crucially, this setup lets you define typographic styles that work together visually. Getting the line height and spacing right for each font size is key. Trying to tweak those individually scattered throughout your CSS is a recipe for disaster.

And always define font sizes in rem so they scale with the user‘s base font size preference! Never pixels.

Use Em Units for Spacing

Many developers reach for pixels when defining paddings and margins. The problem is pixel values are fixed while content is dynamic.

Instead, use em units for spacing. These scale with the font size, maintaining proper proportions as the type grows or shrinks. Half the current font size is a good starting point for things like button padding.

Ems can take some getting used to, but they‘re a powerful tool once you wrap your head around them. The result is spacing that adapts to its content and remains balanced at any scale. This is especially valuable for responsive designs.

Embrace CSS Grid

CSS Grid is a layout game changer. It makes previously difficult tasks like vertical alignment trivial. No more messing with absolute positioning, transforms, flexbox contortions, or JavaScript hacks!

Despite broad browser support, I still see many developers using clunky 12-column grid systems based on float or flexbox. These impose rigid constraints and result in excessive markup and styles.

Instead, define grids based on the content‘s needs. You can create 2-dimensional layouts with simple CSS like:

.container {
  display: grid;
  grid-template-columns: 200px 1fr 1fr;
  grid-gap: 1rem; 
}

Let the content drive the grid structure, not the other way around. It‘s incredibly freeing once you get comfortable with Grid.

Use Flexbox for Alignment

Another pet peeve of mine is seeing text-align used for layout rather than text flow. This doesn‘t work well across writing modes and languages. Even worse is text-align: justify which can cause issues for dyslexic readers.

The better approach is to use flexbox for aligning and distributing elements, both horizontally and vertically. With simple rules like justify-content and align-items, you can discard text-align entirely in most cases.

Save text-align for actual paragraph text. Everything else should be handled by the flex layout.

Don‘t Remove Outline on Focus

Most browsers have a default focus style, usually a blue outline around the focused element. Many sites remove this without providing an alternative affordance.

The focus outline is crucial for keyboard navigation and accessibility. Removing it without a replacement makes your site harder to use for many people.

If you don‘t like the default browser focus ring, that‘s fine! But always provide an alternate style that meets accessibility contrast requirements on :focus. Something like:

*:focus {
  outline: 2px dotted #000;
}

There are lots of creative options that can fit your site‘s design language. Just don‘t remove focus outlines without replacing them.

Avoid Opacity for Hiding Content

Using opacity: 0 can be tempting for fading content or revealing it on hover. However, opacity: 0 only visually hides the content. It doesn‘t remove it from the accessibility tree or the DOM flow.

So a screen reader will still read it and it can still be focused with the keyboard. But it won‘t be visible on screen, leading to a very confusing experience.

If content should be hidden, actually remove it from the visual flow with display: none or visibility: hidden. You can still transition it in and out with keyframes if needed.

Save opacity for when content SHOULD be perceivable but needs to be deemphasized visually (like a scrim behind a modal). And watch out for overlapping transparent layers. The opacities will stack unexpectedly.

Stick to Single Class Selectors

In general, aim to style elements using single classes to keep specificity low and even. Avoid relying on type, ID or compound selectors.

IDs are tempting for their efficiency, but their styles will override any other selectors. And IDs must be unique, so they‘re not useful for repeatable styles.

Requiring a specific HTML structure with compound selectors like .header > .nav li a introduces fragility. The styles break if the nesting changes.

Even targeting bare elements with type selectors like a {} can cause unintended side effects and specificity issues down the line.

A single class is the safest, most reusable selector. Get comfortable with a naming convention like BEM to target different concerns separately.

Respect the Cascade

Many developers fight against CSS specificity and source order with increasingly complex selectors. The cascade is your friend! Work with it, not against it.

In general, write simpler rulesets that build on each other additively:

.button {
  background: blue;  
}
.button-large {
  padding: 1em;
  font-size: 1.5em;
}

Here, .button-large inherits styles from .button and layers on its own. No need to create a complex .button.button-large selector.

The source order matters, so put baseline styles first, then component-specific styles, then overrides and utilities. Avoid using !important as it disrupts this natural flow.

There are always exceptions, but staying true to the cascade will eliminate many specificity bugs and make your CSS much easier to follow and maintain.

Avoid Text Transform

It‘s common to use text-transform: uppercase for buttons, headings, and other typographic treatments.

However, this can cause internationalization issues in many languages. The uppercase transform is often inaccurate for non-Latin alphabets, diacritics and ligatures.

It also makes the text less readable, as it doesn‘t respect true capitalization rules (e.g. leaving articles lowercase).

Instead, provide the properly cased content in your HTML and avoid altering it with text-transform. It‘s more predictable and typographically correct.

Conclusion

These are just a few of the CSS rules I‘ve found most helpful in my work. Some are informed by accessibility and internationalization concerns. Others stem from maintainability and consistency goals. All of them are grounded in real-world experience.

Adopting a set of standards like this has made writing CSS much more enjoyable and far less error-prone for me. I spend less time fighting specificity bugs, untangling unnamed colors, or reinventing typography for every element.

My biggest piece of advice: Be intentional and consistent. Establish a clear system and stick to it. Your future self will thank you!

I hope you found these tips helpful. Let me know which ones resonate with you – or what I missed. Happy styling!

Similar Posts