CSS :target Pseudo Clase
La pseudo-clase CSS :target selecciona los elementos que son el destino de un enlace interno. Aprende sobre ella y practica con ejemplos.
La pseudo-clase :target coincide con el elemento cuyo id es igual al fragmento de la URL actual — la parte que sigue al #. Cuando visitas una URL como page.html#section2, el elemento con id="section2" se convierte en el destino, y :target te permite aplicarle estilos.
Esta página explica cómo funciona :target, cuándo usarlo, sus limitaciones y cuatro patrones prácticos que puedes construir sin JavaScript: un resaltado en la página, un menú de pestañas, una caja modal y un lightbox.
Cómo funciona :target
El navegador rastrea un elemento destino por página — el elemento cuyo id coincide con el fragmento de la URL actual. Al hacer clic en un enlace de la misma página como <a href="#section2"> se actualiza el fragmento, lo que:
- desplaza el elemento correspondiente a la vista, y
- hace que ese elemento coincida con
:target, aplicando los estilos que hayas escrito para él.
Como navegar a un fragmento es una entrada real en el historial, el botón Atrás funciona como "deshacer": vuelve al fragmento anterior (o a ningún fragmento), por lo que un menú, modal o lightbox basado en :target se cierra solo cuando el usuario presiona Atrás.
/* Style the element currently referenced by the URL fragment */
:target {
border: 2px solid #1c87c9;
background-color: #eee;
}Algunas cosas importantes a tener en cuenta:
- Solo un elemento puede ser el destino a la vez — el fragmento es un valor único, por lo que
:targetaplica estilos como máximo a un elemento de la página. - Es un selector con estado. El estado vive en la URL, no en el marcado ni en JavaScript, que es exactamente por qué puede manejar widgets interactivos sin scripting.
- Un
#vacío borra el destino. Enlazar ahref="#"(ohref="#nonexistent") elimina la coincidencia, que es cómo funcionan los botones "cerrar" en los ejemplos de modal y lightbox a continuación.
Cuándo usarlo
Recurre a :target cuando quieras interactividad ligera, sin scripts, que esté naturalmente vinculada a la URL:
- Resaltar el destino de un enlace de salto dentro de la página (notas al pie, entradas de glosario, una tabla de contenidos).
- Widgets de mostrar/ocultar — pestañas, acordeones, modales, lightboxes — donde una URL que se pueda compartir o marcar como favorita es una ventaja.
Prefiere JavaScript (o elementos nativos como <details> y <dialog>) cuando necesites que el estado abierto no cambie la URL, cuando debas capturar el foco para la accesibilidad, o cuando varios paneles deban estar abiertos al mismo tiempo.
Nota de accesibilidad: dado que
:targetalterna la visibilidad mediante la navegación, los usuarios de teclado y lectores de pantalla mueven el foco al elemento objetivo automáticamente — un punto a su favor. Pero no puede capturar el foco dentro de un modal, por lo que para diálogos reales el elemento nativo<dialog>es la opción más robusta.
:target es una pseudo-clase como :hover y :focus; para un recorrido más amplio por los selectores, consulta CSS Selectors.
Sintaxis
:target {
/* CSS declarations */
}Versión
:target es ampliamente compatible con todos los navegadores modernos. Está definido en:
Ejemplo: resaltar un destino de salto
Haz clic en un enlace y el párrafo correspondiente obtiene un borde y fondo porque se convierte en el :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>Ejemplo: un menú de pestañas
Cada enlace de pestaña apunta a un panel oculto. Solo el panel cuyo id coincide con el fragmento se muestra, por lo que la "pestaña" visible es la última en la que hiciste clic:
<!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>Ejemplo: una caja modal
El .modal está oculto por defecto y solo se muestra cuando es el :target. El enlace "Open Modal" establece el fragmento en #modal; el botón de cerrar enlaza a #, lo que borra el destino y oculta el modal de nuevo:
<!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>Existe una ligera diferencia entre las cajas modales y los lightboxes. Un lightbox se puede cerrar haciendo clic en la superposición oscurecida fuera de la ventana emergente, mientras que una caja modal solo se cierra al interactuar dentro de ella (en este caso, el botón de cerrar).
Ejemplo: un lightbox
El lightbox funciona de la misma manera que el modal, pero una superposición a pantalla completa (.close::before) se sitúa detrás del contenido y también enlaza a #, de modo que hacer clic en cualquier lugar fuera de la figura lo cierra:
<!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>Selectores relacionados
:hovery:focus— otras pseudo-clases interactivas para estilizar estados accionados por el usuario.:not()— útil para estilizar todo excepto el destino actual, p. ej..modal:not(:target).:rooty:empty— más pseudo-clases estructurales.- CSS Selectors — una descripción completa de los tipos de selectores.