CSS

Understanding CSS Gradients

Tom VanAntwerp
7 min read
Understanding CSS Gradients
This article was written over 18 months ago and may contain information that is out of date. Some content may still be relevant, but please refer to official documentation for the latest information.

Color gradients can help improve the design aesthetic of a site. But it's not always so easy to write the CSS to make them work the way you want. There are plenty of tools online for visually building gradients and getting back the CSS to implement them. But those tools won't help as much with debugging or tweaking things at the margin. It's worth having a basic idea of how gradients work so you can manually adjust them yourself.

The most basic linear gradient

A linear gradient smoothly transitions between colors in a single direction. So if you had a box, and you wanted to start with black and transition to white, you could do it like this:

background: linear-gradient(black, white);

Here, you've created a CSS class and set the background of any element with that class to have a linear gradient. This gradient will start with the first color, black, and smoothly interpolate to white.

Linear gradient direction

Right now, the top edge of the element will be black and the bottom edge will be white. If we wanted to make the left edge black and the right edge white, we could add a direction specifying that.

-   background: linear-gradient(black, white);
+   background: linear-gradient(to right, black, white);

Now, we're telling the gradient to go from left to right. You can use directions like to top, to top right, to right, to bottom right, etc. When not specified, the default direction is to bottom.

You can also specify direction more granularly with other units. You can use degrees (deg), gradians (grad), radians (rad), or turns (turn). Our to right example could be rewritten as 90deg, 100grad, 1.5708rad, or 0.25turn.

Linear gradient colors

This gradient is...really boring. It is not at all something we'd want to use. Let's pick some better colors!

-   background: linear-gradient(to right, black, white);
+   background: linear-gradient(to right, red, green, blue);

Ok, this gradient is pretty bad too. But at least it has color!

These colors are called color stops. If you want another color in the gradient, just add another color stop. By default, the color stops are distributed evenly across the gradient. But color stops can also accept a position that specify where along the gradient that color should be.

-   background: linear-gradient(to right, red, green, blue);
+   background: linear-gradient(to right, red, green 40%, blue);

By specifying 40% after green, we've set green to appear 40% along the way through the gradient rather than at the default midpoint. I've used percentages here, but you can also use specific units like pixels.

Color stops with positions can also be used to create striped patterns like so:

-   background: linear-gradient(to right, red, green 40%, blue);
+   background: linear-gradient(to right, red 20%, green 20% 40%, blue 40%);

Here, our first color red is solid from the start until 20% along the gradient. Then, green immediately takes over at 20%, and goes until 40%. Finally, blue takes over at 40%, and continues to the end of the gradient. The first color stop is assumed to begin at 0%, and the last is assumed to end at 100%.

Combining gradients

Using colors with transparency, and background blend modes, you can overlay different gradients to achieve a variety of color effects.

background:
  linear-gradient(to right, rgba(200, 40, 10, 1), rgba(230, 40, 10, 0)),
  linear-gradient(to left, hsl(220, 80%, 45%, 1), hsl(220, 80%, 45%, 0)),
  linear-gradient(0.5turn, rgba(20, 230, 30, 1), rgba(20, 230, 20, 0));
background-blend-mode: difference;

Repeating gradients

Let's say you want to create a repeating striped line pattern. Creating all of the necessary color stops would be impractical. But that's where repeating-linear-gradient comes in! Define the necesary color stops once, and watch it tile across the element.

background: repeating-linear-gradient(
  135deg,
  hsl(180, 60%, 70%) 0 10px, /* a 10px-wide blue stripe */
  hsl(0, 0%, 95%) 10px 20px /* a 10px-wide white stripe */
)

Radial gradients

The humble linear gradient transitions colors along a single direction, like an ocean wave moving toward the shore. But the radial gradient is like a ripple in a pond, moving outward in all directions from a single starting point.

background: radial-gradient(black, white);

Notice the default behavior of this basic radial-gradient. The point from which the transition begins defaults to the center of the element. The shape it makes is not circular, but elliptical; it is expanding and contracting to match the shape of the element. Color stops work the same way that they do with linear gradients.

Radial gradients take an optional shape, size, and position before their color stops.

Circle or ellipse

Radial gradients default to an elliptical shape to stretch and fit the element they are part of. But you can also specify they be circular instead, regardless of element dimensions.

.one {
  background: radial-gradient(ellipse, black, white);
}

.two {
  background: radial-gradient(circle, black, white);
}

Radial gradient position

The default center position is limiting for making really interesting gradients. Thankfully, it's very easy to specify a different position with the at keyword.

/* The default is farthest corner. The shape will intersect at the element's corners which are furthest from the starting point.  */
.one {
  background: radial-gradient(circle at top left, black, white);
}

/* With farthest-side, the shape will intersect with the most distant straight edge of the element. */
.two {
  background: radial-gradient(circle at 100%, black, white);
}

/* Same as farthest-corner, except now it's the closest one. */
.three {
  background: radial-gradient(circle at bottom, black, white);
}

/* Same as the farthest-side, except now it's the closest one. */
.four {
  background: radial-gradient(circle at 30% 70%, black, white);
}

Radial gradient size

There are four ways to size a radial gradient in relation to its element. When a radial gradient is drawn, it creates either a circle or ellipse that intersects the edges of the element in a certain way. The gradient is interpolated from the starting point to that invisible shape intersecting the element edge. The radial gradient's size determines where that shape intersects the edges of the element.

/* The default is farthest corner. The shape will intersect at the element's corners which are furthest from the starting point.  */
.one {
  background: radial-gradient(ellipse farthest-corner at 30%, black, white);
}

/* With farthest-side, the shape will intersect with the most distant straight edge of the element. */
.two {
  background: radial-gradient(ellipse farthest-side at 30%, black, white);
}

/* Same as farthest-corner, except now it's the closest one. */
.three {
  background: radial-gradient(ellipse closest-corner at 30%, black, white);
}

/* Same as the farthest-side, except now it's the closest one. */
.four {
  background: radial-gradient(ellipse closest-side at 30%, black, white);
}

Combining radial gradients

Like we did with linear gradients, we can get creative with radial gradients to create unique and colorful backgrounds! By now, you should understand enough about how gradients work in CSS that you can read the code below, and understand how it's constructing the gradient background you see here.

background:
  repeating-radial-gradient(circle, hsl(190, 80%, 70%, 0.2) 0px 35px, transparent 35px 70px),
  radial-gradient(at top right, hsl(150, 70%, 50%, 1), hsl(200, 80%, 40%, 0)),
  radial-gradient(circle at 0% 50%, hsl(300, 75%, 40%), hsl(200, 90%, 30%, 0)),
  radial-gradient(circle at bottom center, hsl(30, 70%, 70%, 1), hsl(30, 70%, 70%, 0));

Conic gradients

There's one last instance of gradient in CSS to cover: the conic gradient. If the linear gradient moves like an ocean wave, and the radial gradient moves like ripples in a move, the conic gradient moves like the hands on a clock. This one is a bit weird compared to linear and radial, and you may not find much use for it. But it's worth letting you know that it exists.

  background: conic-gradient(black, white);

Where previously color stops used percentages or units to designate position in the gradient, in the conic gradient, you would use angles. All the units you used in linear gradients to designate direction can instead be used in conic gradients for color position.

  border-radius: 50%;
  background: conic-gradient(red 0 120deg, green 120deg 240deg, blue 240deg 0deg);

Conic gradients don't have a repeating version like the others, but you can use other background properties to repeat them. Using such properties can have interesting results. As unlikely as it sounds, you can create a checkerboard pattern with a repeating conic gradient!

  background: conic-gradient(red 0 120deg, green 120deg 240deg, blue 240deg 0deg);

Accessibility

While conic gradients can allow you to create interesting things like pie charts and checkerboards, keep in mind that screen readers do not interpret anything from these styles. If you populated a report with pie charts made from conic gradients, a screen reader would not be able to explain the charts to its user. You probably shouldn't try to use these gradients for anything other than aesthetics.

Conclusion

Hopefully this introduction to CSS gradients will help you feel more comfortable working with the code for them directly, and not feeling beholden to an online generator tool. By all means, feel free to use tools to create complex gradients more quickly than writing them by hand! But now you can have confidence that, when the time comes to make tweaks to them in the code, you'll be able to do so yourself.

About the author

Tom VanAntwerp

Tom VanAntwerp

Senior Software Engineer

Keep reading

View all posts →

CSS Container Queries, what are they?

In this blog post, we take a look at container queries, a new feature that makes designing websites easier and more flexible. ...

Jesús Padrón6 mins
CSS

An example-based guide to CSS Cascade Layers

CSS Cascade Layers make style management simple—see how in this example-driven guide....

Dane Grant4 mins
CSS

Understanding the Difference Between `:focus` and `:focus-visible` in CSS

Understanding the Difference Between :focus and :focus visible in CSS I have learned my fair share about the importance of keyboard accessibility, so I know that visual indication of the focused element is very important. But the well known :focus pseudo class is not always the best fit for this job. That's where :focus visible comes in. Let's look at the differences between these two pseudo classes and explore the best practices for using them effectively. What is the :focus Pseudo Class? The :focus pseudo class is a CSS selector that applies styles to any element that receives focus, regardless of how that focus was triggered. This includes focus events from keyboard navigation, mouse clicks, and touch interactions. Example Usage of :focus In this example, the button will display a blue outline whenever it is focused, whether the user clicks on it with a mouse, taps it on a touchscreen, or navigates to it using the keyboard. What is the :focus visible Pseudo Class? The :focus visible pseudo class is more specialized. It only applies styles to an element when the browser determines that the focus should be visible. This typically occurs when the user navigates via the keyboard or assistive technologies rather than through mouse or touch input. Example Usage of :focus visible Here, the button will only show a blue outline when focused through keyboard navigation or another input method that usually requires visible focus indicators. Key Differences Between :focus and :focus visible :focus Behavior: Applies to any element that receives focus, regardless of the input method. Use Cases: Ensures that all interactions with the element are visually indicated, whether by mouse, keyboard, or touch. :focus visible Behavior: Applies styles only when the focus should be visible, such as using a keyboard or assistive technology. Use Cases: Ideal for scenarios where you want to provide focus indicators only to keyboard and assistive technology users while avoiding unnecessary outlines for mouse and touch users, typically required by design. Accessibility Implications :focus Pros: Guarantees that all users can see when an element is focused, which is critical for accessibility. Cons: Can lead to a suboptimal experience for mouse users, as focus styles may appear unnecessarily during mouse interactions. :focus visible Pros: Enhances user experience by showing focus indicators only when necessary, thus keeping the interface clean for mouse and touch users. Tailors the experience for keyboard and assistive technology users, providing them with clear visual cues. Cons: Additional considerations may be required to ensure that focus indicators are not accidentally omitted, especially in older browsers that do not support :focus visible. There may be cases where you want to show focus indicators for all users, regardless of input method. Best Practices for Using :focus and :focus visible To achieve the best accessibility and user experience, combining both :focus and :focus visible in your CSS is often a good idea. Combining :focus and :focus visible Here is a Stackblitz example of what such styling could look like for you to try out and play with. Additional Tips Test with Keyboard and Assistive Technology: Ensure that your web application is navigable using a keyboard (Tab, Shift + Tab, etc.) and that focus indicators are visible for those who rely on them. It's never a bad idea to include accessibility testing in your e2e testing suite. Provide Clear Focus Indicators: Make sure that focus indicators are prominent and easy to see. A subtle or hard to spot focus indicator can severely impact accessibility for users who rely on keyboard navigation. Conclusion The :focus visible pseudo class offers a more refined way to manage focus indicators, improving accessibility and user experience, particularly for keyboard and assistive technology users. By understanding the differences between :focus and :focus visible, and applying best practices in your CSS, you can create more accessible and user friendly web applications. Remember, accessibility should never be an afterthought. By thoughtfully applying focus styles, you ensure that all users, regardless of how they interact with your site, can easily navigate and interact....

Jan Kaiser3 mins
AccessibilityCSSPlaywright

How to Truncate Strings Easily with CSS

Learn how to truncate text in CSS, focusing on single-line and multi-line truncation using properties like overflow, text-overflow, and -webkit-line-clamp. It highlights CSS’s simplicity and responsiveness compared to JavaScript-based truncation....

Mark Shenouda4 mins
CSS