Comparación de varias formas de ocultar cosas en CSS | Programar Plus

Pensaría 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 utilizan con mayor frecuencia display: none para ocultar el contenido de la página. Desafortunadamente, esta forma de ocultar contenido no es a prueba de balas porque ahora ese contenido es ahora “inaccesible” para los lectores de pantalla. Es tentador usarlo, pero especialmente en los casos en que algo solo debe ocultarse visualmente, no lo alcance.

El hecho es que hay muchas formas de “ocultar” cosas en CSS, cada una con sus ventajas y desventajas, que dependen en gran medida de cómo se utilice. Vamos a revisar cada técnica aquí y terminar con un resumen que nos ayudará a decidir cuál usar y cuándo.

Cómo detectar diferencias entre las técnicas.

Para ver una diferencia entre las diferentes formas de ocultar contenido, debemos introducir algunas métricas. Métricas que usaremos para comparar los métodos. Decidí desglosar eso haciendo preguntas centradas en cuatro áreas particulares que afectan el diseño, el rendimiento y la accesibilidad:

  1. Accesibilidad: ¿El contenido oculto es leído por un lector de pantalla?
  2. Documento fluir: ¿El elemento oculto afectará el diseño del documento?
  3. Representación: ¿Se renderizará el modelo de caja del elemento oculto?
  4. Desencadenadores de eventos: ¿El elemento detecta clics o enfoca?

Ahora que tenemos nuestros criterios fuera del camino, comparemos los métodos. Nuevamente, pondremos todo junto al final de manera que podamos usarlo como referencia para tomar decisiones al esconder cosas en CSS.

Método 1: El 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 representa.

El elemento seguirá mostrándose en el marcado, si inspecciona la página podrá ver el elemento. El modelo de caja no se generará ni aparecerá en la página, lo que también se aplica a todos sus hijos.

Y lo que es más, si el elemento tiene oyentes de eventos, digamos 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 se mostrarán y registrarán los clics.

La visualización es la única propiedad que afectará la activación de la solicitud de imagen. Si una etiqueta de imagen (o elemento padre) tiene un display propiedad establecida en none ya sea a través de CSS en línea o por selector, el se descargará la imagen. Por otro lado, si la imagen se aplica con un 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 un <img> etiqueta. Por otro lado, cuando aplicamos la imagen a un elemento con un 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 es leído por un lector de pantalla?
¿El elemento oculto afectará el diseño del documento?
¿Se renderizará el modelo de caja del elemento oculto?
¿El elemento detecta clics o enfoca?

Método 2: El visibility propiedad

Si un elemento visibility la propiedad está establecida en hidden, entonces el elemento está “visualmente oculto”. Estar “oculto visualmente” se parece mucho a lo que display: none lo hace, pero es increíblemente diferente en que el elemento se genera y se renderiza, pero 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 estás usando una capa invisible que te hace invisible para los demás, pero aún puedes chocar con cosas. Estás físicamente allí, 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 con visibility y display se comportan igual en términos de accesibilidad y desencadenantes de eventos. Los elementos invisibles son inaccesibles para los lectores de pantalla y no registran eventos, como vemos en la siguiente demostración que es exactamente igual que el último ejemplo, pero simplemente intercambia display: none con visibility: hidden.

Métrico Resultado
¿El contenido oculto es leído por un lector de pantalla?
¿El elemento oculto afectará el diseño del documento?
¿Se renderizará el modelo de caja del elemento oculto?
¿El elemento detecta clics o enfoca?

Método 3: El opacity propiedad

El opacity la propiedad solo afecta al visual aspecto del elemento. Si establecemos un elemento opacity a cero, el elemento será completamente transparente. De nuevo, es muy parecido a visibility: hidden donde estamos cubriendo un manto invisible sobre el elemento donde es invisible, pero aún está físicamente presente.

En otras palabras, lo que tenemos es un elemento hueco y transparente que actúa como cualquier otro elemento, solo que es invisible. Suena mucho como el 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 es leído por un lector de pantalla?
¿El elemento oculto afectará el diseño del documento?
¿Se renderizará el modelo de caja del elemento oculto?
¿El elemento detecta clics o enfoca?

Método 4: El position propiedad

Empujar un elemento fuera de la pantalla con posicionamiento absoluto es otra forma en que los desarrolladores a menudo ocultan cosas. Utilizando top y left, podemos empujar el elemento tan lejos de la pantalla que nunca se verá. Es como esconder el tarro de galletas fuera de la casa para que los niños (¡o tal vez usted!) No puedan encontrarlos.

“Absoluto” es la palabra clave aquí. Si ponemos position a absolute, se saca un elemento 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 le reserva ningún espacio, lo que hace que el elemento quede fuera de orden visualmente, colocándolo en el 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 de documentos 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 es leído por un lector de pantalla?
¿El elemento oculto afectará el diseño del documento?
¿Se renderizará el modelo de caja del elemento oculto?
¿El elemento detecta clics o enfoca?

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 El 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 causa saltos repentinos de página no es tan grande. Otro enfoque para la ocultación accesible combina el posicionamiento absoluto, el clip propiedad y 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 la propiedad width y height en cero. Desafortunadamente, eso no funcionará porque algunos lectores de pantalla ignorarán 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 desbordará fácilmente el espacio, por lo que también necesitamos overflow: hidden para asegurarse de que no se derrame 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á oculto visualmente. Lo que hay que tener en cuenta es que clip fue desaprobado a favor de clip-path pero sigue siendo 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 oculto” es abordar el texto accesible fuera de la pantalla difuminado, 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 de nuevo a casa” se leerá como “Bienvenido de nuevo a casa”.

Una solución simple a este problema es establecer el 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 se muestren ciertos elementos con enfoque nativo y sitios activos 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 es leído por un lector de pantalla?
¿El elemento oculto afectará el diseño del documento?
¿Se renderizará el modelo de caja del elemento oculto?
¿El elemento detecta clics o enfoca?

Menciones honoríficas

Hay incluso más métodos que los cinco que hemos cubierto. Por ejemplo, el text-indent La propiedad puede empujar el texto fuera 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 está usando transform para escalar o mover el elemento fuera del camino. Funciona igual, solo visualmente, como opacity.

.hidden {
  transform: scale(0);
}

¡Pongamos todo junto!

Llegamos a una solución que ocultará visualmente el contenido pero seguirá siendo accesible. Entonces, ¿debería dejar de usar display: none? No, esta sigue siendo la mejor manera de ocultar un elemento por completo (visualmente y de forma accesible).

Dicho esto, vale la pena mencionar que si desea lograr un resultado opuesto, oculte algo del lector de pantalla, el aria-hidden="true" El atributo ocultará el contenido de los lectores de pantalla, pero no visualmente.

Con eso, 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 Monitor Visibilidad Opacidad Posición Camino accesible
¿El contenido oculto es leído por un lector de pantalla?
¿El elemento oculto afectará el diseño del documento?
¿Se renderizará el modelo de caja del elemento oculto?
¿El elemento detecta clics o enfoca?