CSS Striped Patterns Using Hard Color Stops

CSS gradients create seamless striped patterns by eliminating the default color interpolation between color stops, resulting in crisp, solid bands of color. By placing two distinct color stops at the exact same position—or by using modern shorthand where an ending stop is smaller than the preceding one—the browser generates an instantaneous transition rather than a smooth fade. When combined with repeated gradient dimensions or dedicated repeating functions, these hard transitions tile across an element infinitely without visible seams.

The Mechanics of Hard Color Stops

By default, CSS linear gradients calculate a smooth color transition across the distance between two points. For example, a gradient running from red 0% to blue 100% blends smoothly across the entire container.

To eliminate this transition and produce a solid stripe, you must position adjacent color stops at the exact same location:

background: linear-gradient(90deg, #3498db 0% 50%, #2ecc71 50% 100%);

Because #3498db ends at 50% and #2ecc71 begins immediately at 50%, the transition distance is zero pixels. The browser renders a sharp boundary known as a hard stop.

Modern CSS allows a shorthand technique known as the zero-stop fix:

background: linear-gradient(90deg, #3498db 20px, #2ecc71 0 40px);

According to the CSS specification, if a color stop is set to a value smaller than the one before it (such as 0 after 20px), the browser automatically increases its value to match the previous stop, forcing a hard edge without repeating numeric values.

Achieving Seamless Repetition

There are two primary methods to make these hard-stop stripes repeat seamlessly across any element size.

Method 1: Using background-size

You can define a single self-contained pattern cycle using a standard linear-gradient, constrain its dimensions with background-size, and allow background-repeat to tile it across the element.

.striped-box {
  background-image: linear-gradient(
    90deg,
    #ff6b6b 0% 50%,
    #feca57 50% 100%
  );
  background-size: 40px 100%;
  background-repeat: repeat-x;
}

This method is predictable because the pattern cycle matches the tile size. The seam remains invisible because the pattern completes its full alternating cycle inside the 40-pixel boundary before restarting.

Method 2: Using repeating-linear-gradient()

The repeating-linear-gradient() function automatically repeats color stops indefinitely without needing explicit background-size definitions. The repetition interval is dictated by the position of the final color stop.

.striped-box {
  background: repeating-linear-gradient(
    90deg,
    #48dbfb 0px 20px,
    #1dd1a1 20px 40px
  );
}

The browser measures the pattern length from 0px to 40px and automatically loops this entire sequence. Because the end of the second stripe (40px) touches the start of the next cycle's first stripe (0px), the boundary between tiles remains mathematically seamless.

Seamless Diagonal Stripes

Creating diagonal stripes introduces geometry that can lead to misalignments if calculated manually with background-size. Using repeating-linear-gradient() resolves this issue because the browser projects the color stops along an angled gradient ray perpendicular to the stripes:

.diagonal-stripes {
  background: repeating-linear-gradient(
    45deg,
    #2c3e50 0px 15px,
    #ecf0f1 15px 30px
  );
}

By defining the color stops directly along the 45-degree ray, the stripes maintain consistent thickness and infinite repetition without relying on rectangular tile calculations that might cause seam artifacts.