Как сделать так чтобы при нажатии на кнопку открывалось новое окно html

Обновлено: 01.05.2024

Модальное окно html + css, несколько вариантов модальных окон, открытие, закрытие модального окна, открытие модального окна по ссылке, открытие модального окна по кнопке! В общем попытаемся разобраться в скрипте модального окна!

Самое простое модальное окно

Что такое "Модальное окно"

Определение, что такое "Модальное окно"!? "Модальное окно" - это всплывающий элемент, который покрывает все пространство монитора и делает невозможным другие действия на сайте до того, пока вы не закроете это окно!

Алгоритм создания модального окна:

На самом деле, если разобраться, то нам всего то понадобится несколько кнопок и пара div, чтобы это все работало!

Удивительно, что когда сталкиваешься с темой модального окна, то такое ощущение, что люди просто хотят, чтобы вы сошли с ума от того количества кода, которое они используют для вывода и закрытия модального окна!!
Я не претендую на истину в последней инстанции, и вы всегда с помощью поиска всегда сможете найти огромное количество вариантов модальных окон! Но наш принцип максимально просто и минимум кода во всех скриптах - и модальные окна здесь не исключения!

Самое простое модельное окно html + css

Чтобы забрендировать данный скрипт, поскольку я его написал самолично, то он будет называться ->"DW modal window"

Что потребуется для создания модального окна!?

Основной блок модального окна, который по умолчанию будет скрыт (display: none;), как вы наверное уже догадались вниже идущем коде четыре элемента

1). затемнение(zatemnenie),
2). само окно(window)
3). закрытие окна(close_window)
4). Содержание модального окна

И далее нам потребуются стили для нашего модального окна, не буду расписывать каждую строчку -> соберем весь код модального окна вместе:

Скрипт модального окна в сборе -> html + css

Мы недавно ввели новые фишки такие как. : для данного пункта у нас, кроме кода. который расположен ниже

Пример модального окна на отдельной странице

Теперь в этом пункте нашего повествования о модальных окнах соберем наш код модального окна все вместе.

Кнопки являются одним из популярных элементов интерфейса и часто применяются внутри форм, например, для отправки введённой информации в форме на сервер.

Кнопки на веб-странице можно создать несколькими способами — с помощью элемента или элемента .

Рассмотрим вначале добавление кнопки через и его синтаксис.

Атрибуты кнопки перечислены в табл. 1.

Табл. 1. Атрибуты
Атрибут Описание
name Имя кнопки, предназначено для того, чтобы обработчик формы мог её идентифицировать.
disabled Блокирует кнопку и не позволяет на неё нажимать.
form Идентификатор формы для связывания кнопки с элементом .
type Для обычной кнопки значением является button .
value Надпись на кнопке.
autofocus Кнопка получает фокус после загрузки документа.

Создание кнопки показано в примере 1.

Пример 1. Добавление кнопки

Примите во внимание, что учитываются все пробелы в надписи на кнопке, в отличие от обычного текста HTML, поэтому можно ставить любое количество пробелов, которые в итоге влияют на ширину кнопки. Но правильнее, конечно же, задавать вид кнопки через CSS. Результат примера показан на рис. 1.

Рис. 1. Вид кнопки

Для таких кнопок есть ряд обязательных правил:

Второй способ создания кнопки основан на использовании элемента . Он по своему действию напоминает результат, получаемый с помощью . Но в отличие от него предлагает расширенные возможности по созданию кнопок. Например, на подобной кнопке можно размещать любые элементы HTML, включая изображения и таблицы. На рис. 2 показаны разные виды кнопок, полученные с помощью .

" width="567" height="206" />

Рис. 2. Кнопки, созданные с помощью

Синтаксис создания такой кнопки следующий.

Атрибуты перечислены в табл. 1, но в отличие от кнопки атрибут value определяет только отправляемое на сервер значение, а не надпись на кнопке. Если требуется вывести на кнопке изображение, то добавляется внутрь , как показано в примере 2.

Пример 2. Рисунок на кнопке

В данном примере показано создание обычной кнопки с текстом, а также кнопки с одновременным использованием текста и рисунка. Размер кнопки зависит от содержимого , но пробелы игнорируются, поэтому простым увеличением их количества, как в случае использования , ширину кнопки изменить не удастся.

Для также есть ряд ограничений:

Кнопка Submit

Для отправки данных на сервер предназначена специальная кнопка Submit. Её вид ничем не отличается от обычных кнопок, но при нажатии на неё происходит переход к обработчику формы по адресу, указанному атрибутом action элемента . Программа-обработчик, получает данные, введённые пользователем в полях формы, производит с ними необходимые манипуляции, после чего возвращает результат в виде HTML-документа. Что именно делает обработчик, зависит от автора сайта, например, подобная технология применяется при создании опросов, форумов, тестов и многих других вещей.

Синтаксис создания кнопки Submit зависит от используемого элемента или .

Пример 3. Отправка данных на сервер

Кнопка Reset

При нажатии на кнопку Reset данные формы возвращаются к первоначальным значениям. Как правило, эту кнопку применяют для очистки введённой в полях формы информации. Для больших форм от использования кнопки Reset лучше вообще отказаться, чтобы по ошибке на неё не нажать, ведь тогда придётся заполнять форму заново.

Синтаксис создания указанной кнопки прост и похож на другие кнопки.

В примере 4 показана форма с одним текстовым полем, которое уже содержит предварительно введённый текст с помощью атрибута value элемента . После изменения текста и нажатия на кнопку «Очистить», значение поля будет восстановлено и в нём снова появится надпись «Введите текст».

Пример 4. Кнопка для очистки формы

Значение кнопки Reset никогда не пересылается на сервер. Если надпись на кнопке опустить, иными словами, не задавать атрибут value , на кнопке по умолчанию будет добавлен текст «Сбросить».

Вёрстка таких окон сначала кажется простой задачей. Модальные окна можно сделать даже без помощи JS только лишь с помощью CSS, но на практике они оказываются неудобными, и из-за маленьких недочетов модальные окна раздражают посетителей сайта.

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


Вообще говоря, есть несколько готовых скриптов, JavaScript библиотек, реализующих функционал модальных окон, например:

  • Arctic Modal,
  • jquery-modal,
  • iziModal,
  • Micromodal.js,
  • tingle.js,
  • Bootstrap Modal (из библиотеки Bootstrap) и др.

(в статье не рассматриваем решения на базе Frontend-фреймворков)

Несколькими из них я пользовался сам, но почти у всех находил какие-то недостатки. Некоторые из них требуют подключения библиотеки jQuery, которая есть не на всех проектах. Для разработки своего решения, нужно сначала определиться с требованиями.

Что мы ждём от модальных окон? Отвечая на этот вопрос, я основывался на докладе «Знакомьтесь, модальное окно» Анны Селезнёвой, а так-же на относительно старой статье NikoX «arcticModal — jQuery-плагин для модальных окон».

Итак, чтобы нам хотелось видеть?

Дисклеймер: Прежде чем мы рассмотрим подробности, сразу дам ссылку на готовый код получившейся библиотеки (HystModal) на GitHub, а также ссылку на демо+документацию.

Начнём с разметки.

1. Разметка HTML и CSS

1.1. Каркас модальных окон

Как открыть окно быстро? Самое простое решение: разместить всю разметку модального окна сразу в HTML странице. Затем скрывать/показывать это окно при помощи переключения классов CSS.

Набросаем такую разметку HTML (я назвал этот скрипт «hystmodal»):

Сделаем так, чтобы .hystmodal растягивался на всё окно браузера и закрывал собой содержимое страницы. Чтобы этого добиться, установим фиксированное позиционирование в CSS и приравняем свойства top, bottom, left и right к нулю.

В этом коде сделаны ещё две вещи:

  1. Так как мы хотим центрировать окно внутри страницы, превращаем .hystmodal в flex-контейнер с выравниваем его потомков по центру по вертикали и горизонтали.
  2. Окно может быть больше высоты экрана браузера, поэтому мы устанавливаем overflow-y: auto , чтобы при переполнении возникала полоса прокрутки. Также, для сенсорных экранов (в основном для Safari) нам стоит установить свойство -webkit-overflow-scrolling: touch , чтобы сенсорная прокрутка работала именно на этом блоке а не на странице.

Теперь установим стили для самого окна.

Кажется возникли сложности.

Проблема №1. Если высота окна больше высоты окна браузера, то контент окна будет обрезан сверху.


Это возникает из-за свойства justify-content: center . Оно позволяет нам удобно выровнять потомков по основной оси (по вертикали), но если потомок становится больше родителя то часть его становится недоступной даже при прокручиваемом контейнере. Подробнее можно посмотреть на stackoverflow. Решение – установить justify-content: flex-start , а потомку установить margin:auto . Это выровняет его по центру.

Проблема №2. В ie-11 если высота окна больше высоты окна браузера, то фон окна обрезается.

Решение: мы можем установить flex-shrink:0 потомку – тогда обрезки не происходит.

Проблема №3. В браузерах кроме Chrome нет отступа от нижней границы окна (т.е. padding-bottom не сработал).

Сложно сказать баг это браузеров или наоборот соответствует спецификации, но решения два:

  • установить псевдоэлемент ::after после потомка и дать ему высоту вместо padding
  • обернуть элемент в дополнительный блок и дать отступы уже ему.

Воспользуемся вторым методом. Добавим обертку .hystmodal__wrap . Так мы заодно обойдём и проблему №1, а вместо padding у родителя установим margin-top и margin-top у самого .hystmodal__window .

Наш итоговый html:

В код также добавлены некоторые aria и role атрибуты для обеспечения доступности.

Обновленный код CSS для обертки и окна.

1.2 Скрываем окно

Сейчас наше окно всегда видно. Когда говорят о скрытии элементов, первое что приходит на ум это переключать свойство display со значения none до нашего значения flex.

Но этот подход нас не устроит, ведь свойство display не анимируется. Все переходы дочерних элементов, указанные в свойстве transition, работать не будут.

Нам поможет другое свойство visibility:hidden . Оно скроет окно визуально, хотя и зарезервирует под него место. А так как все будущие окна на странице имеют фиксированное
позиционирование – они будут полностью скрыты и не повлияют на остальную страницу. Кроме того, на элементы с visibility:hidden нельзя установить фокус с клавиатуры, а от скрин-ридеров мы уже скрыли окна с помощью атрибута aria-hidden="true" .

Добавим также классы для открытого окна:

1.3 Оформление подложки

В лучшем случае, нам нужен отдельный html-элемент в качестве оверлея. Можно использовать и имеющийся элемент модального окна .hystmodal в качестве оверлея, но тогда анимация на этом элементе (например переход opacity) будет затрагивать и внутренние элементы. В итоге, не получится анимировать разные свойства для окна и оверлея отдельно.

Просто разместим элемент .hystmodal__shadow прямо перед закрывающим . В будущем, сделаем так, чтобы этот элемент создавался автоматически из js при инициализации библиотеки.

1.4 Отключение прокрутки страницы

Когда модальное окна открывается, мы хотим, чтобы страница под ним не прокручивалась.
Самый простой способ этого добиться — повесить overflow:hidden для body или html, когда окно открывается. Однако с этим есть проблема:

Проблема №4. В браузере Safari на iOS страница будет прокручиваться, даже если на тег html или body повешен overflow:hidden .
Решается двумя способами, либо блокированием событий прокрутки (touchmove, touchend или touchsart) из js вида:

Однако при этом блокируется и прокрутка самого модального окна, а также все прокручиваемые блоки внутри окна, если они будут. Требуется дополнительные проверки селекторов из js, что приводит к усложнению кода, поэтому рассмотрим другой вариант.

ps: можно конечно применить библиотеку scroll-lock, в которую заложено это решение, но в статье было решено воспользоваться другим вариантом.

Другое решение – основано частично на CSS. Пусть когда окно открывается, на элемент будет добавляться класс .hystmodal__opened :

Благодаря position:fixed , окно не будет прокручиваться даже в safari, однако здесь тоже не всё гладко:

Проблема №5. При открытии/закрытии окна страница прокручивается в начало.
Действительно, это происходит из-за изменения свойства position, текущая прокрутка окна сбрасывается.

Для решения, нам нужно написать следующий JS (упрощенно):

При открытии:

При закрытии:

Отлично, приступим к JavaScript коду.

2. Код JavaScript

2.2 Каркас библиотеки

Нам нужна совместимость со старыми браузерами включая IE11 поэтому нам нужно выбрать из 2 вариантов кодинга:

  • Разрабатывать на старом стандарте ES5, и использовать только те фичи, которые поддерживают все браузеры.
  • Применить современный синтаксис ES6, но подключить транспайлер Babel, который автоматически преобразует код для всех браузеров и встроит необходимые полифилы.
    Было принято решение использовать второй вариант, с прицелом на будущее.
    Приступим.

Основа нашей библиотеки единственный класс HystModal . Ниже я приведу скелет кода с комментариями, а потом добавим остальной функционал.

Итак, мы описали класс HystModal . Чтобы всё работало, нужно всего лишь подключить наш скрипт и создать экземпляр класса:

Проблема №6: если в браузере есть фиксированный скроллбар (который влияет на ширину страницы), то при открытии/закрытии окна происходит сдвиг контента, когда полоса прокрутки то появляется то пропадает.

Действительно – скроллбар пропадает и контент страницы перераспределяется. Чтобы решить эту проблему, можно добавить отступ справа к тегу html, равный ширине скроллбара когда он пропадает.

Однако ширина скроллбара может быть разной в разных браузерах и операционных системах. Кроме того, скроллбара может не быть на коротких страницах или он может быть плавающим (например, в Chrome на Android). Поэтому ширину нужно вычислять динамически из скрипта.

Дополним метод _bodyScrollControl()

Почему код метода close() упрощён? Дело в том, что просто убирая классы CSS у элементов, мы не можем анимировать закрытие окна.

Проблема №7. При закрытии окна, свойство visibility:hidden применяется сразу и не даёт возможности анимировать закрытие окна.

Причина этого известна: свойство visibility:hidden не анимируется. Конечно, можно обойтись без анимации, но, если она нужна, сделаем следующее.

  • Создадим дополнительный CSS-класс .hystmodal—moved почти такой-же как и .hystmodal--active
  • Затем при закрытии сначала добавим этот класс к окну и повесим обработчик события «transitionend» на модальном окне. Затем удалим класс `.hystmodal—active , таким образом вызывая css-переход. Как только переход завершится, сработает обработчик события «transitionend», в котором сделаем всё остальное и удалим сам обработчик события.

Ниже: новая версия методов закрытия окна:

Вы заметили, что мы создали ещё один метод _closeAfterTransition() и перенесли основную логику закрытия туда. Это нужно, чтобы удалить обработчик события transitionend после закрытия окна, ведь в метод removeEventListener необходимо передать именно ту функцию, которую мы привязывали.

Кроме того, если анимация не будет нужна, можно просто вызвать this._closeAfterTransition() не вешая его на событие.

Как мы помним, внутри addEventListener, this будет указывать на селектор где происходит событие, а не на наш экземпляр класса, поэтому в конструкторе нужно добавить ещё одну строчку для жёсткой привязки метода к this.

2.2 Закрытие окна по клику на оверлей

Нам нужно обработать ещё одно событие – закрытие окна по клику на элемент подложки .hystmodal__wrap . Мы можем повесить обработчик клика на документ для делегирования события как при открытии и проверить что событие произошло на .hystmodal__wrap примерно так:

Это будет работать, но есть один малозаметный недостаток.

Проблема №8. Если кнопку мыши нажать внутри окна, а отпустить за его пределами (над подложкой), окно закрывается.

Представьте, что в окне форма. Вы выделяете текст в поле ввода и случайно двигаете мышь чуть дальше, курсор заходит на подложку и вдруг окно закрывается, всё вдруг пропадает из виду. Не хотелось бы, чтобы так было.

Окно закрывается потому что по спецификации, если нажатие и отпускание мыши были на разных элементах, то событие click сработает на самом ближайшем общем для них элементе, а у нас это как раз .hystmodal__wrap .

Мы могли бы решить это изменением html, добавляя ещё один div сразу после .hystmodal__window и размещая его визуально под окном. Но нам бы не хотелось добавлять лишний пустой div ещё сильнее усложняя разметку.

Мы можем разбить наш addEventListener на два отдельных обработчика: для событий mousedown и mouseup и будем проверять чтобы оба события происходили именно на .hystmodal__wrap . Добавим новые обработчики событий в наш метод eventsFeeler()

2.3 Управление фокусом

У нас заготовлено два метода для управления фокусом: focusContol() для переноса фокуса внутрь окна и обратно при его закрытии, а также focusCatcher(event) для блокирования ухода фокуса из окна.

Решения для фокуса были реализованы аналогично js-библиотеке «Micromodal» (Indrashish Ghosh). А именно:

1. В служебный массив сохраним все css селекторы на которых может быть установлен фокус (свойство помещаем в init()):

2. В методе focusContol() находим первый такой селектор в окне и устанавливаем на него фокус, если окно открывается. Если же окно закрывается – то переводим фокус на this.starter :

3. В методе focusCatcher() находим в окне и превращаем в массив коллекцию всех элементов на которых может быть фокус. И проверяем, если фокус должен был выйти на пределы окна, то вместо этого устанавливаем фокус снова на первый или последний элемент (ведь фокус можно переключать как по Tab так и по Shift+Tab в обратную сторону).

Результирующий код метода focusCatcher:

По сути мы реализовали все необходимое для успешного создания модальных окон, осталось ещё несколько дел:

Проблема №9. В IE11 не работают методы Element.closest() и Object.assign() .

Для поддержки Element.closest, воспользуемся полифилами для closest и matches от MDN.

Можно их вставить просто так, но так как у нас проект всё равно собирается webpack, то удобно воспользоваться пакетом element-closest-polyfill который просто вставляет этот код.

Для поддержки Object.assign , можно воспользоваться уже babel-плагином @babel/plugin-transform-object-assign

3. Заключение и ссылки

Повторяя начало статьи, всё изложенное выше, я оформил в маленькую библиотеку hystModal под MIT-лицензией. Вышло 3 кБ кода при загрузке с gzip. Ещё написал для неё подробную документацию на русском и английском языке.

Что вошло ещё в библиотеку hystModal, чего не было в статье:

  • Настройки (вкл/выкл управление фокусом, варианты закрытия, ожидание анимации закрытия)
  • Коллбеки (функции вызывающиеся перед открытием окна и после его закрытия (в них передаётся объект модального окна))
  • Добавлен запрет на какие-либо действия пока анимация закрытия окна не завершится, а также ожидание анимации закрытия текущего окна перед открытием нового (если окно открывается из другого окна).
  • Оформление кнопки-крестика закрытия в CSS
  • Минификация CSS и JS плагинами Webpack.

Если вам будет интересна эта библиотека, буду рад звёздочке в GitHub, или напишите в Issues о найденных багах. (Особенно большие проблемы, наверное, в грамматике английской версии документации, так как мои знания языка пока на начальном уровне. Связаться со мной также можно в Instagram

Девушка на картинке как бы спрашивает — Куда жать?

Используйте для кнопок — кнопки, а для ссылок — ссылки.

Разделитель

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

Разделитель

Для кого эта статья?

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

Во вторых для верстальщика к которому пришёл макет без состояний, чтобы было куда дизайнера послать.

В третьих чтобы вместо очередной тирады о разнице в кнопках\ссылках и нужности дизайна состояний, просто давать ссылку.

Разделитель

Содержание

Разделитель

Ссылки

Разделитель

Введение

Когда наводят указатель на ссылку которая кнопка то в левом нижнем углу появляется надпись javascript:;:

Или адрес с решёткой:

Контекстное меню предлагает открыть ссылку в новой вкладке: сохранить, копировать…

ПКМ на такой кнопке и контекстное меню любезно предложит:

ctrl + ЛКМ на такой кнопке откроют новую вкладку на которой будет ровно та страница, с которой она была открыта.

Кроме того такая ссылка с решёткой в качестве ссылки, станет :visited , если ещё не стала до этого, и приобретёт соотстветствующее стилевое оформление. Если дизайнер его конечно не зарезал, что в большинстве случаев конечно зря, о чём ниже.

В JavaScript скриптах для таких кнопок дополнительно используется e.preventDefault() , чтобы предотвратить действие кнопки по умолчанию (переход по ссылке) "— это костыль.

Разделитель

Ссылка

Разделитель

У ссылки должны быть стили для обычного, :active , :visited , :focus и :hover состояний.

Разделитель

Антипаттерн

Поздравляю! С такими стилями все ваши ссылки визуально превратятся в обычный текст. Найти их на странице станет крайне затруднительно.

Антипример с неразличимыми ссылками

И помните, если вы ставите !important и не очень понимаете почему вы без него не можете обойтись, то читайте это слово как импотент. Возможно вам нужно немного изменить селектор для того, чтобы перекрыть тот, который вам мешает.

Разделитель

Состояния

текст с различными состояниями ссылки

a — обычное состояние

В обычном состоянии a должна быть синей или подчёркнутой, а лучше и синей и подчёркнутой, чтобы пользователь без наведения мыши понимал, что это — ссылка. Пользователь привык к тому, что синие слова на странице это ссылки, даже если они не подчёркнуты. Если вам не нравится синий цвет для ссылок, меняйте его, но тогда ссылки подчёркивайте.

a:hover — наведение

Когда курсор находится над ссылкой, она становится :hover и в данном примере приобретает подчёркивание. Так пользователь поймёт, что это точно ссылка, на которую можно кликнуть.

a:focus — фокус клавиатуры

Когда на ссылку устанавливается указатель, перемещаемый табулятором TAB ↹
она становится :focus . В 2016 году это может показаться странным, но есть люди которые работают с сайтам посредством клавиатуры. У некоторых вовсе сломана мышь. В любом случае, занулять :focus состояние — это преступление против таких людей.

Особые спецэфекты применять не обязательно, достаточно таких как у :focus .

CSS чтобы не писать дважды:

a:active — клик

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

a:visited — ранее посещённая страница

:visited , поможет пользователю не забыть какие странички он уже открывал и не открывать их повторно. Так вместе с :active и :hover мы чуточку разгрузим интернет от случайных загрузок, и сделаем его чуть лучше и быстре.

Разделитель

В эпоху HTML4 вместо кнопок использовались ссылки подчёрнутые пунктирной линией. Этот паттерн устарел.

Подчёркивание пунктирной линией рекомендуется для тултипов при наведении.
Например у такое выделение поможет понять, что можно навести указатель и получить расшифровку.

Разделитель

Пример нестандартного оформления ссылок:

Пример на котором состояния ссылок оформленны нестандартно

Разделитель

Слова в ссылке должны подчиняться правилам русского языка, капс непозволителен (исключение — аббревиатуры)

Разделитель

HTML5

  • Если клик не меняет адрес страницы,
  • адрес нельзя скопировать
  • и нельзя этим адресом поделиться — это кнопка.

В кнопке позволителен капс, при условии, что вы не используете аббревиатуры. Особенно в неочевидных местах.
Если у вас встречаются аббревиатуры, то верхний регистр в кнопке не желателен, выделяйте их другим способом. Не искушайте пользователей тапать по тому, что не тапается. У пользователей тачскрина нет возможности подсмотреть :hover или :focus состояние. Ну или есть, но происходит это всё не очень удобно, обычно уже после свершившегося тапа.

Разделитель

Доступность

может быть недоступен на архаичных браузерах или устройствах. У кнопок не применятся стили без специальных JavaScript скриптов.
Но вас это не должно беспокоить. На таких устройствах часто и JavaScript не работает. И быть может CSS.

Вообще если следовать идеологии что всё, что должно обрабатываться JavaScript'ом, должно добавляться JavaScript'ом, такой проблемы вовсе не возникнет.

Разделитель

Поведение внутри формы

по умолчанию имеет атрибут type=submit даже если его не прописать.

Ещё этот атрибут может принимать значения reset для сброса заполнения в форме
и button чтобы исключить влияние на форму. Правила хорошего тона предполагают,
что везде нужно писать .

Но на деле можно ограничится полной записью только внутри ,
type=submit в остальных местах ни на, что не влияет.

Это кстати отличный сбособ для стилизации кнопки отправки формы.
В отличии от , в содержимое
button можно писать любой HTML код, а не только текст.
Например


Это даёт даже больше свободы в стилевом оформлении чем

Разделитель

Состояния

Похожи на состояния у ссылок за исключением того, что у кнопок нет состояния :visited , зато есть состояние :disabled .
Обычно дефолтное оформление браузера выпиливается основательно, иногда с нейтрализацией отображения состояний отличных от обычного.
Да. Этот гайд для тебя, любитель превратить веб-страницу в бумажный аналог.

Стилей для этих штучек понадобится немного больше, но всё не так страшно. Кроме того ребята из Twitter и отчасти Google уже позаботились о реализации велосипеда.
Тёплый ламповый Bootstrap "и новомодный MaterializeCSS, например.

Разделитель

Отображение

отображение состояний кнопки

Так выглядит в моём Chrome 54:

На картинке button , button:hover , button:focus , button:active соответственно.

Без излишеств. Но учитывая движение Google в направлении Material Design, вполне может статься так, что в скором времени их заменят на подобные аналоги.

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


Почему возникает проблема

Ссылка — это элемент навигации. Обычно она представляет собой текст, нажимая на который, пользователь переходит на другую страницу или перемещается к другому месту на текущей странице. То есть ссылка отвечает за взаимосвязь веб-ресурсов или разделов одного ресурса.

Ссылки создаются с помощью тега .

Для кнопок используют тег .

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

Пример двух кнопок, где нижняя похожа на ссылку Пример ссылки, похожей на кнопку

Что случится, если вместо ссылки сделать кнопку

Контекстное меню при клике правой кнопкой мыши на кнопку

Контекстное меню при клике правой кнопкой мыши на кнопку

Такая кнопка не позволит открыть страницу в новой вкладке и через комбинацию клавиш — Ctrl и левая кнопка мыши.

При наведении курсора на правильную ссылку её адрес появляется внизу окна браузера. URL-адрес, обёрнутый в , не отобразится.

Адрес правильной ссылки в окне браузера при наведении на неё курсора

Адрес правильной ссылки в окне браузера при наведении на неё курсора

Что произойдёт, если вместо кнопки сделать ссылку

Когда мы кликаем на ссылку правой кнопкой, браузер показывает, что можно сделать именно со ссылкой.

Контекстное меню при клике правой кнопкой мыши на ссылку

Контекстное меню при клике правой кнопкой мыши на ссылку

Как определить элемент по макету

Конкретные указания часто прописывают в техническом задании к макету. В стайлгайде самого макета можно посмотреть состояния элемента.

У ссылки должны быть стили для состояния покоя, при наведения курсора :hover , в момент нажатия :focus , активного :active и иногда состояния, когда пользователь уже посещал эту страницу :visited .

У кнопки нет состояния :visited , зато есть состояние блока :disabled .

Состояния ссылок в стайлгайде макета

Состояния ссылок в стайлгайде макета

Однако рассчитывать только на макет не нужно. У ссылки может не быть :visited , а у блока :disabled — это может запутать.

Всё-таки кнопка или ссылка?

Если дизайнер по каким-то причинам не отрисовал состояния вообще, то придётся руководствоваться одной логикой.

Ссылка

Кнопка

За что отвечает

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

Что видит пользователь

При наведении курсора на ссылку внизу окна браузера возникает её адрес.

При наведении курсора на ссылку внизу окна браузера не отображается адрес.

Через меню по клику правой кнопкой мыши нельзя скопировать адрес или поделиться им.

Пример, чтобы расставить всё по своим местам

На макете отрисована фраза «Войти». Если клик по ней должен открывать окно для ввода регистрационных данных на этой же странице, это кнопка. Если при нажатии должна открываться отдельная страница для входа, это ссылка.


Другие великие противостояния

Ссылки ссылками, а промокод VESELO даст приятную скидку на любой профессиональный курс в HTML Academy. Например, на курс «Анимации для фронтендеров» можно записаться в любой момент, а пользы для карьеры будет целый вагон.

Читайте также: