¿Por qué CSS2.1 define valores de desbordamiento que no sean “visibles” para establecer un nuevo contexto de formato de bloque?

La especificación CSS2.1 exige que el overflow que no sea visible establezca un nuevo “contexto de formato de bloque” . Esto me parece extraño, que una propiedad cuyo objective obvio es ocultar el desbordamiento sin afectar el diseño, realmente afecte el diseño de una manera importante.

Parece que los valores de desbordamiento distintos de los visible combinan dos características completamente independientes: si se crea un BFC y si el desbordamiento está oculto. No es como “desbordamiento: oculto”, es completamente sin sentido, sin un BFC, porque los flotadores históricamente pueden desbordar su elemento principal, ocultar el desbordamiento sin cambiar el diseño parece razonable.

¿Cuáles son los motivos de esta decisión, suponiendo que se conozcan? ¿Las personas que trabajaron en la especificación describieron por qué se decidió que este fuera el caso?

Le pregunté sobre esto en la lista de correo en su nombre; el hilo se puede encontrar aquí . En resumen, esto tiene que ver con el contenido de desplazamiento en su mayor parte :

Fundamentalmente, porque si la especificación no dice esto, entonces tener flotadores que se cruzan con algo que se puede desplazar requerirá que el navegador vuelva a envolver (alrededor de los flotantes intrusos) el contenido del elemento desplazable cada vez que se desplaza. Esto es técnicamente lo que requiere CSS 2.0, pero nunca se implementó, y habría sido un gran problema para la velocidad de desplazamiento.

David

Lo más probable es que se refiera al contenido desplazable en una caja que puede aparecer fuera del elemento primario del elemento flotante, pero que se intersecaría con el elemento flotante. No creo que esto esté relacionado con el reenvasado de contenido alrededor de un flotador dentro de un contenedor desplazable, ya que eso ya sucede naturalmente, además de que el flotador se engancharía en el contenedor y se desplazaría junto con el rest de su contenido de todos modos .

Finalmente, esto tiene sentido para mí. De hecho, voy a dar un ejemplo aquí, así que espero que tenga sentido para ti y para cualquier otra persona que se esté preguntando. Considere un escenario que involucre dos cuadros con la misma altura fija y overflow: visible (el valor predeterminado), de los cuales el primero contiene un flotante que se extiende más allá de la altura de sus padres:

 

...

...

...

 /* Presentational properties omitted */ div { height: 80px; } div:first-child:before { float: left; height: 100px; margin: 10px; content: 'Float'; } 

Observe la similitud con uno de los ejemplos dados en la sección 9.5 . El segundo cuadro aquí simplemente muestra contenido desbordante para los propósitos de esta respuesta.

Esto está bien ya que el contenido nunca se desplazará, pero cuando el overflow se establece en algo que no sea visible , eso hace que el contenido no solo sea recortado por los límites del cuadro, sino que también se convierta en desplazable. Si el segundo cuadro tiene un overflow: auto , así es como se vería si un navegador implementara la especificación original de CSS2:

Debido a la flotación, intentar desplazar el contenido provocaría que el navegador tuviera que volver a envolverlo para que no quede oscurecido por el flotador (y ¿qué debería pasarle a la parte que se desplaza por el borde superior?). Probablemente se vería algo así cuando se desplaza hacia abajo:

La clave aquí es que el navegador debe volver a envolver el contenido cada vez que lo vuelve a pintar durante el desplazamiento . Para los navegadores que son capaces de desplazamiento suave basado en píxeles, es decir, todos ellos, ¡puedo ver por qué sería un desastre de rendimiento! (Y una experiencia de usuario también).

Pero eso es para cuando el usuario puede desplazarse por el contenido, ¿verdad? Esto tendría sentido para el overflow: auto y overflow: scroll , pero ¿qué pasa con overflow: hidden ?

Bueno, una idea errónea común es que un contenedor con overflow: hidden simplemente oculta el contenido por recorte y no se puede desplazar. Esto no es completamente cierto :

Si bien no se proporciona el desplazamiento de la IU, el contenido aún se puede desplazar programáticamente, y varias páginas realizan ese desplazamiento (por ejemplo, al configurar scrollTop en el elemento correspondiente).

-Boris

De hecho, esto es lo que se vería si la segunda casilla se configurara como overflow: hidden y luego desplazada hacia abajo con el siguiente JavaScript:

 var div = document.getElementsByTagName('div')[1]; div.scrollTop = div.scrollHeight; 

Nuevamente, observe que el contenido debería ser envuelto nuevamente para evitar ser oscurecido por el flotador.

Aunque esto no sería tan doloroso para el rendimiento como la UI de desplazamiento estuvo disponible, mi mejor opción es que crearon cajas con cualquier valor de overflow que no sea visible generan un nuevo BFC principalmente por el bien de la coherencia.


Y entonces, este cambio se produjo en CSS2.1, documentado aquí . Ahora bien, si aplica un valor de overflow que no sea visible solo al segundo recuadro, lo que hace un navegador es empujar todo el recuadro para dejarle espacio al flotante, porque el recuadro ahora crea un nuevo contexto de formato de bloque que incluye su contenido, en lugar de fluyendo alrededor del flotador. Este comportamiento particular se especifica en el siguiente párrafo :

El cuadro de borde de una tabla, un elemento reemplazado de nivel de bloque o un elemento en el flujo normal que establece un nuevo contexto de formato de bloque (como un elemento con ‘desbordamiento’ que no sea ‘visible’) no debe superponerse al margen de cualquiera flota en el mismo contexto de formato de bloque como el elemento mismo. Si es necesario, las implementaciones deben borrar dicho elemento colocándolo debajo de cualquier flotador anterior, pero puede colocarlo adyacente a dichos flotadores si hay suficiente espacio. Incluso pueden hacer que la caja de frontera de dicho elemento sea más estrecha que la definida en la sección 10.3.3. CSS2 no define cuándo un UA puede colocar dicho elemento al lado del flotante o en qué medida dicho elemento puede volverse más estrecho.

Esto es lo que parece con el overflow: auto por ejemplo:

Tenga en cuenta que no hay autorización; si la segunda casilla estaba clear: left o clear: both serían empujadas hacia abajo , no hacia un lado, independientemente de si establecieron su propio BFC.

Si aplica el overflow: auto al primer cuadro en su lugar, el flotante se recorta en su cuadro contenedor con el rest del contenido debido a su altura fija, que se establece en 80px en el código de ejemplo anterior:

Si revierte el primer cuadro a height: auto (el valor predeterminado), anulando o quitando la height: 80px statement de height: 80px desde arriba, se estira a la altura del flotante:

Esto también es nuevo en CSS2.1, ya que un elemento con height: auto que genera un nuevo contexto de formato de bloque (es decir, una raíz de contexto de formato de bloque ) se extenderá verticalmente a la altura de sus flotantes, y no solo lo suficiente para contiene su contenido de flujo a diferencia de un cuadro normal. Los cambios están documentados aquí y aquí . El cambio que conduce al efecto secundario de encoger la caja para que no se cruce con el flotador se documenta aquí .

En ambos casos, no importa lo que hagas con la segunda casilla, nunca se verá afectada por la flotación porque ha sido restringida por los límites de su contenedor.

Sé que esta será una respuesta especulativa, sin embargo, después de leer las especificaciones algunas veces aquí está mi punto de vista sobre esto:

De qué se trata la sección 9.4.1 es cualquier elemento de bloque que no contiene completamente o no llena el espacio de contención. Por ejemplo, cuando se hace flotar un elemento, ya no se completa el 100% del elemento primario, como lo hacen los elementos de flujo. Los bloques en línea, las celdas de tabla y los títulos de tabla también son elementos que pueden afectar el alto y el ancho pero que no son intrínsecamente el 100% del padre (yes table> tr> td es uno que llenaría el 100% de sus padres pero está diseñado para permitir múltiples td de modo que el td no cuente, ya que se reducirá automáticamente para acomodar td adicionales) esto también se aplica a cualquier desbordamiento que no sea visible porque rompe la contención del elemento de bloque.

Entonces, si estoy leyendo esto correctamente, la manera en que funciona es que la sección 9.4.1 se refiere a elementos de bloque que rompen las reglas de contención predeterminadas de los elementos del bloque como se especifica en la sección 9.2.1