conic-gradient()

Juan Diego Rodríguez on

Get affordable and hassle-free WordPress hosting plans with Cloudways — start your free trial today.

The CSS conic-gradient() function creates a gradient by placing colors around a circle, making them smoothly transition across its circumference. It’s called a conic gradient since it usually looks like a cone seen from above.

body { background-image: conic-gradient(from 45deg in oklch, white, black, white); }

It’s mainly used with the background-image property. That’s because gradients are actually images generated by the browser, making them ideal for setting backgrounds. But that’s just the most common way you’ll see the conic-gradient() function used in CSS, as we’ll see.

The conic-gradient() function is defined in the CSS Images Module Level 4 specification.

Related Guide: CSS Gradients

Syntax

conic-gradient([from [ <angle> | <zero> ] at <position> <color-interpolation-method>]?, <angular-color-stop-list>)

We’ll break down these arguments one by one, but what this is essentially saying is that a conical gradient is produced with an angle, a position, a color space, and then positioning the colors used in the gradient.

Arguments

/* Basic Gradients */ conic-gradient(cyan, magenta, cyan); conic-gradient(red 90deg, purple 180deg, red); /* Gradient angles */ conic-gradient(from 20deg, white, black, white); conic-gradient(from 0.5turn, blue, yellow, blue); /* Gradient positions */ conic-gradient(at right bottom, yellow, green, yellow); conic-gradient(at 60px 20%, coral, orange, coral); /* Interpolation method */ conic-gradient(in oklab, #ff0, hsl(120 100 50), yellow); conic-gradient(in lch longer hue, yellow, blue, yellow); /* All together */ conic-gradient(from 40deg at left top in hsl longer hue, yellow 50deg, oklch(0.87 0.14 99) 100deg, yellow);

Let’s look at each one of those arguments to get a better idea of what they do and how they influence the appearance of gradients.

from <angle> | <zero>

Colors are placed around a circle, which can be rotated by a certain degree to twist the entire gradient. It works by writing the from keyword followed by the <angle> to rotate the gradient. If not defined, it defaults to 0deg.

at <position>

In short: It defines the center point of the gradient.

To use it, we write the at keyword followed by the <position> syntax for each axis. This includes relative values like 40% 20%, absolute units like 30px 100px, and physical values like left topcenter or right bottom. If omitted, it defaults to center. Logical values don’t seem to be allowed.

<angular-color-stop-list>

In short: It defines the colors used and their position on the gradient, all in a comma-separated list.

Each color stop has a given <color> followed by two optional <angle-percentage> values:

  • A single <color> value lets CSS decide where to place the color.
  • <color> <angle-percentage> value defines where the given color should be found.
  • Lastly, <color> <angle-percentage> <angle-percentage> defines a starting and ending angle for the color to appear.

<color-interpolation-method>

In short: It defines the color space used and the path taken from one color to another.

To use it, we start with the in keyword followed by one of the many color spaces defined in CSS:

<color-interpolation-method> = in [ <rectangular-color-space> | <polar-color-space> <hue-interpolation-method>? ] <rectangular-color-space> = srgb | srgb-linear | display-p3 | a98-rgb | prophoto-rgb | rec2020 | lab | oklab | xyz | xyz-d50 | xyz-d65 <polar-color-space> = hsl | hwb | lch | oklch

It can be either written at the beginning of conic-gradient() or just before defining the <angular-color-stop-list>.

If the color space uses polar coordinates (i.e., hslhwblch and oklch), then we can also define the path taken by the gradient using the <hue-interpolation-method> syntax.

Basic usage

Similar to radial gradients, conic gradients work around a center point. However, this time, colors are placed around that center point, instead of away from it.

The syntax can be a little hard to get at first, so let’s start with the most basic conic gradient:

.gradient { background-image: conic-gradient(cyan, yellow, magenta); }

Tip: Remember that conic-gradient() returns an <image> type, meaning it’s used within the background-image (or background) property rather than, say, the background-color property, which does not support CSS gradient functions.

Here, the colors cyanyellow and magenta are placed clockwise around a center point beginning from the 12:00 mark, and since we only specified the colors, CSS will place them equidistantly across the gradient. However, you’ll notice an ugly hard stop at the top instead of a smooth transition. This is because “equidistantly” in CSS means that each color is separated by the same angle, so…

  • cyan at 0deg
  • yellow at 180deg
  • magenta at 360deg

Since 0deg is the same as 360deg, both colors end up sharing borders:

Conic Gradient with hard stop between cyan and magenta

Removing the hard stop is as easy as having the first color be the same as the last one:

.gradient { background-image: conic-gradient(magenta, cyan, yellow, magenta); }

This time, magenta is placed at 0deg and 360deg, sharing borders and automatically placing the rest of the colors evenly across the gradient:

Conic gradient without hard stops between colors

If we don’t want CSS to place colors to its liking, we can set the position ourselves after each color, either using an <angle> or <percentage>. Valid values include:

  • Degrees (deg)
  • Gradians (grad)
  • Percentages (%)
  • Radians (rad)
  • Turns (turn)

For example, the following will set blue to appear at 90deg, instead of the default 180deg. Then, the transition will be carried out as usual:

.gradient { background-image: conic-gradient(lightblue, blue 90deg, lightblue); }

We can also span a color across two angles by defining a starting and ending angle. For instance, we can make solid orange span from 90deg (right) to 270deg (left), and then transition to red.

.gradient { background-image: conic-gradient(red, orange 90deg 270deg, red); }

Rotating gradient with the from keyword

It’s also possible to rotate the whole gradient using the from keyword. We can write from followed by an <angle>. This will shift the starting position (12:00, if we’re looking at a clock) where colors emerge.

For example, we can rotate the same gradient by multiples of 90deg:

.deg0 { /* default is 0deg */ background: conic-gradient(crimson, purple, crimson); } .deg90 { background-image: conic-gradient(from 90deg, crimson, purple, crimson); } .deg180 { background-image: conic-gradient(from 180deg, crimson, purple, crimson); } .deg270 { background-image: conic-gradient(from 270deg, crimson, purple, crimson); }

Note: I inserted a black ray to better see the point of rotation.

This also gives us the chance to animate the conic gradient’s rotation. We’ll first create a custom property holding the desired angle, which can then be animated using @keyframes from 0deg to 360deg.

@property --spin { syntax: "<angle>"; initial-value: 0deg; inherits: false; } @keyframes spinning { 0%, 50% { --spin: 0deg; } 100% { --spin: 360deg; } } 

Note: We need to register the custom variable with @property for the animation to work because, otherwise, CSS is unable to read the --spin value as a numeric length unit and instead reads it as a string that cannot be interpolated. Learn more about why that is in this article.

Then we can create the conic gradient as usual, inserting the --spin variable to animate the whole rotation:

.gradient { background-image: conic-gradient(from var(--spin), white, black, white); animation: spinning 3s ease-in-out infinite; }

Moving gradients with the at keyword

We can also choose the conic gradient’s center position using the at keyword. By default, the gradient’s center point is placed at the center of the gradient, but we can move it by defining its horizontal and vertical position.

The available options are:

  • Physical values, like left topcenter right or bottom.
.element { background: conic-gradient(at center top, blue, crimson, blue); }
  • Lengths, like 20px 60px, or 20vw. These are placed away from the gradient’s box top left corner.
.element { background: conic-gradient(at 20px 60px, blue, lightblue, blue); }
  • Percentages, like 40% 20% or 25%. They are relative to the gradient’s box size and placed from its top-left corner.
.element { background: conic-gradient(at 40% 20%, green, chartreuse, green); }

It’s also worth noting that both lengths and percentages can be lower than zero or bigger than the gradient’s box, placing the gradient’s center outside its box.

.element { background: conic-gradient(at -20px 110%, red, yellow, red); }

Note: The conic-gradient() function does not appear to support logical keywords, like start or block-end.

Hard color stops

While earlier we dismissed hard color stops as ugly, we can still use them to create decorative visual flourishes in a design. For example, we could create a pie chart. Each color angle is declared immediately after the next color, such that they share borders and give no chance for the transition at all:

.gradient { background: conic-gradient(blue 0deg 45deg, lightblue 45deg 180deg, navy 180deg 360deg); /* same as */ background: conic-gradient(blue 45deg, lightblue 45deg 180deg, navy 180deg); }

Note: While this example demonstrates how to use hard color stops in a conical gradient, do not use the conic-gradient() function to create an actual real pie chart, or any other infographics for that matter. They don’t hold any semantic meaning and should only be used decoratively. You might consider using SVG instead.

This technique isn’t limited to charts; we can even use it to create complex flags beyond striped ones. For example, this is my best rendition of the Seychelles flag using hard stops and only a conic-gradient() (and sorry if I didn’t get the exact dimensions correct):

.gradient { background-image: conic-gradient( at bottom left, #002f6c 9%, #fed141 9% 14.5%, #d22730 14.5% 20%, #ffffff 20% 23%, #007a33 23% ); }

Notice how we used only the first quarter (0% to 25%) of the conic gradient to cover the whole flag!

Patterns?!

While hard stops are fun by themselves, their real power comes from patterns. For a better look at its potential, Ana Tudor has an amazing post showcasing patterns easily achievable by conic gradients and hard stops. Here’s a checkboard pattern as just one example of what we can make with conic-gradient():

Checkboard pattern

This pattern can be achieved with a single conic-gradient(). We’ll focus on a set of four tiles and use it to create the pattern.

Checkboard pattern seen as conic gradient

To be super precise, we can use hard stops to fill each quarter of the gradient with a solid color:

.element { background-image: conic-gradient(#f0d9b5 25%, #b58863 0% 50%, #f0d9b5 50% 75%, #b58863 75%); }

What’s left is to reduce the size of the background using the background-size property, and because the background-repeat property is set to repeat by default, it will fill the whole element, repeating the checkboard pattern.

.element { background-image: conic-gradient(#f0d9b5 25%, #b58863 0% 50%, #f0d9b5 50% 75%, #b58863 75%); background-size: 100px 100px; }

Not only backgrounds but masks!

Remember! conic-gradient(), and gradients in general, return an <image> type. So while they are commonly used inside background-image, they are equally valid in every other property that takes an image. The most notorious case being masks, which allow us to apply either images, SVGs, or gradients above an element to hide certain parts of it.

In this case, we use the mask-image property, whose syntax is the same as background-image:

.element { mask-image: conic-gradient(...); }

By default, when a gradient is applied as a mask, transparent colors will hide the element, while solid colors will leave it as is. The specific color doesn’t matter, just its transparency. You can think of it as though you anre assigning the transparency of the image through the gradient. For example, the following uses hard stops to create transparent rays along the image:

img { mask-image: conic-gradient( at bottom left, transparent 0% 5%, #fff 5% 15%, transparent 15% 20%, #fff 20% 25% ); }

This holds whenever mask-mode is set to alpha, which is by default.

Masks are a world of their own, so if you want to learn more about them, I recommend “Apply effects to images with the CSS mask-image property” by Rachel Andrew for an introduction to masking, and “CSS Masking” by Ahmad Shadeed for real-world uses.

Demo

Specification

The conic-gradient() function and color interpolation methods are defined in the CSS Images Module Level 4, which is currently in Editor’s Draft.

Browser support

Both the conic-gradient() base and the interpolation method syntax are supported across all browsers.

More information