geometry - How do CSS triangles work?

ID : 466

viewed : 326

Tags : cssgeometrypolygoncss-shapescss





Top 5 Answer for geometry - How do CSS triangles work?

vote vote

98

CSS Triangles: A Tragedy in Five Acts

As alex said, borders of equal width butt up against each other at 45 degree angles:

borders meet at 45 degree angles, content in middle

When you have no top border, it looks like this:

no top border

Then you give it a width of 0...

no width

...and a height of 0...

no height either

...and finally, you make the two side borders transparent:

transparent side borders

That results in a triangle.

vote vote

82

The borders use an angled edge where they intersect (45° angle with equal width borders, but changing the border widths can skew the angle).

Border example

div {    width: 60px;    border-width: 30px;    border-color: red blue green yellow;    border-style: solid;  }
<div></div>

Have a look to the jsFiddle.

By hiding certain borders, you can get the triangle effect (as you can see above by making the different portions different colours). transparent is often used as an edge colour to achieve the triangle shape.

vote vote

73

Start with a basic square and borders. Each border will be given a different color so we can tell them apart:

.triangle {     border-color: yellow blue red green;     border-style: solid;     border-width: 200px 200px 200px 200px;     height: 0px;     width: 0px; }
<div class="triangle"></div>

which gives you this:

square with four borders

But there's no need for the top border, so set its width to 0px. Now our border-bottom of 200px will make our triangle 200px tall.

.triangle {     border-color: yellow blue red green;     border-style: solid;     border-width: 0px 200px 200px 200px;     height: 0px;     width: 0px; }
<div class="triangle"></div>

and we will get this:

bottom half of square with four borders

Then to hide the two side triangles, set the border-color to transparent. Since the top-border has been effectively deleted, we can set the border-top-color to transparent as well.

.triangle {     border-color: transparent transparent red transparent;     border-style: solid;     border-width: 0px 200px 200px 200px;     height: 0px;     width: 0px; }
<div class="triangle"></div>

finally we get this:

triangular bottom border

vote vote

60

Different approach: CSS3 triangles with transform rotate

Triangular shape is pretty easy to make using this technique. For people who prefer to see an animation explaining how this technique works here it is :

gif animation : how to make a triangle with transform rotate

Otherwise, here is detailed explanation in 4 acts (this is not a tragedy) of how to make an isosceles right-angled triangle with one element.

  • Note 1 : for non isosceles triangles and fancy stuff, you can see step 4.
  • Note 2 : in the following snippets, the vendor prefixes aren't included. they are included in the codepen demos.
  • Note 3 : the HTML for the following explanation is always : <div class="tr"></div>

STEP 1 : Make a div

Easy, just make sure that width = 1.41 x height. You may use any techinque (see here) including the use of percentages and padding-bottom to maintain the aspect ratio and make a responsive triangle. In the following image, the div has a golden yellow border.

In that div, insert a pseudo element and give it 100% width and height of parent. The pseudo element has a blue background in the following image.

Making a CSS triangle with transform roate step 1

At this point, we have this CSS :

.tr {     width: 30%;     padding-bottom: 21.27%; /* = width / 1.41 */     position: relative; }  .tr: before {     content: '';     position: absolute;     top: 0;     left: 0;     width: 100%;     height: 100%;     background: #0079C6; } 

STEP 2 : Let's rotate

First, most important : define a transform origin. The default origin is in the center of the pseudo element and we need it at the bottom left. By adding this CSS to the pseudo element :

transform-origin:0 100%; or transform-origin: left bottom;

Now we can rotate the pseudo element 45 degrees clockwise with transform : rotate(45deg);

Creating a triangle with CSS3 step 2

At this point, we have this CSS :

.tr {     width: 30%;     padding-bottom: 21.27%; /* = width / 1.41 */     position: relative; }  .tr:before {     content: '';     position: absolute;     top: 0;     left: 0;     width: 100%;     height: 100%;     background: #0079C6;     transform-origin: 0 100%;             transform: rotate(45deg); } 

STEP 3 : hide it

To hide the unwanted parts of the pseudo element (everything that overflows the div with the yellow border) you just need to set overflow:hidden; on the container. after removing the yellow border, you get... a TRIANGLE! :

DEMO

CSS triangle

CSS :

.tr {     width: 30%;     padding-bottom: 21.27%; /* = width / 1.41 */     position: relative;     overflow: hidden; }  .tr:before {     content: '';     position: absolute;     top: 0;     left: 0;     width: 100%;     height: 100%;     background-color: #0079C6;     transform-origin: 0 100%;     transform: rotate(45deg); } 

STEP 4 : go further...

As shown in the demo, you can customize the triangles :

  1. Make them thinner or flatter by playing with skewX().
  2. Make them point left, right or any other direction by playing with the transform orign and rotation direction.
  3. Make some reflexion with 3D transform property.
  4. Give the triangle borders
  5. Put an image inside the triangle
  6. Much more... Unleash the powers of CSS3!

Why use this technique?

  1. Triangle can easily be responsive.
  2. You can make a triangle with border.
  3. You can maintain the boundaries of the triangle. This means that you can trigger the hover state or click event only when the cursor is inside the triangle. This can become very handy in some situations like this one where each triangle can't overlay it's neighbours so each triangle has it's own hover state.
  4. You can make some fancy effects like reflections.
  5. It will help you understand 2d and 3d transform properties.

Why not use this technique?

  1. The main drawback is the browser compatibility, the 2d transform properties are supported by IE9+ and therefore you can't use this technique if you plan on supporting IE8. See CanIuse for more info. For some fancy effects using 3d transforms like the reflection browser support is IE10+ (see canIuse for more info).
  2. You don't need anything responsive and a plain triangle is fine for you then you should go for the border technique explained here : better browser compatibility and easier to understand thanks to the amazing posts here.
vote vote

53

Here is an animation in JSFiddle I created for demonstration.

Also see snippet below.

This is an Animated GIF made from a Screencast

Animated Gif of Triangle

transforms = [           {'border-left-width'   :'30', 'margin-left': '70'},           {'border-bottom-width' :'80'},           {'border-right-width'  :'30'},           {'border-top-width'    :'0', 'margin-top': '70'},           {'width'               :'0'},           {'height'              :'0', 'margin-top': '120'},           {'borderLeftColor'     :'transparent'},           {'borderRightColor'    :'transparent'}  ];      $('#a').click(function() {$('.border').trigger("click");});  (function($) {      var duration = 1000      $('.border').click(function() {  		  for ( var i=0; i < transforms.length; i++ ) {          $(this)           .animate(transforms[i], duration)  		  }      }).end()  }(jQuery))
.border {      margin: 20px 50px;      width: 50px;      height: 50px;      border-width: 50px;      border-style: solid;      border-top-color: green;      border-right-color: yellow;      border-bottom-color: red;      border-left-color: blue;      cursor: pointer  }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>  <script src="https://code.jquery.com/color/jquery.color-2.1.2.min.js"></script>  Click it!<br>  <div class="border"></div>


Random version

/**   * Randomize array element order in-place.   * Using Durstenfeld shuffle algorithm.   */  function shuffleArray(array) {      for (var i = array.length - 1; i > 0; i--) {          var j = Math.floor(Math.random() * (i + 1));          var temp = array[i];          array[i] = array[j];          array[j] = temp;      }      return array;  }    transforms = [           {'border-left-width'   :'30', 'margin-left': '70'},           {'border-bottom-width' :'80'},           {'border-right-width'  :'30'},           {'border-top-width'    :'0', 'margin-top': '70'},           {'width'               :'0'},           {'height'              :'0'},           {'borderLeftColor'     :'transparent'},           {'borderRightColor'    :'transparent'}  ];  transforms = shuffleArray(transforms)        $('#a').click(function() {$('.border').trigger("click");});  (function($) {      var duration = 1000      $('.border').click(function() {  		  for ( var i=0; i < transforms.length; i++ ) {          $(this)           .animate(transforms[i], duration)  		  }      }).end()  }(jQuery))
.border {      margin: 50px;      width: 50px;      height: 50px;      border-width: 50px;      border-style: solid;      border-top-color: green;      border-right-color: yellow;      border-bottom-color: red;      border-left-color: blue;      cursor: pointer  }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>  <script src="https://code.jquery.com/color/jquery.color-2.1.2.min.js"></script>  Click it!<br>  <div class="border"></div>


All at once version

$('#a').click(function() {$('.border').trigger("click");});  (function($) {      var duration = 1000      $('.border').click(function() {          $(this)           .animate({'border-top-width': 0            ,           					 'border-left-width': 30          ,           					 'border-right-width': 30         ,           					 'border-bottom-width': 80        ,           					 'width': 0                       ,           					 'height': 0                      ,                     'margin-left': 100,                     'margin-top': 150,           					 'borderTopColor': 'transparent',           					 'borderRightColor': 'transparent',           					 'borderLeftColor':  'transparent'}, duration)      }).end()  }(jQuery))
.border {      margin: 50px;      width: 50px;      height: 50px;      border-width: 50px;      border-style: solid;      border-top-color: green;      border-right-color: yellow;      border-bottom-color: red;      border-left-color: blue;      cursor: pointer  }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>  <script src="https://code.jquery.com/color/jquery.color-2.1.2.min.js"></script>  Click it!<br>  <div class="border"></div>

Top 3 video Explaining geometry - How do CSS triangles work?







Related QUESTION?