CSS псевдокласс :target
Псевдокласс :target выбирает элемент, на который указывает фрагмент текущего URL. Узнайте о псевдоклассе и практикуйтесь на примерах.
Псевдокласс :target соответствует элементу, чей id совпадает с фрагментом текущего URL — частью после символа #. Когда вы переходите по URL вида page.html#section2, элемент с id="section2" становится целью, и :target позволяет стилизовать его.
На этой странице объясняется, как работает :target, когда его стоит применять, каковы его ограничения, и рассматриваются четыре практических паттерна без JavaScript: подсветка на странице, меню с вкладками, модальное окно и лайтбокс.
Как работает :target
Браузер отслеживает один целевой элемент на странице — тот, чей id совпадает с текущим фрагментом URL. Нажав на ссылку на той же странице, например <a href="#section2">, вы обновляете фрагмент, что:
- прокручивает соответствующий элемент в поле зрения, и
- делает этот элемент соответствующим
:target, применяя все написанные для него стили.
Поскольку переход по фрагменту создаёт реальную запись в истории, кнопка «Назад» работает как «Отмена»: она возвращает к предыдущему фрагменту (или к отсутствию фрагмента), поэтому меню, модальное окно или лайтбокс на основе :target закрываются сами, когда пользователь нажимает «Назад».
/* Style the element currently referenced by the URL fragment */
:target {
border: 2px solid #1c87c9;
background-color: #eee;
}Несколько важных моментов:
- Только один элемент может быть целью одновременно — фрагмент имеет единственное значение, поэтому
:targetстилизует не более одного элемента на странице. - Это состоятельный селектор. Состояние хранится в URL, а не в разметке или JavaScript — именно поэтому он может управлять интерактивными виджетами без скриптов.
- Голый
#сбрасывает цель. Ссылка наhref="#"(илиhref="#nonexistent") удаляет совпадение — именно так работают кнопки «закрыть» в примерах с модальным окном и лайтбоксом ниже.
Когда использовать
Используйте :target, когда нужна лёгкая интерактивность без скриптов, естественно привязанная к URL:
- Подсветка цели перехода по ссылке на той же странице (сноски, элементы глоссария, оглавление).
- Виджеты показа/скрытия — вкладки, аккордеоны, модальные окна, лайтбоксы — там, где поделиться ссылкой или добавить её в закладки является дополнительным преимуществом.
Предпочтите JavaScript (или нативные элементы вроде <details> и <dialog>), когда открытое состояние не должно менять URL, когда необходимо удерживать фокус для обеспечения доступности, или когда несколько панелей должны быть открыты одновременно.
Заметка о доступности: поскольку
:targetпереключает видимость через навигацию, пользователи клавиатуры и программ чтения с экрана автоматически переводят фокус на целевой элемент — это его преимущество. Однако он не может удерживать фокус внутри модального окна, поэтому для настоящих диалогов нативный элемент<dialog>является более надёжным выбором.
:target — это псевдокласс, как :hover и :focus; для более широкого обзора селекторов см. CSS Selectors.
Синтаксис
:target {
/* CSS declarations */
}Версия
:target широко поддерживается во всех современных браузерах. Он определён в:
Пример: подсветка цели перехода
Нажмите на ссылку, и соответствующий абзац получит рамку и фон, так как становится :target:
<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
<style>
:target {
border: 2px solid #1c87c9;
background-color: #eeeeee;
}
</style>
</head>
<body>
<h2>:target selector example</h2>
<p>
<a href="#example1">Jump to Paragraph 1</a>
</p>
<p>
<a href="#example2">Jump to Paragraph 2</a>
</p>
<p id="example1">
<strong>Paragraph 1</strong>
</p>
<p id="example2">
<strong>Paragraph 2</strong>
</p>
</body>
</html>Пример: меню с вкладками
Каждая ссылка-вкладка указывает на скрытую панель. Отображается только панель, чей id совпадает с фрагментом, поэтому «активной» вкладкой является последняя нажатая:
<!DOCTYPE html>
<html>
<head>
<style>
.tab-menu div {
display: none;
background-color: #f5f5f5;
padding: 0 20px 20px;
}
.tab-menu a {
text-decoration: none;
padding: 10px;
margin: 20px 0;
display: inline-block;
}
.tab-menu div:target {
display: block;
}
</style>
</head>
<body>
<h1>:target selector example</h1>
<div class="tab-menu">
<a href="#html">HTML</a>
<a href="#css">CSS</a>
<a href="#php">PHP</a>
<div id="html">
<h2>
<a href="https://www.w3docs.com/learn-html.html">Learn HTML</a>
</h2>
<p>HTML-Hyper Text Markup Language
</p>
</div>
<div id="css">
<h2>
<a href="https://www.w3docs.com/learn-css.html">Learn CSS</a>
</h2>
<p>CSS-Cascading Style Sheets
</p>
</div>
<div id="php">
<h2>
<a href="https://www.w3docs.com/learn-php.html">Learn PHP</a>
</h2>
<p>PHP-Hypertext Preprocessor
</p>
</div>
</div>
</body>
</html>Пример: модальное окно
.modal скрыт по умолчанию и отображается, только когда является :target. Ссылка «Открыть модальное окно» устанавливает фрагмент #modal; кнопка закрытия ведёт на #, что сбрасывает цель и скрывает модальное окно:
<!DOCTYPE html>
<html>
<head>
<style>
h1+a {
text-decoration: none;
padding: 10px 20px;
background-color: #8ebf42;
color: #ffffff;
font-family: sans-serif;
}
/* Add animation (Chrome, Safari, Opera) */
@-webkit-keyframes example {
from {
top: -100px;
opacity: 0;
}
to {
top: 0px;
opacity: 1;
}
}
/* Add animation (Standard syntax) */
@keyframes example {
from {
top: -100px;
opacity: 0;
}
to {
top: 0px;
opacity: 1;
}
}
/* The modal's background */
.modal {
display: none;
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgb(0, 0, 0);
background-color: rgba(0, 0, 0, 0.4);
}
/* Display the modal when targeted */
.modal:target {
display: table;
position: absolute;
}
/* The modal box */
.modal-dialog {
display: table-cell;
vertical-align: middle;
}
/* The modal's content */
.modal-dialog .modal-content {
margin: auto;
background-color: #f3f3f3;
position: relative;
padding: 0;
outline: 0;
border: 1px #777 solid;
text-align: justify;
width: 80%;
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
/* Add animation */
-webkit-animation-name: example;
/* Chrome, Safari, Opera */
-webkit-animation-duration: 0.5s;
/* Chrome, Safari, Opera */
animation-name: example;
animation-duration: 0.5s;
}
/* The button used to close the modal */
.closebtn {
text-decoration: none;
float: right;
font-size: 35px;
font-weight: bold;
color: #fff;
}
.closebtn:hover,
.closebtn:focus {
color: #000;
text-decoration: none;
cursor: pointer;
}
.container {
padding: 2px 16px;
text-align: center;
line-height: 1.6;
}
header {
background-color: #337ab7;
font-size: 25px;
color: white;
}
header h2 {
text-align: left;
}
footer {
background-color: #337ab7;
font-size: 20px;
color: white;
}
footer p {
text-align: right;
}
</style>
</head>
<body>
<h1>:target selector example</h1>
<a href="#modal">Open Modal</a>
<div id="modal" class="modal">
<div class="modal-dialog">
<div class="modal-content">
<header class="container">
<a href="#" class="closebtn">×</a>
<h2>Header</h2>
</header>
<div class="container">
<p>Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.</p>
</div>
<footer class="container">
<p>Footer</p>
</footer>
</div>
</div>
</div>
</body>
</html>Между модальными окнами и лайтбоксами есть небольшое различие. Лайтбокс можно закрыть, нажав на затемнённую область вне всплывающего окна, тогда как модальное окно закрывается только при взаимодействии внутри него (здесь — кнопкой закрытия).
Пример: лайтбокс
Лайтбокс работает так же, как и модальное окно, но полноэкранный оверлей (.close::before) находится позади содержимого и также ссылается на #, поэтому нажатие в любом месте за пределами изображения закрывает его:
<!DOCTYPE html>
<html>
<head>
<style>
h1+a {
background-color: #8ebf42;
padding: 20px 40px;
color: #ffffff;
text-decoration: none;
font-size: 20px;
margin: 15px 0;
display: inline-block;
}
/* Unopened lightbox */
.lightbox {
display: none;
}
/* Opened lightbox */
.lightbox:target {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
/* Lightbox content */
.lightbox figcaption {
width: 25rem;
position: relative;
padding: 1.5em;
background-color: #8ebf42;
}
/* Close button */
.lightbox .close {
position: relative;
display: block;
}
.lightbox .close::after {
right: -1rem;
top: -1rem;
width: 2rem;
height: 2rem;
position: absolute;
display: flex;
z-index: 1;
align-items: center;
justify-content: center;
background-color: black;
border-radius: 50%;
color: white;
content: "×";
cursor: pointer;
}
/* Lightbox overlay */
.lightbox .close::before {
left: 0;
top: 0;
width: 100%;
height: 100%;
position: fixed;
background-color: rgba(0, 0, 0, .7);
content: "";
cursor: default;
}
</style>
</head>
<body>
<h1>:target selector example</h1>
<a href="#lightbox">Open Lightbox</a>
<div class="lightbox" id="lightbox">
<figure>
<a href="#" class="close"></a>
<figcaption>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec felis enim, placerat id eleifend eu, semper vel sem.
</figcaption>
</figure>
</div>
</body>
</html>Связанные селекторы
:hoverи:focus— другие интерактивные псевдоклассы для стилизации состояний, инициируемых пользователем.:not()— полезен для стилизации всего кроме текущей цели, например.modal:not(:target).:rootи:empty— другие структурные псевдоклассы.- CSS Selectors — полный обзор типов селекторов.