Triángulo CSS responsivo con ancho de porcentaje


El siguiente código creará una flecha justo debajo de un elemento <a>:

JSFiddle

.btn {
    position: relative;
    display: inline-block;
    width: 100px;
    height: 50px;
    text-align: center;
    color: white;
    background: gray;
    line-height: 50px;
    text-decoration: none;
}
.btn:after {
    content: "";
    position: absolute;
    bottom: -10px;
    left: 0;
    width: 0;
    height: 0;
    border-width: 10px 50px 0 50px;
    border-style: solid;
    border-color: gray transparent transparent transparent;   
}
<a href="#" class="btn">Hello!</a>

El problema es que tenemos que indicar el ancho del enlace para obtener una flecha de un tamaño adecuado porque no podemos indicar el ancho del borde en píxeles.

¿Cómo hacer un porcentaje de triángulo responsivo basado?

Author: Gleb Kemarsky, 2014-08-18

6 answers

Puedes usar un pseudo elemento sesgado y rotado para crear un triángulo responsivo bajo el enlace:

DEMO (cambiar el tamaño de la ventana de resultados para ver cómo reacciona)

El triángulo mantiene su relación de aspecto con la propiedad padding-bottom.

Si desea que la forma adapte su tamaño de acuerdo con su contenido, puede eliminar el ancho en la clase .btn

.btn {
  position: relative;
  display: inline-block;
  height: 50px; width: 50%;
  text-align: center;
  color: white;
  background: gray;
  line-height: 50px;
  text-decoration: none;
  padding-bottom: 15%;
  background-clip: content-box;
  overflow: hidden;
}
.btn:after {
  content: "";
  position: absolute;
  top:50px;  left: 0;
  background-color: inherit;
  padding-bottom: 50%;
  width: 57.7%;
  z-index: -1;
  transform-origin: 0 0;
  transform: rotate(-30deg) skewX(30deg);
}
/** FOR THE DEMO **/

body {
  background: url('http://i.imgur.com/qi5FGET.jpg');
  background-size: cover;
}
<a href="#" class="btn">Hello!</a>

Para obtener más información sobre triángulos sensibles y cómo hacer ellos, usted puede echar un vistazo a Triángulos con transformar girar (triángulos simples y elegantes)

 44
Author: web-tiki,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-05 09:37:00

Otra solución a esto sería usar una ruta de clip CSS para recortar un triángulo de un bloque de color. Sin embargo, no es compatible con IE, pero podría usarse para herramientas internas, etc.

DEMO

Escrito con SCSS para mayor facilidad.

.outer {
  background: orange;
  width: 25%;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  padding: 1em;

  p {
    margin: 0;
    text-align: center;
    color: #fff;
  }

  &:after {
    content: '';
    position: absolute;
    top: 100%;
    left: 0; 
    right: 0;
    padding-bottom: 10%;
    background: orange;
    -webkit-clip-path: polygon(0% 0%, 100% 0%, 50% 100%);
    clip-path: polygon(0% 0%, 100% 0%, 50% 100%);
  }

}
 6
Author: Probocop,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-18 11:01:12

Encontré una solución que funciona con cualquier ancho/alto. Puedes usar dos pseudo-elementos con linear-gradient fondo, así, (violín):

.btn {
    position: relative;
    display: inline-block;
    width: 100px;
    height: 50px;
    text-align: center;
    color: white;
    background: gray;
    line-height: 50px;
    text-decoration: none;
}
.btn:before {
    content: "";
    position: absolute;
    top: 100%;
    right: 0;
    width: 50%;
    height: 10px;
    background: linear-gradient(to right bottom, gray 50%, transparent 50%)
}

.btn:after {
    content: "";
    position: absolute;
    top: 100%;
    left: 0;
    width: 50%;
    height: 10px;
    background: linear-gradient(to left bottom, gray 50%, transparent 50%)
}
 5
Author: Alexandr Subbotin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-08-10 08:05:25

Una versión modificada del siguiente código puede ayudarlo a lograr esto

HTML

<div class="triangle-down"></div>

CSS

.triangle-down {
    width: 10%;
    height: 0;
    padding-left:10%;
    padding-top: 10%;
    overflow: hidden;
}
.triangle-down:after {
    content: "";
    display: block;
    width: 0;
    height: 0;
    margin-left:-500px;
    margin-top:-500px;

    border-left: 500px solid transparent;
    border-right: 500px solid transparent;
    border-top: 500px solid #4679BD;
}

Para leer más sobre los triángulos responsivos: Triángulos CSS Responsivos

 4
Author: lessismore,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-02-12 22:13:00

Probé las otras respuestas y encontré que eran demasiado complejas y/o difíciles de manejar para manipular la forma del triángulo. En su lugar, decidí crear una forma de triángulo simple como svg.

La altura del triángulo se puede establecer en un valor absoluto, o como un porcentaje del rectángulo para que pueda responder en ambas direcciones si es necesario.

html, body{
  height:100%;
  width:100%;
}
.outer{
  width:20%;
  height:25%;
  background:red;
  position:relative;
  
}
.inner{
  height:100%;
  width:100%;
  background-color:red;
}
.triangle-down{
  height:25%;
  width:100%;
  position:relative;
}
.triangle-down svg{
  height:100%;
  width:100%;
  position:absolute;
  top:0;
}
svg .triangle-path{
  fill:red;
}
<div class="outer">
<div class="inner"></div>
  <div class="triangle-down">
<svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="none" viewBox="0 0 2 1">
 <g>
  <path class="triangle-path" d="M0,0 l2,0 l-1,1 z" />
 </g>
</svg>
</div>

Probado FF, Chrome, IE, Edge, mob Safari y mob Chrome

 2
Author: Will Jenkins,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-17 09:57:17

Tomé la respuesta de @Probocop y se me ocurrió lo siguiente:

<style>
    .btn {
        background-color: orange;
        color: white;
        margin-bottom: 50px;
        padding: 15px;
        position: relative;
        text-align: center;
        text-decoration: none;
    }

    .btn:after {
        background-color: inherit;
        clip-path: url('data:image/svg+xml;utf8,%3Csvg xmlns="http://www.w3.org/2000/svg"%3E%3Cdefs%3E%3CclipPath id="p" clipPathUnits="objectBoundingBox"%3E%3Cpolygon points="0 0, 1 0, 0.5 1" /%3E%3C/clipPath%3E%3C/defs%3E%3C/svg%3E#p'); /* fix for firefox (tested in version 52) */
        clip-path: polygon(0% 0%, 100% 0%, 50% 100%);
        content: '';
        height: 50px;
        left: 0;
        position: absolute;
        right: 0;
        top: 100%;
    }
</style>

<a href="#" class="btn">Hello!</a>

Esto funciona en Chrome y he añadido una solución para Firefox. No funciona en el borde, sin embargo, si disminuye la altura de la flecha hacia abajo, entonces no se ve tan mal.

Tenga en cuenta que si está utilizando bootstrap tendrá que cambiar el nombre o anular algunos de los estilos que aplica. Si decide cambiarle el nombre, también debe agregar lo siguiente a la .estilo btn:

box-sizing: content-box;
 0
Author: nfplee,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-30 09:26:04