Распечатать статью

Про :target

Перевод статьи On :target с сайта css-tricks.com, автор Крис Койер, переводчик Влад Мержевич

Псевдоселектор :target срабатывает, когда между собой совпадают значение после решётки в URL (это значение будем называть «хэш») и идентификатор элемента.

Здесь после решётки в URL идёт «voters»

Здесь после решётки в URL идёт «voters»

 

HTML

<section id="voters">
  Контент
</section>

CSS

:target {
   background: yellow;
};

Пока используется указанный URL, элемент <section> будет жёлтого фона, как это задано в нашем CSS.

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

Главной возможностью является изменение стиля используя «состояния». Когда страница имеет определённый хэш, это и есть состояние. Оно не так универсально, как манипуляция с именами классов (так как хэш может быть единственным и он связан только с одним элементом), но в чём-то похоже. Всё, что вы можете сделать изменением класса для модификации состояния, можно сделать, когда элемент находится в состоянии :target. Например: сменить цвет, заменить изображение, что-нибудь скрыть/показать, в общем, что угодно.

Я хотел бы упомянуть те случаи, когда :target является хорошим выбором.

  • Когда необходимо «состояние».
  • Когда требуется переход к разным частям страницы.
  • Когда следует повлиять на историю браузера.

Все эти вещи мы затронем в этой статье.

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

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

Примеры:

<a href="#voters">Перейти</a>
<a href="http://example.com/#specific-part">Перейти</a>

Прыжки по странице

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

К примеру, однажды я попробовал разные методы для получения функциональных вкладок на CSS, но в итоге решил использовать чекбоксы и это была лучшая идея, потому что она лишена проблемы с прыгающей страницей. Ян Ханссон в CSS Science также показал несколько хороших примеров вкладок. Его третий пример использует :target, абсолютно позиционированные элементы спрятаны в верхней части страницы для предотвращения прыжков по странице. Это умно, но в действительности никак не решает проблему, потому что означает, что страница будет прыгать вверх когда вкладки располагаются ниже на странице.

Идеальное применение: выделение разделов

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

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

Это может дезориентировать

Это может дезориентировать

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

Так что давайте решать проблему!

Один известный метод называется Техника исчезновения жёлтого. Он был использован 37 signals в ситуации, когда новый контент добавлялся на страницу и к нему пытались привлечь внимание пользователей. Джонатан Снук перенёс идею в CSS и соединил её с :target.

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

Структура состоит из навигации содержащей ссылки на разделы по их 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 для замены URL без добавления записи в историю браузера. Иногда это нужно, иногда нет. По крайней мере, у вас есть выбор, в отличие от исходного поведения, когда щелчок по хэш-ссылке всегда добавляется в историю.

Но есть и плохая новость

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

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

Источник:  css-live.ru
Вы можете оставить комментарий, или обратную ссылку на Ваш сайт.

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

Похожие статьи