¿Cómo funcionan los triángulos CSS?



Answers

Los bordes usan un borde en ángulo donde se cruzan (ángulo de 45 ° con bordes de ancho igual, pero cambiar el ancho de los bordes puede sesgar el ángulo).

jsFiddle .

Al ocultar ciertos bordes, puede obtener el efecto de triángulo (como puede ver arriba haciendo diferentes porciones de diferentes colores). transparent se utiliza a menudo como un color de borde para lograr la forma de triángulo.

Question

Hay muchas formas de CSS diferentes en CSS Tricks - Formas de CSS y estoy particularmente desconcertado 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?




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/




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 alrededor

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. Entonces un hombre común puede entender. Div tiene dimensiones de 150 x 150 píxeles con el borde de 50 píxeles. La imagen está 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 está 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.

Por lo tanto, obtuvimos el triángulo que necesitábamos.




Casi todas las respuestas se enfocan en el triángulo construido usando el borde así que voy a elaborar el método del gradiente lineal (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 tamaño para obtener el triángulo que queremos y esto no responderá:

.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, debemos considerar valores de dirección predefinidos, como to bottom , to top , etc. En este caso, podemos obtener cualquier tipo de forma de triángulo mientras lo mantenemos receptivo.

1) rectángulo triá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 50%,red 0);
  border:1px solid;
  animation:change 2s linear infinite alternate;
}
.tri-2 {
  background:linear-gradient(to top right, transparent 50%,red 0);
  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 este, necesitaremos 2 gradientes lineales como el anterior y cada uno tendrá la mitad del ancho (o la altura). Es como si creáramos una imagen espejo del primer triángulo.

.tri {
  display:inline-block;
  width:100px;
  height:100px;
  background-image:
  linear-gradient(to bottom right, transparent 50%,red 0),
  linear-gradient(to bottom left, transparent 50%,red 0);
  background-size:50.9% 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 complicado 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 el cálculo más complejo para transformar el triángulo isósceles en uno equilátero.

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

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

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

Entonces debemos confiar en cacl() para hacer 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 50%,red 0),
  linear-gradient(to bottom left, transparent 50%,red 0);
  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>

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 tenemos que hacer cálculos 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 hemos llegado al límite de CSS, ya que incluso con calc() no podremos implementar esto, así que simplemente necesitamos recopilar el resultado final de forma manual 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 inclinación y tenemos más opciones para obtener más triángulo:

.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 alguna situación:

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>




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

caso de uso ejemplo:

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

Página de juegos

Nota IMPORTANTE:
si el triángulo parece estar pixelado en algunos navegadores, pruebe uno de los métodos que se describen here .




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




Enfoque diferente:

Triángulos CSS3 con transformación 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 isósceles en ángulo recto con un elemento.

  • Nota 1: para triángulos no isósceles y cosas elegantes, puedes ver el paso 4 .
  • Nota 2: en los siguientes fragmentos, los prefijos del vendedor no están incluidos. están incluidos en las demos 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 el width = 1.41 x height . Puede usar cualquier techinque ( consulte aquí ), incluido el uso de porcentajes y relleno de 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 de 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: defina un origen de transformación . El origen predeterminado está en el centro del pseudo elemento y lo necesitamos en la parte inferior izquierda. Al agregar 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: ocultarlo

Para ocultar las partes no deseadas del pseudo elemento (todo lo que desborda el div con el borde amarillo) solo tiene que configurar el 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. skewX() más delgados o más planos jugando con skewX() .
  2. Haga que apunten a la izquierda, a la derecha o en cualquier otra dirección jugando con la dirección de rotación y la dirección de transformación.
  3. Haga una reflexión con la propiedad de transformación 3D.
  4. Dale al triángulo los bordes
  5. Pon una imagen dentro del triángulo
  6. Mucho más ... ¡Libera los poderes de CSS3 !

¿Por qué usar esta técnica?

  1. Triangle puede responder fácilmente.
  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 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 superponer sus vecinos, por lo que cada triángulo tiene su propio estado de vuelo estacionario.
  4. Puede hacer algunos efectos extravagantes como reflejos .
  5. Le ayudará a comprender las propiedades de transformación en 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 utilizar esta técnica si planea soportar IE8. Ver CanIuse para más información. Para algunos efectos sofisticados, el uso de transformadas en 3D, como el soporte del navegador de reflejos , es IE10 + (ver canIuse para más información).
  2. No necesitas nada receptivo y un triángulo simple está bien para ti, entonces debes ir a la técnica de borde que se explica aquí: una mejor compatibilidad con el navegador y más fácil de entender gracias a las publicaciones sorprendentes aquí.



Considera el siguiente triángulo

.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 diagrama a continuación explica las dimensiones, tenga en cuenta que 15px se utilizó para el borde inferior y 10px se utilizó para izquierda y derecha.

También es muy fácil hacer un triángulo en ángulo recto al quitar el borde derecho.




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

Como normalmente usamos bordes de 1 o 2 píxeles, nunca notamos que los bordes forman ángulos de 45 ° entre sí con el mismo ancho y si el ancho cambia, el grado de ángulo también cambia, ejecuta el código CSS que creé 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 ningún ancho o alto, 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 los bordes izquierdo y derecho invisibles para hacer nuestro triángulo deseable de la siguiente manera:

.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 desea ejecutar el fragmento para ver los pasos, he creado una secuencia de imágenes para ver todos los pasos en una imagen:




Links