Tip of the week #001: Pill buttons

Tips on how to create pill shaped buttons with CSS.

One way to create a pill shape...

Here's how to create a pill shape with CSS:

Language: css
.pill {
  height: 57px;
  border-radius: 28.5px;
}

The rule is simple: as long as the width is greater than the height (a rectangle), the border-radius of all four corners needs to be half the height of the element. At least that's the idea.

One way to create a pill shape.
One way to create a pill shape.

As you can see it becomes a bit weird to set the border-radius value to half a pixel, with 28.5 being half the height of 57. It feels like magic numbering.

Another drawback to this solution is that you would need to know the height of your shape at any given time (e.g. in media queries). Of course, custom properties and calc() can help you with that, so that you at least only have to keep the height up to date:

Language: css
.pill {
  --height: 57px;
  --radius: calc(var(--height) / 2);
  
  height: var(--height);
  border-radius: var(--radius);
}

@media (min-width: 1000px) {
  .pill {
    --height: 64px;
  }
}

...however, issues arise

In a more realistic scenario, you wouldn't necessarily set a fixed height on your shape, be it a button, a tag or any other pill shaped UI component.

Most likely the height would be computed by a combination of line-height, font-size or paddings.

Here's what that would look like:

Language: css
.pill {
  font-size: 1.25rem;
  padding-inline: 2em;
  padding-block: 0.8em;
  line-height: 1.25;
  border-radius: /* What to put here? */
}

I wouldn't recommend going down the route of calculating the height yourself. The solution is simpler than that.

A simpler approach

As mentioned, the rule for creating pill shapes is to have a border-radius of half the height of the element. However, you'll get the same result if you have a value of anything greater than half the height. This means that you can set the radius to something stupidly high, and you'll always get a pill shape.

My go-to value for this is 999em. One could argue that this also feels a bit like magic numbering, so add a comment if necessary.

Language: css
.pill {
  font-size: 1.25rem;
  padding-inline: 2em;
  padding-block: 0.8em;
  line-height: 1.25;
  border-radius: 999em; /* Creates a pill shape */
}

The result is a nice, dynamically adaptable pill shape:


Bonus

A real pill shaped button 💊

See the Pen Pill shaped button by Håvard Brynjulfsen (@havardob) on CodePen.