Правильный способ сделать кнопку ссылкой

Статья последний раз была обновлена 04.03.2023

Правильный способ сделать кнопку ссылкой

Опубликовано:
2013-03-05

Иногда возникает задача оформить ссылку как стандартную кнопку. В общем случае так делать нежелательно: ссылка по определению просто указывает на определённый ресурс, в то время как нажатие кнопки обычно инициирует некоторое действие. Но если задача возникла, то имеет смысл хотя бы делать это правильно.

Правильно

Синтаксически правильное («валидное») и кроссбраузерное решение состоит в том, чтобы заключить кнопку в простейшую форму. Кнопке при этом следует добавить атрибут type="submit", чтобы её нажатие инициировало отправку формы (в современных браузерах и IE8+ атрибут необязателен), а в атрибут action формы — поместить URL-адрес, на который должна вести «кнопка-ссылка»:

<form action="/example/">

    <button type="submit">Кнопка-ссылка</button>

</form>

«Кнопка-ссылка» из данного примера ведёт на страницу с адресом /example/.

Строка запроса

Строка запроса представляет собой GET-параметры в виде пар имя=значение, фигурирующие в URL-адресе после первого вопросительного знака.

Если URL-адрес, на который должна указывать ссылка, содержит строку запроса, то следует для каждого из GET-параметров добавить в форму скрытое поле с соответствующими атрибутами name и value:

<form action="/example/">

    <input type="hidden" name="foo"   value="bar" />

    <input type="hidden" name="lorem" value="ipsum" />

    <button type="submit">Кнопка-ссылка</button>

</form>

Данная форма ведёт на страницу /example/?foo=bar&lorem=ipsum.

Chromium/Blink и WebKit

В браузерах на основе движков Chromium / Blink (Chrome, Opera 15+, Яндекс.Браузер, Vivaldi) и WebKit (Safari) есть баг (1, 2), из-за которого вопросительный знак, отделяющий строку запроса от основной части адреса, добавляется к адресу даже в случае отсутствия полей в форме. Поэтому, например, форма:

<form action="/example/">

    <button type="submit">Кнопка-ссылка</button>

</form>

приведёт на адрес /example/? вместо правильного /example/.

Обойти это можно, настроив автоматическое серверное перенаправление (редирект) с URL-адреса, оканчивающегося вопросительным знаком, на такой же URL-адрес без воспросительного знака.

Неправильно

Кнопка внутри ссылки

Нередко встречается решение «в лоб», состоящее в том, чтобы просто поместить элемент BUTTON внутрь ссылки:

<a href="/example/"><button>Кнопка-ссылка</button></a>

Но, во-первых, согласно HTML5 такое решение синтаксически некорректно («невалидно»): ссылка не должна содержать интерактивные элементы; во-вторых, такая ссылка не будет работать в Internet Explorer (IE) ниже 9-й версии.

Кнопка с JS-обработчиком щелчка

Порой используется кнопка с JavaScript-обработчиком события щелчка:


<button onclick="location.href = '/example/'">Кнопка-ссылка</button>

Но и это решение имеет серьёзные недостатки:

  • не работает при выключенном JavaScript;
  • возможны проблемы с индексацией поисковиками, не исполняющими JavaScript-код.

Написать комментарий

Комментарии
morontt 2013-03-08

Чего только не придумают… 🙂 Хотя вот ссылка кнопкой — это на каждом шагу буквально встречается.

Александр 2013-06-30

Марат, очень помогла ваша статья. Огромное спасибо!

Это самый грамотный и актуальный на сегодня ответ в интернете, который мне удалось найти.

Продолжите, пожалуйста, тему — «Правильный способ сделать картинку ссылкой» (1 вариант — только HTML; 2 вариант — CSS; …). В сети масса устаревших и в корне неверных рекомендаций — кто на что горазд…

И еще один вопрос-просьба. По адресу http://api.yandex.ru/share/ Яндекс раздает невалидный код. На недоуменные вопросы в клубе разработчиков (http://clubs.ya.ru/share/) отвечают: «А зачем вам эта валидность?» Не могли бы Вы исправить их код?

Никита 2013-11-15

Есть и у этого способа подводные камни. Вот такие вот штуки ( http://s020.radikal.ru/i720/1311/34/bfe7beda17fe.jpg ) при использовании кнопок предыдущей и следующей страницы. Мешается ужасно. Как обойти непонятно.

Marat Tanalin (автор) 2013-11-16

Никита, если вы о подтверждении, запрашиваемом браузером при попытке обновить страницу (или вернуться на неё по браузерной истории), загруженную в результате отправки формы, то это имеет место только в отношении форм, отправляемых методом POST (когда данные отправляются отдельным HTTP-пакетом).

В данной же заметке описывается отправка форм методом GET (когда данные передаются непосредственно в URL-адресе страницы-адресата в виде пар имя=значение, добавляемых после вопросительного знака к адресу, указанному в атрибуте action формы), и соответствующие страницы пользователь может беспрепятственно обновлять или возвращаться на них без каких-либо запросов на подтверждение от браузера.

Наташа 2015-01-22

Спасибо большое за информацию. У меня есть один «дурацкий» вопрос :-). Почему при размещении 2 и более кнопок на одной странице (с разными url адресами) все они работают в одном направлении?

Marat Tanalin (автор) 2015-01-22

Наташа, скорее всего, в вашем HTML-коде есть ошибки (например, у первой из двух форм отсутствует закрывающий тег </form>). На всякий случай обратите внимание, что каждую кнопку-ссылку следует заключать в собственную форму, при этом формы не должны быть вложенными друг в друга.

В общем случае при любых странных проблемах полезно проверять код HTML-страницы валидатором.

Наташа 2015-01-22

Спасибо, мне следовало быть более внимательной. И за Валидатор отдельное спасибо )))

thnx 2015-02-05

Весь интернет перерыл пока искал! спасибо мне очень помогло! и ошибок никаких нет в браузерах.

ValeriusSoft 2015-05-27

Не работает на движок OpenCart 2.0.2

<?php

$uri = $_SERVER[‘REQUEST_URI’];

$qPos = strpos($uri, ‘?’);

if ($qPos === strlen($uri) — 1) {

    header(‘HTTP/1.1 301 Moved Permanently’);

    header(‘Location: ‘ . substr($uri, 0, $qPos));

}

?>

Может у вас есть код для .htaccess ?

Marat Tanalin (автор) 2015-05-27

ValeriusSoft, см. новую заметку «Удаляем пустую строку запроса из URL».

Den 2015-09-11

как привязать код возврата на предыдущую страницу <a href=»#» onclick=»history.back();return false;»>

к кнопке?

код кнопки:

 <td colspan=»2″ align=»left» valign=»top» height=»116″><a class=»fasc-button fasc-size-medium fasc-type-glossy fasc-rounded-medium ico-fa fasc-ico-before fa-reply-all» style=»background-color: #33809e; color: #ffffff;» data-fasc-style=»background-color:#33809e;color:#ffffff;»>назад</a></td>

За ранее спасибо.

Marat Tanalin (автор) 2015-09-11

Den, в вашем случае ссылка функционально не является ссылкой (указывает на фиктивный пустой якорь # и существует только для исполнения JS-кода при щелчке), поэтому можно просто заменить элемент A на элемент BUTTON, сохранив прежний onclick-обработчик.

Но в общем случае использование JavaScript для реализации ссылки на предыдущую страницу нежелательно, т. к.:

  • JS может быть выключен в браузере пользователя, и тогда такая ссылка работать не будет, запутывая пользователя;
  • пользователь может попадать на одну и ту же страницу с разных страниц вашего сайта (тогда ссылка «Назад» будет всегда указывать на разные страницы), со страницы другого сайта (тогда предыдущий пункт в истории браузера будет указывать на страницу другого сайта — например, поисковика) или отсутствовать вообще (если страница открыта из закладок браузера, и тогда JS-ссылка «Назад» работать не будет).

При необходимости URL-адрес предыдущей страницы имеет смысл вставлять в ссылку явным образом на серверной стороне, а лучше — воздержаться от дублирования встроенной функциональности браузера.

Den 2015-09-11

Логично. Спасибо за быстрый ответ. Буду искать другой путь

Mig 2015-09-16

Спасибо, что просветили! Я тоже сначала сделал не правильно.

anstrem 2015-09-18

ИМХО правильный способ кнопку все таки ссылкой не делать, а просто визуализировать ссылку в виде кнопки:

<a style=»box-shadow: 0 0 5px rgba(0,0,0,0.3); border: 1px solid #333; display: inline-block; padding: 5px 15px; text-decoration: none; background: linear-gradient(to bottom, #fcfff4, #e9e9ce); color: #C9DC7D;» href=»ссылка»>Оставить отзыв</a>

С цветами и стилями только сами поиграйтесь, а то тут какой то ужас стоит 🙂

Marat Tanalin (автор) 2015-09-18

anstrem, такая кнопка будет отличаться внешне от системных кнопок, имеющих оформление, родное (native) для операционной системы.

Галина 2015-09-28

В html5 , по-моему, можно оформить кнопку-ссылку проще :

<button onclick=»javascript:window.location.href = ‘index.html'» title=»На главную»>На главную</button>

и не мучиться с настройкой редиректа

Marat Tanalin (автор) 2015-09-28

Галина, такая кнопка не будет работать при выключенном JavaScript.

Кстати, ссылка на главную страницу не должна указывать на файл.

Галина 2015-09-28

автор, согласна.

Андрей 2015-10-06

Спасибо за подробное описание!

Но у меня не получилось.

Вот код (это популярная в сети кнопка)

 <a href=»#» data-path-hover=»m 0,0 0,47.7775 c 24.580441,3.12569 55.897012,-8.199417 90,-8.199417 34.10299,0 65.41956,11.325107 90,8.199417 L 180,0 z»>

                    <figure>

                        <img src=»https://s3-us-west-2.amazonaws.com/s.cdpn.io/81117/teresa_postcard.jpg» />

                        <svg viewBox=»0 0 180 320″ preserveAspectRatio=»none»><path d=»m 0,0 0,171.14385 c 24.580441,15.47138 55.897012,24.75772 90,24.75772 34.10299,0 65.41956,-9.28634 90,-24.75772 L 180,0 0,0 z»/></svg>

                        <figcaption>

                            <h2>Guess Who?</h2>

                            <p>Was born Agnes Gonxha Bojaxhiu.</p>

                            <button >Learn More about Mother Teresa</button>

                        </figcaption>

                    </figure>

                </a>

_________________

Что не делаю, все равно код невалидный.

Marat Tanalin (автор) 2015-10-06

Андрей, скорее всего, JS-логика, привязанная к такой кнопке, зависит от конкретной, заранее определённой HTML-структуры, и с этим ничего не поделать. Для полной уверенности можно попробовать заменить обрамляющую ссылку на форму с тем же атрибутом data-path-hover — если не заработает (скорее всего), то ветер с моря дул не судьба.

SkyFfs 2015-11-24

Спасибо, помогло! )

Badrainbow 2015-12-18

Самое логичное решение

<input value=»HTML форум» onclick=»location.href=’http://адрес/'» type=»button»>

Юлия 2016-03-12

Скажите пожалуйста, а можно ли в этой форме кнопки поменять цвет кнопки и шрифта?

<form action=»/kontakty»>

    <button type=»submit»>Записаться на консультацию</button>

</form>

Marat Tanalin (автор) 2016-03-13

Юлия, используйте CSS-свойства background и color.

Юлия 2016-03-14

Спасибо)

Сергей 2016-04-27

Добрый день.

Я только-только начал изучать html.

Сейчас пытаюсь сделать элементы выпадающего списка ссылками на якоря.Это возможно сделать, используя только html?

Спасибо.

Marat Tanalin (автор) 2016-04-27

Сергей, если под выпадающим списком подразумевается HTML-элемент SELECT, то средствами статического HTML (без JavaScript) переход с его помощью на якоря не реализовать.

Замечу, что в общем случае выпадающий список — не самый удобный способ навигации (например, нет возможности открыть произвольную ссылку в новой вкладке). Если ссылок не очень много, целесообразнее реализовать навигацию в виде UL-списка обычных ссылок.

Сергей 2016-04-27

Просто было любопытно. Понял Вас, приму к сведению.

Спасибо за ответ.

MER11111111 2017-01-10

Всем привет,информация точна и подробная,спасибо автору,но у меня возник вопрос,если у меня сайт разделён фреймами,то как задать условия появления страницы,ссылка которой в кнопке,в определённом фрейме?(у меня на сайте есть верхний фрейм,боковой(там где находится кнопка) и центральный фрейм(в котором и должен появиться файл,который указан ссылкой) )

Marat Tanalin (автор) 2017-01-10

@MER11111111 Для указания окна или фрейма, в который следует загружать ресурс, на который указывает ссылка, предназначен атрибут target, в качестве значения которого в случае фрейма следует указать значение атрибута name соответствующего фрейма. Но на самом деле фреймы как подход давно устарели, вместо них следует использовать шаблонизацию на стороне сервера.

ЧИТАЙТЕ ТАКЖЕ:  Футер прилипающий к низу страницы | Олег Мурашов

Написать комментарий

http://tanalin.com/blog/2013/03/link-button/

Губарь Маргарита Александровна