Create a triangle with CSS

24

The squares that show the color of an item can have up to two colors that in the latter case should be presented as below:

Both colors are applied in the CSS property background . What is to be done is to have a square to present the color and in cases where there is a second color a new element is applied inside the square of the main color.

Problem

The inner element naturally has a square shape, but in order to get to the desired layout, it should be in a triangular form.

Example in JSFiddle

HTML

<div class="color">
    <div></div>
</div>

CSS

.color{
    width:40px;
    height:40px;
    background:white;
}
.color > div{
    background:black;
    width:20px;
    height:20px;
}

Question

How to pass a block element to a triangular shape via CSS?

    
asked by anonymous 24.01.2014 / 16:18

4 answers

25

The trick to solving this is quite interesting. It is based on the fact that when two edges of an element meet, they form an angle of 45 degrees to each other.

Imagine your 40px square without dimensions (% w / w% and% w / w), and with the 4 edges defined, all with a thickness of 20px and each border with a different color. The result looks like this:

TheaboveexamplewasgeneratedwiththefollowingCSS:

.color > div{ border-top: 20px solid black; border-right: 20px solid blue; border-bottom: 20px solid green; border-left: 20px solid red; }

Demo on jsfiddle

In the example above, we use the 4 edges, each with a thickness of 20px. To achieve the effect you want, two borders, both with the thickness equivalent to the size of the side of your square (that is, 40px), are enough:

.color > div{
    border-left: 40px solid transparent;
    border-bottom: 40px solid black;
}

Demo no jsfiddle

Above we use the left (transparent) and lower (black) edges. But you can achieve the same effect by using the right (black) and upper (transparent) edges:

.color > div{
    border-right: 40px solid black;
    border-top: 40px solid transparent;
}

Demo no jsfiddle

Understanding this mechanism, you can generate several types of triangles, including the ones you ask for in the question. To generate a square with diagonal split and two colors, you can either use the outer div to define one of the colors, or color the borders that I set as transparent in the examples.

One more example, its black and red square:

.color > div{
    border-right: 40px solid red;
    border-top: 40px solid black;
}

Demo no jsfiddle

    
24.01.2014 / 16:38
7

You can do this for example through transparent borders (I'm not sure if pre-CSS3 is available):

border-left: 40px solid transparent;
border-right: 0px solid transparent;
border-bottom: 40px solid black;

Example in jsFiddle . Source: css-tricks.com

That is, instead of assigning width , height and background , you use border-left and border-right - transparent, one with zero and the other with the desired width - and border-bottom - with the desired height and background color.

    
24.01.2014 / 16:35
3

I use this method a lot to create a triangle with borders, but if I understood your question well, and looking at the images you gave as an example, you want a triangle that can not be done with borders, since is an effect that comes diagonally, starting with "top left", right?

For this case, do the following:

background: #000; /* para navegadores sem suporte a gradient */

/* IE9 SVG, precisamos declarar uma class para o elemento e no CSS um "filter: none" */
background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIxMDAlIiB5Mj0iMTAwJSI+CiAgICA8c3RvcCBvZmZzZXQ9IjAlIiBzdG9wLWNvbG9yPSIjMDAwMDAwIiBzdG9wLW9wYWNpdHk9IjEiLz4KICAgIDxzdG9wIG9mZnNldD0iNTAlIiBzdG9wLWNvbG9yPSIjMDAwMDAwIiBzdG9wLW9wYWNpdHk9IjEiLz4KICAgIDxzdG9wIG9mZnNldD0iNTAlIiBzdG9wLWNvbG9yPSIjZmYwMDA0IiBzdG9wLW9wYWNpdHk9IjEiLz4KICA8L2xpbmVhckdyYWRpZW50PgogIDxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIGZpbGw9InVybCgjZ3JhZC11Y2dnLWdlbmVyYXRlZCkiIC8+Cjwvc3ZnPg==);
background: -moz-linear-gradient(-45deg, #000 0%, #000 50%, #ff0004 50%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, right bottom, color-stop(0%,#000), color-stop(50%,#000), color-stop(50%,#ff0004)); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(-45deg, #000 0%,#000 50%,#ff0004 50%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(-45deg, #000 0%,#000 50%,#ff0004 50%); /* Opera 11.10+ */
background: -ms-linear-gradient(-45deg, #000 0%,#000 50%,#ff0004 50%); /* IE10+ */
background: linear-gradient(135deg, #000 0%,#000 50%,#ff0004 50%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#000', endColorstr='#ff0004',GradientType=1 ); /* IE6-8 fallback on horizontal gradient */

This will give you an equal effect you requested.

    
28.01.2014 / 19:50
2

As it was not quoted I will give a solution using the pseudo-element ::after

With it you create an element within div from CSS, use transform to rotate 45 graus and position with transform-origin

See the result in the example

.wrapper {
    position: relative;
    overflow: hidden;
    width: 100px;
    height: 100px;
    background-color: black;
}
.wrapper::after {
    content: "";
    position: absolute;
    width: 200%;
    height: 200%;
    background-color: red;
    transform: rotate(45deg);
    transform-origin: left top;
}
<div class="wrapper"></div>

Second option using clip-path see browser support link (apparently does not work in IE)

.wrapper {
    position: relative;
    overflow: hidden;
    width: 100px;
    height: 100px;
    background-color: red;
}
.tri {
    height: 100%;
    width: 100%;
    -webkit-clip-path: polygon(0 0, 0% 100%, 100% 100%);
    clip-path: polygon(0 0, 0% 100%, 100% 100%);
    background-color: black;
}
<div class="wrapper">
    <div class="tri"></div>
</div>

Official W3C documentation of clip-phat link

NOTE: Another solution would still be using SVG: link

    
10.04.2018 / 20:44