¿Cómo hacer una elegante flecha usando CSS?

102

Ok, entonces todos saben que puedes hacer un triángulo usando esto:

#triangle {
    width: 0;
    height: 0;
    border-left: 50px solid transparent;
    border-right: 50px solid transparent;
    border-bottom: 100px solid red;
}

Y eso produce un triángulo relleno sólido. Pero, ¿cómo harías un triángulo con forma de flecha de tipo hueco, como este?

una flecha con solo dos líneas que se cruzan en el punto.  Como un signo mayor que:>

Tommay
fuente
3
Dos rectángulos rotados.
SLaks
5
¿Utiliza una fuente muy grande?
GolezTrol
2
AAAAAHHHH. j08691 lo tiene. ¡Gracias!
Tommay
4
Compruebe @ j08691 Fiddle su derecho sobre el dinero. Otra forma de lograr esto es usar un paquete de fuentes como Awesome Fonts fortawesome.github.io/Font-Awesome/icon/chevron-right
crazymatt

Respuestas:

93

Se puede utilizar el beforeo afterpseudo-elemento y aplicar un poco de CSS a la misma. Hay varias formas. Puede agregar ambos beforey after, y rotar y colocar cada uno de ellos para formar una de las barras. Una solución más sencilla es agregar dos bordes solo al beforeelemento y rotarlo usando transform: rotate.

Desplácese hacia abajo para obtener una solución diferente que use un elemento real en lugar de los elementos pseuso

En este caso, agregué las flechas como viñetas en una lista y usé emtamaños para que se ajusten correctamente a la fuente de la lista.

ul {
    list-style: none;
}

ul.big {
    list-style: none;
    font-size: 300%
}

li::before {
    position: relative;
    /* top: 3pt; Uncomment this to lower the icons as requested in comments*/
    content: "";
    display: inline-block;
    /* By using an em scale, the arrows will size with the font */
    width: 0.4em;
    height: 0.4em;
    border-right: 0.2em solid black;
    border-top: 0.2em solid black;
    transform: rotate(45deg);
    margin-right: 0.5em;
}

/* Change color */
li:hover {
  color: red; /* For the text */
}
li:hover::before {
  border-color: red; /* For the arrow (which is a border) */
}
<ul>
    <li>Item1</li>
    <li>Item2</li>
    <li>Item3</li>
    <li>Item4</li>
</ul>

<ul class="big">
    <li>Item1</li>
    <li>Item2</li>
    <li>Item3</li>
    <li>Item4</li>
</ul>

Por supuesto, no es necesario usar beforeo after, también puede aplicar el mismo truco a un elemento normal. Para la lista anterior es conveniente, porque no necesita marcado adicional. Pero a veces es posible que desee (o necesite) el marcado de todos modos. Puedes usar un divo spanpara eso, e incluso he visto a personas reciclar el ielemento para 'íconos'. De modo que ese marcado podría verse a continuación. <i>Es discutible si usarlo para esto es correcto, pero también puede usar span para esto para estar seguro.

/* Default icon formatting */
i {
  display: inline-block;
  font-style: normal;
  position: relative;
}

/* Additional formatting for arrow icon */
i.arrow {
    /* top: 2pt; Uncomment this to lower the icons as requested in comments*/
    width: 0.4em;
    height: 0.4em;
    border-right: 0.2em solid black;
    border-top: 0.2em solid black;
    transform: rotate(45deg);
}
And so you can have an <i class="arrow" title="arrow icon"></i> in your text.
This arrow is <i class="arrow" title="arrow icon"></i> used to be deliberately lowered slightly on request.
I removed that for the general public <i class="arrow" title="arrow icon"></i> but you can uncomment the line with 'top' <i class="arrow" title="arrow icon"></i> to restore that effect.

Si busca más inspiración, asegúrese de consultar esta increíble biblioteca de íconos CSS puros de Nicolas Gallagher . :)

GolezTrol
fuente
Esto funcionó bastante bien, pero hay un par de cosas que necesitan modificaciones. 1. ¿Cómo movería la flecha ligeramente hacia abajo sin mover el resto del texto hacia abajo con ella? Intenté #arrow :: after y luego establecí un margin-top, pero eso movió todo hacia abajo, incluido el texto. 2. Necesito que cambie de color al pasar el mouse. En este momento, solo el texto cambia de color. ¿Cómo puedo cambiar tanto el texto como la flecha?
Tommay
Para cambiar el color de la flecha, deberá cambiar el border-color, ya que la flecha no es en realidad un carácter sino un borde. Para el posicionamiento, puede agregar position: relativea la flecha y moverla usando topy left. He mostrado tanto en el primer fragmento modificado como el posicionamiento también en el segundo fragmento. Tenga en cuenta la bonita combinación li:hover::beforeque se refiere al beforepseudoelemento de un elemento de lista flotante.
GolezTrol
En realidad, una cosa más: estoy tratando de centrar este texto ahora (con el elemento after). El problema es que este elemento posterior aparentemente ocupa mucho espacio invisible y, como resultado, el texto parece estar muy descentrado. ¿Cómo establecería ese espacio invisible en 0? Intenté left: 0 y right: 0, junto con margin-left: 0 y margin-right: 0, ninguno funcionó.
Tommay
No estoy exactamente seguro de lo que quiere decir, pero el pseudo-elemento ya tiene un margen de 0por sí mismo, por lo que necesitaría un margen negativo para cancelar cualquier espacio en blanco. Por ejemplo, en el segundo fragmento, puede agregar margin-left: -0.4em;para colocar la flecha junto a la palabra anterior sin ningún espacio.
GolezTrol
Publiqué
71

Esto se puede resolver mucho más fácilmente que las otras sugerencias.

Simplemente dibuje un cuadrado y aplique una borderpropiedad a solo 2 lados de unión.

Luego, gire el cuadrado de acuerdo con la dirección en la que desea que apunte la flecha, por ejemplo: transform: rotate(<your degree here>)

.triangle {
    border-right: 10px solid; 
    border-bottom: 10px solid;
    height: 30px;
    width: 30px;
    transform: rotate(-45deg);
}
<div class="triangle"></div>

Alan Dunning
fuente
1
Esta es la respuesta perfecta, realmente debe ser la aceptada. Muy simple e igualmente efectivo.
Andrew Faulkner
@AndrewFaulkner Me alegro de haber ayudado.
Alan Dunning
38

Chevrones / flechas sensibles

que cambian de tamaño automáticamente con el texto y son de color del mismo color. Plug and play :)
juegos de demostración jsBin

ingrese la descripción de la imagen aquí

body{
  font-size: 25px; /* Change font and  see the magic! */
  color: #f07;     /* Change color and see the magic! */
} 

/* RESPONSIVE ARROWS */
[class^=arr-]{
  border:       solid currentColor;
  border-width: 0 .2em .2em 0;
  display:      inline-block;
  padding:      .20em;
}
.arr-right {transform:rotate(-45deg);  -webkit-transform:rotate(-45deg);}
.arr-left  {transform:rotate(135deg);  -webkit-transform:rotate(135deg);}
.arr-up    {transform:rotate(-135deg); -webkit-transform:rotate(-135deg);}
.arr-down  {transform:rotate(45deg);   -webkit-transform:rotate(45deg);}
This is <i class="arr-right"></i> .arr-right<br>
This is <i class="arr-left"></i> .arr-left<br>
This is <i class="arr-up"></i> .arr-up<br>
This is <i class="arr-down"></i> .arr-down

Roko C. Buljan
fuente
1
¡Vaya, ese símbolo en realidad se llama "Esquina superior derecha" ! Agradable. :) Menos control sobre el ancho que con un borde, pero aún +1 para mostrar la posibilidad de fuentes. Para otros símbolos, esto podría ser mejor que un truco de forma CSS.
GolezTrol
Tenga en cuenta que los iconos de fuentes no funcionarán bien si el usuario no tiene la fuente, por lo que debe asegurarse de tener alternativas adecuadas a las fuentes que están disponibles para la mayoría de los sistemas. También puede optar por descargar la fuente a través de CSS, pero es una pérdida de ancho de banda hacer eso para un par de iconos. Sin embargo, si tiene muchos íconos o desea tenerlos en su propio estilo, puede optar por agregarlos todos a su propia fuente de íconos y cargarlos a través de CSS. De esa manera, está (casi) seguro de tener disponible la fuente correcta sin tener que descargar fuentes enormes para un puñado de símbolos.
GolezTrol
En HTML 4.0 se adoptó un conjunto total con 38887 caracteres. dado que el v. 6.2.0 September 2012 1conjunto de UTF-8caracteres Unicode se elevó a 110182, y ahora tenemos HTML5 y el UTF-8 predeterminado y se ve, nuestro personaje se ve bien: unicode.org/Public/UNIDATA/UnicodeData.txt
Roko C. Buljan
El hecho de que el personaje exista no significa que pueda mostrarse. Necesitará la fuente adecuada para mostrarlo. Esa es la razón por la que fallaron los caracteres en la primera versión de su respuesta: porque la fuente predeterminada de mi navegador no incluía esos caracteres. Entonces, para usar un carácter como este, necesitará especificar qué fuentes usar y debe proporcionar alternativas adecuadas a otras fuentes si no están disponibles en todas las plataformas. Por ejemplo, el \231dpersonaje podría estar disponible aquí, pero no en una Mac o un dispositivo Android. La versión HTML y la codificación de respuesta no tienen nada que ver con eso.
GolezTrol
¿Puedes hacerlo más delgado? ¿En lugar de ser tan gordo? Cambiar el peso de la fuente no hace nada.
James111
14

Aquí hay un enfoque diferente:

1) Utilice el carácter de multiplicación: &times;×

2) Esconde la mitad con overflow:hidden

3) Luego agregue un triángulo como un pseudo elemento para la punta.

La ventaja aquí es que no se necesitan transformaciones. (Funcionará en IE8 +)

VIOLÍN

.arrow {
  position: relative;
}
.arrow:before {
  content: '×';
  display: inline-block;
  position: absolute;
  font-size: 240px;
  font-weight: bold;
  font-family: verdana;
  width: 103px;
  height: 151px;
  overflow: hidden;
  line-height: 117px;
}
.arrow:after {
  content: '';
  display: inline-block;
  position: absolute;
  left: 101px;
  top: 51px;
  width: 0;
  height: 0;
  border-style: solid;
  border-width: 25px 0 25px 24px;
  border-color: transparent transparent transparent black;
}
<div class="arrow"></div>

Danield
fuente
2
Funciona en Internet Explorer, Chrome y Firefox.
Thomas
11

Solo use antes y después de los pseudo-elementos - CSS

*{box-sizing: border-box; padding: 0; margin: 0}
:root{background: white; transition: background .3s ease-in-out}
:root:hover{background: red }
div{
  margin: 20px auto;
  width: 150px;
  height: 150px;
  position:relative
}

div:before, div:after{
  content: '';
  position: absolute;
  width: 75px;
  height: 20px;
  background: black;
  left: 40px
}

div:before{
  top: 45px;
  transform: rotateZ(45deg)
}

div:after{
  bottom: 45px;
  transform: rotateZ(-45deg)
}
<div/>

Gildas.Tambo
fuente
8

Otro enfoque que usa bordes y no propiedades CSS3 :

div, div:after{
    border-width: 80px 0 80px 80px;
    border-color: transparent transparent transparent #000;
    border-style:solid;
    position:relative;
}
div:after{
    content:'';
    position:absolute;
    left:-115px; top:-80px;
    border-left-color:#fff;
}
<div></div>

web-tiki
fuente
4

>en sí es una flecha muy maravillosa! Simplemente anteponga un div y modifíquelo.

div{
  font-size:50px;
}
div::before{
  content:">";
  font: 50px 'Consolas';
  font-weight:900;
}
<div class="arrowed">Hatz!</div>

nicael
fuente
2
Ese es un símbolo "mayor que", no una flecha.
Mark Knol
@MarkKnol ¿Cuál es la diferencia entre esto y cómo se ve la flecha de todos los demás? Esta parece ser la mejor solución hasta ahora para mí.
dallin
2

Flecha izquierda derecha con efecto de desplazamiento con el truco de sombra de cuadro de Roko C. Buljan

.arr {
  display: inline-block;
  padding: 1.2em;
  box-shadow: 8px 8px 0 2px #777 inset;
}
.arr.left {
  transform: rotate(-45deg);
}
.arr.right {
  transform: rotate(135deg);
}
.arr:hover {
  box-shadow: 8px 8px 0 2px #000 inset
}
<div class="arr left"></div>
<div class="arr right"></div>

vinayakj
fuente
1

Necesitaba cambiar inputuna flecha por una en mi proyecto. A continuación se muestra el trabajo final.

#in_submit {
  background-color: white;
  border-left: #B4C8E9;
  border-top: #B4C8E9;
  border-right: 3px solid black;
  border-bottom: 3px solid black;
  width: 15px;
  height: 15px;
  transform: rotate(-45deg);
  margin-top: 4px;
  margin-left: 4px;
  position: absolute;
  cursor: pointer;
}
<input id="in_submit" type="button" class="convert_btn">

Aquí violín

Mostafa
fuente
¡Código impresionante! Solo usa un elemento que es difícil de hacer :)
www139
0

.arrow {
  display : inline-block;
  font-size: 10px; /* adjust size */
  line-height: 1em; /* adjust vertical positioning */
  border: 3px solid #000000;
  border-left: transparent;
  border-bottom: transparent;
  width: 1em; /* use font-size to change overall size */
  height: 1em; /* use font-size to change overall size */
}

.arrow:before {
  content: "\00a0"; /* needed to hook line-height to "something" */
}

.arrow.left {
  margin-left: 0.5em;
  -webkit-transform: rotate(225deg);
  -moz-transform: rotate(225deg);
  -o-transform: rotate(225deg);
  -ms-transform: rotate(225deg);
  transform: rotate(225deg);
}

.arrow.right {
  margin-right: 0.5em;
  -webkit-transform: rotate(45deg);
  -moz-transform: rotate(45deg);
  -o-transform: rotate(45deg);
  -ms-transform: rotate(45deg);
  transform: rotate(45deg);
}

.arrow.top {
  line-height: 0.5em; /* use this to adjust vertical positioning */
  margin-left: 0.5em;
  margin-right: 0.5em;
  -webkit-transform: rotate(-45deg);
  -moz-transform: rotate(-45deg);
  -o-transform: rotate(-45deg);
  -ms-transform: rotate(-45deg);
  transform: rotate(-45deg);
}

.arrow.bottom {
  line-height: 2em;
  /* use this to adjust vertical positioning */
  margin-left: 0.5em;
  margin-right: 0.5em;
  -webkit-transform: rotate(135deg);
  -moz-transform: rotate(135deg);
  -o-transform: rotate(135deg);
  -ms-transform: rotate(135deg);
  transform: rotate(135deg);
}
<div>
  here are some arrows
  <div class='arrow left'></div> space
  <div class='arrow right'></div> space
  <div class='arrow top'></div> space
  <div class='arrow bottom'></div> space with proper spacing?
</div>

Similar a Roko C, pero un poco más de control sobre el tamaño y la ubicación.

Beto
fuente