Заметки в категории «Вёрстка» (страница 3)

Заголовок для поля ввода и его доступность

Подпись или заголовок для поля ввода размечается тегом <label>. Наличие связанного с ним элемента <input>, <textarea> или <select> не является обязательным условиям. Хотя, при отсутствии такого элемента, сам заголовок приобретает другой смысл и может быть размечен другим тегом.

<label> может быть как обёрткой для поля ввода, так и быть связанным с ним с помощью атрибутов. Вот несколько типовых вариантов разметки:

Вариант №1:

<label>
  Фамилия <input type="text" name="family-name">
</label>

Вариант №2:


<label for="family-name-field">Фамилия</label>
<input id="family-name-field" type="text" name="family-name">

Клик по надписи в обоих случаях приведёт к том, что связанное с этой надписью поле ввода получит фокус. В первом случае связь инпута и лейбла определяется явно (фокус получает первое дочернее поле ввода). Во втором случае связь осуществляется с помощью атрибута id у поля ввода и аналогично значения у атрибута for лейбла.

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

Подсказка в поле ввода

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


<input type="text" placeholder="Фамилия" name="family-name">

Но не стоит путать подсказку и подпись.

Доступность

Но совсем отказываться от <label> нельзя из-за того, что вспомогательные технологи не зачитывают подсказки. Тег нужно оставить в разметке, но скрыть его от пользователя.


<label for="family-name-field" class="hidden">Фамилия</label>
<input id="family-name-field" type="text"
    placeholder="Фамилия" name="family-name">

Скрыв подпись к полю ввода с помощью стиля display: none , мы не решили проблему с доступностью текста подписи. Вспомогательные технологии игнорируют элементы, к которым применён такой стиль.

Вернуть видимость текста можно опять же несколькими способами.

Способ №1


<label>
  <span class="hidden">Фамилия</span>
  <input type="text" placeholder="Фамилия" name="family-name">
</label>

Текст подсказки оборачивается в дополнительный элемент, который уже скрывается стилем display: none.

Скринридеры понимает, что <label> видим для пользователя и зачитывает его содержимое, не обращая внимания на то, что оно оказывается скрытым.

Способ №2


<label id="family-name-label"
    for="family-name-field" class="hidden">Фамилия</label>
<input aria-labelledby="family-name-label"
    id="family-name-field" type="text"
    placeholder="Фамилия" name="family-name">

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

Как вариант, явно указать подпись можно с помощью атрибута aria-label.

Способ №3


<label for="family-name-field" class="visuallyhidden">Фамилия</label>
<input id="family-name-field" type="text"
    placeholder="Фамилия" name="family-name">

Класс visuallyhidden выключает элемент из потока и делает его размеры 1×1 пиксель. Формально подсказка остаётся видимой и зачитывается ридерами, но фактически её не видно на экране.

У всех способов есть свои плюсы и минусы:

  • первый вариант оказался в итоге самым компактным и универсальным, но появился дополнительный элемент в разметке;
  • второй вариант самый громоздкий (требуется слишком много атрибутов и два уникальных идентификатора), но в то же время и самый надёжный;
  • третий вариант выглядит хорошим компромиссом, если не позаботиться о том, чтобы id инпута не повторялся на странице.
Комментарии к заметке: 2

Охота за последним видимым элементом

Последний элемент среди соседей можно выбрать селектором псевдо-класса :last-child.


.item { display: block; }
.item:last-child { font-weight: bold; }

Разметка:


<div>
  <div class="item item_rank_1">Object “A”</div>
  <div class="item item_rank_1">Object “B”</div>
  <div class="item item_rank_0">Object “C”</div>
</div>

Но, если с помощью медиа-запроса скрыть часть элементов списка, то получить последний видимый элемент уже так просто не выйдет.


@media (max-width: 600px) {
  .item_rank_0 { display: none; }
}

Казалось бы можно использовать селектор .item_rank_1:last-child , но это так не работает. Псевдо-класс :last-child позволяет найти только одного последнего ребёнка своего родителя.

Но мы уже живём в мире HTML5, где можно грабить корованы и придумывать свои собственные теги (оригинал ). По этому вместо того, чтобы отличаться классами, элементы будут отличаются названиями тегов.


<div>
  <item-rank-1 class="item">Object “A”</item-rank-1>
  <item-rank-1 class="item">Object “B”</item-rank-1>
  <item-rank-0 class="item">Object “C”</item-rank-0>
</div>

Да, так тоже можно, если очень хочется.

Теперь в медиа-запросе можно использовать селектор :last-of-type для того, чтобы получить последний элемент группы, которая не была скрыта.


@media (max-width: 600px) {
  item-rank-0.item { display: none; }
  item-rank-1:last-of-type { font-weight: bold; }
}

Таким способом можно создавать любые теги и они будут прекрасно поддаваться оформлению через CSS. Для IE < 9 нужно будет их предварительно создать с помощью JavaScript так как делаем это для новых HTML5 элементов.

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

Живой пример

PS: Не забудьте, что вес тега меньше, чем вес класса при определении специфичности селектора. Так же в названии тега обязательно должен быть символ - , чтобы парсер мог отличить обычные элементы от ваших собственных.

Комментарии к заметке: 21

Больше семантики для логотипа

Уже долгое время не утихают споры о том как «правильно» разметить логотип. О некоторых интересных доводах можно, например, прочесть в статье «Ваш логотип — всё еще изображение … как и мой! ». Независимо от того какими именно тегами размечен ваш логотип, логотип компании или продукта, этой разметке всегда можно добавить семантики.

В словаре Schema.org у объекта Organization есть поле logo, которое указывает на картинку с логотипом.


<div itemscope itemtype="http://schema.org/Organization">
  <a href="http://www.apple.com/" itemprop="url">
    <span itemprop="name">Apple</span>
    <img itemprop="logo" alt="Apple Logo"
      src="http://www.apple.com/apple-logo.png">
  </a>
</div>

У Product, Person и Organization есть другое поле — brand. Оно, в свою очередь, может ссылаться на Organization или Brand, в котором уже есть поле logo.


<!-- разметка продукта -->
<div itemscope itemtype="http://schema.org/Product" itemref="_brandApple">
  <a href="http://www.apple.com/pr/products/iphone/iphone.html" itemprop="url">
    <span itemprop="name">iPhone</span>
    <img itemprop="image" alt="iPhone 5 Black"
      src="http://images.apple.com/products/iPhone_5_Black.jpg">
  </a>
</div>

<!-- разметка логотипа -->
<div itemscope itemtype="http://schema.org/Brand" itemprop="brand" id="_brandApple">
  <a href="http://www.apple.com/" itemprop="url">
    <span itemprop="name">Apple</span>
    <img itemprop="logo" alt="Apple Logo"
      src="http://www.apple.com/apple-logo.png">
  </a>
</div>

Итак, чтобы добавить семантики разметке логотипа, опишите его схемой Brand и ссылайтесь на него, там, где это потребуется. Безусловно, логотип может быть так же и самодостаточным объектом на странице.

Комментарии к заметке: 5

Эффективное использование name и url в микроразметке

Каждый значимый объект микроразметки должен иметь свойства name и url . Эти свойства наследуются всеми объектами от Thing . Хоть форматом и не накладывается жестких ограничений на их обязательное присутствие, но фактически, чтобы получить максимальную пользу от микроразметки, они просто необходимы.

Свойство name

Отвечает за название объекта. Оно, скорее всего, будет использоваться для отображения пользователю.


<div itemscope itemtype="http://schema.org/Event">
  <span itemprop="name">Собрание рыцарей круглого стола</span>
  <time datetime="2013-08-23T12:00:00+06:00"
      itemprop="startDate">23 августа 2013 в 12:00</time>
</div>

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

Если подходящего слова или словосочетания не нашлось, то явно укажем его в теге <meta>.


<div itemscope itemtype="http://schema.org/Event">
  <span itemprop="name">Собрание рыцарей
    <span itemscope itemtype="http://schema.org/Product">
      круглого стола
      <meta itemprop="name" content="круглый стол">
    </span>
  </span>
  <time datetime="2013-08-23T12:00:00+06:00"
      itemprop="startDate">23 августа 2013 в 12:00</time>
</div>

Эта разметка будет разобрана на два объекта:


event
  itemType = http://schema.org/Event
  name = Собрание рыцарей круглого стола
  startdate = 2013-08-23T12:00:00+06:00

product
  itemType = http://schema.org/Product
  name = круглый стол

Свойство url

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


<div itemscope itemtype="http://schema.org/Event">
  <a href="/meetups/2013-08-23/" itemprop="url name">Собрание
      рыцарей круглого стола</a>
  <time datetime="2013-08-23T12:00:00+06:00"
      itemprop="startDate">23 августа 2013 в 12:00</time>
</div>

url активно используется для генерации сниппетов Гугла. Поэтому даже при правильной разметке нужный сниппет не будет отображаться в выдаче только из-за отсутствия или не корректном значении этого свойства.

Распространённой ошибкой при указании значения url является банальная подстановка текущего URL страницы, на которой располагается объект. Это допустимо только, если на этой странице размещена только одна сущность. Когда сущностей несколько (например, список событий) или, что хуже, появляются сущности разного типа, то указать один и тот же URL для них нельзя.

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

The fragment is an optional part separated from the front parts by a hash («#»). It holds additional identifying information that provides direction to a secondary resource, e.g., a section heading (in an article) identified by the remainder of the URI. When the primary resource is an HTML document, the fragment is often an id attribute of a specific element and web browsers will make sure this element is visible.

Формально URL уже будут отличаться друг от друга, хотя и ведут на одну и ту же страницу. Это и позволяет отличить различные объекты на ней.


<div itemscope itemtype="http://schema.org/Event" id="meetup-2013-08-23">
  <a href="#meetup-2013-08-23" itemprop="url name">Собрание
      рыцарей круглого стола</a>
  <time datetime="2013-08-23T12:00:00+06:00"
      itemprop="startDate">23 августа 2013 в 12:00</time>
</div>

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

И в заключении хочу обратить внимание, что значение атрибута id может начинаться только с латинской буквы или символа _ . Любые другие символы могут встречаться только начиная со второй позиции в строке.

Оставте свой комментарий

Изящная деградация для SVG картинок

Алексей Тен на своём сайте опубликовал интересную технику подмены SVG изображения на растровый вариант для браузеров, без поддержки SVG.


<svg width="96" height="96">
  <image xlink:href="svg.svg" src="svg.png" width="96" height="96"/>
</svg>

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

Замечу лишь, что деградация слегка агрессивная по отношению с старым версиям Safari (включая iOS), Opera Mobile и Opera Mini. Эти браузеры не распознают inline SVG, но прекрасно отображают SVG в виде внешнего файла, подключаемого через тег <img>.

PS: Крис Койер в свой статье сообщает, что в IE 9, 10 и 11 всё же есть дополнительный запрос альтернативной картинки, а так же приводит ещё несколько техник.

Оставте свой комментарий