home

Псевдо-селектор :target

Псевдо-селектор :target срабатывает при совпадении хэша в URL и ID элемента на странице.

<section id="voters">
   Content
</section>
:target {
   background: yellow;
}

Пока URL будет таким как на картинке, блок section будет иметь желтый фон.

Где это можно использовать?

Один из примеров использования – подсветка “состояний”. Когда URL страницы содержит некий хэш, страница находится в соответствующем состоянии.  Этот способ напоминает манипулирование именами классов, хотя и не является таким универсальным. Все то, что вы обычно делаете изменяя классы, можно использовать для изменения состояния элемента, когда к нему применяется псевдо-селектор :target. Например: изменение цвета, позиционирования, изменение картинок, отображение/скрытие различных элементов, и т.д.

Существует три признака оправданного использования псевдо-селектора :target :

  1. Когда необходимо подчеркнуть “состояние”
  2. Когда приемлемо резкое “перепрыгивание” страницы вниз
  3. Когда приемлемо влияние на историю браузера

Давайте рассмотрим это немного подробнее.

Как получить хэш в URL?

Самый распространенный способ – пользовательский клик по ссылке, включающей хэш. Ссылка может быть как внутренней (которая указывает на текущую страницу), так и полноценной, оканчивающейся хэш-тэгом и значением. Например:

<a href="#voters">Go To There</a>

<a href="http://example.com/#specific-part">Go To There</a>

“Перепрыгивание” страницы

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

Например, однажды я (прим. я – Крис Койер, автор блога css-tricks.com) пробовал различные техники, для имитации создания CSS-табов, и в конце-концов остановился на чекбокс-хаке, поскольку только он позволял обойти проблемы с перепрыгиванием страницы. Йен Хэнсон, создатель CSS Science, также реализовал несколько примеров табов. Его третий пример использует :target и абсолютно позиционируемые элементы, спрятанные вверху страницы, для предотвращения “прыжка”. Это довольно умно, но все же не решение проблемы, поскольку страница прыгает вверх, табы должны располагаться ниже области прыжка.

Прекрасный пример: подсветка секций

Проблема: Клик по хэш-ссылке прокручивает страницу к указанной секции, которая по возможности будет удобно расположена в верхней части окна браузера. Но что если на странице немного контента, а скролл  и вовсе отсутствует?  В этом случае, секция останется в видимой области, но не будет прибита к верху страницы, что странно и не совсем удобно.

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

Давайте это исправим!

Один из самых знаменитых методов исправления этой проблемы, называется “Yellow Fade Technique” (Техника Желтого Затухания). Эта техника была разработана компанией 37 signals, специально для того чтобы обратить внимание пользователей на только что добавленный на страницу контент . Джонатан Снук портировал эту идею на CSS и объединил ее с псевдо-селектором :target.

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

HTML-структура представляет собой обычную навигацию, с привязкой ссылок к соответствующим секциями через ID:

<nav>
  <a href="#one">1</a>
  <a href="#two">2</a>
  <a href="#three">3</a>
</nav>

<section>
  <div id="one"><h2>One</h2>Pellentesque habitant morbi ...</div>
  <div id="two"><h2>Two</h2>Pellentesque habitant morbi ...</div>
  <div id="three"><h2>Three</h2>Pellentesque habitant morbi ...</div>
</section>​

При активации :target, секция немного сдвигается вправо, через трансформацию translateX, поскольку она предотвращает любые проблемы с отступами и странное выравнивание текста; также слева появляется красный маркер, выполненный с помощью кейфрейм-анимации.

:target {
  -webkit-animation: highlight 1s ease;
  -moz-animation: highlight 1s ease;
  -webkit-transform: translateX(20px);
  -moz-transform: translateX(20px);
  -ms-transform: translateX(20px);
  -o-transform: translateX(20px);
}
@-webkit-keyframes highlight {
  0% { border-left-color: red; }
  100% { border-left-color: white; }
}
@-moz-keyframes highlight {
  0% { border-left-color: red; }
  100% { border-left-color: white; }
}
section > div {
  border-left: 40px solid white;
  padding: 10px;
  -webkit-transition: all 0.5s ease;
  -moz-transition: all 0.5s ease;
  -ms-transition: all 0.5s ease;
  -o-transition: all 0.5s ease;
  padding-right: 50px;
  margin-left: -20px;
}

Вот и все. Код отвечает принципам прогрессивного улучшения, поэтому будет нормально выглядеть и работать во всех браузерах.

Демо-страница.

Боремся с прыжками страницы

Предположим, вам понравилась идея использования :target для подсветки секций, но при этом хотелось бы избежать прыжков страницы, при клике по хэш-ссылкам. С помощью jQuery вы можете предотвратить дефолтное поведение  всех хэш-ссылок, а затем использовать метод pushState() (или replaceState()), для изменения URL без передвижения страницы.

$("a[href^=#]").on("click", function(e) {
  e.preventDefault();
  history.pushState({}, "", this.href);
});

Метод replaceState() отличается от pushState() тем, что не добавляет запись о смене URL в историю браузера. Так что, вы можете использовать любой из этих методов на свое усмотрение.

Плохие новости

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

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

Перевод статьи «On :target», автор Chris CoyierПсевдо-селектор

Псевдо-селектор :target: 3 комментария

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

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