Create a triangle with CSS

Asked

Viewed 7,004 times

24

Squares that have the color of an item can have up to two colors that in the latter case should be displayed as shown below:

Exemplo do resultado final

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

Problem

The interior element, of course, has a square shape, but to get to the desired layout, it should be in a triangle shape.

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 triangle shape via CSS ?

4 answers

26


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 square of 40px without dimensions (width and height), and with the 4 edges defined, all with 20px thickness and each edge with a different color. The result has this appearance:

inserir a descrição da imagem aqui

The above example was generated with the following CSS:

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

Demo no jsfiddle

In the example above, we used the 4 edges, each with 20px thickness. To achieve the effect you want, just two edges, both with the thickness equivalent to the size of the side of your square (ie 40px):

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

Demo no jsfiddle

Above we use the edges left (transparent) and bottom (black). But it is possible to get the same effect using the right edge (black) and the top (transparent):

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

Demo no jsfiddle

Understanding this mechanism, it is possible to generate several types of triangle, including the ones you ask in the question. To generate a square with diagonal division and two colors, it is possible both to use the external div to define one of the colors, as well as to color the edges I defined as transparent in the examples.

One more example, your black and red square:

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

Demo no jsfiddle

  • +1 had already seen several examples online, but it’s the first time I understand 100% how this technique actually works!

  • Ball show these effects!

7

It is possible to do this for example through transparent edges (I’m not sure if they are available pre-CSS3):

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 you assign 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.

  • 1

    I think the right edge, zeroed, is not even necessary.

  • @bfavaretto You’re right. I took the code of the generic triangle and adapted, I didn’t look at the "Triangle bottom right". In fact, that ledge is hanging over...

3

I use this method a lot of creating a triangle with edges, but, if I understand your question well, and looking at the images you gave of example, you want a triangle that cannot be done with edges, since it is an effect that comes diagonally, starting with "top left", right?

For this case, do as follows:

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 the same effect you requested.

  • Interesting idea, although it can do with edges, and probably there are fewer compatibility problems. Toast: a demo of your solution :) http://jsfiddle.net/Jfwbr/

  • Give me an example with edges for the image diagonally?

  • In my answer there are several

2

Since it was not cited I will give a solution using the pseudo-element ::after

With it you create an element within the div from the CSS, uses transform to rotate 45 graus and positions 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 support of browsers https://caniuse.com/#feat=css-clip-path (apparently not working 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 documentation W3C of clip-phat https://www.w3.org/TR/css-masking-1/#the-clip-path

NOTE: Another solution would still be using SVG: https://www.w3.org/TR/SVG11/

  • 1

    And neither on Edge :/ - but in the future it will surely be a hand on the wheel :)

  • @Guilhermenascimento Clip-path is too cool, but I’m currently traveling eh in SVG, dear svg eh the future rss

  • SVG use for everything, I even give preference to SVG for icons, instead of fonts.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.