¿Por qué está table-layout: fixed afectando el ancho del elemento padre?

¿Alguien puede explicar por qué mi div con table-layout:fixed está cambiando el ancho de su elemento principal ( body en este caso) para hacerlo 100% cuando no debería ser 100% ya que está posicionado?

 body { border: 2px solid red; height: 100vh; margin:0; padding: 0; position: absolute; } .c{ display: table; width: 80%; /* Any percentage value different from 0 */ table-layout:fixed; outline: 2px solid blue; } 
 
d

Como puede ver arriba, al agregar table-layout:fixed fuerza al cuerpo a ser de ancho completo Y el porcentaje de width en el div funcionará relativamente con el width del body .

Este no es el caso con el siguiente fragmento, donde el comportamiento es de alguna manera lógico e intuitivo:

 body { border: 2px solid red; height: 100vh; margin:0; padding: 0; position: absolute; } .c{ display: table; width: 80%; /* table-layout:fixed; */ outline: 2px solid blue; } 
 
d

¿Cómo funciona table-layout:fixed afecta al elemento padre, que se posiciona en este caso?


Como nota al margen, usar valores de píxeles con width produce un resultado lógico:

 body { border: 2px solid red; height: 100vh; margin:0; padding: 0; position: absolute; } .c{ display: table; width: 200px; table-layout:fixed; outline: 2px solid blue; } 
 
d

También podemos tener cierto desbordamiento con ese extraño comportamiento:

 body { margin:0; position:relative; width:300px; border-top:20px solid green; } .container { border: 2px solid red; height: 100vh; position: absolute; } .c { display: table; width: 120%; table-layout: fixed; outline: 2px solid blue; animation:change 2s linear infinite alternate; } @keyframes change { from{width:1%;} to {width:150%} } 
 
d

Solutions Collecting From Web of "¿Por qué está table-layout: fixed afectando el ancho del elemento padre?"

Parece que no eres el primero en mencionar esto . Podrías ser el segundo, sin embargo.

Para ser claros, esta es una combinación de dos problemas:

  1. El ancho de un elemento absolutamente posicionado es de contracción para ajustar. De alguna manera, se determina que el ancho de contracción es tan amplio como lo permita el bloque que contiene el elemento absuelto. (El bloque contenedor para el body absolutamente posicionado es el bloque que contiene inicial).

  2. Un ancho de porcentaje en un elemento cuyo bloque de contenido depende de su contenido para el auto tamaño da como resultado un comportamiento indefinido.

El Issue # 2 es bastante fácil de cancelar :

las implementaciones acuerdan no calcular el ancho de ningún elemento más de una vez.

es decir, el tamaño del body se ajusta mediante contracción, luego la tabla se establece en 80% de ese ancho y el tamaño del body “no se vuelve a calcular” . La única “indefinición” de esto es que la especificación no requiere o no permite, o de hecho importa lo que hacen las implementaciones.

Entonces, la pregunta se reduce a por qué el ajuste por contracción está rindiendo “lo más ancho posible” en el n. ° 1 antes de determinar el tamaño de la tabla en el n. ° 2. Aquí se muestra cómo la especificación describe la reducción al ajuste para elementos absueltos:

[…] Aproximadamente: calcule el ancho preferido formateando el contenido sin romper líneas a no ser que ocurran saltos de línea explícitos, y también calcule el ancho mínimo preferido, por ejemplo, probando todos los posibles saltos de línea. CSS 2.1 no define el algoritmo exacto. En tercer lugar, calcule el ancho disponible : esto se encuentra resolviendo ‘ancho’ después de configurar ‘izquierda’ (en el caso 1) o ‘derecha’ (en el caso 3) en 0.

Entonces el ancho de contracción es: mínimo (máximo (ancho mínimo preferido, ancho disponible), ancho preferido).

Pero esto no nos dice por qué, ni siquiera eso , el ancho preferido de una tabla de disposición fija es “tan amplio como lo permita su bloque contenedor”. Ni css-sizing-3 ni css-tables-3 parecen contener la respuesta.

Según David Baron (del mismo hilo), que trabaja en Gecko:

Las tablas de diseño fijo informan un tamaño inline de contenido máximo intrínseco como infinito.

(tenga en cuenta que “tamaño en línea de contenido máximo” significa lo mismo que “ancho preferido”)

Así que ahí está nuestra respuesta. El tamaño en línea de contenido máximo ilimitado de las tablas de diseño fijo es lo que hace que el padre con posición absoluta de esta tabla se estire tan ancho como su propio bloque contenedor (el bloque que contiene inicial) permitirá, en contraste con las tablas de diseño automático.

Y, al menos por ahora, esto es lo más cercano que llegaré a una fuente oficial porque estoy teniendo problemas para llegar a la misma conclusión simplemente leyendo css-sizing-3, y no estoy seguro de si la statement de David se basa en El comportamiento de Gecko solo, el comportamiento de todas las implementaciones o el comportamiento específico.

Esta es mi explicación basada en el problema descrito anteriormente, por lo que puede verse como una especulación basada en los requisitos de recompensa para “recursos oficiales”.

Cuando se aplica table-layout: fixed , el contenido ya no impone el diseño, sino que el navegador utiliza cualquier ancho definido de la primera fila de la tabla para definir los anchos de columna. Si no hay anchos presentes en la primera fila, los anchos de columna se dividen en partes iguales en la tabla, independientemente del contenido dentro de las celdas.

Para que un valor de fijo tenga algún efecto, el ancho de la tabla debe establecerse en algo distinto a automático (el valor predeterminado para la propiedad de ancho) … fuente

Once table-layout:fixed; se aplica sin que el contenedor principal tenga ningún ancho establecido y su propio ancho establecido en porcentajes expandiría su contenedor padre (cualquiera que sea ese contenedor sea body / div / etc) al 100% y tomará el ancho especificado (en este caso 80%) a la del padre

Haría esto, ya que su propósito predeterminado es establecer el ancho para asegurarse de que el ancho de sus columnas esté distribuido uniformemente, independientemente de si hay columnas o no. Si no son columnas, trataría el elemento como una columna. Para hacer eso, todavía necesitaría que su ancho sea relativo a su elemento principal (cuando su propio ancho se establece en%).

Ejemplo table-layout:fixed no se aplica porque no tiene un ancho definido, aunque está configurado en el CSS, table-layout:auto se aplica ya que es el predeterminado:

 body { border: 2px solid red; height: 100vh; margin: 0; padding: 0; position: absolute; } .c { display: table; table-layout: fixed; /* width: 80%; */ outline: 2px solid blue; } 
 
d

En tu segundo ejemplo,

 body { border : 2px solid red; height : 100vh; margin : 0; padding : 0; position : absolute; } .c { display : table; width : 80%; outline : 2px solid blue; /* table-layout : fixed; */ } 

Usted ha posicionado completamente el cuerpo, por lo que se saca del flujo normal y no influye en el posicionamiento o el tamaño de su niño .c .

Por lo tanto, el ancho de .c no es el 80% del cuerpo como podría esperar inicialmente.

Sin embargo, puede usar unidades como píxeles o vw para establecer el ancho de .c y el resultado será más intuitivo, como este .

 .c { display : table; width : 80vw; outline : 2px solid blue; /* width : 80%; */ /* table-layout : fixed; */ } 

Del mismo modo, cuando usa table-layout:fixed; su navegador utiliza un algoritmo para calcular el ancho de la tabla que es similar al uso de unidades como píxeles o vw para calcular el ancho de la tabla.

Para citar de la especificación W3C

17.5.2.1 Diseño de tabla fija Con este algoritmo (rápido), el diseño horizontal de la tabla no depende del contenido de las celdas …