What we’re building
Here’s the gradient generator we’re going to build. Click the button at the bottom to generate random new mesh gradients! Once they’re generated, you can copy the CSS to recreate the gradients using the background-image
property in combination with radial-gradient
.
Wait, what’s a mesh gradient?
Good question. Mesh gradient is the name given to a gradient in which multiple colors blend smoothly across a canvas, creating dreamy, colorful patterns. Mesh gradients have been a popular design trope on the web for a while, often seen in website backgrounds, hero sections, and app splash screens.
Stripe’s homepage is a classic example that uses mesh gradients to create a colorful and dynamic aesthetic.


Now we’re up to speed, let’s get building!
Our simple HTML markup
We’ll start with a simple HTML markup which will have the following elements:
- A header title
- A preview box container to show random mesh gradients in real time.
- A button for generating new gradients.
- A code block element to display the CSS used to create each mesh gradient.
- A button to copy the generated CSS
Here is the HTML.
1 |
<div class="container"> |
2 |
<h1>Mesh Gradient Generator</h1> |
3 |
<div id="preview" class="preview"></div> |
4 |
<button id="generateBtn" class="button">Generate New Mesh</button> |
5 |
<div id="cssCode" class="css-code"></div> |
6 |
<button id="copyButton" class="copy-button">Copy CSS</button> |
7 |
</div>
|
Now let’s make the interface more colorful. We’ll use some basic styles for all the elements and also set up a default mesh gradient in the preview element.
Add these styles to your CSS file.
1 |
body { |
2 |
margin: 0; |
3 |
display: flex; |
4 |
justify-content: center; |
5 |
min-height: 100vh; |
6 |
background-color: #fefefe; |
7 |
|
8 |
}
|
9 |
h1 { |
10 |
margin-top: 20px; |
11 |
color: #333; |
12 |
font-size: 2rem; |
13 |
}
|
14 |
|
15 |
.container { |
16 |
width: 100%; |
17 |
max-width: 800px; |
18 |
display: flex; |
19 |
flex-direction: column; |
20 |
gap: 20px; |
21 |
align-items: center; |
22 |
}
|
23 |
|
24 |
|
25 |
.button { |
26 |
padding: 12px 24px; |
27 |
border-radius: 6px; |
28 |
font-size: 1rem; |
29 |
cursor: pointer; |
30 |
color: #000; |
31 |
border: 1px solid #c1c5ce; |
32 |
background-color: #fff; |
33 |
}
|
34 |
|
35 |
.css-code { |
36 |
width: 100%; |
37 |
padding: 16px; |
38 |
border-radius: 8px; |
39 |
font-family: monospace; |
40 |
white-space: pre-wrap; |
41 |
background-color: #f5f5f5; |
42 |
font-size: 14px; |
43 |
}
|
44 |
.copy-button { |
45 |
padding: 8px 16px; |
46 |
border-radius: 4px; |
47 |
font-size: 14px; |
48 |
cursor: pointer; |
49 |
color: #fff; |
50 |
border: none; |
51 |
background-color: #005CE6; |
52 |
}
|
53 |
.copy-button:hover { |
54 |
background-color: #1a4e9d; |
55 |
}
|
How Radial Gradients Work
The magic effect of mesh gradients comes from CSS radial gradients. So what exactly is a radial gradient? In CSS, a radial gradient generates a smooth transition between two or more colors, starting from a specific point and radiating outward towards another color or even transparency.
Here is an example of a radial gradient consisting of 2 colors.
1 |
background: radial-gradient(at 40% 20%, #fc2ee7, #6fa17d); |
The values 40% 20% represent the center of the gradient being positioned 40% from the left and 20% from the top of the enclosing element. The radial gradient above will look like this:
Let’s add two more radial gradients to our box. The CSS for the background of the box will now look like this:
1 |
background: radial-gradient(at 40% 20%, #FC2EE7, transparent 60%), |
2 |
radial-gradient(at 70% 80%, #6FA17D, transparent 60%), |
3 |
radial-gradient(at 20% 70%, #2EFCDB, transparent 60%), |
4 |
radial-gradient(at 80% 30%, #FFA62E, transparent 60%); |
5 |
|
Here is the output of layering 3 radial gradients:
As you can see, the background looks richer and vibrant because we are using multiple colors and placing them at random positions on the canvas.
We’ll layer several of these radial gradients at different positions, using a variety of unique colors at each position to create rich and colorful mesh gradients.
Add a default gradient to the preview
We’ll use the same layering technique to add a default mesh gradient to the preview element. For the preview, we’ll use 7 radial gradients. You can use any number of gradients, but ensure each gradient has unique positions and unique colors.
Update the styles for the preview container to look like this:
1 |
background-image: radial-gradient( |
2 |
at 30% 15%, |
3 |
rgb(255, 102, 204) 0px, |
4 |
transparent 50% |
5 |
),
|
6 |
radial-gradient(at 75% 10%, rgb(102, 255, 204) 0px, transparent 50%), |
7 |
radial-gradient(at 5% 65%, rgb(255, 233, 102) 0px, transparent 50%), |
8 |
radial-gradient(at 85% 55%, rgb(102, 153, 255) 0px, transparent 50%), |
9 |
radial-gradient(at 10% 90%, rgb(255, 153, 51) 0px, transparent 50%), |
10 |
radial-gradient(at 90% 95%, rgb(153, 255, 102) 0px, transparent 50%), |
11 |
radial-gradient(at 15% 5%, rgb(204, 102, 255) 0px, transparent 50%); |
Here we have defined multiple radial-gradients()
layers each positioned at different x and y coordinates. Each gradient starts with a unique color at the center and fades out to transparency .
After combining the radial gradients, we achieve a colorful mesh gradient which looks like this:



Generating random gradients
It’s time to create randomised mesh gradients. We want to ensure that every time you click the generate button, a new mesh gradient is generated and updated in the preview.
We’ll also show a code block containing the exact CSS styles used to create the current mesh gradient.
Let’s first get the elements:
1 |
const preview = document.getElementById("preview"); |
2 |
const generateBtn = document.getElementById("generateBtn"); |
3 |
const cssCode = document.getElementById("cssCode"); |
4 |
const copyButton = document.getElementById("copyButton"); |
Generate random colors and X, Y coordinates
To apply radial gradients to any element, we first need to determine the x and y coordinates where each radial gradient will be applied. To do that, we’ll generate random x and y coordinates on the canvas, ensuring that the radial gradients are randomly distributed across the entire element.
1 |
function generatePoints() { |
2 |
const x = Math.floor(Math.random() * 100); |
3 |
const y = Math.floor(Math.random() * 100); |
4 |
return `${x}% ${y}%`; |
5 |
}
|
The generatePoints()
function will generate random x, y coordinates for each gradient. In CSS radial gradients, these coordinates are defined using percentages.
- 0% 0% will place the gradient at the top-left corner of the element
- 100% 100% will place the gradient at the bottom-right center of the element
- 50% 50 % will place the gradient at the center of the element.
We’ll create a similar function for generating random colors.
1 |
function generateRandomColor() { |
2 |
const r = Math.floor(Math.random() * 256); |
3 |
const g = Math.floor(Math.random() * 256); |
4 |
const b = Math.floor(Math.random() * 256); |
5 |
return `rgb(${r}, ${g}, ${b})`; |
6 |
}
|
Now that we have our points and colors, we’ll use them to determine where each radial gradient will be placed.
Create a function called generateRandomGradient()
.
1 |
function generateRandomGradient() { |
2 |
|
3 |
}
|
To add variety and enhance the richness of our mesh gradients, we’ll use Math.random()
and Math.floor()
to create between 5 and 8 radial gradients.
1 |
const points = Math.floor(Math.random() *4) +5 ; |
Create an empty gradients array to contain the radial gradients .
Now we’ll use a for
loop to create radial gradients based on the number of points. For each iteration, the loop will generate a random position, a random color, and create a radial gradient using the position and color.
1 |
for (let i = 0; i < points; i++) { |
2 |
const position = generatePoints(); |
3 |
const color = generateRandomColor(); |
4 |
|
5 |
gradients.push( |
6 |
`radial-gradient(at ${position}, ${color} 0px, transparent 50% )` |
7 |
);
|
8 |
}
|
Finally, we combine the radial gradients into one string and set the string as the background of the preview element.
This will update the preview with the new mesh gradient.
1 |
preview.style.backgroundImage = backgroundImage; |
The generateRandomGradient()
function now looks like this:
1 |
function generateRandomGradient() { |
2 |
const points = Math.floor(Math.random() * 4) + 5; |
3 |
const backgroundColor = generateRandomColor(); |
4 |
|
5 |
let gradients = []; |
6 |
for (let i = 0; i < points; i++) { |
7 |
const position = generatePoints(); |
8 |
const color = generateRandomColor(); |
9 |
|
10 |
gradients.push( |
11 |
`radial-gradient(at ${position}, ${color} 0px, transparent 50% )` |
12 |
);
|
13 |
}
|
14 |
|
15 |
const backgroundImage = gradients.join(", "); |
16 |
preview.style.backgroundImage = backgroundImage; |
17 |
preview.style.backgroundColor = backgroundColor; |
18 |
|
19 |
}
|
To ensure a new mesh gradient is generated when the generate button is clicked, we’ll hook the button to the generateRandomGradient
function.
We do this by adding a click event listener like this:
1 |
generateBtn.addEventListener("click", generateRandomGradient); |
Now, when you click the generate button, a new colorful mesh gradient will be generated.
Update and Copy Generated CSS
We also want to show a code block containing the CSS code for the current mesh gradient and update it every time a new mesh gradient is generated.
To do this, we will create a new function called updateCSS()
, which looks like this:
1 |
function updateDefaultCss() { |
2 |
const computedStyle = getComputedStyle(preview); |
3 |
const backgroundColor = computedStyle.backgroundColor; |
4 |
const backgroundImage = computedStyle.backgroundImage; |
5 |
console.log(backgroundImage); |
6 |
cssCode.innerText = `.mesh-gradient { |
7 |
background-image: ${backgroundImage}; |
8 |
background-color: ${backgroundColor}; |
9 |
}`; |
10 |
}
|
In this function, we use getComputedStyle()
to read the current styles of the preview box. getComputedStyle()
is a method used to get any CSS property currently applied to an HTML element.
In our case, we use it to get the background color (backGroundColor
) and the background image (backgroundImage
) and update the values on the code block element.
We also need to ensure this function runs every time a new mesh gradient is generated. Update the generateRandomGradient
as shown below.
1 |
function generateRandomGradient() { |
2 |
// the rest of the code
|
3 |
updateDefaultCss(); |
4 |
}
|
The final step is to ensure that when the Copy CSS button is clicked, the values are copied to the clipboard.
1 |
copyButton.addEventListener("click", () => { |
2 |
navigator.clipboard.writeText(cssCode.innerText); |
3 |
alert("CSS Code Copied!"); |
4 |
});
|
Final Demo
Here is the final demo!
Conclusion
That’s a wrap for this tutorial. We’ve learned how to use radial gradients to create beautiful and colorful mesh gradients with CSS!