Comparando varias formas de ocultar cosas en CSS
Se podría pensar que ocultar contenido con CSS es un problema sencillo y resuelto, pero existen múltiples soluciones, cada una de las cuales es única.
Los desarrolladores suelen utilizarlo display: none
para ocultar el contenido de la página. Desafortunadamente, esta forma de ocultar contenido no es infalible porque ahora ese contenido es “inaccesible” para los lectores de pantalla. Es tentador usarlo, pero especialmente en los casos en los que algo solo debe ocultarse visualmente, no lo busques.
El hecho es que hay muchas maneras de “ocultar” cosas en CSS, cada una con sus pros y sus contras, que depende en gran medida de cómo se usa. Revisaremos cada técnica aquí y finalizaremos con un resumen que nos ayudará a decidir cuál usar y cuándo.
Cómo detectar diferencias entre las técnicas.
Para ver la diferencia entre las distintas formas de ocultar contenido, debemos introducir algunas métricas. Métricas que usaremos para comparar los métodos. Decidí desglosarlo haciendo preguntas centradas en cuatro áreas particulares que afectan el diseño, el rendimiento y la accesibilidad:
- Accesibilidad : ¿El contenido oculto se lee mediante un lector de pantalla?
- Flujo de documentos : ¿el elemento oculto afectará el diseño del documento?
- Representación : ¿Se renderizará el modelo de caja del elemento oculto?
- Desencadenantes de eventos: ¿El elemento detecta clics o enfoque?
Ahora que hemos eliminado nuestros criterios, comparamos los métodos. Nuevamente, reuniremos todo al final de manera que podamos usarlo como referencia para tomar decisiones al ocultar cosas en CSS.
Método 1: la display
propiedad
Comenzamos esta publicación con una advertencia sobre el uso display
para ocultar contenido. Y como establecimos, usarlo para ocultar un elemento significa que el elemento no se genera en absoluto. Está en el DOM, pero en realidad nunca se renderizó.
El elemento aún se mostrará en el marcado; si inspecciona la página podrás ver el elemento. El modelo de caja no se generará ni aparecerá en la página, lo que también aplica para todos sus hijos .
Y lo que es más, si el elemento tiene detectores de eventos (por ejemplo, un clic o un desplazamiento) no se registrarán en absoluto. Y como ya hemos comentado, los lectores de pantalla ignorarán todo el contenido. Aquí tenemos dos botones visibles y uno oculto con display: none
. Los tres botones tienen eventos de clic, pero solo los dos botones visibles representarán y registrarán los clics.
La visualización es la única propiedad que afecta la activación de la solicitud de imagen. Si una etiqueta de imagen (o elemento principal) tiene una display
propiedad establecida none
mediante CSS en línea o mediante selector, la imagen se descargará . Por otro lado, si a la imagen se le aplica una background
propiedad, no se descargará .
Este es el caso porque el analizador no ha aplicado el CSS cuando se analiza un documento HTML y encuentra una img
etiqueta. Por otro lado, cuando aplicamos la imagen a un elemento con una background
propiedad, la imagen no se descargará porque el analizador no ha aplicado el CSS donde se llama la imagen. Este comportamiento coincide con todos los navegadores más recientes. La única excepción es IE 11, que descargará imágenes en ambos casos.
Métrico | resultado |
---|---|
¿El contenido oculto se lee mediante un lector de pantalla? | ❌ |
¿El elemento oculto afecta el diseño del documento? | ❌ |
¿Se representará el modelo de caja del elemento oculto? | ❌ |
¿El elemento detecta clics o enfoque? | ❌ |
Método 2: la visibility
propiedad
Si la propiedad de un elemento visibility
se establece en hidden
, entonces el elemento está “visualmente oculto”. Estar “visualmente oculto” se parece mucho a lo que display: none
significa, pero es increíblemente diferente en el sentido de que el elemento se genera y representa, pero es invisible. Esto significa que el modelo de caja del elemento está presente, dándole dimensiones que continúan ocupando espacio en la pantalla aunque no parezca estar allí.
Imagina que llevas una capa invisible que te hace invisible para los demás, pero aún así puedes chocar con cosas. Estás ahí básicamente, incluso si eres invisible para el ojo humano.
Pero ahí es donde terminan las diferencias entre “visualmente oculto” y “no mostrado”. De hecho, los elementos ocultos visibility
se display
comportan iguales en términos de accesibilidad y activadores de eventos. Los elementos invisibles son inaccesibles para los lectores de pantalla y no registrarán eventos, como vemos en la siguiente demostración que es exactamente igual que el último ejemplo, pero simplemente se intercambia display: none
con visibility: hidden
.
Métrico | resultado |
---|---|
¿El contenido oculto se lee mediante un lector de pantalla? | ❌ |
¿El elemento oculto afecta el diseño del documento? | ✅ |
¿Se representará el modelo de caja del elemento oculto? | ✅ |
¿El elemento detecta clics o enfoque? | ❌ |
Método 3: la opacity
propiedad
La opacity
propiedad sólo afecta al aspecto visual del elemento. Si establecemos el valor de un elemento opacity
en cero, el elemento será completamente transparente. Nuevamente, es muy parecido visibility: hidden
a cuando colocamos una capa invisible sobre el elemento donde es invisible, pero aún está básicamente presente.
En otras palabras, lo que tenemos es un elemento hueco, transparente, que actúa como cualquier otro elemento, sólo que es invisible. Suena muy parecido al visibility
método, ¿verdad? La diferencia es que un elemento totalmente transparente sigue siendo accesible para un lector de pantalla y puede registrar eventos, como clics, como vemos en el siguiente ejemplo.
Métrico | resultado |
---|---|
¿El contenido oculto se lee mediante un lector de pantalla? | ✅ |
¿El elemento oculto afecta el diseño del documento? | ✅ |
¿Se representará el modelo de caja del elemento oculto? | ✅ |
¿El elemento detecta clics o enfoque? | ✅ |
Método 4: la position
propiedad
Empujar un elemento fuera de la pantalla con un posicionamiento absoluto es otra forma en que los desarrolladores suelen ocultar cosas. Usando top
y left
, podemos empujar el elemento tan lejos de la pantalla que nunca será visto. Es como esconder el tarro de galletas fuera de la casa para que los niños (¡o tal vez tú!) no puedan encontrarlas.
"Absoluto" es la palabra clave aquí. Si lo configuramos position
en absolute
, un elemento se elimina del flujo de documentos, lo que es una forma de decir que ya no se adhiere a su posición natural en el DOM. En otras palabras, la página no reserva ningún espacio para ella, lo que desordena visualmente el elemento, posicionándolo en su elemento más cercano si lo hay, o en la raíz del documento si no hay nada más.
Aprovechamos el posicionamiento absoluto sacando el elemento "oculto" del flujo del documento y desplazándolo hacia la parte superior izquierda con valores de -9999px
.
.hidden { position: absolute; top: -9999px; left: -9999px;}
Métrico | Efecto |
---|---|
¿El contenido oculto se lee mediante un lector de pantalla? | ✅ |
¿El elemento oculto afectará el diseño del documento? | ❌ |
¿Se representará el modelo de caja del elemento oculto? | ✅ |
¿El elemento detecta clics o enfoque? | ✅ |
Si el elemento oculto contiene contenido enfocable, la página se desplazará hasta el elemento cuando esté enfocado, creando un salto repentino.
Método 5: la clase "visualmente oculta"
Hasta ahora, el position
método es lo más cercano que hemos visto a una forma amigable con la accesibilidad para ocultar cosas en CSS. Pero el problema con el contenido enfocable que provoca saltos repentinos de página no es grande. Otro enfoque para el ocultamiento accesible combina el posicionamiento absoluto, la clip
propiedad y el desbordamiento oculto. Scott O'Hara lo escribió en su blog en 2017.
.visually-hidden:not(:focus):not(:active) { clip: rect(0 0 0 0); clip-path: inset(50%); height: 1px; overflow: hidden; position: absolute; white-space: nowrap; width: 1px;}
Analicemos eso.
Necesitamos eliminar el elemento del flujo de documentos. La mejor manera de hacer esto es usando position: absolute
. Esto eliminará el elemento, pero no lo sacaremos de la pantalla.
.visually-hidden { position: absolute;}
Podemos ocultar el elemento estableciendo las propiedades de ancho y alto en cero. Desafortunadamente, eso no funcionará porque algunos lectores de pantalla ignorarán los elementos con ancho y alto cero. Lo que podemos hacer es establecerlo en el segundo valor más bajo, 1px
. Eso significa que el contenido fácilmente desbordará el espacio, por lo que también debemos overflow: hidden
asegurarnos de que no se desborde visualmente.
.visually-hidden { height: 1px; overflow: hidden; position: absolute; width: 1px;}
Para ocultar ese cuadrado de un píxel, podemos usar la propiedad de recorte CSS. Es perfecto para esta situación, ya que no afecta a los lectores de pantalla. El contenido está ahí pero, nuevamente, está visualmente oculto. Lo que hay que tener en cuenta es que clip
quedó en desuso, clip-path
pero aún es necesario si necesitamos admitir versiones anteriores de Internet Explorer.
.visually-hidden { clip: rect(0 0 0 0); clip-path: inset(50%); height: 1px; overflow: hidden; position: absolute; width: 1px;}
Otra pieza del rompecabezas de la clase “visualmente oculta” es abordar el texto accesible borroso fuera de la pantalla, una rareza que elimina los espacios en blanco entre las palabras, lo que hace que se lean en voz alta como una gran cadena de palabras. Por ejemplo, "Bienvenido a casa" se leerá como "Bienvenido a casa".
Una solución simple a este problema es configurar white-space: nowrap
:
.visually-hidden { clip: rect(0 0 0 0); clip-path: inset(50%); height: 1px; overflow: hidden; position: absolute; white-space: nowrap; width: 1px;}
¡Y finalmente! Lo último a considerar es permitir que ciertos elementos con enfoque nativo y sitios activos se muestren cuando están enfocados, mientras se continúa evitando que se muestren otros elementos, como párrafos. Podemos usar el :not
pseudo-selector para eso.
.visually-hidden:not(:focus):not(:active) { clip: rect(0 0 0 0); clip-path: inset(50%); height: 1px; overflow: hidden; position: absolute; white-space: nowrap; width: 1px;}
Métrico | Resultado |
---|---|
¿El contenido oculto se lee mediante un lector de pantalla? | ✅ |
¿El elemento oculto afectará el diseño del documento? | ❌ |
¿Se representará el modelo de caja del elemento oculto? | ❌ |
¿El elemento detecta clics o enfoque? | ✅ |
Menciones honoríficas
Hay incluso más métodos que los cinco que hemos cubierto. Por ejemplo, la text-indent
propiedad puede sacar texto de la pantalla como el position
método:
.hidden { text-indent: -9999em;}
Desafortunadamente, este enfoque no concuerda con los modos de escritura RTL . Eso lo hace menos adaptable que otras soluciones que hemos cubierto.
Otro método es utilizar transform
para escalar o mover el elemento a un lado. Funciona igual, solo visualmente, que opacity
.
.hidden { transform: scale(0);}
¡Juntemos todo!
Llegamos a una solución que ocultará visualmente el contenido pero seguirá siendo accesible. Entonces, ¿deberías dejar de consumir display: none
? No, esta sigue siendo la mejor manera de ocultar un elemento por completo (visual y accesible).
Dicho esto, vale la pena mencionar que si desea lograr el resultado opuesto: ocultar algo al lector de pantalla, el aria-hidden="true"
atributo ocultará el contenido a los lectores de pantalla, pero no visualmente.
Dicho esto, aquí hay una tabla completa que compara todos los enfoques. Úselo para guiar sus decisiones sobre cómo ocultar contenido la próxima vez que se encuentre en esa situación.
Métrico | Mostrar | Visibilidad | Opacidad | Posición | Manera Accesible |
---|---|---|---|---|---|
¿El contenido oculto se lee mediante un lector de pantalla? | ❌ | ❌ | ✅ | ✅ | ✅ |
¿El elemento oculto afectará el diseño del documento? | ❌ | ✅ | ✅ | ❌ | ❌ |
¿Se representará el modelo de caja del elemento oculto? | ❌ | ✅ | ✅ | ✅ | ❌ |
¿El elemento detecta clics o enfoque? | ❌ | ❌ | ✅ | ✅ | ✅ |
Deja un comentario