4

I'm trying to use CSS to generate the below gradient image. However, I'm struggling with the alignment. You will notice in my snippet the problem. I tried absolute positioning them but that was just making things worse.

gradient

.gradients {
  position: relative;
  width: 100%;
}

.gradients div {
  height: 40px;
}

.bottom-gradient {
  -ms-transform: rotate(0.6deg);
  -webkit-transform: rotate(0.6deg);
  transform: rotate(0.6deg);
  background: -moz-linear-gradient(left, rgba(37, 52, 47, 0.9) 0%, rgba(3, 95, 26, 0.9) 100%);
  background: -webkit-gradient(linear, left top, right top, color-stop(0%, rgba(37, 52, 47, 0.9)), color-stop(100%, rgba(3, 95, 26, 0.9)));
  background: -webkit-linear-gradient(left, rgba(37, 52, 47, 0.9) 0%, rgba(3, 95, 26, 0.9) 100%);
  background: -o-linear-gradient(left, rgba(37, 52, 47, 0.9) 0%, rgba(3, 95, 26, 0.9) 100%);
  background: -ms-linear-gradient(left, rgba(37, 52, 47, 0.9) 0%, rgba(3, 95, 26, 0.9) 100%);
  background: linear-gradient(to right, rgba(37, 52, 47, 0.9) 0%, rgba(3, 95, 26, 0.9) 100%);
  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#80414c46', endColorstr='#80035f1a', GradientType=1);
}

.top-gradient {
  -ms-transform: rotate(0.6deg);
  -webkit-transform: rotate(0.6deg);
  transform: rotate(0.10deg);
  background: -moz-linear-gradient(left, rgba(3, 95, 26, 0.9) 0%, rgba(37, 52, 47, 0.9) 100%);
  background: -webkit-gradient(linear, left top, right top, color-stop(0%, rgba(3, 95, 26, 0.9)), color-stop(100%, rgba(37, 52, 47, 0.9)));
  background: -webkit-linear-gradient(left, rgba(3, 95, 26, 0.9) 0%, rgba(37, 52, 47, 0.9) 100%);
  background: -o-linear-gradient(left, rgba(3, 95, 26, 0.9) 0%, rgba(37, 52, 47, 0.9) 100%);
  background: -ms-linear-gradient(left, rgba(3, 95, 26, 0.9) 0%, rgba(37, 52, 47, 0.9) 100%);
  background: linear-gradient(to right, rgba(3, 95, 26, 0.9) 0%, rgba(37, 52, 47, 0.9) 100%);
  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#80035f1a', endColorstr='#80414c46', GradientType=1);
}
<div class="gradients">
  <div class="top-gradient"></div>
  <div class="bottom-gradient"></div>
</div>
Temani Afif
  • 245,468
  • 26
  • 309
  • 415
imvain2
  • 15,480
  • 1
  • 16
  • 21

2 Answers2

1

position: absolute or a negative margin would work, but require hard-coded values. A more flexible alternative would be to add transform: translateY(-100%) to your .bottom-gradient.

As you already have a transform: rotate(0.6deg) on this element, you can just append the translateY to it:

.bottom-gradient { transform: rotate(0.6deg) translateY(-100%) }

In an effort to replicate the image a bit closer, I've also made the following changes:

  • Changed the rotation of the gradients to 1deg and -1deg.
  • Changed the height to 16px;

.gradients {
  position: relative;
  width: 100%;
}

.gradients div {
  height: 16px;
}

.bottom-gradient {
  -ms-transform: rotate(-1deg) translateY(-100%);
  -webkit-transform: rotate(-1deg) translateY(-100%);
  transform: rotate(-1deg) translateY(-100%);
  background: -moz-linear-gradient(left, rgba(37, 52, 47, 0.9) 0%, rgba(3, 95, 26, 0.9) 100%);
  background: -webkit-gradient(linear, left top, right top, color-stop(0%, rgba(37, 52, 47, 0.9)), color-stop(100%, rgba(3, 95, 26, 0.9)));
  background: -webkit-linear-gradient(left, rgba(37, 52, 47, 0.9) 0%, rgba(3, 95, 26, 0.9) 100%);
  background: -o-linear-gradient(left, rgba(37, 52, 47, 0.9) 0%, rgba(3, 95, 26, 0.9) 100%);
  background: -ms-linear-gradient(left, rgba(37, 52, 47, 0.9) 0%, rgba(3, 95, 26, 0.9) 100%);
  background: linear-gradient(to right, rgba(37, 52, 47, 0.9) 0%, rgba(3, 95, 26, 0.9) 100%);
  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#80414c46', endColorstr='#80035f1a', GradientType=1);
}

.top-gradient {
  -ms-transform: rotate(1deg);
  -webkit-transform: rotate(1deg);
  transform: rotate(1deg);
  background: -moz-linear-gradient(left, rgba(3, 95, 26, 0.9) 0%, rgba(37, 52, 47, 0.9) 100%);
  background: -webkit-gradient(linear, left top, right top, color-stop(0%, rgba(3, 95, 26, 0.9)), color-stop(100%, rgba(37, 52, 47, 0.9)));
  background: -webkit-linear-gradient(left, rgba(3, 95, 26, 0.9) 0%, rgba(37, 52, 47, 0.9) 100%);
  background: -o-linear-gradient(left, rgba(3, 95, 26, 0.9) 0%, rgba(37, 52, 47, 0.9) 100%);
  background: -ms-linear-gradient(left, rgba(3, 95, 26, 0.9) 0%, rgba(37, 52, 47, 0.9) 100%);
  background: linear-gradient(to right, rgba(3, 95, 26, 0.9) 0%, rgba(37, 52, 47, 0.9) 100%);
  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#80035f1a', endColorstr='#80414c46', GradientType=1);
}
<div class="gradients">
  <div class="top-gradient"></div>
  <div class="bottom-gradient"></div>
</div>
Tyler Roper
  • 21,445
  • 6
  • 33
  • 56
0

You can optimize your code using only pseudo elements and by defining the gradient once.

.gradients {
  position: relative;
  height: 40px;
  margin:40px 0;
}
.gradients:before,
.gradients:after{
  content:"";
  position:absolute;
  top:0;
  left:0;
  right:0;
  bottom:0;
  transform: rotate(2deg);
  background: linear-gradient(to right, rgba(37, 52, 47, 0.9), rgba(3, 95, 26, 0.9));
}
.gradients:after {
  /* since it's the same gradient in the other direction, you can simply make a mirror image of it*/
  transform:scaleX(-1) rotate(2deg);
}
<div class="gradients">
</div>

You can also consider skew() instead of rotate to obtain a different effect probably closer to what you want. Notice the difference in the edges:

.gradients {
  position: relative;
  height: 40px;
  margin:40px 0;
}
.gradients:before,
.gradients:after{
  content:"";
  position:absolute;
  top:0;
  left:0;
  right:0;
  bottom:0;
  transform: skewY(2deg);
  background: linear-gradient(to right, rgba(37, 52, 47, 0.9), rgba(3, 95, 26, 0.9));
}
.gradients:after {
  /* since it's the same gradient in the other direction, you can simply make a mirror image of it*/
  transform:scaleX(-1) skewY(2deg);
}
<div class="gradients">
</div>

I also suspect you want to have something responsive which means that the distance between both gradients should not change when your resize the window (which is not the case for the above solutions). To do so here is an idea that rely on SVG and background:

.gradients {
  position: relative;
  height: 80px;
  margin:40px 0;
  background-image: url('data:image/svg+xml;charset=UTF-8,<svg version="1.1"  xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" preserveAspectRatio="none" viewBox="0 0 25 30" ><defs><linearGradient id="one" ><stop offset="0%" stop-color="rgba(37, 52, 47, 0.9)"/><stop offset="100%" stop-color="rgba(3, 95, 26, 0.9)" /></linearGradient><linearGradient id="two" ><stop offset="0%" stop-color="rgba(3, 95, 26, 0.9)" /><stop offset="100%" stop-color="rgba(37, 52, 47, 0.9)"/></linearGradient></defs><polygon points="25,7 25,25 0,18 0,0" fill="url(%23one)"/><polygon points="25,0 25,18 0,25 0,7" fill="url(%23two)"/></svg>');
  background-size:100%;
}
<div class="gradients">
</div>

Here is the code of the SVG expanded with different colors to better understand:

svg {
  width:100%;
  height:100px;
}
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" preserveAspectRatio="none" viewBox="0 0 25 30">
  <defs>
    <linearGradient id="one" >
        <stop offset="0%" stop-color="blue"/>
        <stop offset="100%" stop-color="red" />
   </linearGradient>
   <linearGradient id="two" >
        <stop offset="0%" stop-color="yellow" />
        <stop offset="100%" stop-color="purple"/>
  </linearGradient>
 </defs>
 <!-- update the value 7 and 18 by keeping it the same between both polygon -->
 <polygon points="25,7 25,25 0, 18 0, 0" fill="url(#one)"/>
 <polygon points="0, 7 0, 25 25,18 25,0" fill="url(#two)"/>
 
</svg>
Temani Afif
  • 245,468
  • 26
  • 309
  • 415