Search code examples
htmlcsslinear-gradientscss-shapes

CSS apply gradient to right triangle shape with solid fill


I want to apply the same gradient to the triangle (class="triangle-right") as the rectangle (class="fillblue"). I have seen some other examples but they are not working for me. Combining both shapes and using a single class would be awesome too!

JS FIDDLE HERE!

CSS:

.fillblue {
background: rgb(208,228,247); /* Old browsers */
background: -moz-linear-gradient(top,  rgba(208,228,247,1) 0%, rgba(115,177,231,1) 24%, rgba(10,119,213,1) 50%, rgba(83,159,225,1) 79%, rgba(135,188,234,1) 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(208,228,247,1)), color-stop(24%,rgba(115,177,231,1)), color-stop(50%,rgba(10,119,213,1)), color-stop(79%,rgba(83,159,225,1)), color-stop(100%,rgba(135,188,234,1))); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top,  rgba(208,228,247,1) 0%,rgba(115,177,231,1) 24%,rgba(10,119,213,1) 50%,rgba(83,159,225,1) 79%,rgba(135,188,234,1) 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top,  rgba(208,228,247,1) 0%,rgba(115,177,231,1) 24%,rgba(10,119,213,1) 50%,rgba(83,159,225,1) 79%,rgba(135,188,234,1) 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(top,  rgba(208,228,247,1) 0%,rgba(115,177,231,1) 24%,rgba(10,119,213,1) 50%,rgba(83,159,225,1) 79%,rgba(135,188,234,1) 100%); /* IE10+ */
background: linear-gradient(to bottom,  rgba(208,228,247,1) 0%,rgba(115,177,231,1) 24%,rgba(10,119,213,1) 50%,rgba(83,159,225,1) 79%,rgba(135,188,234,1) 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#d0e4f7',   
    endColorstr='#87bcea',GradientType=0 ); /* IE6-9 */

height: 40px;
width: 100px;
display: inline-block;
float: left;
color: white;
text-align: center;
line-height: 40px;
font-weight: bold;
}

   .triangle-right {
width: 0;
height: 0;
border-top: 20px solid transparent;
border-left: 40px solid lightblue;
border-bottom: 20px solid transparent;
float: left;
}

HTML:

<div class="fillblue">Step 1</div><div class="triangle-right"></div>

Solution

  • Final Result

    Part 1: Giving the triangle a gradient

    The easiest way to achieve this would be to invert your triangle. and extend the length of the element with the gradient.

    JSFiddle demo.

    Inverting the triangle

    Rather than giving the border-left on the triangle a solid colour, you want to give the top and bototm borders the colour (in this case we want to match the background colour, so lets make these white as that's the JSFiddle background colour):

    .triangle-right {
        ...
        border-top: 20px solid white;
        border-left: 40px solid transparent;
        border-bottom: 20px solid white;
    }
    

    If you're unsure what this achieves, here is an example of the triangle when the top and bottom borders are set to red instead of white:

    Red Example

    Increasing the width of your gradient element

    As your triangle is 40px wide, we need to increase the width of our gradient element by 40px. For this I've used padding to ensure the text remains in the same place:

    .fillblue {
        ...
        padding-right: 40px;
    }
    

    With the same red triangle we used above, this is what it now looks like:

    Stage 2 Example

    Positioning the inverted triangle on top of our gradient element

    Now we simply need to set a negative margin on our inverted triangle to make it appear on top of our gradient element:

    .triangle-right {
        ...
        margin-left: -40px;
    }
    

    Finally, using the red triangle again, our finished result looks like this:

    Final Example


    Part 2: Combining both shapes into one element

    To do this we can make use of the :after pseudo-element.

    JSFiddle demo.

    First off, lets modify our HTML:

    <div class="fillblue">Step 1</div>
    

    Now lets give our .fillblue element relative positioning. We do this so that we can absolutely position our triangle in the next step:

    .fillblue {
        ...
        position: relative;
    }
    

    Now we modify our previous .triangle-right styling to use this :after pseudo-element instead:

    .fillblue:after {
        width: 0;
        height: 0;
        border-top: 20px solid white;
        border-left: 40px solid transparent;
        border-bottom: 20px solid white;
    }
    

    Finally we give it the new properties to position it correctly and actually make it display:

    .fillblue:after {
        ...
        content: '';
        position: absolute;
        top: 0;
        right: 0;
    }