4

I'm currently displaying 2 triangles on the bottom of my page, one on the left and one on the right. The right triangle is transparent. Both triangles have one color.

I want the triangle-bottom-right to have an additional gradient level (additional color stops).

It should go from left to right, start with rgba(70, 70, 70, 0.15) and end with rgba(70, 70, 70, 0). The target browser is Chrome (running through Electron).

The resulting triangles should be able to resize to the browser width, the height is constant.

My CSS:

.triangle-footer {
    position: relative;
    bottom: 0px;
    height: 176px;
    width: 100%;
}
.triangle-bottom-left {
    position: absolute;
    width: 40%;
    height: 100%;
    left: 0px;
    bottom: 0px;
    background: linear-gradient(to right top, rgba(94, 194, 82, 100) 50%, rgba(255, 255, 255, 0) 50%);
}
.triangle-bottom-right {
    position: absolute;;
    width: 125%;
    height: 140%;
    right: 0px;
    bottom: 0px;
    background: linear-gradient(to left top, rgba(70, 70, 70, 0.15) 50%, rgba(255, 255, 255, 0) 50%);
}

My HTML:

<div class="ui fixed bottom sticky triangle-footer">
  <div class="triangle-bottom-left"></div>
</div>

<div class="ui fixed bottom sticky triangle-footer">
  <div class="triangle-bottom-right"></div>
</div>

(Using Semantic-UI for the bottom stickyness)

Live Example: http://jsfiddle.net/fu2dhfdv/1/

5
  • Couldn't quite understand. The bottom right triangle already has the specified gradient. What is it that you're looking for? Can you add an image of the expected output if possible? Commented Apr 29, 2016 at 9:41
  • Done. Hope it's clearer now. I want the triangle-bottom-right to start wíth one color one the left, and end with a different color on the right. Commented Apr 29, 2016 at 9:45
  • OK, so you mean that within the triangle created through gradients you need a gradient that goes from left-right (or right-left) instead of right-bottom to left-top? That is going to be really tough because the triangle itself is created only because of that right-bottom to left-top gradient. If you add another layer above or below it with a left-right gradient, it won't get you this effect. What you probably need is a mask unless the top half of your right triangle can be white instead of transparent. Commented Apr 29, 2016 at 9:45
  • Yes, as long as the 2nd gradient overrides the colors of the triangle created through gradients. Commented Apr 29, 2016 at 9:49
  • How would it work with a mask? I'm open for any implementation, the only thing I need is the width percentage on those triangles, so they resize to the browser width. Commented Apr 29, 2016 at 9:52

2 Answers 2

5

As far as I am aware this cannot be done using linear-gradient background image alone because the right triangle itself shows up as a triangle only because it is transparent for 50% and filled for rest. If we put another layer of left-to-right gradient on top of this layer then the gradient will show up for the entire square area of triangle-bottom-right (or) if we put the left-to-right gradient on bottom of this layer then also it will show up for the entire square area because the top half of gradient that produces the triangle is transparent. So, the only choices are (a) to make top half as "white" and place the 2nd gradient below it or (b) use a mask or clip-path to hide the top half.

Using SVG Mask:

Since neither CSS mask nor CSS clip-path has good browser support at present. The best option is to make use of inline SVG for the mask like in the below snippet.

.triangle-footer {
  position: relative;
  bottom: 0px;
  height: 176px;
  width: 100%;
}
.triangle-bottom-left {
  position: absolute;
  width: 40%;
  height: 100%;
  left: 0px;
  bottom: 0px;
  background: linear-gradient(to right top, rgba(94, 194, 82, 100) 50%, rgba(255, 255, 255, 0) 50%);
}
.triangle-bottom-right {
  position: absolute;
  width: 125%;
  height: 140%;
  right: 0px;
  bottom: 0px;
}
svg {
  position: relative;
  right: 0px;
  bottom: 0px;
  width: 100%;
  height: 100%;
}
polygon#right-triangle {
  fill: url(#grad);
  mask: url(#triangle);
}
<script src="http://semantic-ui.com/dist/semantic.js"></script>
<link href="http://semantic-ui.com/dist/semantic.css" rel="stylesheet" />
<div class="ui fixed bottom sticky triangle-footer">
  <div class="triangle-bottom-left"></div>
</div>

<div class="ui fixed bottom sticky triangle-footer">
  <div class="triangle-bottom-right">
    <svg viewBox="0 0 100 100" preserveAspectRatio="none">
      <defs>
        <linearGradient id="grad">
          <stop offset="0%" stop-color="rgba(70, 70, 70, 0.35)" />
          <stop offset="100%" stop-color="rgba(255, 255, 255, 0)" />
        </linearGradient>
        <mask id="triangle">
          <polygon points="0,0 100,0 100,100 0,100" fill="black" />
          <polygon points="0,90 0,100 100,100 100,0" fill="white" />
        </mask>
      </defs>
      <polygon points="0,0 100,0 100,100 0,100" id="right-triangle" />
    </svg>
  </div>
</div>


Using SVG Polygon: (can be done with path element also)

This can also be done using one SVG polygon element instead of a mask like in the below snippet. I will leave it to you to choose one :)

.triangle-footer {
  position: relative;
  bottom: 0px;
  height: 176px;
  width: 100%;
}
.triangle-bottom-left {
  position: absolute;
  width: 40%;
  height: 100%;
  left: 0px;
  bottom: 0px;
  background: linear-gradient(to right top, rgba(94, 194, 82, 100) 50%, rgba(255, 255, 255, 0) 50%);
}
.triangle-bottom-right {
  position: absolute;
  width: 125%;
  height: 140%;
  right: 0px;
  bottom: 0px;
}
svg {
  position: relative;
  right: 0px;
  bottom: 0px;
  width: 100%;
  height: 100%;
}
polygon#right-triangle {
  fill: url(#grad);
}
<script src="http://semantic-ui.com/dist/semantic.js"></script>
<link href="http://semantic-ui.com/dist/semantic.css" rel="stylesheet" />
<div class="ui fixed bottom sticky triangle-footer">
  <div class="triangle-bottom-left"></div>
</div>

<div class="ui fixed bottom sticky triangle-footer">
  <div class="triangle-bottom-right">
    <svg viewBox="0 0 100 100" preserveAspectRatio="none">
      <defs>
        <linearGradient id="grad">
          <stop offset="0%" stop-color="rgba(70, 70, 70, 0.35)" />
          <stop offset="100%" stop-color="rgba(255, 255, 255, 0)" />
        </linearGradient>
      </defs>
      <polygon points="0,90 0,100 100,100 100,0" id="right-triangle" />
    </svg>
  </div>
</div>


Using CSS Masks: (best for you as Chrome is the only target)

Since you've indicated that the target browser is only Chrome and given that CSS mask is supported in it, you can also use the -webkit-mask-image property with a linear-gradient like in below snippet. I have listed it as last only because it is least recommended for any other user viewing this thread with a different browser requirement.

.triangle-footer {
  position: relative;
  bottom: 0px;
  height: 176px;
  width: 100%;
}
.triangle-bottom-left {
  position: absolute;
  width: 40%;
  height: 100%;
  left: 0px;
  bottom: 0px;
  background: linear-gradient(to right top, rgba(94, 194, 82, 100) 50%, rgba(255, 255, 255, 0) 50%);
}
.triangle-bottom-right {
  position: absolute;
  width: 125%;
  height: 140%;
  right: 0px;
  bottom: 0px;
  background: linear-gradient(to right, rgba(70, 70, 70, 0.15), rgba(255, 255, 255, 0));
  -webkit-mask-image: linear-gradient(to top left, white 50%, transparent 50%);
}
<script src="http://semantic-ui.com/dist/semantic.js"></script>
<link href="http://semantic-ui.com/dist/semantic.css" rel="stylesheet" />
<div class="ui fixed bottom sticky triangle-footer">
  <div class="triangle-bottom-left"></div>
</div>

<div class="ui fixed bottom sticky triangle-footer">
  <div class="triangle-bottom-right">
  </div>
</div>


Using CSS Clip Path: (again useful since Chrome is the only target)

It can be done with CSS clip-path also like in the below snippet. The right-bottom element is clipped to the required triangle-ish shape and a left-to-right gradient is applied to it.

.triangle-footer {
  position: relative;
  bottom: 0px;
  height: 176px;
  width: 100%;
}
.triangle-bottom-left {
  position: absolute;
  width: 40%;
  height: 100%;
  left: 0px;
  bottom: 0px;
  background: linear-gradient(to right top, rgba(94, 194, 82, 100) 50%, rgba(255, 255, 255, 0) 50%);
}
.triangle-bottom-right {
  position: absolute;
  width: 125%;
  height: 140%;
  right: 0px;
  bottom: 0px;
  background: linear-gradient(to right, rgba(70, 70, 70, 0.15), rgba(255, 255, 255, 0));
  -webkit-clip-path: polygon(0% 90%, 0% 100%, 100% 100%, 100% 0%);
}
<script src="http://semantic-ui.com/dist/semantic.js"></script>
<link href="http://semantic-ui.com/dist/semantic.css" rel="stylesheet" />
<div class="ui fixed bottom sticky triangle-footer">
  <div class="triangle-bottom-left"></div>
</div>

<div class="ui fixed bottom sticky triangle-footer">
  <div class="triangle-bottom-right">
  </div>
</div>

Sign up to request clarification or add additional context in comments.

6 Comments

Good answer as always ! But since the triangle is a separate element used only for this purpose, it could be transform: rotated. (And get better support)
Fair point @vals. It would need the element to be larger and also have an angled linear-gradient to cover for the rotation. Are you planning to post a separate answer? If yes, I will refrain from updating that into my answer.
Actually now I remember @vals I did try with transforms (you'd see the irrelevant transform-origin in both CSS snippets) but dropped it because the angles produced varying results due to width having to be dynamic.
You are right, that could be a problem ... I will try to solve it :-)
I hadn't noticed the requirement about handling the variations in width... That makes rotation or other transforms unsuitable (or at least I couldn't find the way). :-(
|
2

just for info and to be seen as a potential fallback on plain white background.

3 gradients + background-size could work.

html {
  min-height:100%;
  background:
    linear-gradient(to  left, rgba(255,255,255,0.75), rgba(255,255,255,0) 60%) bottom no-repeat,
    linear-gradient(to top left, rgba(0,0,0,0.1) 50%, transparent 50%)bottom right no-repeat,
    linear-gradient( to top right, #5EC252 50%, transparent 50%)bottom left no-repeat white;  
  background-size:100% 245px, 127% 245px ,  40%  170px;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.