Кнопка или ссылка?
Я знаю хабр не для жалоб,
но доколе
использовать ты будешь
— ссылки вместо кнопок<UserName />
‽
Автор иллюстрации <Marat Hilmanov>
gray-monkey@yandex.ru
Если коротко:
Используйте для кнопок — кнопки, а для ссылок — ссылки.
Для кнопок использовать
ссылки
— не комильфо.
Это не исчерпывающее руководство по кнопкам и не пример невероятного дизайна, а лишь попытка показать, что есть разница между ссылками и кнопками.
Для кого эта статья?
В первую очередь для дизайнера который делает макет сайта, но не дорисовывает детали свойственные вебу. Своеобразная попытка объяснить, что веб-сайт лежит за пределами плоской полиграфии.
Во вторых для верстальщика к которому пришёл макет без состояний, чтобы было куда дизайнера послать.
В третьих чтобы вместо очередной тирады о разнице в кнопках\ссылках и нужности дизайна состояний, просто давать ссылку.
Содержание
Ссылки
Введение
<a href="javascript:;">Ссылка которая кнопка</a>
Когда наводят указатель на ссылку которая кнопка то в левом нижнем углу появляется надпись javascript:;:
Или адрес с решёткой:
ПКМ
на такой кнопке и контекстное меню любезно предложит:
ctrl
+ ЛКМ
на такой кнопке откроют новую вкладку на которой будет ровно та страница, с которой она была открыта.
Кроме того такая ссылка с решёткой в качестве ссылки, станет :visited
, если ещё не стала до этого, и приобретёт соотстветствующее стилевое оформление. Если дизайнер его конечно не зарезал, что в большинстве случаев конечно зря, о чём ниже.
В JavaScript скриптах для таких кнопок дополнительно используется e.preventDefault()
, чтобы предотвратить действие кнопки по умолчанию (переход по ссылке) "— это костыль.
<a href="//link.url">Ссылка</a>
- Если клик приведёт к смене адреса,
- этот адрес можно скопировать,
- отправить по электронной почте,
- на него можно снова зайти,
- это не адрес самой страницы
— это ссылка.
У ссылки должны быть стили для обычного, :active
, :visited
, :focus
и :hover
состояний.
Антипаттерн
a {
color: black !important;
text-decoration: none !important;
cursor: default !important;
}
Поздравляю! С такими стилями все ваши ссылки визуально превратятся в обычный текст. Найти их на странице станет крайне затруднительно.
И помните, если вы ставите !important
и не очень понимаете почему вы без него не можете обойтись, то читайте это слово как импотент. Возможно вам нужно немного изменить селектор для того, чтобы перекрыть тот, который вам мешает.
Состояния
a
— обычное состояние
a {
color: #0645ad;
cursor: pointer;
text-decoration: none;
}
В обычном состоянии a
должна быть синей или подчёркнутой, а лучше и синей и подчёркнутой, чтобы пользователь без наведения мыши понимал, что это — ссылка. Пользователь привык к тому, что синие слова на странице это ссылки, даже если они не подчёркнуты. Если вам не нравится синий цвет для ссылок, меняйте его, но тогда ссылки подчёркивайте.
a:hover
— наведение
a:hover {
text-decoration: underline;
}
Когда курсор находится над ссылкой, она становится :hover
и в данном примере приобретает подчёркивание. Так пользователь поймёт, что это точно ссылка, на которую можно кликнуть.
a:focus
— фокус клавиатуры
a:focus {
text-decoration: underline;
}
Когда на ссылку устанавливается указатель, перемещаемый табулятором TAB ↹
она становится :focus
. В 2016 году это может показаться странным, но есть люди которые работают с сайтам посредством клавиатуры. У некоторых вовсе сломана мышь. В любом случае, занулять :focus
состояние — это преступление против таких людей.
Особые спецэфекты применять не обязательно, достаточно таких как у :focus
.
CSS чтобы не писать дважды:
a:focus, a:hover {
text-decoration: underline;
}
a:active
— клик
a:active {
color: #faa700;
}
Важное состояние :active
происходит когда пользователь уже кликнул на ссылку, но клавишу ещё не отпустил. Помогает пользователю понять, что его клик сработал, и ему не нужно кликать по ней несколько раз, чтобы точно перейти на нужную страницу.
a:visited
— ранее посещённая страница
a:visited {
color: #0b0080;
}
Можно все посмотреть‽
:visited
, поможет пользователю не забыть какие странички он уже открывал и не открывать их повторно. Так вместе с :active
и :hover
мы чуточку разгрузим интернет от случайных загрузок, и сделаем его чуть лучше и быстре.
В эпохуHTML4
вместо кнопок использовались ссылки подчёрнутые пунктирной линией. Этот паттерн устарел.
Подчёркивание пунктирной линией рекомендуется для тултипов при наведении.
Например у<abbr>
такое выделение поможет понять, что можно навести указатель и получить расшифровку.
Пример нестандартного оформления ссылок:
Слова в ссылке должны подчиняться правилам русского языка, капс непозволителен (исключение — аббревиатуры)
HTML5 <button>Кнопка</button>
- Если клик не меняет адрес страницы,
- адрес нельзя скопировать
- и нельзя этим адресом поделиться — это кнопка.
В кнопке позволителен капс, при условии, что вы не используете аббревиатуры. Особенно в неочевидных местах.
Если у вас встречаются аббревиатуры, то верхний регистр в кнопке не желателен, выделяйте их другим способом. Не искушайте пользователей тапать по тому, что не тапается. У пользователей тачскрина нет возможности подсмотреть:hover
или:focus
состояние. Ну или есть, но происходит это всё не очень удобно, обычно уже после свершившегося тапа.
Доступность
<button />
может быть недоступен на архаичных браузерах или устройствах. У кнопок не применятся стили без специальных JavaScript скриптов.
Но вас это не должно беспокоить. На таких устройствах часто и JavaScript не работает. И быть может CSS.
Вообще если следовать идеологии что всё, что должно обрабатываться JavaScript'ом, должно добавляться JavaScript'ом, такой проблемы вовсе не возникнет.
Что JSΩ, то JSॐ! Как говорится.
Поведение внутри формы
<button>
по умолчанию имеет атрибут type=submit
даже если его не прописать.
Ещё этот атрибут может принимать значения reset
для сброса заполнения в форме
и button
чтобы исключить влияние на форму. Правила хорошего тона предполагают,
что везде нужно писать <button type="button">Кнопка</button>
.
Но на деле можно ограничится полной записью только внутри <form></form>
,
type=submit
в остальных местах ни на, что не влияет.
Это кстати отличный сбособ для стилизации кнопки отправки формы.
В отличии от<input type="submit" value="Кнопка" />
, в содержимое
button
можно писать любой HTML код, а не только текст.
Например
<button> <img src="/images/icon.svg" title="Красная таблетка" alt="Иконка" /> <span style="color: red;">Красный</span> <span style="color: blue;">Синий</span> </button>
Это даёт даже больше свободы в стилевом оформлении чем<input type="image" />
Состояния
Похожи на состояния у ссылок за исключением того, что у кнопок нет состояния :visited
, зато есть состояние :disabled
.
Обычно дефолтное оформление браузера выпиливается основательно, иногда с нейтрализацией отображения состояний отличных от обычного.
Да. Этот гайд для тебя, любитель превратить веб-страницу в бумажный аналог.
Стилей для этих штучек понадобится немного больше, но всё не так страшно. Кроме того ребята из Twitter и отчасти Google уже позаботились о реализации велосипеда.
Тёплый ламповый Bootstrap "и новомодный MaterializeCSS, например.
Отображение
Так выглядит <button>Кнопка</button>
в моём Chrome 54:
На картинке button
, button:hover
, button:focus
, button:active
соответственно.
Без излишеств. Но учитывая движение Google в направлении Material Design, вполне может статься так, что в скором времени их заменят на подобные аналоги.
CSS
Для наглядности — мой вариант велосипеда который выглядит странновато, но для примера сойдёт.

Обычная, наведение, клик, отключена соответственно.
button
— обычное состояние
button {
background: none;
outline: none;
border: none;
text-transform: uppercase;
}
button:hover
, button:focus
— при наведении
button:hover, button:focus {
color: hsla(108, 12%, 0%, 1);
box-shadow: -1px 1px 2px hsla(108, 62%, 42%, 1);
background-color: hsla(108, 62%, 92%, 1)
}
button:active
— в момент клика
button:active {
color: hsla(108, 42%, 32%, 1);
box-shadow: -2px 4px 8px hsla(64, 64%, 42%, 1);
background-color: hsla(64, 64%, 92%, 1);
}
button:disable
— отключена
button:disabled {
color: hsla(0, 0%, 64%, 1);
background: none;
box-shadow: none;
opacity: 1;
}
Пример посложнее
Посмотреть в живую на JSFiddle
button {
margin: .8rem;
font-size: 1.42rem;
padding: 1rem;
background: hsla(180, 90%, 64%, 1);
color: hsla(180, 90%, 12%, 1);
text-shadow: 1px 1px 1px hsla(180, 90%, 32%, 1);
box-shadow: -4px 4px 0 0 hsla(180, 90%, 22%, .87), -3px 4px 3px hsla(180, 42%, 11%, 1), 1px 5px 4px hsla(180, 42%, 11%, 1), -4px 1px 0 0 hsla(180, 90%, 32%, 1), inset 0 0 1px 0 hsla(180, 90%, 90%, 1);
border: 1px hsla(180, 92%, 56%, 1) solid;
border-top-color: hsla(180, 92%, 64%, 1);
border-radius: 5px;
outline: none;
position: relative;
transition: all .22s ease-in;
}
button:hover {
background: hsla(420, 90%, 42%, 1);
color: hsla(420, 90%, 12%, 1);
text-shadow: 1px 1px 1px hsla(420, 90%, 32%, 1);
border: 1px hsla(420, 92%, 56%, 1) solid;
border-top-color: hsla(420, 90%, 64%, 1);
box-shadow: -4px 4px 0 0 hsla(420, 90%, 22%, .87), -3px 4px 3px hsla(420, 42%, 11%, 1), 1px 5px 4px hsla(420, 42%, 11%, 1), -4px 1px 0 0 hsla(420, 90%, 32%, 1), inset 0 0 1px 0 hsla(420, 90%, 90%, 1);
}
button:focus {
background: hsla(108, 90%, 42%, 1);
color: hsla(108, 90%, 12%, 1);
text-shadow: 1px 1px 1px hsla(108, 90%, 32%, 1);
border: 1px hsla(108, 92%, 56%, 1) solid;
border-top-color: hsla(108, 90%, 64%, 1);
box-shadow: -4px 4px 0 0 hsla(108, 90%, 22%, .87), -3px 4px 3px hsla(108, 42%, 11%, 1), 1px 5px 4px hsla(108, 42%, 11%, 1), -4px 1px 0 0 hsla(108, 90%, 32%, 1), inset 0 0 1px 0 hsla(108, 90%, 90%, 1);
}
button:active {
background: hsla(420, 90%, 42%, 1);
color: hsla(420, 90%, 12%, 1);
text-shadow: 1px 1px 1px hsla(420, 90%, 32%, 1);
transform: translate(-4px, 4px);
border: 1px hsla(420, 92%, 22%, 1) solid;
border-top-color: hsla(420, 92%, 56%, 1);
box-shadow: 0 0 0 0 hsla(420, 90%, 22%, .87), 0 0 0 hsla(420, 42%, 11%, 1), 0 0 0 hsla(420, 42%, 11%, 1), 0 0 0 0 hsla(420, 90%, 32%, 1), inset 1px 1px 4px 0 hsla(420, 90%, 22%, 1);
}
button:disabled {
background: hsla(420, 0%, 64%, 1);
color: hsla(420, 0%, 12%, 1);
text-shadow: 1px 1px 1px hsla(420, 0%, 32%, 1);
transform: translate(-4px, 4px);
border: 1px hsla(420, 0%, 22%, 1) solid;
border-top-color: hsla(420, 0%, 56%, 1);
box-shadow: 0 0 0 0 hsla(420, 0%, 22%, .87), 0 0 0 hsla(420, 42%, 11%, 1), 0 0 0 hsla(420, 42%, 11%, 1), 0 0 0 0 hsla(420, 0%, 32%, 1), inset 1px 1px 4px 0 hsla(420, 0%, 22%, 1);
}
button:disabled.in_ajax
{
background: hsla(108, 22%, 64%, 1);
color: hsla(108, 22%, 12%, 1);
text-shadow: 1px 1px 1px hsla(108, 22%, 32%, 1);
transform: translate(-4px, 4px);
border: 1px hsla(108, 22%, 22%, 1) solid;
border-top-color: hsla(108, 22%, 56%, 1);
box-shadow: 0 0 0 0 hsla(108, 22%, 22%, .87), 0 0 0 hsla(420, 42%, 11%, 1), 0 0 0 hsla(420, 42%, 11%, 1), 0 0 0 0 hsla(420, 0%, 32%, 1), inset 1px 1px 4px 0 hsla(420, 0%, 22%, 1);
}
Дизайнеру
Ты цээсэсов можешь и не знать, но состояния отрисовать обязан!
От дизайнера помимо макета с обычным состоянием ссылки или кнопки, требуется прилагать различные состояния, дабы не устраивать верстальщику батхерт.
Например так:
Ребята из Google сделали такой макет.
Спасибо
Спасибо, что дочитали. Всё здесь написаннное не является 100% истиной в последней инстанции.
Репозиторий
GitHub
Ссылка на репозиторий этой статьи. Если хотите дополнить или исправить, присылайте пожалуйста Pull Request