Как сделать кнопку, которая ведет на страницу
Напишите обычную ссылку <a href> и оформите ее через CSS, чтобы она выглядела как кнопка. Она переходит на страницу как любая ссылка и сохраняет все возможности ссылки: открытие в новой вкладке, копирование адреса ссылки и превью URL при наведении.
Правила, которые превращают ссылку в кнопку:
display: inline-blockпозволяет внутренним отступам раздвинуть блок и оставляет его в строке текста.text-decoration: noneубирает подчеркивание.colorиbackgroundзаменяют синий цвет ссылки.:focus-visibleдает пользователям клавиатуры заметную рамку фокуса.
Тот же класс работает и у <button>, поэтому кнопка отправки формы и ссылка на другую страницу могут выглядеть одинаково, а работу делать каждая свою.
Кнопка или ссылка: какой элемент выбрать
Вопрос в том, что происходит при клике, а не в том, как это выглядит.
| Клик | Что использовать | Примеры |
|---|---|---|
| Ведет на другой URL | <a href> | Регистрация, Подробнее, Цены, Скачать |
| Меняет что-то на этой странице | <button type="button"> | Открыть меню, Воспроизвести, В корзину, Показать пароль |
| Отправляет форму | <button type="submit"> | Войти, Найти, Сохранить |
Ссылка, объявленная как «ссылка», и кнопка, объявленная как «кнопка», сообщают пользователям программ чтения с экрана, что произойдет. Различается и поведение клавиатуры: Enter срабатывает у обоих, а Space только у кнопок (на ссылке Space прокручивает страницу). Сам элемент кнопки описан на странице кнопка в HTML.
Почему не стоит класть кнопку в ссылку
Этот вариант большинство пробует первым:
<!-- Invalid: interactive content inside <a> -->
<a href="/signup"><button>Sign up</button></a>
<!-- Invalid the other way round, too -->
<button><a href="/signup">Sign up</a></button>
Стандарт HTML запрещает оба варианта: <a> и <button> не могут содержать интерактивные элементы. На практике клавиатура получает две остановки Tab на один элемент управления, программа чтения с экрана может объявить «ссылка, кнопка, Sign up», а перейдет ли клик по ссылке, зависит от браузера. Выберите один элемент.
Почему не стоит использовать onclick с location.href
Другой частый обходной путь это кнопка, которая задает URL через JavaScript. Выглядит она так же, как ссылка:
(В примере используется window.open, потому что превью не должно уходить на другую страницу; обычно пишут location.href = '...'.) Наведите курсор и кликните правой кнопкой по обоим элементам: только настоящая ссылка показывает свой URL и предлагает «Открыть ссылку в новой вкладке» и «Копировать адрес ссылки». Кнопка к тому же не поддерживает Ctrl+клик и клик колесиком, браузер не отмечает ее как посещенную, а поисковики не переходят по ней как по ссылке. Если цель это URL, пишите <a href>.
Кнопка формы, которая открывает URL
Есть один случай, когда <button>, ведущая на другую страницу, уместна: когда она отправляет данные. Классический пример это поле поиска. action формы это URL, а method="get" помещает поля в строку запроса:
Нажмите Search: на настоящей странице браузер перешел бы на https://duckduckgo.com/?q=html+button+link. Превью вместо перехода показывает данные. formaction отправляет ту же форму на другой URL со второй кнопки.
Неактивные ссылки-кнопки
У ссылок нет атрибута disabled; <a disabled> ничего не делает. Чтобы выключить ссылку-кнопку, уберите ее href (<a> без href не является ссылкой, по нему нельзя кликнуть и на нем нельзя сфокусироваться) и отметьте ее aria-disabled="true", чтобы об этом знали и стили, и программы чтения с экрана:
Нажмите Tab в превью: фокус попадает только на первую кнопку. Некоторые сайты оставляют href и добавляют pointer-events: none, но это блокирует только мышь. Ссылка остается доступной по Tab, и Enter все равно по ней переходит.
Кнопки новой вкладки и скачивания
Все атрибуты ссылки продолжают работать у ссылки, оформленной как кнопка:
<a class="btn" href="/files/guide.pdf" download>Download the guide</a>
<a class="btn" href="https://github.com/" target="_blank" rel="noopener">GitHub</a>
Это еще одна причина использовать <a>: у <button> нет ни download, ни target. Подробнее о target на странице открыть ссылку в новой вкладке.
Частые ошибки
- Кнопка внутри ссылки или ссылка внутри кнопки. Некорректный HTML с непредсказуемым поведением.
<button onclick="location.href=...">для простой навигации. Ни новой вкладки, ни копирования ссылки, ни обхода поисковиками.role="button"у ссылки, которая ведет на страницу. Пользователи программ чтения с экрана слышат, что это кнопка, а потом страница меняется. Оставьте ее ссылкой.- Ссылки в виде кнопок для действий вроде «Удалить» или «Открыть меню» с
href="#". Если ничего не загружается, используйте<button type="button">. <a disabled>. У ссылок такого атрибута нет. Уберитеhref.- Забытый
display: inline-block, из-за чего вертикальные отступы наезжают на строки сверху и снизу.
Часто задаваемые вопросы
Как сделать кнопку, которая ведет на другую страницу?
Используйте ссылку и оформите ее как кнопку: <a href="/signup" class="btn">Sign up</a> плюс CSS для внутренних отступов, фона, скругления углов и text-decoration: none. Она выглядит как кнопка и ведет себя как ссылка, которой и является.
Можно ли поставить кнопку внутрь тега a?
Нет. Стандарт HTML не разрешает интерактивное содержимое вроде <button> внутри <a>. Браузеры обрабатывают это по-разному, пользователи клавиатуры получают две остановки Tab на один элемент управления, а программы чтения с экрана объявляют его путано. Используйте один элемент.
Есть ли у кнопки атрибут href?
Нет. У <button> нет href. Чтобы отправить браузер по URL, используйте <a href> или поместите кнопку в <form> с action (атрибут formaction у кнопки его переопределяет).
Плохо ли использовать onclick с location.href у кнопки?
Это работает, но читатель теряет все, что дают ссылки: клик колесиком и Ctrl+клик для новой вкладки, «Копировать адрес ссылки», превью URL при наведении, а поисковики не переходят по ней как по ссылке. Если цель это URL, используйте <a>.
Как отключить ссылку, которая выглядит как кнопка?
У ссылок нет атрибута disabled. Уберите href, чтобы она перестала быть ссылкой, добавьте aria-disabled="true" и оформите ее как неактивную. Верните href, когда она снова должна работать.