Статьи

Доступные сноски с CSS

На днях я играл со счетчиками CSS и думал об их использовании для работы со сносками. Согласно Плагиату, который имеет удивительно длинную статью по этому вопросу, сноски:

[…] Заметки, размещенные внизу страницы. Они цитируют ссылки или комментируют обозначенную часть текста над ним.

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

Проблема сносок в Интернете заключается в том, что их может быть сложно поддерживать. Если вам часто приходится работать с одним и тем же документом, меняя порядок разделов и добавляя ссылки по пути, может быть утомительно пересчитывать все существующие сноски. Например, если у вас есть 3 существующие ссылки на сноски в документе, и вы хотите добавить еще одну, но для части содержимого, которая встречается раньше всех остальных, вы должны переименовать их все. Не хорошо…

Мы могли бы использовать счетчики CSS, чтобы сделать все это намного проще. Что если нам не нужно было вести нумерацию вручную, и это можно сделать автоматически? Единственное, на что нам следует обратить внимание, это то, что порядок фактических примечаний в нижнем колонтитуле соответствует порядку появления ссылок в тексте.

Создание образца документа

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

<article>
  <h1>CSS-Powered Footnotes</h1>

  <p>Maintaining <a href="#footnotes">footnotes</a> manually can be a pain. 
  By using <a href="#css">CSS</a> <a href="#css-counters">counters</a> to add 
  the numbered references in the text and an ordered list to display the actual 
  footnotes in the footer, it becomes extremely easy.</p>

  <footer>
    <ol>
      <li id="footnotes">Footnotes are notes placed at the bottom of a page. They 
      cite references or comment on a designated part of the text above it.</li>

      <li id="css">Cascading Style Sheets</li>

      <li id="css-counters">CSS counters are, in essence, variables maintained by 
      CSS whose values may be incremented by CSS rules to track how many times 
      they're used.</li>
    </ol>
  </footer>
</article>

Наш пример облегчен: у нас есть некоторый контент в элементе <article><a><footer>

С несколькими стилями это может выглядеть так:

Доступные сноски с CSS - сырая версия

Сделать его доступным

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

 <footer>
  <h2 id="footnote-label">Footnotes</h2>
  <ol>
    ...
  </ol>
</footer>

Затем мы хотим описать все наши ссылки этим заголовком, используя атрибут aria-describedby

 <p>Maintaining <a aria-describedby="footnote-label" href="#footnotes">footnotes</a> 
manually can be a pain. By using <a aria-describedby="footnote-label" href="#css">CSS</a> 
<a aria-describedby="footnote-label" href="#css-counters">counters</a> to add the 
numbered references in the text and an ordered list to display the actual footnotes 
in the footer, it becomes extremely easy.</p>

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

Добавление ссылок

Я знаю, что вы думаете: он сказал, что будут счетчики CSS. Где счетчики CSS? Не беспокойся, друг мой, они идут.

То, что мы собираемся сделать, это увеличить счетчик для каждой ссылки в документе, у которого атрибут aria-describedbyfootnote-label Затем мы отобразим счетчик, используя ::after Оттуда, это все о применении стилей CSS.

 /**
 * Initialiazing a `footnotes` counter on the wrapper
 */
article {
  counter-reset: footnotes;
}

/**
 * Inline footnotes references
 * 1. Increment the counter at each new reference
 * 2. Reset link styles to make it appear like regular text
 */
a[aria-describedby="footnote-label"] {
  counter-increment: footnotes; /* 1 */
  text-decoration: none; /* 2 */
  color: inherit; /* 2 */
  cursor: default; /* 2 */
  outline: none; /* 2 */
}

/**
 * Actual numbered references
 * 1. Display the current state of the counter (e.g. `[1]`)
 * 2. Align text as superscript
 * 3. Make the number smaller (since it's superscript)
 * 4. Slightly offset the number from the text
 * 5. Reset link styles on the number to show it's usable
 */
a[aria-describedby="footnote-label"]::after {
  content: '[' counter(footnotes) ']'; /* 1 */
  vertical-align: super; /* 2 */
  font-size: 0.5em; /* 3 */
  margin-left: 2px; /* 4 */
  color: blue; /* 5 */
  text-decoration: underline; /* 5 */
  cursor: pointer; /* 5 */
}

/**
 * Resetting the default focused styles on the number
 */
a[aria-describedby="footnote-label"]:focus::after {
  outline: thin dotted;
  outline-offset: 2px;
}

Теперь это выглядит так:

Доступные сноски с CSS

Довольно мило, а? В качестве последнего штриха при переходе к сноске из ссылки мы хотим выделить примечание в нижнем колонтитуле, чтобы мы фактически увидели, на какую ссылку ссылаются, что мы можем сделать с помощью псевдокласса :target

 footer :target {
  background: yellow;
}

Это немного сырой, так что не стесняйтесь настраивать. Хотя я должен сказать, что мне нравится чистый желтый для выделения – это выглядит так аутентично:

Доступные сноски с CSS - сноска нацелена

Нашей демоверсии нужен последний элемент, который должен быть полностью доступным (а также довольно крутым): ссылки на контент. Подумайте об этом: вы фокусируете ссылку, переходите к соответствующей заметке в нижнем колонтитуле, читаете ее, а затем … ничего. Вам нужен способ вернуться туда, где вы оставили!

Предоставить эти ссылки не так сложно: нам нужно только добавить уникальный идентификатор ID для каждой ссылки в контенте, чтобы они могли быть связаны с. Я решил пойти просто и взять идентификатор, на который они ссылаются, и просто добавить к нему -ref

 <p>Maintaining <a aria-describedby="footnote-label" href="#footnotes" id="footnotes-ref">footnotes</a> 
manually can be a pain. By using <a aria-describedby="footnote-label" href="#css" id="css-ref">CSS</a> 
<a aria-describedby="footnote-label" href="#css-counters" id="css-counters-ref">counters</a> 
to add the numbered references in the text and an ordered list to display the actual 
footnotes in the footer, it becomes extremely easy.</p>

Затем каждый элемент списка из нижнего колонтитула имеет собственную ссылку на соответствующий id Содержимое ссылки – это значок Unicode обратной ссылки (↩), и он имеет атрибут aria-label

 <ol>
  <li id="footnotes">Footnotes are notes placed at the bottom of a page. 
  They cite references or comment on a designated part of the text above it. 
  <a href="#footnotes-ref" aria-label="Back to content"></a></li>
  <li id="css">Cascading Style Sheets 
  <a href="#css-ref" aria-label="Back to content"></a></li>
  <li id="css-counters">CSS counters are, in essence, variables maintained 
  by CSS whose values may be incremented by CSS rules to track how many 
  times they're used. <a href="#css-counters-ref" aria-label="Back to content"></a></li>
</ol>

Чтобы нацелить эти ссылки в CSS, мы можем полагаться на атрибут aria-labelaria-describedby

 [aria-label="Back to content"] {
  font-size: 0.8em;
}

Вот как выглядит финальная демка:

Последние мысли

С помощью всего лишь нескольких строк CSS и нескольких атрибутов ARIA нам удалось создать сноски на основе CSS, которые доступны и не нуждаются в JavaScript. Как это круто?

По теме я очень рекомендую Semantic CSS с интеллектуальными селекторами от Heydon Pickering . Кроме того, не забудьте проверить a11y.css от Gaël Poupard, чтобы проверить доступность ваших страниц.

Огромное спасибо Хейдону Пикерингу за его ценную помощь в доступе к этой демонстрации.