# Repeating linear gradient in CSS: stripes, rings and patterns

[Canonical HTML page](https://gradiently.design/guide/css-repeating-gradient)

repeating-linear-gradient() takes one short run of colour and tiles it forever along a line. That one idea gives you stripes, awnings, progress bars and, with its radial and conic siblings, rings and sunbursts, all without an image.

## The short version

- A repeating linear gradient repeats its colour stops along the gradient line, and the length of one repeat is the position of the last stop.
- Hard stripes come from giving two colours the same position, so the colour changes instantly instead of blending.
- Diagonal stripes made with repeating-linear-gradient join without a seam at any angle, unlike a tiled linear gradient with background-size.
- repeating-radial-gradient() makes rings and ripples, and repeating-conic-gradient() makes rays and sunbursts.
- Hard colour edges can look jagged on screen, and a transition of half a pixel to a pixel softens them.

A **repeating linear gradient** in CSS repeats a short run of colour stops along a line until it fills the element. Write `repeating-linear-gradient(45deg, #f472b6 0 14px, #fdf2f8 14px 28px)` and you get diagonal pink stripes, each 14 pixels wide, with no image file. The length of one repeat is set by the last stop, here 28px. Use the same idea with `repeating-radial-gradient()` for rings and `repeating-conic-gradient()` for rays.

## How repeating-linear-gradient() works

The syntax is identical to an ordinary [linear gradient](https://gradiently.design/guide/css-linear-gradient). The difference is what happens after the last stop: instead of holding the final colour, the browser starts the pattern again. Two rules do most of the work.

- **The last stop position is the tile length.** Stops at `0`, `14px` and `28px` repeat every 28 pixels.
- **Two colours at the same position make a hard edge.** `#f472b6 0 14px, #fdf2f8 14px 28px` jumps from pink to pale pink at 14px with no blend.
- **Each stop can take two positions.** `#f472b6 0 14px` means solid pink from 0 to 14px, which is shorter than writing the colour twice.
- **Use lengths, not percentages, for stripes.** Percentages are relative to the gradient line, so stripes stretch when the element resizes.

```css
/* Soft repeat: colours blend within each 40px band */
.soft { background-image: repeating-linear-gradient(90deg, #ede9fe 0px, #c4b5fd 20px, #ede9fe 40px); }

/* Hard stripes: two colours share each boundary */
.stripes { background-image: repeating-linear-gradient(45deg, #f472b6 0 14px, #fdf2f8 14px 28px); }

/* Uneven stripes: wide band, thin band */
.ticket { background-image: repeating-linear-gradient(90deg, #0f766e 0 36px, #f0fdfa 36px 40px); }
```

End the soft repeat on the colour you started with, or you will see a hard seam every 40 pixels.

## Stripe patterns to copy

- Candy stripes: `repeating-linear-gradient(45deg, #f472b6 0 14px, #fdf2f8 14px 28px)`
- Teal awning: `repeating-linear-gradient(90deg, #0f766e 0 40px, #f0fdfa 40px 80px)`
- Navy pinstripe: `repeating-linear-gradient(90deg, #334155 0 1px, #0f172a 1px 12px)`
- Caution tape: `repeating-linear-gradient(135deg, #fde68a 0 10px, #1c1917 10px 20px)`
- Ruled paper: `repeating-linear-gradient(0deg, #fdf6ec 0 22px, #bfdbfe 22px 23px)`
- Three tone violet: `repeating-linear-gradient(90deg, #7c3aed 0 8px, #a78bfa 8px 16px, #ede9fe 16px 24px)`

Six stripe patterns. Change the angle to turn any of them, and change the lengths to scale them; the pattern always joins cleanly.

Ruled paper is a good example of an asymmetric repeat: 22 pixels of paper, one pixel of line. The same pattern with a red margin line on top makes a convincing notebook. More pattern ideas, including grids and dots, are in [CSS patterns](https://gradiently.design/guide/css-patterns).

## Repeating gradients or background-size

You can also make stripes with an ordinary `linear-gradient()` and `background-size`, which tiles a small image of the gradient. Both work. They behave differently at angles.

### linear-gradient + background-size

- Tiles a rectangle, so 45 degree stripes need careful maths to line up
- Pixel exact for horizontal and vertical stripes
- Easy to combine with other tiles in a grid
- Animate by moving `background-position` one tile

### repeating-linear-gradient

- Repeats along the gradient line, joins cleanly at any angle
- Stripe width set directly in pixels
- One declaration, no size to keep in sync
- Animate by moving `background-position` along the line

For anything diagonal, reach for the repeating version first. For checkerboards and grids, where you need two directions at once, `background-size` with layered gradients is simpler.

```css
.checker {
  background-image: repeating-conic-gradient(#e7e5e4 0 25%, #fafaf9 0 50%);
  background-size: 24px 24px;
}

.grid {
  background-color: #0f172a;
  background-image:
    linear-gradient(#1e293b 1px, transparent 1px),
    linear-gradient(90deg, #1e293b 1px, transparent 1px);
  background-size: 32px 32px;
}
```

Two patterns that need `background-size`. The checkerboard is the classic transparency backdrop; the grid suits technical pages and dashboards.

The checkerboard's second colour starts at position `0`. A stop can never sit before the previous one, so the browser moves it up to where the last colour ended, which makes a hard edge without repeating the number. It is a handy shorthand in any gradient, repeating or not.

## Rings with repeating-radial-gradient()

The radial version repeats outwards from a centre, so stripes become rings. Move the centre with `at` to make ripples spreading from a corner. As with [radial gradients](https://gradiently.design/guide/css-radial-gradient), `circle` keeps rings round; the default ellipse stretches them to the box.

- Indigo target: `repeating-radial-gradient(circle at 50% 50%, #312e81 0 10px, #4338ca 10px 20px)`
- Soft ripples from a corner: `repeating-radial-gradient(circle at 0% 100%, #fdf6ec 0, #f5d0a9 12px, #fdf6ec 24px)`
- Amber sunburst: `repeating-conic-gradient(from 0deg, #f59e0b 0deg 10deg, #fde68a 10deg 20deg)`
- Low rays from the floor: `repeating-conic-gradient(from 0deg at 50% 100%, #0f172a 0deg 6deg, #1e293b 6deg 12deg)`

Two radial and two conic repeats. Conic stops are angles: the sunburst repeats every 20 degrees, so it has 18 rays of each colour.

## Rays with repeating-conic-gradient()

Conic gradients sweep round a point, so their stops are angles. Pick a repeat that divides 360 evenly, such as 20, 30 or 45 degrees, or the last ray will be a different width from the rest. Keep the two colours close in value for a background; high contrast rays vibrate on screen and pull attention from everything else. The full syntax is in [CSS conic gradients](https://gradiently.design/guide/css-conic-gradient).

## How to fix jagged stripe edges

Hard edges at an angle can look stepped, and at some zoom levels browsers render them unevenly, so a few stripes look thicker than others. The fix is to give each edge a tiny transition instead of a perfect jump.

```css
/* Jagged: a perfect hard edge */
.hard { background-image: repeating-linear-gradient(45deg, #f472b6 0 14px, #fdf2f8 14px 28px); }

/* Smoother: one pixel of blend at each edge */
.smooth {
  background-image: repeating-linear-gradient(
    45deg,
    #f472b6 0 13.5px,
    #fdf2f8 14.5px 27.5px,
    #f472b6 28.5px
  );
}
```

The blend is too small to see as a gradient, but it lets the browser antialias the edge.

> **Thin lines and high density screens** A one pixel line can render as two half strength pixels on some screens. If a pinstripe looks blurry, try a whole number of device pixels or a slightly wider line in a softer colour.

## An animated barber pole progress bar

Moving `background-position` by exactly one repeat makes stripes travel without a jump. For a 45 degree pattern with a 28px repeat, the distance along the horizontal axis is the repeat divided by the sine of the angle, about 39.6px.

```css
.progress {
  background-image: repeating-linear-gradient(45deg, #6d28d9 0 14px, #8b5cf6 14px 28px);
  /* one horizontal repeat wider than the bar, so it can slide */
  background-size: calc(100% + 39.6px) 100%;
  background-repeat: no-repeat;
  animation: stripes 1s linear infinite;
}

@keyframes stripes {
  from { background-position: 0 0; }
  to { background-position: -39.6px 0; }
}

@media (prefers-reduced-motion: reduce) {
  .progress { animation: none; }
}
```

The image is one repeat wider than the bar and slides left by exactly that repeat, so the loop has no jump. Low contrast violets read as activity rather than alarm, and since `background-position` repaints, keep it to small elements.

For larger animated backgrounds, see [CSS animated gradients](https://gradiently.design/guide/css-animated-gradient), which covers cheaper techniques. Stripes and rings are great for details, tickets and loading states. For a background people recognise as yours, Gradiently's Marks add material, light and grain that a repeating pattern can't, and render at every size you design in.

## FAQ

### What is the difference between linear-gradient and repeating-linear-gradient?

A linear gradient holds its last colour after the final stop. A repeating linear gradient starts the stops again, so a short pattern fills the whole element.

### How do I make stripes in CSS?

Use hard stops in a repeating gradient: `repeating-linear-gradient(45deg, #f472b6 0 14px, #fdf2f8 14px 28px)` makes 14 pixel diagonal stripes.

### How do I set the size of a repeating gradient?

The position of the last colour stop sets the length of one repeat. Use pixel lengths so stripes stay the same width at every element size.

### Why do my CSS stripes look jagged?

Perfect hard edges at an angle can alias. Leave a gap of about one pixel between each pair of stops so the browser can smooth the edge.

### Can I make rings or rays with repeating gradients?

Yes. `repeating-radial-gradient()` makes rings and `repeating-conic-gradient()` makes rays; conic stops are angles rather than lengths.
