Here are a few different approaches for creating the equilateral triangle shape using CSS. Creation of diagonals is still not any easier but now the shape can at-least have a transparent background even when the body has a gradient (or) an image as its background.
Option 1: Using Pseudo-elements and Skew Transforms
In this method we use a couple of pseudo-elements and skew them in opposite directions (inward) to create the diagonal lines whereas the line at the bottom is produced using a border-bottom
on the parent. We can also produce trapezoids using this approach.
Cons: This approach would not work if the body
background and shape
background are different and the body
background is not a solid color.
.triangle {
position: relative;
width: 200px;
border-bottom: 2px solid white;
color: white;
margin: 20px auto;
overflow: hidden;
}
.shape1 {
height: 174px;
}
.shape2 {
height: 101px;
}
.triangle:before,
.triangle:after {
position: absolute;
content: '';
height: 100%;
width: 0%;
bottom: 0px;
transform-origin: left bottom;
}
.triangle:before {
left: 0px;
border-right: 2px solid white;
}
.triangle.shape1:before {
transform: skew(-30deg);
}
.triangle.shape2:before {
transform: skew(-45deg);
}
.triangle:after {
right: 0px;
border-left: 2px solid white;
}
.triangle.shape1:after {
transform: skew(30deg);
}
.triangle.shape2:after {
transform: skew(45deg);
}
.triangle span {
position: absolute;
width: 100%;
text-align: center;
top: 50%;
}
/* Just for demo */
*{
box-sizing: border-box;
}
body {
background: radial-gradient(ellipse at center, #400, #100);
}
.trapezoid {
position: relative;
border-bottom: 2px solid white;
color: white;
margin: 20px auto;
width: 200px;
height: 50px;
}
.trapezoid:before,
.trapezoid:after {
position: absolute;
content: '';
height: 100%;
width: 40%;
bottom: -1px;
border-top: 2px solid white;
transform-origin: left bottom;
}
.trapezoid:before {
left: 0px;
border-left: 2px solid white;
transform: skew(-45deg);
}
.trapezoid:after {
right: 0px;
border-right: 2px solid white;
transform: skew(45deg);
}
.trapezoid span {
position: absolute;
width: 100%;
text-align: center;
top: 30%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div class='triangle shape1'>
<span>content</span>
</div>
<div class='triangle shape2'>
<span>content</span>
</div>
<br/>
<!-- Just something extra to illustrate -->
<div class='trapezoid'>
<span>content</span>
</div>
<br/>
Here is a variation of Option 1 which would work when the background of the body
and that of the shape are different and the body
background is a solid color.
.triangle{
position: relative;
width: 200px;
border-bottom: 2px solid black;
color: red;
background: beige;
margin: 20px auto;
overflow: hidden;
}
.shape1{
height: 174px;
}
.shape2{
height: 101px;
}
.triangle:before, .triangle:after{
position: absolute;
content: '';
height: 101%;
width: 100%;
bottom: 0px;
background: red;
transform-origin: left bottom;
}
.triangle:before{
left: -200px;
border-right: 2px solid black;
}
.triangle.shape1:before{
transform: skew(-30deg);
}
.triangle.shape2:before{
transform: skew(-45deg);
}
.triangle:after{
right: -200px;
border-left: 2px solid black;
}
.triangle.shape1:after{
transform: skew(30deg);
}
.triangle.shape2:after{
transform: skew(45deg);
}
.triangle span{
position: absolute;
width: 100%;
text-align: center;
top: 50%;
}
/* Just for demo */
*{
box-sizing: border-box;
}
body{
background: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div class='triangle shape1'>
<span>content</span>
</div>
<div class='triangle shape2'>
<span>content</span>
</div>
Here is another variation of Option 1 which supports gradient background for both inside and outside the triangle shape.
.triangle {
position: relative;
width: 200px;
border-bottom: 2px solid white;
color: white;
margin: 20px auto;
overflow: hidden;
}
.shape1 {
height: 174px;
}
.shape2 {
height: 101px;
}
.triangle:before,
.triangle:after {
position: absolute;
content: '';
height: 99%;
width: 50%;
z-index: -1;
transform-origin: left bottom;
}
.triangle:before {
left: 0px;
top: 100%;
border-top: 3px solid white;
background: linear-gradient(90deg, #003333, #773333);
}
.triangle.shape1:before {
border-top: 4px solid white;
transform: skewY(-60deg);
}
.triangle.shape2:before {
transform: skewY(-45deg);
}
.triangle:after {
right: 0px;
top: 0%;
border-top: 3px solid white;
background: linear-gradient(90deg, #773333, #FF3333);
}
.triangle.shape1:after {
border-top: 4px solid white;
transform: skewY(60deg);
}
.triangle.shape2:after {
transform: skewY(45deg);
}
.triangle span {
position: absolute;
width: 100%;
text-align: center;
top: 50%;
}
/* Just for demo */
*{
box-sizing: border-box;
}
body {
background: radial-gradient(ellipse at center, #400, #100);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div class='triangle shape1'>
<span>content</span>
</div>
<div class='triangle shape2'>
<span>content</span>
</div>
Screenshot:

Triangles with different angles can be easily created by modifying the skew
angle and the height of the parent div
. But, as we are using skew
the borders tend to become thinner as the skew angle approaches 90deg (or -90deg) but that shouldn't be too big a problem because with such high angles you can barely have fit any text inside.
Option 2: Using Linear Gradients
In this method, we use a couple of angled linear-gradient
backgrounds (each of which are 50% width of the container) and slant them in opposite directions to produce the diagonal lines.
.triangle {
position: relative;
border-bottom: 2px solid white;
color: white;
margin: 20px auto;
height: 174px;
width: 200px;
background: linear-gradient(to top left, transparent 49.5%, white 49.5%, white 50.5%, transparent 50.5%), linear-gradient(to top right, transparent 49.5%, white 49.5%, white 50.5%, transparent 50.5%);
background-size: 50% 100%;
background-position: 1px 0px, 99px 0px;
background-repeat: no-repeat;
}
.triangle span {
position: absolute;
width: 100%;
text-align: center;
top: 50%;
}
/* Just for demo*/
body {
background: radial-gradient(ellipse at center, #400, #100);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div class='triangle'>
<span>content</span>
</div>
Cons: Angled gradients are known for producing jagged lines.
Note: Irrespective of which approach is chosen, you would still have to do text wrapping to make the text stay inside the shape.