Como fazer uma flecha extravagante usando CSS?


102

Ok, então todos sabem que você pode fazer um triângulo usando isto:

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

E isso produz um triângulo sólido preenchido. Mas como você faria um triângulo em forma de seta do tipo oco, como este?

uma seta com apenas duas linhas que se cruzam no ponto.  Como um sinal de maior que:>


3
Dois retângulos girados.
SLaks de


5
Usando uma fonte muito grande?
GolezTrol

2
AAAAAHHHH. j08691 conseguiu. Obrigado!
Tommay

4
Verifique @ j08691 Fiddle está certo sobre o dinheiro. Outra maneira de conseguir isso é usar um pacote de fontes como Awesome Fonts fortawesome.github.io/Font-Awesome/icon/chevron-right
crazymatt

Respostas:


93

Você pode usar o beforeou afterpseudo-elemento e aplique um pouco de CSS para ele. Existem várias maneiras. Você pode adicionar beforee after, e girar e posicionar cada um deles para formar uma das barras. Uma solução mais fácil é adicionar duas bordas apenas ao beforeelemento e girá-lo usando transform: rotate.

Role para baixo para uma solução diferente que usa um elemento real em vez dos elementos pseuso

Nesse caso, adicionei as setas como marcadores em uma lista e usei os emtamanhos para fazê-los dimensionar adequadamente com a fonte da 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>

Claro que você não precisa usar beforeou after, pode aplicar o mesmo truque a um elemento normal também. Para a lista acima, é conveniente, porque você não precisa de marcação adicional. Mas às vezes você pode querer (ou precisar) a marcação de qualquer maneira. Você pode usar um divou spanpara isso, e eu até vi pessoas reciclarem o ielemento para 'ícones'. Portanto, essa marcação pode ser semelhante a abaixo. Se usar <i>para isso está certo é discutível, mas você pode usar span para isso também por segurança.

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

Se você busca mais inspiração, não deixe de conferir esta incrível biblioteca de ícones CSS puros de Nicolas Gallagher . :)


Isso funcionou muito bem, mas há algumas coisas que precisam de modificação. 1. Como moveria a seta ligeiramente para baixo sem mover o resto do texto com ela? Tentei #arrow :: after e, em seguida, definir uma margem superior, mas isso moveu tudo para baixo, incluindo o texto. 2. Preciso mudar de cor ao passar o mouse. No momento, apenas o texto muda de cor. Como faço para que o texto e a seta sejam alterados?
Tommay

Para alterar a cor da seta, você precisará alterar o border-color, uma vez que a seta na verdade não é um caractere, mas uma borda. Para o posicionamento, você pode adicionar position: relativeà seta e movê-la usando tope left. Eu mostrei tanto no primeiro snippet modificado, quanto o posicionamento também no segundo snippet. Observe a bela combinação li:hover::beforeque se refere ao beforepseudoelemento de um item de lista suspenso.
GolezTrol

Na verdade, mais uma coisa: estou tentando centralizar este texto agora (com o elemento depois). O problema é que esse elemento posterior está aparentemente ocupando muito espaço invisível e, como resultado, o texto parece estar extremamente descentralizado. Como eu definiria esse espaço invisível para 0? Tentei left: 0 e right: 0, junto com margin-left: 0 e margin-right: 0, nenhum funcionou.
Tommay

Não tenho certeza do que você quer dizer, mas o pseudo-elemento já tem uma margem de 0si mesmo, então você precisaria de uma margem negativa para cancelar qualquer espaço em branco. Por exemplo, no segundo trecho, você pode adicionar margin-left: -0.4em;para colocar a seta ao lado da palavra anterior sem nenhum espaço.
GolezTrol

Eu postei uma nova pergunta em stackoverflow.com/questions/27549099/…
Tommay

71

Isso pode ser resolvido muito mais facilmente do que as outras sugestões.

Simplesmente desenhe um quadrado e aplique uma borderpropriedade a apenas 2 lados de união.

Em seguida, gire o quadrado de acordo com a direção que você deseja que a seta aponte, por exemplo: 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>


1
Esta é a resposta perfeita, realmente precisa ser aceita. Muito simples e tão eficaz.
Andrew Faulkner

@AndrewFaulkner Que bom que ajudou.
Alan Dunning

38

Chevrons / setas responsivos

eles são redimensionados automaticamente com o seu texto e são coloridos da mesma cor. Plug and play :)
playground de demonstração jsBin

insira a descrição da imagem aqui

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


1
Uau, esse símbolo é realmente chamado de "Canto superior direito" ! Agradável. :) Menos controle sobre a largura do que com uma borda, mas ainda +1 para mostrar a possibilidade de fontes. Para outros símbolos, isso pode ser melhor do que um truque de forma CSS.
GolezTrol

Observe que os ícones de fonte não funcionarão bem se o usuário não tiver a fonte, portanto, certifique-se de ter substitutos adequados para as fontes disponíveis para a maioria dos sistemas. Você também pode escolher baixar a fonte por meio de CSS, mas é um desperdício de largura de banda fazer isso com alguns ícones. Se você tem muitos ícones, ou deseja tê-los em seu próprio estilo, pode optar por adicionar todos eles à sua própria fonte de ícone e carregá-los por meio de CSS. Dessa forma, você tem (quase) certeza de ter a fonte certa disponível sem ter que baixar fontes enormes para um punhado de símbolos.
GolezTrol

Na HTML 4.0, um conjunto total foi adotado contendo 38887 caracteres. uma vez que os caracteres v. 6.2.0 September 2012 1Unicode UTF-8definidos aumentam para 110182, e agora tendo HTML5 e o UTF-8 padrão e a aparência, nosso personagem está com boa aparência: unicode.org/Public/UNIDATA/UnicodeData.txt
Roko C. Buljan

O fato de o personagem existir não significa que ele possa ser exibido. Você precisará da fonte adequada para mostrá-lo. Essa é a razão pela qual os caracteres da primeira versão da sua resposta falharam: porque a fonte padrão do meu navegador não incluía esses caracteres. Portanto, para usar um caractere como este, você precisará especificar quais fontes usar e fornecer fallbacks adequados para outras fontes, se elas não estiverem disponíveis em todas as plataformas. Por exemplo, o \231dpersonagem pode estar disponível aqui, mas não em um Mac ou dispositivo Android. A versão HTML e a codificação da resposta não têm nada a ver com isso.
GolezTrol

Você pode torná-lo mais fino? Em vez de ser tão gordo? Alterar a espessura da fonte não faz nada.
James111

14

Aqui está uma abordagem diferente:

1) Use o caractere de multiplicação: &times;×

2) Esconder a metade com overflow:hidden

3) Em seguida, adicione um triângulo como um pseudoelemento para a ponta.

A vantagem aqui é que nenhuma transformação é necessária. (Funcionará no IE8 +)

FIDDLE

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


2
Funciona no Internet Explorer, Chrome e Firefox.
Thomas

11

Use apenas antes e depois dos 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/>


8

Outra abordagem que usa bordas e nenhuma propriedade 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>


4

>em si é uma flecha muito maravilhosa! Basta acrescentar um div com ele e estilizá-lo.

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


2
Isso é um símbolo de "maior que", não uma seta.
Mark Knol

@MarkKnol Qual é a diferença entre isso e como a flecha de todos os outros se parece? Esta parece ser a melhor solução para mim.
dallin

2

Seta para a esquerda para a direita com efeito de foco usando o truque de sombra de caixa 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>


1

Eu precisava mudar um inputpara uma flecha no meu projeto. Abaixo está o trabalho 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">

Aqui Fiddle


Código incrível! Ele usa apenas um elemento, o que é difícil de fazer :)
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>

Semelhante ao Roko C, mas com um pouco mais de controle sobre o tamanho e o posicionamento.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.