Как сделать причудливую стрелку с помощью CSS?

102

Итак, все знают, что можно сделать треугольник, используя это:

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

И это дает сплошной закрашенный треугольник. Но как сделать такой треугольник в виде полой стрелки?

стрелка только с двумя линиями, которые пересекаются в точке.  Как знак больше:>

Томмей
источник
3
Два повернутых прямоугольника.
SLaks
5
Используете очень крупный шрифт?
GolezTrol
2
AAAAAHHHH. j08691 понял. Спасибо!
Tommay
4
Проверьте @ j08691 Право на деньги. Другой способ добиться этого - использовать пакет шрифтов, например Awesome Fonts fortawesome.github.io/Font-Awesome/icon/chevron-right
crazymatt

Ответы:

93

Вы можете использовать псевдоэлемент beforeили afterи применить к нему некоторый CSS. Есть разные способы. Вы можете добавить beforeи after, и повернуть и расположить каждый из них, чтобы сформировать одну из полос. Более простое решение - добавить две границы только к beforeэлементу и повернуть его с помощью transform: rotate.

Прокрутите вниз до другого решения, в котором вместо псевдоэлементов используется реальный элемент.

В этом случае я добавил стрелки как маркеры в список и использовал emразмеры, чтобы они соответствовали шрифту списка.

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>

Конечно, вам не нужно использовать beforeили after, вы можете применить тот же трюк и к обычному элементу. Для приведенного выше списка это удобно, так как дополнительная разметка не требуется. Но иногда вам может понадобиться (или понадобится) разметка. Вы можете использовать divили spanдля этого, и я даже видел, как люди даже использовали этот iэлемент для «значков». Таким образом, разметка может выглядеть так, как показано ниже. Вопрос <i>о том, правильно ли это использовать, является спорным, но вы можете использовать и span для этого, чтобы быть в безопасности.

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

Если вы ищете больше вдохновения, обязательно ознакомьтесь с этой замечательной библиотекой иконок на чистом CSS от Николаса Галлахера . :)

ГолезТрол
источник
Это сработало довольно хорошо, но есть пара вещей, которые нужно изменить. 1. Как мне слегка переместить стрелку вниз, не перемещая вместе с ней остальной текст? Я попробовал #arrow :: after, а затем установил margin-top, но это сдвинуло все вниз, включая текст. 2. Мне нужно, чтобы он менял цвет при наведении курсора. Прямо сейчас меняет цвет только текст. Как изменить текст и стрелку?
Tommay
Чтобы изменить цвет стрелки, вам нужно будет изменить border-color, так как стрелка на самом деле не символ, а граница. Для позиционирования вы можете добавить position: relativeстрелку и перемещать ее с помощью topи left. Я показал как в измененном первом фрагменте, так и позиционирование во втором фрагменте. Обратите внимание на красивую комбинацию, li:hover::beforeкоторая относится к beforeпсевдоэлементу элемента списка при наведении курсора.
GolezTrol
Собственно, еще кое-что: сейчас я пытаюсь центрировать этот текст (с элементом after). Проблема в том, что этот элемент after, по-видимому, занимает много невидимого места, и в результате текст выглядит очень смещенным по центру. Как мне установить это невидимое пространство на 0? Я пробовал left: 0 и right: 0, а также margin-left: 0 и margin-right: 0, ни один из них не работал.
Tommay
Я не совсем уверен, что вы имеете в виду, но у псевдоэлемента уже есть маржа 0сам по себе, поэтому вам понадобится отрицательная маржа, чтобы отменить любые пробелы. Например, во втором фрагменте вы можете добавить margin-left: -0.4em;стрелку рядом с предыдущим словом без пробела.
GolezTrol
Я разместил новый вопрос на stackoverflow.com/questions/27549099/…
Tommay
71

Это можно решить намного проще, чем другие предложения.

Просто нарисуйте квадрат и примените borderсвойство только к 2 соединяющимся сторонам.

Затем поверните квадрат в соответствии с направлением, в котором должна указывать стрелка, например: 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
Это идеальный ответ, он действительно должен быть принятым. Очень просто и не менее эффективно.
Эндрю Фолкнер
@AndrewFaulkner Рад, что это помогло.
Алан Даннинг,
38

Отзывчивые шевроны / стрелки

они автоматически изменяют размер вместе с вашим текстом и окрашиваются в один цвет. Plug and play :)
демонстрационная площадка jsBin

введите описание изображения здесь

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
Вау, этот символ на самом деле называется «Правый верхний угол» ! Ницца. :) Меньше контроля над шириной, чем с рамкой, но все же +1 за возможность отображения шрифтов. Для других символов это может быть лучше, чем трюк с формой CSS.
GolezTrol
Обратите внимание, что значки шрифтов не будут работать, если у пользователя нет шрифта, поэтому вы должны убедиться, что у вас есть соответствующие резервные копии шрифтов, которые доступны для большинства систем. Вы также можете выбрать загрузку шрифта через CSS, но это пустая трата пропускной способности для пары значков. Однако если у вас много значков или вы хотите, чтобы они были в вашем собственном стиле, вы можете добавить их все в свой собственный шрифт значков и загрузить его через CSS. Таким образом, вы (почти) уверены, что у вас есть правильный шрифт, без необходимости загружать огромные шрифты для нескольких символов.
GolezTrol
Еще в HTML 4.0 был принят общий набор из 38887 символов. поскольку набор символов v. 6.2.0 September 2012 1Unicode UTF-8увеличивается до 110182, и теперь с HTML5 и UTF-8 по умолчанию и выглядит наш персонаж хорошо выглядит: unicode.org/Public/UNIDATA/UnicodeData.txt
Роко С. Бульян
Тот факт, что персонаж существует, не означает, что он может быть отображен. Для его отображения вам понадобится подходящий шрифт. Вот почему символы в первой версии вашего ответа не удались: потому что шрифт по умолчанию в моем браузере не включал эти символы. Итак, чтобы использовать такой символ, вам нужно будет указать, какие шрифты использовать, и вы должны предоставить соответствующие резервные варианты для других шрифтов, если они доступны не на всех платформах. Например, \231dперсонаж может быть доступен здесь, но не на Mac или устройстве Android. HTML-версия и кодировка ответа тут не при чем.
GolezTrol
Можно сделать тоньше? Вместо того, чтобы быть таким толстым? Изменение веса шрифта ничего не дает.
James111
14

Вот другой подход:

1) Используйте символ умножения: &times;×

2) Спрячьте половину overflow:hidden

3) Затем добавьте треугольник в качестве псевдоэлемента для наконечника.

Преимущество здесь в том, что никаких преобразований не требуется. (Будет работать в 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
Работает в Internet Explorer, Chrome и Firefox.
Thomas
11

Просто используйте до и после псевдоэлементов - 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
источник
8

Другой подход с использованием границ и без свойств 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

>сама по себе очень замечательная стрелка! Просто добавьте к нему div и стилизуйте его.

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

никель
источник
2
Это символ «больше», а не стрелка.
Марк Кнол
@MarkKnol Чем это отличается от того, как выглядит стрелка у всех остальных? Мне это кажется лучшим решением.
dallin
2

Стрелка влево-вправо с эффектом наведения с помощью трюка с тенями Роко К. Бульяна

.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
источник
1

Мне нужно было изменить inputв моем проекте стрелку. Ниже финальная работа.

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

Здесь скрипка

Мостафа
источник
Отличный код! Он использует только один элемент, что сложно сделать :)
www139 05
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>

Подобно Roko C, но немного больше контроля над размером и размещением.

боб
источник