Double Position Color Stops: A Gradient Syntax Worth Knowing

Most CSS developers know that a gradient stop consists of a color and optional position, but fewer realize the spec allows assigning two positions to a single color stop. This isn’t just a syntax quirk—it’s a practical way to create solid-color stripes in a gradient without repeating the color value.

Double position syntax replaces what would normally be two consecutive stops that share the same color. Instead of writing color 10%, color 20%, you write color 10% 20%. This is particularly valuable when working with striped patterns, where you need an abrupt transition from one color to the next.

Consider a simple horizontal stripe pattern using eight colors:

Screenshot. Shows 8 vertical rainbow stripes, from left to right: violet, magenta, red, orange, yellow, yellowish green, teal, blue.
Desired gradient result.

The colors in question are #5461c8, #c724b1, #e4002b, #ff6900, #f6be00, #97d700, #00ab84, and #00a3e0.

The Traditional Way

Without double positions, you need to explicitly mark both endpoints of every color segment. Since there are eight stripes, each occupies 12.5% of the gradient’s width. The resulting CSS looks like this:

linear-gradient(90deg, 
             #5461c8 12.5% /* 1*12.5% */, 
  #c724b1 0, #c724b1 25%   /* 2*12.5% */, 
  #e4002b 0, #e4002b 37.5% /* 3*12.5% */, 
  #ff6900 0, #ff6900 50%   /* 4*12.5% */, 
  #f6be00 0, #f6be00 62.5% /* 5*12.5% */, 
  #97d700 0, #97d700 75%   /* 6*12.5% */, 
  #00ab84 0, #00ab84 87.5% /* 7*12.5% */, 
  #00a3e0 0)

Some repetition can be trimmed by remembering that a stop position smaller than a previous one triggers a sharp transition. Using 0 for the starting position of each new color is always safe, since zero is guaranteed to be less than any positive previous value. This trick means #c724b1 25%, #e4002b 0 is equivalent to #c724b1 25%, #e4002b 25%.

Preprocessors can reduce the maintenance burden of changing a stripe color, since each color still appears in only one logical place:

$c: #5461c8 #c724b1 #e4002b #ff6900 #f6be00 #97d700 #00ab84 #00a3e0;

@function get-stops($c-list) {
  $s-list: ();
  $n: length($c-list);
  $u: 100%/$n;
	
  @for $i from 1 to $n {
    $s-list: $s-list, 
             nth($c-list, $i) $i*$u, 
             nth($c-list, $i + 1) 0
  }

  @return $s-list
}

.strip {
  background: linear-gradient(90deg, get-stops($c)))
}

But this only removes repetition from the source—the generated CSS still contains duplicated color values, which inflates file size and adds unnecessary complexity.

Where Stripes Help Even More

The complexity becomes especially obvious with simpler patterns like diagonal hashes, built with repeating-linear-gradient():

Screenshot. Shows a pattern of diagonal light grey hashes on a white background.
Desired hashes result

Even without an extensive palette, this pattern forces you to state #444 twice—once for the hash color and once for the following stop that ends it:

repeating-linear-gradient(-45deg, 
    #ccc /* can't skip this, repeating gradient won't work */, 
    #ccc 2px, 
    transparent 0, 
    transparent 9px /* can't skip this either, tells where gradient repetition starts */)

Those two stops are required: they are what instruct the repeating gradient where to start over when the background-size rectangle is repeated.

The Double Position Solution

With double position syntax, each color and its two boundary positions live on the same stop. For the eight-stripe rainbow, the source becomes:

linear-gradient(90deg, 
    #5461c8 12.5%, 
    #c724b1 0 25%, 
    #e4002b 0 37.5%, 
    #ff6900 0 50%, 
    #f6be00 0 62.5%, 
    #97d700 0 75%, 
    #00ab84 0 87.5%, 
    #00a3e0 0)

And the hash pattern requires only a single mention of each color:

repeating-linear-gradient(-45deg, 
    #ccc 0 2px, 
    transparent 0 9px)

Not only does this eliminate CSS file bloat, it also reduces typo risk: if you change a color, you change it once.

Browser Support Is Solid

What about whether linear-gradient() and repeating-linear-gradient() behave consistently across browsers? Most modern ones have you covered. It works in Safari, Chromium-based browsers including Edge, and Firefox. Older Edge versions and some mobile browsers might not support it. As long as you can either provide a fallback for those cases or don’t need to support them at all, the double position syntax is worth adopting now.