css3 triangulos - ¿Cómo funcionan los triángulos CSS?




border generador (15)

Considera el triángulo de abajo

.triangle {
    border-bottom:15px solid #000;
    border-left:10px solid transparent;
    border-right:10px solid transparent;
    width:0;
    height:0;
}

Esto es lo que se nos da:

¿Por qué salió en esta forma? El siguiente diagrama explica las dimensiones, tenga en cuenta que se utilizaron 15 px para el borde inferior y 10 píxeles para el derecho e izquierdo.

Es bastante fácil hacer un triángulo rectángulo también quitando el borde derecho.

Hay muchas formas diferentes de CSS en CSS Tricks - Shapes of CSS y estoy particularmente confundido con un triángulo:

#triangle-up {
  width: 0;
  height: 0;
  border-left: 50px solid transparent;
  border-right: 50px solid transparent;
  border-bottom: 100px solid red;
}
<div id="triangle-up"></div>

¿Cómo y por qué funciona?


SASS (SCSS) triángulo mixin

Escribí esto para que sea más fácil (y SECO) generar automáticamente un triángulo CSS:

// 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;
}

Ejemplo de caso de uso:

span {
  @include triangle(bottom, red, 10px);
}

Página de juegos

Nota IMPORTANTE:
Si el triángulo parece pixelado en algunos navegadores, pruebe uno de los métodos descritos here .


CSS clip-path

Esto es algo que siento que esta pregunta ha pasado por alto; clip-path

clip-path en pocas palabras

Recortar, con la propiedad de clip-path , es similar a cortar una forma (como un círculo o un pentágono) de un pedazo de papel rectangular. La propiedad pertenece a la especificación " CSS Masking Module Level 1 ". La especificación establece que "el enmascaramiento de CSS proporciona dos medios para ocultar parcial o totalmente partes de elementos visuales: enmascaramiento y recorte".

clip-path utilizará el elemento en lugar de sus bordes para cortar la forma que especifique en sus parámetros. Utiliza un sistema de coordenadas basado en porcentajes super simple que hace que la edición sea muy fácil y significa que puedes recogerlo y crear formas extrañas y maravillosas en cuestión de minutos.

Ejemplo de forma de triángulo

div {
  -webkit-clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
  clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
  background: red;
  width: 100px;
  height: 100px;
}
<div></div>

Abajo

Tiene un gran inconveniente en este momento, uno es su mayor falta de soporte, solo está cubierto en los navegadores -webkit- y no tiene soporte en IE y es muy parcial en FireFox.

Recursos

Aquí hay algunos recursos y material útiles para ayudar a entender mejor clip-path y también comenzar a crear el suyo propio.


Enfoque diferente. Con gradiente lineal (para IE, solo IE 10+). Puedes usar cualquier ángulo:

.triangle {
    margin: 50px auto;
    width: 100px;
    height: 100px;
/* linear gradient */
    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%);
 /* FF3.6+ */
    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)));
 /* Chrome,Safari4+ */
    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%);
 /* Chrome10+,Safari5.1+ */
    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%);
 /* Opera 11.10+ */
    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%);
 /* IE10+ */
    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%);
 /* W3C */;
}
<div class="triangle"></div>

Aquí está jsfiddle


Aquí hay otro violín.

.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;
}

https://jsfiddle.net/qdhvdb17/


Yendo un paso más allá, usando css basado en esto, agregué flechas a mi espalda y a los siguientes botones (sí, sé que no es un 100% de navegador cruzado, pero que no es muy elegante).

.triangle {
  width: 0;
  height: 0;
  border-left: 50px solid transparent;
  border-right: 50px solid transparent;
  border-bottom: 100px solid red;
  margin:20px auto;
}

.triangle-down {
  border-bottom:none;
  border-top: 100px solid red;
}

.triangle-left {
  border-left:none;
  border-right: 100px solid red;
  border-bottom: 50px solid transparent;
  border-top: 50px solid transparent;
}

.triangle-right {
  border-right:none;
  border-left: 100px solid red;
  border-bottom: 50px solid transparent;
  border-top: 50px solid transparent;
}

.triangle-after:after {
  width: 0;
  height: 0;
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  border-bottom: 5px solid red;
  margin:0 5px;
  content:"";
  display:inline-block;
}

.triangle-after-right:after {
  border-right:none;
  border-left: 5px solid blue;
  border-bottom: 5px solid transparent;
  border-top: 5px solid transparent;

}

.triangle-before:before {
  width: 0;
  height: 0;
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  border-bottom: 5px solid blue;
  margin:0 5px;
  content:"";
  display:inline-block;
}

.triangle-before-left:before {
  border-left:none;
  border-right: 5px solid blue;
  border-bottom: 5px solid transparent;
  border-top: 5px solid transparent;

}
<div class="triangle"></div>
<div class="triangle triangle-down"></div>
<div class="triangle triangle-left"></div>
<div class="triangle triangle-right"></div>

<a class="triangle-before triangle-before-left" href="#">Back</a>
<a class="triangle-after triangle-after-right" href="#">Next</a>


Triángulos CSS: Una tragedia en cinco actos

Como dijo alex , los bordes de igual anchura se topan entre sí en ángulos de 45 grados:

Cuando no tienes un borde superior, se ve así:

Entonces le das un ancho de 0 ...

... y una altura de 0 ...

... y finalmente, haces los dos bordes laterales transparentes:

Eso resulta en un triángulo.


Aquí hay una animación en JSFiddle que creé para demostración.

También vea el fragmento a continuación.

Este es un GIF animado hecho de un Screencast

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>

Versión aleatoria

/**
 * 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>

Todo a la vez 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>


Digamos que tenemos el siguiente div:

<div id="triangle" />

Ahora edite el CSS paso a paso, para que tenga una idea clara de lo que está sucediendo

PASO 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;
    }

Este es un div simple. Con un CSS muy simple. Así que un laico puede entender. Div tiene unas dimensiones de 150 x 150 píxeles con el borde de 50 píxeles. La imagen se adjunta:

PASO 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;
}

Ahora acabo de cambiar el color del borde de los 4 lados. La imagen está adjunta.

PASO: 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;
}

Ahora acabo de cambiar el alto y ancho de div de 150 píxeles a cero. La imagen esta adjunta

PASO 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;
}

Ahora he hecho todos los bordes transparentes aparte del borde inferior. La imagen se adjunta a continuación.

PASO 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;
}

Ahora acabo de cambiar el color de fondo a blanco. La imagen está adjunta.

De ahí tenemos el triángulo que necesitábamos.


Comience con un cuadrado básico y bordes. Cada borde tendrá un color diferente para que podamos distinguirlos:

.triangle {
    border-color: yellow blue red green;
    border-style: solid;
    border-width: 200px 200px 200px 200px;
    height: 0px;
    width: 0px;
}

lo que te da this :

this

Pero no es necesario el borde superior, así que establece su ancho a 0px . Ahora, nuestro borde inferior de 200px hará que nuestro triángulo tenga una altura de 200 px.

.triangle {
    border-color: yellow blue red green;
    border-style: solid;
    border-width: 0px 200px 200px 200px;
    height: 0px;
    width: 0px;
}

y obtendremos this :

this

Luego, para ocultar los dos triángulos laterales, establezca el color del borde como transparente. Dado que el borde superior se ha eliminado de manera efectiva, también podemos establecer el color de borde superior en transparente.

.triangle {
    border-color: transparent transparent red transparent;
    border-style: solid;
    border-width: 0px 200px 200px 200px;
    height: 0px;
    width: 0px;
}

finalmente conseguimos this :

this


Enfoque diferente:

Triángulos CSS3 con transformar rotar

La forma triangular es bastante fácil de hacer usando esta técnica. Para las personas que prefieren ver una animación que explique cómo funciona esta técnica, aquí está:

De lo contrario, aquí hay una explicación detallada en 4 actos (esto no es una tragedia) de cómo hacer un triángulo rectángulo isósceles con un elemento.

  • Nota 1: para los triángulos no isósceles y cosas de fantasía, puede ver el paso 4 .
  • Nota 2: en los siguientes fragmentos, los prefijos del proveedor no están incluidos. Se incluyen en las demostraciones de codepen .
  • Nota 3: el HTML para la siguiente explicación es siempre: <div class="tr"></div>

PASO 1: Haz un div

Fácil, solo asegúrate de que width = 1.41 x height . Puede usar cualquier técnica ( vea aquí ), incluido el uso de porcentajes y el relleno del fondo para mantener la relación de aspecto y hacer un triángulo sensible . En la siguiente imagen, el div tiene un borde amarillo dorado.

En ese div, inserta un pseudo elemento y dale el 100% de ancho y alto del padre. El pseudo elemento tiene un fondo azul en la siguiente imagen.

En este punto, tenemos este 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;
}

PASO 2: Vamos a rotar

Primero, lo más importante: definir un origen de transformación . El origen predeterminado está en el centro del pseudo-elemento y lo necesitamos en la parte inferior izquierda. Añadiendo este CSS al pseudo elemento:

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

Ahora podemos rotar el pseudo elemento 45 grados en el sentido de las agujas del reloj con transform : rotate(45deg);

En este punto, tenemos este 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);
}

PASO 3: esconderlo

Para ocultar las partes no deseadas del pseudoelemento (todo lo que desborda el div con el borde amarillo) solo necesita configurar overflow:hidden; en el contenedor. Después de quitar el borde amarillo, obtienes ... ¡un TRIÁNGULO ! :

DEMO

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);
}

PASO 4: ir más lejos ...

Como se muestra en la demostración , puede personalizar los triángulos:

  1. Haz que sean más delgados o más planos jugando con skewX() .
  2. Haz que apunten hacia la izquierda, hacia la derecha o en cualquier otra dirección jugando con la transformación orign y la dirección de rotación.
  3. Hacer alguna reflexión con la propiedad transformar 3D.
  4. Dar los bordes triangulares.
  5. Pon una imagen dentro del triángulo.
  6. Mucho más ... ¡Desata los poderes de CSS3 !

¿Por qué utilizar esta técnica?

  1. Triángulo puede ser fácilmente sensible.
  2. Puedes hacer un triángulo con borde .
  3. Puedes mantener los límites del triángulo. Esto significa que puede activar el estado de desplazamiento o hacer clic en el evento solo cuando el cursor está dentro del triángulo . Esto puede ser muy útil en algunas situaciones como esta, donde cada triángulo no puede superponerse a sus vecinos, por lo que cada triángulo tiene su propio estado de desplazamiento.
  4. Puedes hacer algunos efectos de fantasía como reflejos .
  5. Te ayudará a entender las propiedades de transformación 2d y 3d.

¿Por qué no usar esta técnica?

  1. El principal inconveniente es la compatibilidad del navegador , las propiedades de transformación 2d son compatibles con IE9 + y, por lo tanto, no puede usar esta técnica si planea admitir IE8. Vea CanIuse para más información. Para algunos efectos sofisticados, el uso de transformaciones 3d como la compatibilidad con el navegador de reflexión es IE10 + (consulte canIuse para obtener más información).
  2. No necesitas nada que responda y un triángulo plano es bueno para ti, entonces deberías optar por la técnica de borde que se explica aquí: mejor compatibilidad con el navegador y más fácil de entender gracias a las increíbles publicaciones aquí.

Esta es una pregunta antigua, pero creo que valdrá la pena compartir cómo crear una flecha usando esta técnica de triángulo.

Paso 1:

Vamos a crear 2 triángulos, para el segundo usaremos :after pseudo class y lo posicionaremos justo debajo del otro:

.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;
    }
<div class="arrow arrow-up"> </div>

Paso 2

Ahora solo tenemos que establecer el color del borde predominante del segundo triángulo en el mismo color del fondo:

.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;
    }
<div class="arrow arrow-up"> </div>

Violín con todas las flechas:
http://jsfiddle.net/tomsarduy/r0zksgeu/


De acuerdo, este triángulo se creará debido a la forma en que los bordes de los elementos trabajan juntos en HTML y CSS ...

Como usualmente usamos bordes de 1 o 2px, nunca notamos que los bordes formen ángulos de 45 ° entre sí con el mismo ancho y si el ancho cambia, el grado del ángulo también se modifica, ejecute el código CSS que he creado a continuación:

.triangle {
  width: 100px;
  height: 100px;
  border-left: 50px solid black;
  border-right: 50px solid black;
  border-bottom: 100px solid red;
}
<div class="triangle">
</div>

Luego, en el siguiente paso, no tenemos ancho ni altura, algo como esto:

.triangle {
  width: 0;
  height: 0;
  border-left: 50px solid black;
  border-right: 50px solid black;
  border-bottom: 100px solid red;
}
<div class="triangle">
</div>

Y ahora hacemos invisibles los bordes izquierdo y derecho para hacer nuestro triángulo deseable como se muestra a continuación:

.triangle {
  width: 0;
  height: 0;
  border-left: 50px solid transparent;
  border-right: 50px solid transparent;
  border-bottom: 100px solid red;
}
<div class="triangle"></div>

Si no está dispuesto a ejecutar el fragmento para ver los pasos, he creado una secuencia de imágenes para ver todos los pasos en una imagen:


Casi todas las respuestas se centran en el triángulo construido usando el borde, así que voy a elaborar el método de linear-gradient (como se inició en la respuesta de @lima_fil ).

Usar un valor de grado como 45° nos obligará a respetar una proporción específica de height/width para obtener el triángulo que queremos y esto no será sensible:

.tri {
  width:100px;
  height:100px;
  background:linear-gradient(45deg, transparent 50%,red 0);
  
  /*To illustrate*/
  border:1px solid;
}
Good one
<div class="tri"></div>
bad one
<div class="tri" style="width:150px"></div>
bad one
<div class="tri" style="height:30px"></div>

En lugar de hacer esto, deberíamos considerar valores de dirección predefinidos como to bottom , to top , etc. En este caso, podemos obtener cualquier tipo de forma de triángulo y al mismo tiempo mantenerlo sensible.

1) triángulo rectángulo

Para obtener dicho triángulo necesitamos un gradiente lineal y una dirección diagonal como to bottom right , to top left , to bottom left , etc.

.tri-1,.tri-2 {
  display:inline-block;
  width:100px;
  height:100px;
  background:linear-gradient(to bottom left, transparent 49.8%,red 50%);
  border:1px solid;
  animation:change 2s linear infinite alternate;
}
.tri-2 {
  background:linear-gradient(to top right, transparent 49.8%,red 50%);
  border:none;
}

@keyframes change {
  from {
    width:100px;
    height:100px;
  }
  to {
    height:50px;
    width:180px;
  }
}
<div class="tri-1"></div>
<div class="tri-2"></div>

2) triángulo isósceles

Para esto necesitaremos 2 gradientes lineales como arriba y cada uno tomará la mitad del ancho (o la altura). Es como si creamos una imagen de espejo del primer triángulo.

.tri {
  display:inline-block;
  width:100px;
  height:100px;
  background-image:
  linear-gradient(to bottom right, transparent 49.8%,red 50%),
  linear-gradient(to bottom left, transparent 49.8%,red 50%);
  background-size:50.5% 100%; /* I use a value slightly bigger than 50% to avoid having a small gap between both gradient*/
  background-position:left,right;
  background-repeat:no-repeat;
  
  animation:change 2s linear infinite alternate;
}


@keyframes change {
  from {
    width:100px;
    height:100px;
  }
  to {
    height:50px;
    width:180px;
  }
}
<div class="tri"></div>

3) triángulo equilátero

Este es un poco difícil de manejar, ya que necesitamos mantener una relación entre la altura y el ancho del degradado. Tendremos el mismo triángulo que el anterior, pero haremos que el cálculo sea más complejo para transformar el triángulo isósceles en uno equilátero.

Para hacerlo más fácil, consideraremos que el ancho de nuestra div es conocido y la altura es lo suficientemente grande como para poder dibujar nuestro triángulo en el interior ( height >= width ).

Tenemos nuestros dos gradientes g1 y g2 , la línea azul es el ancho de la div w y cada gradiente tendrá un 50% ( w/2 ) y cada lado del triángulo debería ser igual a w . La línea verde es la altura de ambos gradientes hg y podemos obtener fácilmente la siguiente fórmula:

(w/2)² + hg² = w² ---> hg = (sqrt(3)/2) * w ---> hg = 0.866 * w

Podemos confiar en calc() para realizar nuestro cálculo y obtener el resultado necesario:

.tri {
  --w:100px;
  width:var(--w);
  height:100px;
  display:inline-block;
  background-image:
  linear-gradient(to bottom right, transparent 49.8%,red 50%),
  linear-gradient(to bottom left, transparent 49.8%,red 50%);
  background-size:calc(var(--w)/2 + 0.5%)  calc(0.866 * var(--w));
  background-position:
    left bottom,right bottom;
  background-repeat:no-repeat;
  
}
<div class="tri"></div>
<div class="tri" style="--w:80px"></div>
<div class="tri" style="--w:50px"></div>

Otra forma es controlar la altura de div y mantener la sintaxis de gradiente fácil:

.tri {
  --w:100px;
  width:var(--w);
  height:calc(0.866 * var(--w));
  display:inline-block;
  background:
   linear-gradient(to bottom right, transparent 49.8%,red 50%) left,
   linear-gradient(to bottom left,  transparent 49.8%,red 50%) right;
  background-size:50.2% 100%;
  background-repeat:no-repeat;
  
}
<div class="tri"></div>
<div class="tri" style="--w:80px"></div>
<div class="tri" style="--w:50px"></div>

4) triángulo aleatorio

Para obtener un triángulo aleatorio, es fácil ya que simplemente necesitamos eliminar la condición del 50% de cada uno PERO debemos mantener dos condiciones (ambas deben tener la misma altura y la suma de ambas anchuras debe ser del 100%).

.tri-1 {
  width:100px;
  height:100px;
  display:inline-block;
  background-image:
  linear-gradient(to bottom right, transparent 50%,red 0),
  linear-gradient(to bottom left, transparent 50%,red 0);
  background-size:20% 60%,80% 60%;
  background-position:
    left bottom,right bottom;
  background-repeat:no-repeat;
  
 
}
<div class="tri-1"></div>

Pero ¿y si queremos definir un valor para cada lado? Simplemente necesitamos hacer el cálculo de nuevo!

Definamos hg1 y hg2 como la altura de nuestro gradiente (ambos son iguales a la línea roja), luego wg1 y wg2 como el ancho de nuestro gradiente ( wg1 + wg2 = a ). No voy a detallar el cálculo pero al final tendremos:

wg2 = (a²+c²-b²)/(2a)
wg1 = a - wg2
hg1 = hg2 = sqrt(b² - wg1²) = sqrt(c² - wg2²)

Ahora que hemos llegado al límite de CSS, incluso con calc() no podremos implementar esto, por lo que simplemente necesitamos recopilar el resultado final manualmente y usarlo como tamaño fijo:

.tri {
  --wg1: 20px; 
  --wg2: 60px;
  --hg:30px; 
  width:calc(var(--wg1) + var(--wg2));
  height:100px;
  display:inline-block;
  background-image:
  linear-gradient(to bottom right, transparent 50%,red 0),
  linear-gradient(to bottom left, transparent 50%,red 0);

  background-size:var(--wg1) var(--hg),var(--wg2) var(--hg);
  background-position:
    left bottom,right bottom;
  background-repeat:no-repeat;
  
}
<div class="tri" ></div>

<div class="tri" style="--wg1:80px;--wg2:60px;--hg:100px;" ></div>

Prima

No debemos olvidar que también podemos aplicar rotación y / o sesgo y tenemos más opciones para obtener más triángulos:

.tri {
  --wg1: 20px; 
  --wg2: 60px;
  --hg:30px; 
  width:calc(var(--wg1) + var(--wg2));
  height:100px;
  display:inline-block;
  background-image:
  linear-gradient(to bottom right, transparent 50%,red 0),
  linear-gradient(to bottom left, transparent 50%,red 0);

  background-size:var(--wg1) var(--hg),var(--wg2) var(--hg);
  background-position:
    left bottom,right bottom;
  background-repeat:no-repeat;
  
}
<div class="tri" ></div>

<div class="tri" style="transform:skewY(25deg)"></div>

<div class="tri" style="--wg1:80px;--wg2:60px;--hg:100px;" ></div>


<div class="tri" style="--wg1:80px;--wg2:60px;--hg:100px;transform:rotate(20deg)" ></div>

Y, por supuesto, debemos tener en cuenta la solución SVG que puede ser más adecuada en algunas situaciones:

svg {
 width:100px;
 height:100px;
}

polygon {
  fill:red;
}
<svg viewBox="0 0 100 100"><polygon points="0,100 0,0 100,100" /></svg>
<svg viewBox="0 0 100 100"><polygon points="0,100 50,0 100,100" /></svg>
<svg viewBox="0 0 100 100"><polygon points="0,100 50,23 100,100" /></svg>
<svg viewBox="0 0 100 100"><polygon points="20,60 50,43 80,100" /></svg>


Puede ser irrelevante, tal vez no, pero hace algún tiempo, creé una función jQuery que hace lo mismo, pero horizontalmente.

Lo llamé "Strippex" para 'banda' + 'texto', demo: http://cdpn.io/FcIBg

No estoy diciendo que esta sea la solución de ningún problema, pero ya intenté aplicar css a la mitad de un personaje, pero horizontalmente, entonces la idea es la misma, la realización puede ser horrible, pero funciona.

Ah, y lo más importante, ¡me divertí mucho al crearlo!





css css3 geometry polygon css-shapes