There're plenty of different CSS shapes over at CSS Tricks - Shapes of CSS and I'm particularly puzzled with a triangle:
#triangle-up {_x000D_
width: 0;_x000D_
height: 0;_x000D_
border-left: 50px solid transparent;_x000D_
border-right: 50px solid transparent;_x000D_
border-bottom: 100px solid red;_x000D_
}
_x000D_
<div id="triangle-up"></div>
_x000D_
How and why does it work?
This question is related to
css
geometry
polygon
css-shapes
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;
}
_x000D_
<div class="triangle"></div>
_x000D_
which gives you this:
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;
}
_x000D_
<div class="triangle"></div>
_x000D_
and we will get this:
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;
}
_x000D_
<div class="triangle"></div>
_x000D_
finally we get this:
here is another fiddle:
.container:after {
position: absolute;
right: 0;
content: "";
margin-right:-50px;
margin-bottom: -8px;
border-width: 25px;
border-style: solid;
border-color: transparent transparent transparent #000;
width: 0;
height: 0;
z-index: 10;
-webkit-transition: visibility 50ms ease-in-out,opacity 50ms ease-in-out;
transition: visibility 50ms ease-in-out,opacity 50ms ease-in-out;
bottom: 21px;
}
.container {
float: left;
margin-top: 100px;
position: relative;
width: 150px;
height: 80px;
background-color: #000;
}
.containerRed {
float: left;
margin-top: 100px;
position: relative;
width: 100px;
height: 80px;
background-color: red;
}
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 :
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.
<div class="tr"></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.
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;
}
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);
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);
}
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! :
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);
}
As shown in the demo, you can customize the triangles :
skewX()
.Try This:-
.triangle {_x000D_
border-color: transparent transparent red transparent;_x000D_
border-style: solid;_x000D_
border-width: 0px 200px 200px 200px;_x000D_
height: 0px;_x000D_
width: 0px;_x000D_
}
_x000D_
<div class="triangle"></div>
_x000D_
Taking it one step further, using css based on this I added arrows to my back and next buttons (yes I know its not 100% cross-browser, but slick none the less).
.triangle {_x000D_
width: 0;_x000D_
height: 0;_x000D_
border-left: 50px solid transparent;_x000D_
border-right: 50px solid transparent;_x000D_
border-bottom: 100px solid red;_x000D_
margin:20px auto;_x000D_
}_x000D_
_x000D_
.triangle-down {_x000D_
border-bottom:none;_x000D_
border-top: 100px solid red;_x000D_
}_x000D_
_x000D_
.triangle-left {_x000D_
border-left:none;_x000D_
border-right: 100px solid red;_x000D_
border-bottom: 50px solid transparent;_x000D_
border-top: 50px solid transparent;_x000D_
}_x000D_
_x000D_
.triangle-right {_x000D_
border-right:none;_x000D_
border-left: 100px solid red;_x000D_
border-bottom: 50px solid transparent;_x000D_
border-top: 50px solid transparent;_x000D_
}_x000D_
_x000D_
.triangle-after:after {_x000D_
width: 0;_x000D_
height: 0;_x000D_
border-left: 5px solid transparent;_x000D_
border-right: 5px solid transparent;_x000D_
border-bottom: 5px solid red;_x000D_
margin:0 5px;_x000D_
content:"";_x000D_
display:inline-block;_x000D_
}_x000D_
_x000D_
.triangle-after-right:after {_x000D_
border-right:none;_x000D_
border-left: 5px solid blue;_x000D_
border-bottom: 5px solid transparent;_x000D_
border-top: 5px solid transparent;_x000D_
_x000D_
}_x000D_
_x000D_
.triangle-before:before {_x000D_
width: 0;_x000D_
height: 0;_x000D_
border-left: 5px solid transparent;_x000D_
border-right: 5px solid transparent;_x000D_
border-bottom: 5px solid blue;_x000D_
margin:0 5px;_x000D_
content:"";_x000D_
display:inline-block;_x000D_
}_x000D_
_x000D_
.triangle-before-left:before {_x000D_
border-left:none;_x000D_
border-right: 5px solid blue;_x000D_
border-bottom: 5px solid transparent;_x000D_
border-top: 5px solid transparent;_x000D_
_x000D_
}
_x000D_
<div class="triangle"></div>_x000D_
<div class="triangle triangle-down"></div>_x000D_
<div class="triangle triangle-left"></div>_x000D_
<div class="triangle triangle-right"></div>_x000D_
_x000D_
<a class="triangle-before triangle-before-left" href="#">Back</a>_x000D_
<a class="triangle-after triangle-after-right" href="#">Next</a>
_x000D_
Consider the below triangle
.triangle {
border-bottom:15px solid #000;
border-left:10px solid transparent;
border-right:10px solid transparent;
width:0;
height:0;
}
This is what we are given:
Why it came out in this shape? The below diagram explains the dimensions, note that 15px was used for the bottom border and 10px was used for left and right.
It's pretty easy to make a right-angle triangle also by removing the right border.
Different approach. With linear gradient (for IE, only IE 10+). You can use any angle:
.triangle {_x000D_
margin: 50px auto;_x000D_
width: 100px;_x000D_
height: 100px;_x000D_
/* linear gradient */_x000D_
background: -moz-linear-gradient(-45deg, rgba(255,0,0,0) 0%, rgba(255,0,0,0) 50%, rgba(255,0,0,1) 50%, rgba(255,0,0,1) 100%);_x000D_
/* FF3.6+ */_x000D_
background: -webkit-gradient(linear, left top, right bottom, color-stop(0%,rgba(255,0,0,0)), color-stop(50%,rgba(255,0,0,0)), color-stop(50%,rgba(255,0,0,1)), color-stop(100%,rgba(255,0,0,1)));_x000D_
/* Chrome,Safari4+ */_x000D_
background: -webkit-linear-gradient(-45deg, rgba(255,0,0,0) 0%,rgba(255,0,0,0) 50%,rgba(255,0,0,1) 50%,rgba(255,0,0,1) 100%);_x000D_
/* Chrome10+,Safari5.1+ */_x000D_
background: -o-linear-gradient(-45deg, rgba(255,0,0,0) 0%,rgba(255,0,0,0) 50%,rgba(255,0,0,1) 50%,rgba(255,0,0,1) 100%);_x000D_
/* Opera 11.10+ */_x000D_
background: -ms-linear-gradient(-45deg, rgba(255,0,0,0) 0%,rgba(255,0,0,0) 50%,rgba(255,0,0,1) 50%,rgba(255,0,0,1) 100%);_x000D_
/* IE10+ */_x000D_
background: linear-gradient(135deg, rgba(255,0,0,0) 0%,rgba(255,0,0,0) 50%,rgba(255,0,0,1) 50%,rgba(255,0,0,1) 100%);_x000D_
/* W3C */;_x000D_
}
_x000D_
<div class="triangle"></div>
_x000D_
Here is jsfiddle
Lets say we have the following div:
<div id="triangle" />
Now Edit the CSS step-by-step, so you will get clear idea what is happening around
STEP 1: JSfiddle Link:
#triangle {
background: purple;
width :150px;
height:150PX;
border-left: 50px solid black ;
border-right: 50px solid black;
border-bottom: 50px solid black;
border-top: 50px solid black;
}
This is a simple div. With a very simple CSS. So a layman can understand. Div has dimensions 150 x 150 pixels with the border 50 pixels. The image is attached:
STEP 2: JSfiddle Link:
#triangle {
background: purple;
width :150px;
height:150PX;
border-left: 50px solid yellow ;
border-right: 50px solid green;
border-bottom: 50px solid red;
border-top: 50px solid blue;
}
Now I just changed the border-color of all 4 sides. The image is attached.
STEP:3 JSfiddle Link:
#triangle {
background: purple;
width :0;
height:0;
border-left: 50px solid yellow ;
border-right: 50px solid green;
border-bottom: 50px solid red;
border-top: 50px solid blue;
}
Now I just changed the height & width of div from 150 pixels to zero. The image is attached
STEP 4: JSfiddle:
#triangle {
background: purple;
width :0px;
height:0px;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-bottom: 50px solid red;
border-top: 50px solid transparent;
}
Now I have made all the borders transparent apart from the bottom border. The image is attached below.
STEP 5: JSfiddle Link:
#triangle {
background: white;
width :0px;
height:0px;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-bottom: 50px solid red;
border-top: 50px solid transparent;
}
Now I just changed the background color to white. The image is attached.
Hence we got the triangle we needed.
OK, this triangle will get created because of the way that borders of the elements work together in HTML and CSS...
As we usually use 1 or 2px borders, we never notice that borders make a 45° angles to each others with the same width and if the width changes, the angle degree get changed as well, run the CSS code I created below:
.triangle {_x000D_
width: 100px;_x000D_
height: 100px;_x000D_
border-left: 50px solid black;_x000D_
border-right: 50px solid black;_x000D_
border-bottom: 100px solid red;_x000D_
}
_x000D_
<div class="triangle">_x000D_
</div>
_x000D_
Then in the next step, we don't have any width or height, something like this:
.triangle {_x000D_
width: 0;_x000D_
height: 0;_x000D_
border-left: 50px solid black;_x000D_
border-right: 50px solid black;_x000D_
border-bottom: 100px solid red;_x000D_
}
_x000D_
<div class="triangle">_x000D_
</div>
_x000D_
And now we make the left and right borders invisible to make our desirable triangle as below:
.triangle {_x000D_
width: 0;_x000D_
height: 0;_x000D_
border-left: 50px solid transparent;_x000D_
border-right: 50px solid transparent;_x000D_
border-bottom: 100px solid red;_x000D_
}
_x000D_
<div class="triangle"></div>
_x000D_
If you not willing to run the snippet to see the steps, I've created an image sequence to have a look at all steps in one image:
clip-path
This is something I feel this question has missed; clip-path
clip-path
in a nutshellClipping, with the
clip-path
property, is akin to cutting a shape (like a circle or a pentagon) from a rectangular piece of paper. The property belongs to the “CSS Masking Module Level 1” specification. The spec states, “CSS masking provides two means for partially or fully hiding portions of visual elements: masking and clipping”.
clip-path
will use the element itself rather than its borders to cut the shape you specify in its parameters. It uses a super simple percentage based co-ordinate system which makes editing it very easy and means you can pick it up and create weird and wonderful shapes in a matter of minutes.
div {_x000D_
-webkit-clip-path: polygon(50% 0%, 0% 100%, 100% 100%);_x000D_
clip-path: polygon(50% 0%, 0% 100%, 100% 100%);_x000D_
background: red;_x000D_
width: 100px;_x000D_
height: 100px;_x000D_
}
_x000D_
<div></div>
_x000D_
It does have a major downside at the moment, one being it's major lack of support, only really being covered within -webkit-
browsers and having no support on IE and only very partial in FireFox.
Here are some useful resources and material to help better understand clip-path
and also start creating your own.
clip-path has the best result for me - works great for divs/containers with and without fixed dimensions:
.triangleContainer{
position: relative;
width: 500px;
height: 500px;
}
.triangleContainer::before{
content: "";
position: absolute;
background:blue;
top: 0;
left: 0;
width: 100%;
height: 100%;
clip-path: polygon(50% 0, 0 100%, 100% 100%);
}
The borders use an angled edge where they intersect (45° angle with equal width borders, but changing the border widths can skew the angle).
div {_x000D_
width: 60px;_x000D_
border-width: 30px;_x000D_
border-color: red blue green yellow;_x000D_
border-style: solid;_x000D_
}
_x000D_
<div></div>
_x000D_
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.
If you want to apply border to the triangle read this: Create a triangle with CSS?
Almost all the answers focus on the triangle built using border so I am going to elaborate the linear-gradient
method (as started in the answer of @lima_fil).
Using a degree value like 45°
will force us to respect a specific ratio of height/width
in order to obtain the triangle we want and this won't be responsive:
.tri {_x000D_
width:100px;_x000D_
height:100px;_x000D_
background:linear-gradient(45deg, transparent 49.5%,red 50%);_x000D_
_x000D_
/*To illustrate*/_x000D_
border:1px solid;_x000D_
}
_x000D_
Good one_x000D_
<div class="tri"></div>_x000D_
bad one_x000D_
<div class="tri" style="width:150px"></div>_x000D_
bad one_x000D_
<div class="tri" style="height:30px"></div>
_x000D_
Instead of doing this we should consider predefined values of direction like to bottom
, to top
, etc. In this case we can obtain any kind of triangle shape while keeping it responsive.
1) Rectangle triangle
To obtain such triangle we need one linear-gradient and a diagonal direction like to bottom right
, to top left
, to bottom left
, etc
.tri-1,.tri-2 {_x000D_
display:inline-block;_x000D_
width:100px;_x000D_
height:100px;_x000D_
background:linear-gradient(to bottom left, transparent 49.5%,red 50%);_x000D_
border:1px solid;_x000D_
animation:change 2s linear infinite alternate;_x000D_
}_x000D_
.tri-2 {_x000D_
background:linear-gradient(to top right, transparent 49.5%,red 50%);_x000D_
border:none;_x000D_
}_x000D_
_x000D_
@keyframes change {_x000D_
from {_x000D_
width:100px;_x000D_
height:100px;_x000D_
}_x000D_
to {_x000D_
height:50px;_x000D_
width:180px;_x000D_
}_x000D_
}
_x000D_
<div class="tri-1"></div>_x000D_
<div class="tri-2"></div>
_x000D_
2) isosceles triangle
For this one we will need 2 linear-gradient like above and each one will take half the width (or the height). It's like we create a mirror image of the first triangle.
.tri {_x000D_
display:inline-block;_x000D_
width:100px;_x000D_
height:100px;_x000D_
background-image:_x000D_
linear-gradient(to bottom right, transparent 49.5%,red 50%),_x000D_
linear-gradient(to bottom left, transparent 49.5%,red 50%);_x000D_
background-size:50.3% 100%; /* I use a value slightly bigger than 50% to avoid having a small gap between both gradient*/_x000D_
background-position:left,right;_x000D_
background-repeat:no-repeat;_x000D_
_x000D_
animation:change 2s linear infinite alternate;_x000D_
}_x000D_
_x000D_
_x000D_
@keyframes change {_x000D_
from {_x000D_
width:100px;_x000D_
height:100px;_x000D_
}_x000D_
to {_x000D_
height:50px;_x000D_
width:180px;_x000D_
}_x000D_
}
_x000D_
<div class="tri"></div>
_x000D_
3) equilateral triangle
This one is a bit tricky to handle as we need to keep a relation between the height and width of the gradient. We will have the same triangle as above but we will make the calculation more complex in order to transform the isosceles triangle to an equilateral one.
To make it easy, we will consider that the width of our div is known and the height is big enough to be able to draw our triangle inside (height >= width
).
We have our two gradient g1
and g2
, the blue line is the width of the div
w
and each gradient will have 50% of it (w/2
) and each side of the triangle sould be equal to w
. The green line is the height of both gradient hg
and we can easily obtain the formula below:
(w/2)² + hg² = w²
---> hg = (sqrt(3)/2) * w
---> hg = 0.866 * w
We can rely on calc()
in order to do our calculation and to obtain the needed result:
.tri {_x000D_
--w:100px;_x000D_
width:var(--w);_x000D_
height:100px;_x000D_
display:inline-block;_x000D_
background-image:_x000D_
linear-gradient(to bottom right, transparent 49.5%,red 50%),_x000D_
linear-gradient(to bottom left, transparent 49.5%,red 50%);_x000D_
background-size:calc(var(--w)/2 + 0.5px) calc(0.866 * var(--w));_x000D_
background-position:_x000D_
left bottom,right bottom;_x000D_
background-repeat:no-repeat;_x000D_
_x000D_
}
_x000D_
<div class="tri"></div>_x000D_
<div class="tri" style="--w:80px"></div>_x000D_
<div class="tri" style="--w:50px"></div>
_x000D_
Another way is to control the height of div and keep the syntax of gradient easy:
.tri {_x000D_
--w:100px;_x000D_
width:var(--w);_x000D_
height:calc(0.866 * var(--w));_x000D_
display:inline-block;_x000D_
background:_x000D_
linear-gradient(to bottom right, transparent 49.8%,red 50%) left,_x000D_
linear-gradient(to bottom left, transparent 49.8%,red 50%) right;_x000D_
background-size:50.2% 100%;_x000D_
background-repeat:no-repeat;_x000D_
_x000D_
}
_x000D_
<div class="tri"></div>_x000D_
<div class="tri" style="--w:80px"></div>_x000D_
<div class="tri" style="--w:50px"></div>
_x000D_
4) Random triangle
To obtain a random triangle, it's easy as we simply need to remove the condition of 50% of each one BUT we should keep two condition (both should have the same height and the sum of both width should be 100%).
.tri-1 {_x000D_
width:100px;_x000D_
height:100px;_x000D_
display:inline-block;_x000D_
background-image:_x000D_
linear-gradient(to bottom right, transparent 50%,red 0),_x000D_
linear-gradient(to bottom left, transparent 50%,red 0);_x000D_
background-size:20% 60%,80% 60%;_x000D_
background-position:_x000D_
left bottom,right bottom;_x000D_
background-repeat:no-repeat;_x000D_
_x000D_
_x000D_
}
_x000D_
<div class="tri-1"></div>
_x000D_
But what if we want to define a value for each side? We simply need to do calculation again!
Let's define hg1
and hg2
as the height of our gradient (both are equal to the red line) then wg1
and wg2
as the width of our gradient (wg1 + wg2 = a
). I will not going to detail the calculation but at then end we will have:
wg2 = (a²+c²-b²)/(2a)
wg1 = a - wg2
hg1 = hg2 = sqrt(b² - wg1²) = sqrt(c² - wg2²)
Now we have reached the limit of CSS as even with calc()
we won't be able to implement this so we simply need to gather the final result manually and use them as fixed size:
.tri {_x000D_
--wg1: 20px; _x000D_
--wg2: 60px;_x000D_
--hg:30px; _x000D_
width:calc(var(--wg1) + var(--wg2));_x000D_
height:100px;_x000D_
display:inline-block;_x000D_
background-image:_x000D_
linear-gradient(to bottom right, transparent 49.5%,red 50%),_x000D_
linear-gradient(to bottom left, transparent 49.5%,red 50%);_x000D_
_x000D_
background-size:var(--wg1) var(--hg),var(--wg2) var(--hg);_x000D_
background-position:_x000D_
left bottom,right bottom;_x000D_
background-repeat:no-repeat;_x000D_
_x000D_
}
_x000D_
<div class="tri" ></div>_x000D_
_x000D_
<div class="tri" style="--wg1:80px;--wg2:60px;--hg:100px;" ></div>
_x000D_
Bonus
We should not forget that we can also apply rotation and/or skew and we have more option to obtain more triangle:
.tri {_x000D_
--wg1: 20px; _x000D_
--wg2: 60px;_x000D_
--hg:30px; _x000D_
width:calc(var(--wg1) + var(--wg2) - 0.5px);_x000D_
height:100px;_x000D_
display:inline-block;_x000D_
background-image:_x000D_
linear-gradient(to bottom right, transparent 49%,red 50%),_x000D_
linear-gradient(to bottom left, transparent 49%,red 50%);_x000D_
_x000D_
background-size:var(--wg1) var(--hg),var(--wg2) var(--hg);_x000D_
background-position:_x000D_
left bottom,right bottom;_x000D_
background-repeat:no-repeat;_x000D_
_x000D_
}
_x000D_
<div class="tri" ></div>_x000D_
_x000D_
<div class="tri" style="transform:skewY(25deg)"></div>_x000D_
_x000D_
<div class="tri" style="--wg1:80px;--wg2:60px;--hg:100px;" ></div>_x000D_
_x000D_
_x000D_
<div class="tri" style="--wg1:80px;--wg2:60px;--hg:100px;transform:rotate(20deg)" ></div>
_x000D_
And of course we should keep in mind the SVG solution which can be more suitable in some situation:
svg {_x000D_
width:100px;_x000D_
height:100px;_x000D_
}_x000D_
_x000D_
polygon {_x000D_
fill:red;_x000D_
}
_x000D_
<svg viewBox="0 0 100 100"><polygon points="0,100 0,0 100,100" /></svg>_x000D_
<svg viewBox="0 0 100 100"><polygon points="0,100 50,0 100,100" /></svg>_x000D_
<svg viewBox="0 0 100 100"><polygon points="0,100 50,23 100,100" /></svg>_x000D_
<svg viewBox="0 0 100 100"><polygon points="20,60 50,43 80,100" /></svg>
_x000D_
I wrote this to make it easier (and DRY) to automatically generate a CSS triangle:
// Triangle helper mixin (by Yair Even-Or)
// @param {Direction} $direction - either `top`, `right`, `bottom` or `left`
// @param {Color} $color [currentcolor] - Triangle color
// @param {Length} $size [1em] - Triangle size
@mixin triangle($direction, $color: currentcolor, $size: 1em) {
$size: $size/2;
$transparent: rgba($color, 0);
$opposite: (top:bottom, right:left, left:right, bottom:top);
content: '';
display: inline-block;
width: 0;
height: 0;
border: $size solid $transparent;
border-#{map-get($opposite, $direction)}-color: $color;
margin-#{$direction}: -$size;
}
span {
@include triangle(bottom, red, 10px);
}
Important note:
if the triangle seems pixelated in some browsers, try one of the methods described here.
And now something completely different...
Instead of using css tricks don't forget about solutions as simple as html entities:
▲
Result:
▲
I know this is an old one, but I'd like to add to this discussion that There are at least 5 different methods for creating a triangle using HTML & CSS alone.
borders
linear-gradient
conic-gradient
transform
and overflow
clip-path
I think that all have been covered here except for method 3, using the conic-gradient
, so I will share it here:
.triangle{_x000D_
width: 40px;_x000D_
height: 40px;_x000D_
background: conic-gradient(at 50% 50%,transparent 135deg,green 0,green 225deg, transparent 0);_x000D_
}
_x000D_
<div class="triangle"></div>
_x000D_
If you want to play around with border-size
, width
and height
and see how those can create different shapes, try this:
const sizes = [32, 32, 32, 32];_x000D_
const triangle = document.getElementById('triangle');_x000D_
_x000D_
function update({ target }) {_x000D_
let index = null;_x000D_
_x000D_
if (target) {_x000D_
index = parseInt(target.id);_x000D_
_x000D_
if (!isNaN(index)) {_x000D_
sizes[index] = target.value;_x000D_
}_x000D_
}_x000D_
_x000D_
window.requestAnimationFrame(() => {_x000D_
triangle.style.borderWidth = sizes.map(size => `${ size }px`).join(' ');_x000D_
_x000D_
if (isNaN(index)) {_x000D_
triangle.style[target.id] = `${ target.value }px`;_x000D_
}_x000D_
});_x000D_
}_x000D_
_x000D_
document.querySelectorAll('input').forEach(input => {_x000D_
input.oninput = update;_x000D_
});_x000D_
_x000D_
update({});
_x000D_
body {_x000D_
margin: 0;_x000D_
min-height: 100vh;_x000D_
display: flex;_x000D_
justify-content: center;_x000D_
align-items: center;_x000D_
overflow: hidden;_x000D_
}_x000D_
_x000D_
#triangle {_x000D_
border-style: solid;_x000D_
border-color: yellow magenta blue black;_x000D_
background: cyan;_x000D_
height: 0px;_x000D_
width: 0px;_x000D_
}_x000D_
_x000D_
#controls {_x000D_
position: fixed;_x000D_
bottom: 0;_x000D_
left: 0;_x000D_
right: 0;_x000D_
background: white;_x000D_
display: flex;_x000D_
box-shadow: 0 0 32px rgba(0, 0, 0, .125);_x000D_
}_x000D_
_x000D_
#controls > div {_x000D_
position: relative;_x000D_
width: 25%;_x000D_
padding: 8px;_x000D_
box-sizing: border-box;_x000D_
display: flex;_x000D_
}_x000D_
_x000D_
input {_x000D_
margin: 0;_x000D_
width: 100%;_x000D_
position: relative;_x000D_
}
_x000D_
<div id="triangle" style="border-width: 32px 32px 32px 32px;"></div>_x000D_
_x000D_
<div id="controls">_x000D_
<div><input type="range" min="0" max="128" value="32" id="0" /></div>_x000D_
<div><input type="range" min="0" max="128" value="32" id="1" /></div>_x000D_
<div><input type="range" min="0" max="128" value="32" id="2" /></div>_x000D_
<div><input type="range" min="0" max="128" value="32" id="3" /></div>_x000D_
<div><input type="range" min="0" max="128" value="0" id="width" /></div>_x000D_
<div><input type="range" min="0" max="128" value="0" id="height" /></div>_x000D_
</div>
_x000D_
Here is an animation in JSFiddle I created for demonstration.
Also see snippet below.
This is an Animated GIF made from a Screencast
transforms = [_x000D_
{'border-left-width' :'30', 'margin-left': '70'},_x000D_
{'border-bottom-width' :'80'},_x000D_
{'border-right-width' :'30'},_x000D_
{'border-top-width' :'0', 'margin-top': '70'},_x000D_
{'width' :'0'},_x000D_
{'height' :'0', 'margin-top': '120'},_x000D_
{'borderLeftColor' :'transparent'},_x000D_
{'borderRightColor' :'transparent'}_x000D_
];_x000D_
_x000D_
_x000D_
$('#a').click(function() {$('.border').trigger("click");});_x000D_
(function($) {_x000D_
var duration = 1000_x000D_
$('.border').click(function() {_x000D_
for ( var i=0; i < transforms.length; i++ ) {_x000D_
$(this)_x000D_
.animate(transforms[i], duration)_x000D_
}_x000D_
}).end()_x000D_
}(jQuery))
_x000D_
.border {_x000D_
margin: 20px 50px;_x000D_
width: 50px;_x000D_
height: 50px;_x000D_
border-width: 50px;_x000D_
border-style: solid;_x000D_
border-top-color: green;_x000D_
border-right-color: yellow;_x000D_
border-bottom-color: red;_x000D_
border-left-color: blue;_x000D_
cursor: pointer_x000D_
}
_x000D_
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>_x000D_
<script src="https://code.jquery.com/color/jquery.color-2.1.2.min.js"></script>_x000D_
Click it!<br>_x000D_
<div class="border"></div>
_x000D_
/**_x000D_
* Randomize array element order in-place._x000D_
* Using Durstenfeld shuffle algorithm._x000D_
*/_x000D_
function shuffleArray(array) {_x000D_
for (var i = array.length - 1; i > 0; i--) {_x000D_
var j = Math.floor(Math.random() * (i + 1));_x000D_
var temp = array[i];_x000D_
array[i] = array[j];_x000D_
array[j] = temp;_x000D_
}_x000D_
return array;_x000D_
}_x000D_
_x000D_
transforms = [_x000D_
{'border-left-width' :'30', 'margin-left': '70'},_x000D_
{'border-bottom-width' :'80'},_x000D_
{'border-right-width' :'30'},_x000D_
{'border-top-width' :'0', 'margin-top': '70'},_x000D_
{'width' :'0'},_x000D_
{'height' :'0'},_x000D_
{'borderLeftColor' :'transparent'},_x000D_
{'borderRightColor' :'transparent'}_x000D_
];_x000D_
transforms = shuffleArray(transforms)_x000D_
_x000D_
_x000D_
_x000D_
$('#a').click(function() {$('.border').trigger("click");});_x000D_
(function($) {_x000D_
var duration = 1000_x000D_
$('.border').click(function() {_x000D_
for ( var i=0; i < transforms.length; i++ ) {_x000D_
$(this)_x000D_
.animate(transforms[i], duration)_x000D_
}_x000D_
}).end()_x000D_
}(jQuery))
_x000D_
.border {_x000D_
margin: 50px;_x000D_
width: 50px;_x000D_
height: 50px;_x000D_
border-width: 50px;_x000D_
border-style: solid;_x000D_
border-top-color: green;_x000D_
border-right-color: yellow;_x000D_
border-bottom-color: red;_x000D_
border-left-color: blue;_x000D_
cursor: pointer_x000D_
}
_x000D_
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>_x000D_
<script src="https://code.jquery.com/color/jquery.color-2.1.2.min.js"></script>_x000D_
Click it!<br>_x000D_
<div class="border"></div>
_x000D_
$('#a').click(function() {$('.border').trigger("click");});_x000D_
(function($) {_x000D_
var duration = 1000_x000D_
$('.border').click(function() {_x000D_
$(this)_x000D_
.animate({'border-top-width': 0 ,_x000D_
'border-left-width': 30 ,_x000D_
'border-right-width': 30 ,_x000D_
'border-bottom-width': 80 ,_x000D_
'width': 0 ,_x000D_
'height': 0 ,_x000D_
'margin-left': 100,_x000D_
'margin-top': 150,_x000D_
'borderTopColor': 'transparent',_x000D_
'borderRightColor': 'transparent',_x000D_
'borderLeftColor': 'transparent'}, duration)_x000D_
}).end()_x000D_
}(jQuery))
_x000D_
.border {_x000D_
margin: 50px;_x000D_
width: 50px;_x000D_
height: 50px;_x000D_
border-width: 50px;_x000D_
border-style: solid;_x000D_
border-top-color: green;_x000D_
border-right-color: yellow;_x000D_
border-bottom-color: red;_x000D_
border-left-color: blue;_x000D_
cursor: pointer_x000D_
}
_x000D_
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>_x000D_
<script src="https://code.jquery.com/color/jquery.color-2.1.2.min.js"></script>_x000D_
Click it!<br>_x000D_
<div class="border"></div>
_x000D_
Others have already explained this well. Let me give you an animation which will explain this quickly: http://codepen.io/chriscoyier/pen/lotjh
Here is some code for you to play with and learn the concepts.
HTML:
<html>
<body>
<div id="border-demo">
</div>
</body>
</html>
CSS:
/*border-width is border thickness*/
#border-demo {
background: gray;
border-color: yellow blue red green;/*top right bottom left*/
border-style: solid;
border-width: 25px 25px 25px 25px;/*top right bottom left*/
height: 50px;
width: 50px;
}
Play with this and see what happens. Set height and width to zero. Then remove top border and make left and right transparent, or just look at the code below to make a css triangle:
#border-demo {
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-bottom: 100px solid blue;
}
This is an old question, but I think will worth it to share how to create an arrow using this triangle technique.
Lets create 2 triangles, for the second one we will use the :after
pseudo class and position it just below the other:
.arrow{
width: 0;
height: 0;
border-radius: 50px;
display: inline-block;
position: relative;
}
.arrow:after{
content: "";
width: 0;
height: 0;
position: absolute;
}
.arrow-up{
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-bottom: 50px solid #333;
}
.arrow-up:after{
top: 5px;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-bottom: 50px solid #ccc;
right: -50px;
}
_x000D_
<div class="arrow arrow-up"> </div>
_x000D_
Now we just have to set the predominant border color of the second triangle to the same color of the background:
.arrow{
width: 0;
height: 0;
border-radius: 50px;
display: inline-block;
position: relative;
}
.arrow:after{
content: "";
width: 0;
height: 0;
position: absolute;
}
.arrow-up{
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-bottom: 50px solid #333;
}
.arrow-up:after{
top: 5px;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-bottom: 50px solid #fff;
right: -50px;
}
_x000D_
<div class="arrow arrow-up"> </div>
_x000D_
Fiddle with all the arrows:
http://jsfiddle.net/tomsarduy/r0zksgeu/
Source: Stackoverflow.com