No-Jank CSS Stripes

Avatar of Chris Coyier
Chris Coyier on

Take your JavaScript to the next level at Frontend Masters.

My mind goes immediately to repeating-linear-gradient and hard-stop gradients when thinking of creating stripes in CSS. You make one stripe by using the same color between two color stops, and another stripe (or more) but using a different color between two colors stops (sharing the one in the middle).

So like:

background: repeating-linear-gradient(
  45deg,
  black,
  black 10px,
  #444 10px,
  #444 11px
);

That will make angled dark gray stripes 10px apart on black.

But this is how it renders on my screen:

Can you see that rendering jankiness where one or two of the stripes seems lighter and thinner than the others? I have no idea why. I assume it’s something to do with sub-pixel rendering or the like. This is not hard to replicate. It’s not just these two colors or this particular angle is just about any stripes created at all with repeating-linear-gradient. It stops being so noticeable with thicker stripes though (say, 5px and thicker).

I made a handful of examples. This one with tighter stripes going the other way is especially prevelant:

I needed to do this the other day, found the jankiness, and remembered this little note in our stripes article. It amounts to: don’t use repeating-linear-gradient. Just use linear-gradient, set a background-size and let it repeat. Indeed, that seems to do the trick. The trouble with this is… how big do you make the background-size? If the stripes are vertical or horizontal, it’s fairly easy to smudge something. But if the stripes are at an angle… calculating the perfect width×height is tricky. I’d guess it’s related to the Pythagorean theorem, but I’m out of my depth there.

So, what do you do?

Use this nice little generator tool thing:

It does whatever fancy math necessary to get it right. You can see the unminified JavaScript here. Search for / GET BACKGROUND SIZE / to see all the math going on. Whatever it’s doing there, the stripes come out perfectly.

Kind of a shame repeating-linear-gradient doesn’t have better visual output as that’s so much easier to reason about, but hey, you gotta do what you gotta do.