Ссылка в заголовке или заголовок в ссылке?

Перевод статьи:  Link in Header? Or Header in Link?
Автор:  Chris Coyier

Эрик Рейнж (Eric Range) вынес на обсуждение, затрагиваемый данным постом вопрос. Что лучше использовать в качестве обертки, заголовок или ссылку при совместном применении соответствующих элементов? С точки зрения HTML5 оба варианта абсолютно вали́дные.

Ссылка в заголовке:

<h1>
<a href="#">
Ten Ways to Have Yourself a Merry Little Christmas
</a>
</h1>

Заголовок в ссылке:

<a href="#">
<h1>
Ten Ways to Have Yourself a Merry Little Christmas
</h1>
</a>

Какой из них выберете вы? Я бы сказал, что все зависит от ситуации.

Кликабельная область.

По умолчанию элемент ссылки является внутристрочным (inline), а заголовок блочным (block). Таким образом, если не изменять эти исходные установки с помощью CSS, то кликабельная область для h1 > a будет соответствовать той, которая выделена светло красным цветом:

Ссылка в заголовке.

И наоборот, вариант a > h1 делает кликабельной всю область блочного элемента заголовка.

Заголовок в ссылке.

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

Вы, вероятно, думаете: «Увеличенная кликабельная область? Но это же хорошо!», что, в принципе, разумно, за исключением следующих моментов:

Неудобства при выделении текста.

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

Выделение текста пользователем.
Странности компоновки.

Наблюдая за этим, вы, конечно же, думаете, что все решаемо с помощью CSS, но как вы отнесетесь к вот такому «сюрпризу», имеющему место при использовании подхода a > h1, в котором у элемента ссылки есть внутренний отступ (*образуемый установкой ненулевого значения для свойства padding либо border):

Проблемы компоновки.

* Здесь не все так очевидно и поэтому давайте немного проясним ситуацию. Дело в том, что согласно стандарту CSS 2.1 при включении в элемент строчного уровня блочного элемента, строчный элемент-обертка разбивается на три внутристрочных блока, один из которых является внутренним «реальным» блоком (в нашем случае заголовком h1), а другие два являются анонимными внутристрочными блоками, образуемыми в данном случае браузером непосредственно перед и после «реального» внутристрочного блока (см. здесь). Такое стандартное поведение браузера остается незаметным до тех пор, пока отображаемая область внешнего элемента ссылки определяется исключительно его содержимым, т.е. текстом. Текст есть только в «реальном» внутристрочном блоке, а анонимные по причине отсутствия контента установлены в нулевую высоту и ширину и поэтому невидимы. Как только мы явным образом влияем на размерность анонимных внутристрочных блоков, устанавливая отличную от нуля границу или внутренний отступ для элемента ссылки, мы делаем их видимыми. Убедитесь в этом сами.

Два заголовка, одна ссылка.

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

<a href="#">
<h1>Cheese is favorite holiday gift</h1>
<p class="subtitle">From a one-person survey held in central Wisconsin</p>
</a>

Вопросы доступности.

Не знаю, я не уверен. А есть ли они вообще в данном случае?

Кто же победил?

Я склоняюсь к варианту h1 > a, как и большинство других людей, что демонстрирует неформальный опрос.

Что, все еще есть над чем поразмышлять?

Обзор комментариев

Тема наделения всех элементов параметрами href="" и target="" обсуждается уже давно. Вопрос упирается главным образом в семантику, а это объясняет то, почему поведение элементов до сих пор не стандартизировано. Кроме того есть мнение, что это приведет к путанице при использовании клавиатуры в качестве основного средства передвижения по сайту, так как все станет фокусируемым, что в свою очередь приведет к возникновению проблем доступности и юзабилити. С этим трудно не согласиться.

Неплохим решением был бы вот такой вариант, если бы не JavaScript:

  • Для семантики включите в элемент атрибут role="link".
  • После клика по элементу активируйте событие open(url, target) и не забудьте при этом в качестве второго параметра указать _self при клике левой кнопкой и _blank — средней.
  • В заключение, чтобы включить наш элемент в последовательность табуляции, добавляем в него атрибут tabindex="0"

Что касается стандарта, то начиная с HTML 5, вложение блочных элементов в строчные уже не является невалидным приемом, хотя браузеры и раньше поддерживали его, несмотря на то, что технически это считалось некорректным. Тем не менее, с семантической точки зрения оправданность такого приема все равно трудно объяснить. Если несколько расширить рамки обсуждаемого в статье вопроса, не ограничиваясь заголовком и ссылкой, то, в принципе, этот случай можно отнести к категории некорректных, под которую подходит и использование отличных от li (или script) элементов непосредственно внутри элемента списка ul (или ol). Более того, даже сейчас есть основания утверждать, что вложенность блочных элементов в строчные все еще невалидна. В первую очередь потому, что в HTML5 уже нет блочных и строчных элементов. В рамках семантики текстового уровня определены фразовые элементы, а для выделения текстовой информации в параграфы и секции используются структурные и группирующие элементы, которые визуализируются посредством боксов строчного либо блочного уровня. Причем новая контентная модель HTML5 предусматривает принадлежность элемента как одной категории контента, так и к нескольким одновременно. Что касается элемента a, то он больше не является фразовым (т.е. выражаясь термином ранних стандартов внутристрочным), а его контентная модель зависит от содержимого. Можно конечно сделать его блочным с помощью декларации display:block, но это уже CSS.

Вообще-то, HTML5 не может допускать включение блоков в строчные элементы априори, поскольку в этом стандарте термины «блочный» и «строчный» элемент вообще отсутствуют. Теперь эти термины используются исключительно в CSS спецификации, которая, как раз таки и не позволяет этого делать. Вложенность HTML элементов и вложенность CSS боксов — теперь это разные, имеющие отдельную логику вещи. Однако в обоих случаях следует придерживаться правил. Если вам действительно не обойтись без включения блока в строчный элемент, то для того, чтобы избежать описанных выше проблем компоновки, вам необходимо для всех элементов содержащих блоки использовать декларацию display:block (или inline-block), независимо от типа HTML элемента, тем более, что HTML5 не запрещает подобную вложенность.

А вопросы доступности у этой темы действительно есть и они неплохо описаны Роджером Йохансоном и Стивом Фолкнером

Еще несколько доводов за и против рассматриваемых здесь вариантов.

h1 > a

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

— в случае с достаточно длинным заголовком, который разбивается на несколько строк, это приводит к смене значка курсора при попадании его между строк текста, что может вызывать недовольство некоторых пользователей, так как при этом им приходится так сказать «прицеливаться» перед кликом.

а > h1

— в мобильных устройствах (по крайней мере, в iOS) выделение находящегося в ссылке заголовка приводит к выбору ссылки, а не текста самого заголовка.

— возникают сложности в случае необходимости стилизации находящихся внутри ссылки элементов в связке с событиями hover, focus и active.

* Примечание переводчика.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *