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

Tommay
fonte
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 . :)

GolezTrol
fonte
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>

Alan Dunning
fonte
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

Roko C. Buljan
fonte
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>

Danield
fonte
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/>

Gildas.Tambo
fonte
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>

web-tiki
fonte
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>

nicael
fonte
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>

vinayakj
fonte
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

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

prumo
fonte