Jak zrobić fantazyjną strzałkę za pomocą CSS?

102

Ok, więc wszyscy wiedzą, że możesz utworzyć trójkąt, używając tego:

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

A to tworzy solidny, wypełniony trójkąt. Ale jak zrobić trójkąt w kształcie pustej strzałki, taki jak ten?

strzałka z tylko dwiema liniami, które przecinają się w punkcie.  Jak znak większe niż:>

Tommay
źródło
3
Dwa obrócone prostokąty.
SLaks
5
Używasz bardzo dużej czcionki?
GolezTrol
2
AAAAAHHHH. j08691 ma to. Dzięki!
Tommay,
4
Sprawdź @ j08691 Fiddle jego prawo do pieniędzy. Innym sposobem na osiągnięcie tego jest użycie pakietu czcionek, takiego jak Awesome Fonts fortawesome.github.io/Font-Awesome/icon/chevron-right
crazymatt

Odpowiedzi:

93

Możesz użyć pseudoelementu beforelub afteri zastosować do niego trochę CSS. Jest wiele sposobów. Możesz dodać oba beforei after, i obrócić i ustawić każdy z nich, aby utworzyć jeden z pasków. Łatwiejszym rozwiązaniem jest dodanie dwóch granic do samego beforeelementu i obrócenie go za pomocą transform: rotate.

Przewiń w dół, aby znaleźć inne rozwiązanie, które używa rzeczywistego elementu zamiast elementów pseuso

W tym przypadku dodałem strzałki jako punktory na liście i użyłem emrozmiarów, aby dopasować je do czcionki listy.

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>

Oczywiście nie musisz używać beforelub after, możesz zastosować tę samą sztuczkę również do zwykłego elementu. W przypadku powyższej listy jest to wygodne, ponieważ nie potrzebujesz dodatkowych znaczników. Ale czasami i tak możesz chcieć (lub potrzebować) znaczników. Możesz użyć do tego divlub span, a nawet widziałem, jak ludzie przetwarzają ten ielement na „ikony”. Więc ten znacznik mógłby wyglądać jak poniżej. To, czy użycie <i>do tego jest właściwe, jest dyskusyjne, ale możesz również użyć do tego zakresu, aby być po bezpiecznej stronie.

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

Jeśli szukasz więcej inspiracji, koniecznie sprawdź tę niesamowitą bibliotekę czystych ikon CSS autorstwa Nicolasa Gallaghera . :)

GolezTrol
źródło
To działało całkiem nieźle, ale jest kilka rzeczy, które wymagają modyfikacji. 1. Jak przesunąć strzałkę nieznacznie w dół, nie przesuwając razem z nią reszty tekstu? Wypróbowałem #arrow :: after, a następnie ustawiłem górny margines, ale to przesunęło wszystko w dół, łącznie z tekstem. 2. Potrzebuję zmiany koloru po najechaniu myszą. Obecnie tylko tekst zmienia kolor. Jak mogę zmienić zarówno tekst, jak i strzałkę?
Tommay,
Aby zmienić kolor strzałki, musisz zmienić border-color, ponieważ strzałka nie jest w rzeczywistości znakiem, ale ramką. Aby ustawić pozycję, możesz dodać position: relativestrzałkę i przesuwać ją za pomocą topi left. Pokazałem zarówno w zmodyfikowanym pierwszym fragmencie, jak i pozycjonowanie w drugim fragmencie. Zwróć uwagę na ładną kombinację, li:hover::beforektóra odnosi się do beforepseudoelementu elementu listy najechanej kursorem.
GolezTrol
Właściwie jeszcze jedno: próbuję teraz wyśrodkować ten tekst (z elementem po). Problem polega na tym, że ten element po elemencie najwyraźniej zajmuje dużo niewidocznej przestrzeni, w wyniku czego tekst wydaje się być skrajnie poza środkiem. Jak ustawić tę niewidzialną przestrzeń na 0? Próbowałem left: 0 i right: 0, razem z margin-left: 0 i margin-right: 0, żaden z nich nie działał.
Tommay,
Nie jestem do końca pewien, co masz na myśli, ale pseudoelement już sam ma margines 0, więc do usunięcia wszelkich białych znaków potrzebny byłby margines ujemny. Na przykład w drugim fragmencie możesz dodać, margin-left: -0.4em;aby umieścić strzałkę obok poprzedniego słowa bez spacji.
GolezTrol
Opublikowałem nowe pytanie na stackoverflow.com/questions/27549099/ ...
Tommay
71

Można to rozwiązać znacznie łatwiej niż inne sugestie.

Po prostu narysuj kwadrat i zastosuj borderwłaściwość tylko do dwóch łączących się stron.

Następnie obróć kwadrat zgodnie z kierunkiem, w którym ma wskazywać strzałka, na przykład: 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
źródło
1
To doskonała odpowiedź, naprawdę musi być akceptowana. Bardzo proste i równie skuteczne.
Andrew Faulkner,
@AndrewFaulkner Cieszę się, że pomogło.
Alan Dunning
38

Czułe szewrony / strzały

ich rozmiar automatycznie z tekstem i są barwione w tym samym kolorze. Podłącz i graj :)
jsBin Demo Playground

wprowadź opis obrazu tutaj

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
źródło
1
Wow, ten symbol faktycznie nazywa się „prawy górny róg” ! Miły. :) Mniejsza kontrola nad szerokością niż w przypadku obramowania, ale wciąż +1 za pokazywanie możliwości czcionek. W przypadku innych symboli może to być lepsze niż sztuczka w kształcie CSS.
GolezTrol
Zauważ, że ikony czcionek nie będą działać dobrze, jeśli użytkownik nie ma czcionki, więc musisz upewnić się, że masz odpowiednie rezerwy czcionek, które są dostępne w większości systemów. Równie dobrze możesz pobrać czcionkę przez CSS, ale marnowanie przepustowości w przypadku kilku ikon. Jeśli jednak masz wiele ikon lub chcesz mieć je w swoim własnym stylu, możesz zdecydować się na dodanie ich wszystkich do własnej czcionki ikony i załadowanie jej przez CSS. W ten sposób masz (prawie) pewność, że masz dostępną odpowiednią czcionkę bez konieczności pobierania ogromnych czcionek dla kilku symboli.
GolezTrol
W HTML 4.0 przyjęto cały zestaw zawierający 38887 znaków. ponieważ liczba znaków v. 6.2.0 September 2012 1Unicode UTF-8wzrosła do 110182, a teraz mając HTML5 i domyślny UTF-8 i wygląda dobrze, nasza postać wygląda dobrze: unicode.org/Public/UNIDATA/UnicodeData.txt
Roko C. Buljan
Fakt, że postać istnieje, nie oznacza, że ​​można ją wyświetlić. Będziesz potrzebować odpowiedniej czcionki, aby to pokazać. To jest powód, dla którego znaki w pierwszej wersji Twojej odpowiedzi zawiodły: ponieważ domyślna czcionka mojej przeglądarki nie zawierała tych znaków. Aby więc użyć takiego znaku, musisz określić, których czcionek użyć, i musisz zapewnić odpowiednie rezerwy dla innych czcionek, jeśli nie są one dostępne na wszystkich platformach. Na przykład \231dpostać może być dostępna tutaj, ale nie na komputerze Mac lub urządzeniu z Androidem. Wersja HTML i kodowanie odpowiedzi nie mają z tym nic wspólnego.
GolezTrol
Czy możesz sprawić, że będzie cieńszy? Zamiast być taki gruby? Zmiana grubości czcionki nic nie robi.
James111,
14

Oto inne podejście:

1) Użyj znaku mnożenia: &times;×

2) Ukryj połowę za pomocą overflow:hidden

3) Następnie dodaj trójkąt jako pseudoelement końcówki.

Zaletą jest to, że nie są potrzebne żadne przekształcenia. (Będzie działać w IE8 +)

SKRZYPCE

.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
źródło
2
Działa w przeglądarce Internet Explorer, Chrome i Firefox.
Thomas
11

Po prostu użyj pseudoelementów przed i po - 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
źródło
8

Inne podejście wykorzystujące obramowania i brak właściwości 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
źródło
4

>sama w sobie jest wspaniałą strzałą! Po prostu dodaj do niego element div i nadaj mu styl.

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

nicael
źródło
2
To symbol „większego niż”, a nie strzała.
Mark Knol
@MarkKnol Jaka jest różnica między tym a wyglądem strzały innych osób? Wydaje mi się, że to najlepsze rozwiązanie.
dallin
2

Strzałka w lewo w prawo z efektem zawisu przy użyciu sztuczki Roko C. Buljan box-shadow

.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
źródło
1

Musiałem zmienić inputstrzałkę w moim projekcie. Poniżej znajduje się praca końcowa.

#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">

Tutaj Fiddle

Mostafa
źródło
Świetny kod! Używa tylko jednego elementu, który jest trudny do zrobienia :)
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>

Podobny do Roko C, ale trochę większa kontrola nad rozmiarem i położeniem.

pion
źródło