---
title: Utility Classes I Have Known and Loved
teaser: 'These are my favorite CSS utility classes. I take them everywhere.

  '
tags: css,sass
author: Stephen Lindberg
published_on: 2021-01-08
---

I have yet to jump head-long into the hypetrain of utility-first CSS
frameworks, but I've been enjoying the benefits of the ideology in small
portions. The pros and cons of a framework like
[Tailwind](https://tailwindcss.com/) compared to
[BEM](http://getbem.com/introduction/) are for another blog post. Today I'd like
to share the indispensable utility classes that I carry with me from project to
project.

## First Up: Margins

Margins are notoriously persnickety. If not accounted
for, they'll break your layout alignment, ruin your padding, and sometimes
[seemingly disappear](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Box_Model/Mastering_margin_collapsing).
This is why I avoid margin rules on component root elements. The component needs
not concern itself with where it appears in relation to other elements in the
layout. With Sass, a simple loop can help us generate several margin classes
that give us the power to tweak margins on-the-fly as we're authoring HTML:

```scss
$directions: "top" "bottom" "left" "right";
$sizes: (
  "zero": 0,
  "auto": auto,
  "xs": $size-extra-small,
  "sm": $size-small,
  "md": $size-medium,
  "lg": $size-large,
  "xl": $size-extra-large
);

@each $name, $size in $_sizes {
  @each $dir in $_directions {
    .m-#{$dir}-#{$name} {
      margin-#{$dir}: $size !important;
    }
  }
}
```

This will generate a margin rule for each combination of size and direction,
such as `m-top-lg` or `m-left-xs`.

You could expand on this idea to create shorthand margin rules, such as a rule
for all directions at once, or only vertical or horizontal directions:

```scss
@each $name, $size in $_sizes {
  .m-#{$name} {
    margin: $size !important;
  }

  .mx-#{$name} {
    margin-left: $size !important;
    margin-right: $size !important;
  }

  .my-#{$name} {
    margin-bottom: $size !important;
    margin-top: $size !important;
  }

  /* … */
}
```

This margin tool is useful for pushing elements around in those pesky cases
where something doesn't align with the layout in quite the way you'd like, or if
you need to remove a margin from an element in a unique scenario.

> I use `!important` in my utility classes because if the class is applied to an
> element, the rule should be applied without doubt. Another way to put it:
> another class should never override a utility's effect. If that is desired,
> the utility class should simply be removed from the element.

## The Stack

Flexbox is wonderful. With `flex-wrap` it provides a responsive container for
our components, however there's a small oversight: the missing `gap` rule. Like CSS
Grid, flexbox has a `gap` rule which creates margins between each column and
row, however `gap` is [not yet universally
supported](https://caniuse.com/flexbox-gap) for `flex` containers. We can create
a workaround for this with a little negative margin hack, which I call a Stack:

```scss
$spacing: 1em;

.stack {
  align-items: flex-start;
  display: flex;
  flex-wrap: wrap;
  margin-left: -$spacing;
  margin-top: -$spacing;

  > * {
    margin: $spacing 0 0 $spacing;
  }
}
```

Each child has a positive top and left margin, while the parent element has a
negative top and left margin which will cancel out the margins of the left-most
and top-most elements in the stack. This is really useful for rows of buttons,
tag labels, and almost anything else you can think of that needs a responsive
container without conforming to the rigidity of a grid. It also plays nicely
with other flex rules like `justify-content: space-between;`.

## Typography

Typography is often subject to the context of the page or layout. It's difficult
to say with certainty that your `<h1>` should always be a certain size, or that
the body text of given page is always `1rem`. Instead of taking the BEM approach
and creating a unique class like `.homepage-hero-header` for every variant, I
find it's much easier to compose a few typographic utility classes to achieve
the result I want. The three utilities I use are for the rules `color`,
`font-size`, and `font-weight`. These will be unique to your project since they
depend heavily on your design system in terms of color and typographic scale.
Mine usually look something like this:

```scss
/* font-size.scss */

.fs-sm {
  font-size: $font-size-small !important;
}

.fs-md {
  font-size: $font-size-small !important;
}

/* … and so on */

/* font-weight.scss */

.fw-reg {
  font-weight: $font-weight-regular !important;
}

.fw-semi {
  font-weight: $font-weight-semibold !important;
}

/* … and so on */

/* font-color.scss */

.fc-base {
  color: $font-color-base !important;
}

.fc-accent {
  color: $font-color-accent !important;
}

/* … and so on */
```

These composable utilities are much easier to use than creating a specific,
named component for every typographic variation, and will reduce stylesheet
bloat over time while still affording you the flexibility to modulate your
typography while adhering to your style guide.

> I sometimes prefix utility classes with `u-` in order to destinguish them as
> utilities within a codebase that is otherwise following a different naming
> convention. This helps myself and others avoid confusing them for components.

So there you have it – a few highly useful utility classes that you can start
using today alongside your favorite flavor of object-oriented CSS.
