Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating the perfect rainbow gradient in CSS

It's easy to create a rainbow in CSS using linear-gradient.

#grad1 {
  height: 200px;
  background: linear-gradient(45deg, red, orange, yellow, green, blue, indigo, violet, red);
}
<div id="grad1"></div>

But look at it! This gradient is aesthetically horrifying. It's streaky, there's ugly strips of pure colour where the endpoints meet, it doesn't loop very well, it's not smooth, and the colours clearly contrast against each other when they should seamlessly blend.

In short: it's a terrible gradient.

I'd like to find the perfect gradient. One that encompasses the rainbow in a slick, smooth way, one that doesn't leave any obvious bumps or visual tearing. Instead of a spiky mess, this gradient is a smooth curve.

Does this gradient exist?

like image 920
snazzybouche Avatar asked Dec 10 '22 02:12

snazzybouche


2 Answers

You need to choose colors that will blend nicely together and more color steps.

background: linear-gradient(90deg, rgba(255,0,0,1) 0%, rgba(255,154,0,1) 10%, rgba(208,222,33,1) 20%, rgba(79,220,74,1) 30%, rgba(63,218,216,1) 40%, rgba(47,201,226,1) 50%, rgba(28,127,238,1) 60%, rgba(95,21,242,1) 70%, rgba(186,12,248,1) 80%, rgba(251,7,217,1) 90%, rgba(255,0,0,1) 100%);

.rainbow-box {
    width: 80vw;
    height: 200px;
    border-radius: 5px;
    background: linear-gradient(
        90deg,
        rgba(255, 0, 0, 1) 0%,
        rgba(255, 154, 0, 1) 10%,
        rgba(208, 222, 33, 1) 20%,
        rgba(79, 220, 74, 1) 30%,
        rgba(63, 218, 216, 1) 40%,
        rgba(47, 201, 226, 1) 50%,
        rgba(28, 127, 238, 1) 60%,
        rgba(95, 21, 242, 1) 70%,
        rgba(186, 12, 248, 1) 80%,
        rgba(251, 7, 217, 1) 90%,
        rgba(255, 0, 0, 1) 100%
    );
}
<div class="rainbow-box"></div>

CSS gradient with a number of color steps, by each 10%

Screenshot of CSS rainbow gradient after rendering in the browser

I made it using CSS gradient generator: https://cssgradient.io/

like image 107
Bartek Avatar answered Jan 02 '23 20:01

Bartek


You can get something that looks better by overlaying the individual red, green, and blue colours, trying to match the human colour cone sensitivities.

Here's an example, but it could be improved by adjusting some of the % numbers in the linear-gradients, and by having smother gradient shapes (currently triangles with cut-off tops).

Rainbow with RGB components.

<!DOCTYPE html>
<html>
<head>
    <title>Rainbow</title>
    <meta charset="UTF-8" />
    <style>
        * { box-sizing: border-box; }

        .separate   { width: 100%; height: 10em; }
        .separate>* { width: 100%; height: 100%; margin-top: 1em; }

        .overlay   { width: 100%; height: 10em; filter: brightness(3); }
        .overlay>* { width: 100%; height: 100%; position: absolute; }
        .overlay>:nth-of-type(1) { opacity: 1; }
        .overlay>:nth-of-type(2) { opacity: .5; }
        .overlay>:nth-of-type(3) { opacity: .33; }
        .overlay>:nth-of-type(4) { opacity: .25; }

        .blue   { background: linear-gradient(
           90deg,                 rgb(0,0,256)  0%, rgb(0,0,256) 5%,  rgb(0,0,0) 20% ); }
        .green  { background: linear-gradient(
           90deg, rgb(0,0,0) 0%,  rgb(0,256,0) 25%, rgb(0,256,0) 35%, rgb(0,0,0) 55% ); }
        .red    { background: linear-gradient(
           90deg, rgb(0,0,0) 15%, rgb(256,0,0) 35%, rgb(256,0,0) 45%, rgb(0,0,0) 100% ); }
        .blue2  { background: linear-gradient(
           90deg, rgb(0,0,0) 65%, rgb(0,0,256) 95%, rgb(0,0,256) 100% ); }
    </style>
</head>
<body>
<h1>Rainbow</h1>
    <div class="overlay">
        <div class="blue"></div>
        <div class="green"></div>
        <div class="red"></div>
        <div class="blue2"></div>
    </div>
    <div class="separate">
        <div class="blue"></div>
        <div class="green"></div>
        <div class="red"></div>
        <div class="blue2"></div>
    </div>
</body>
</html>
like image 29
Ray Butterworth Avatar answered Jan 02 '23 18:01

Ray Butterworth