8

How to create the following rainbow effect using CSS?

i.e. top rounded border with solid rainbow color stops (without inserting html).

enter image description here

Colors are: #c4e17f. #f7fdca, #fad071, #f0766b, #db9dbe, #c49cdf, #6599e2, #61c2e4.

What I have tried so far:

.container {
  background: #596678;
  width: 100%;
  height: 300px;
  display: flex;
  justify-content: center;
  align-items: center;
}

.top-round-rainbow {
  width: 50%;
  height: 50%;
  background: white;
  border-radius: 4px;
  
  background-image: repeating-linear-gradient(to right, #c4e17f 50px, #f7fdca 50px, #fad071 50px, #f0766b, #db9dbe, #c49cdf, #6599e2, #61c2e4);
}
<div class="container">
  <div class="top-round-rainbow">
  </div>
</div>
Temani Afif
  • 245,468
  • 26
  • 309
  • 415
abdul-wahab
  • 2,182
  • 3
  • 21
  • 35

6 Answers6

13

You're not that far off. Just need to set the color stops with equal values so they act as solid colors, and the background size to have it only on top.

.container {
  background: #596678;
  width: 100%;
  height: 300px;
  display: flex;
  justify-content: center;
  align-items: center;
}

.top-round-rainbow {
  width: 400px;
  height: 50%;
  background: white;
  border-radius: 4px;
  
  background-image: repeating-linear-gradient(to right,
  #c4e17f 0px, #c4e17f 50px,
  #f7fdca 50px, #f7fdca 100px,
  #fad071 100px, #fad071 150px,
  #f0766b 150px, #f0766b 200px,
  #db9dbe 200px, #db9dbe 250px,
  #c49cdf 250px, #c49cdf 300px,
  #6599e2 300px, #6599e2 350px,
  #61c2e4 350px, #61c2e4 400px);
  background-size: 100% 10px;
  background-repeat:no-repeat;
}
<div class="container">
  <div class="top-round-rainbow">
  </div>
</div>
Temani Afif
  • 245,468
  • 26
  • 309
  • 415
Facundo Corradini
  • 3,825
  • 9
  • 24
4

You could use after pseudo-element with linear-gradient to create border.

.container {
  background: #596678;
  width: 100%;
  height: 300px;
  display: flex;
  justify-content: center;
  align-items: center;
}

.top-round-rainbow {
  width: 50%;
  height: 50px;
  background: white;
  border-radius: 4px;
  position: relative;
  overflow: hidden;
}

.top-round-rainbow:after {
  content: "";
  position: absolute;
  height: 10px;
  top: 0;
  width: 100%;
  left: 0;
  background: linear-gradient(to right, rgba(196,225,127,1) 0%, rgba(196,225,127,1) 12%, rgba(247,253,202,1) 12%, rgba(247,253,202,1) 25%, rgba(250,208,113,1) 25%, rgba(250,208,113,1) 39%, rgba(240,118,107,1) 39%, rgba(240,118,107,1) 52%, rgba(219,157,190,1) 52%, rgba(219,157,190,1) 65%, rgba(196,156,223,1) 65%, rgba(196,156,223,1) 78%, rgba(101,153,226,1) 78%, rgba(101,153,226,1) 89%, rgba(97,194,228,1) 89%, rgba(97,194,228,1) 100%);
}
<div class="container">
  <div class="top-round-rainbow"></div>
</div>
Temani Afif
  • 245,468
  • 26
  • 309
  • 415
Nenad Vracar
  • 118,580
  • 15
  • 151
  • 176
3

The solutions already provided are perfect but I will add another one using border and gradient. You can also use your gradient as a border-image but pay attention as this won't work with border-radius.

.container {
  background: #596678;
  width: 100%;
  height: 300px;
  display: flex;
  justify-content: center;
  align-items: center;
}

.top-round-rainbow {
  width: 400px;
  height: 50%;
  background: white;
  border-radius:5px;
  border-top: 10px solid;
  border-image:linear-gradient(90deg,
  #c4e17f 0 50px,
  #f7fdca 0 100px,
  #fad071 0 150px,
  #f0766b 0 200px,
  #db9dbe 0 250px,
  #c49cdf 0 300px,
  #6599e2 0 350px,
  #61c2e4 0 400px) 10;
}
<div class="container">
  <div class="top-round-rainbow">
  </div>
</div>
Temani Afif
  • 245,468
  • 26
  • 309
  • 415
  • 1
    Yes, your addition is still helpful. And for you know, my first intuition was too to use gradient with border. – abdul-wahab Feb 27 '18 at 20:08
  • @abdul-wahab i was pretty sure about this when i saw your code ;) that's why i added this ... as it can be a bit difficult to handle the linear-gradient as background and adjust size to make it like border but it remain a great solution, simply pay attention to padding as background is a part of the content unlike border – Temani Afif Feb 27 '18 at 20:31
2

This problem does not necessarily require pseudo-elements or additional layers.

To achieve a stopped gradient, declare colors at intersections.

To limit background-image height to 10px (or any arbitrary number), but retain 100% width, use background-size: 10px 100%.

To prevent the gradient from repeating use background-repeat: no-repeat;.

.container {
  background: #596678;
  width: 100%;
  height: 300px;
  display: flex;
  justify-content: center;
  align-items: center;
}

.top-round-rainbow {
  width: 50%;
  height: 50%;
  border-radius: 4px;
  background: repeating-linear-gradient(to right, #c4e17f 0%, #c4e17f 12.5%, #f7fdca 12.5%, #f7fdca 25%, #fad071 25%, #fad071 37.5%, #f0766b 37.5%, #f0766b 50%, #db9dbe 50%, #db9dbe 62.5%, #c49cdf 62.5%, #c49cdf 75%, #6599e2 75%, #6599e2 87.5%, #61c2e4 87.5%, #61c2e4 100%), white;
  background-size: 100% 10px, 100% 100%;
  background-repeat: no-repeat;
}
<div class="container">
  <div class="top-round-rainbow">
  </div>
</div>
Temani Afif
  • 245,468
  • 26
  • 309
  • 415
user
  • 173
  • 6
1

Another approach, just for the giggles. This time with multiple box shadows.

.container {
  background: #596678;
  width: 100%;
  height: 300px;
  display: flex;
  justify-content: center;
  align-items: center;
}

.top-round-rainbow {
  width: 400px;
  height: 50%;
  background: white;
  box-shadow:
/*white overlay*/
  0 -150px 0 -10px white inset,
/*"borders" that cover each other*/
  50px 0 0 0 #c4e17f inset,
  100px 0 0 0 #f7fdca inset,
  150px 0 0 0 #fad071 inset,
  200px 0 0 0 #f0766b inset,
  250px 0 0 0 #db9dbe inset,
  300px 0 0 0 #c49cdf inset,
  350px 0 0 0 #6599e2 inset,
  400px 0 0 0 #61c2e4 inset;
}
<div class="container">
  <div class="top-round-rainbow">
  </div>
</div>

Not really practical, as we need to know the height of the div. But they make for some cool effects with border-radius :p

.container {
  background: #596678;
  width: 100%;
  height: 300px;
  display: flex;
  justify-content: center;
  align-items: center;
}

.top-round-rainbow {
  width: 400px;
  height: 50%;
  background: white;
  box-shadow:
/*white overlay*/
  0 -150px 0 -10px white inset,
/*"borders" that cover each other*/
  50px 0 0 0 #c4e17f inset,
  100px 0 0 0 #f7fdca inset,
  150px 0 0 0 #fad071 inset,
  200px 0 0 0 #f0766b inset,
  250px 0 0 0 #db9dbe inset,
  300px 0 0 0 #c49cdf inset,
  350px 0 0 0 #6599e2 inset,
  400px 0 0 0 #61c2e4 inset;
  
  border-radius:10px;
}
<div class="container">
  <div class="top-round-rainbow">
  </div>
</div>

and last but not least, one with rounded borders + rounded box-shadow, which makes for an awesome look imho. And makes a little more sense.

.container {
  background: #596678;
  width: 100%;
  height: 300px;
  display: flex;
  justify-content: center;
  align-items: center;
}

.top-round-rainbow {
  width: 400px;
  height: 50%;
  background: white;
  border-radius:10px;
  position:relative;
  overflow:hidden;
  padding-top:10px;
}
  
.top-round-rainbow::before{
  content:"";
  position:absolute; top:0; left:0;
  height:10px; width:100%;
  box-shadow:
  50px 0 0 0 #c4e17f inset,
  100px 0 0 0 #f7fdca inset,
  150px 0 0 0 #fad071 inset,
  200px 0 0 0 #f0766b inset,
  250px 0 0 0 #db9dbe inset,
  300px 0 0 0 #c49cdf inset,
  350px 0 0 0 #6599e2 inset,
  400px 0 0 0 #61c2e4 inset;
  border-radius:10px 0 0 0;
}
<div class="container">
  <div class="top-round-rainbow">
  </div>
</div>
Facundo Corradini
  • 3,825
  • 9
  • 24
0

Just add a new layer, this with let you specify the size of the white area.

Hope this is what you were looking for. Happy to explain or help in a better solution if needed.

.container {
  background: #596678;
  width: 100%;
  height: 300px;
  display: flex;
  justify-content: center;
  align-items: center;
}

.top-round-rainbow {
  width: 50%;
  height: 50%;
  background: white;
  border-radius: 4px;
  border-top-width: 4px;
  background-image: repeating-linear-gradient(to right, #c4e17f 50px, #f7fdca 50px, #fad071 50px, #f0766b, #db9dbe, #c49cdf, #6599e2, #61c2e4);
}

.white-layer {
  width: 100%;
  height: 95%;
  margin-top: 5%;
  background: white;
  border-radius:  0 0 4px 4px;
  border-top-width: 4px;
}
<div class="container">
  <div class="top-round-rainbow">
    <div class="white-layer">
    </div>
  </div>
</div>
Gerardo BLANCO
  • 5,590
  • 1
  • 16
  • 35
  • Thanks, but can you examine more and see if gradient can be made with solid stops, as in the image. Then we'll see how to avoid adding an additional element. – abdul-wahab Feb 27 '18 at 19:11