¿Por qué el <div> exterior aquí no rodea completamente al <div> interior?

Resuelto kshetline asked hace 5 años • 2 respuestas

Tengo un jsfiddle aquí: https://jsfiddle.net/Lh7qbye2/7/

Y una página web de prueba aquí: https://shetline.com/test/test01.html

La pregunta es la siguiente: ¿Por qué el contenido del interior no <div>evita que el exterior <div>se reduzca a menos que el ancho del interior <div>cuando cambia el tamaño de la ventana contenedora a un tamaño estrecho?

imagen de muestra del div interno que escapa del div externo

Actualizaciones basadas en la respuesta que obtuve para el problema:

https://jsfiddle.net/Lh7qbye2/8/

https://shetline.com/test/test02.html

 

Puedo resolver el problema de Chrome o Safari usando:

width: fit-content;

...en el exterior <div>, pero esto no resuelve el problema de Firefox o Edge. Además, MDN marca fit-contentcomo API experimental :

Esta es una API experimental que no debe usarse en código de producción.

word-break: break-allen el exterior <div>, más o menos, ayuda, pero estropea todo el ajuste de palabras. Si intento compensar estableciendo normalroturas en las etiquetas <p>y <button>, la ayuda proporcionada por el exterior break-alldesaparece.

Una cosa que realmente me confunde es que sé que he visto situaciones como esta sin ningún problema indirecto y no tuve que esforzarme más para obtener el comportamiento que esperaba. ¿Qué me falta que esté mal en este ejemplo simplificado?

 

body {
  margin: 4em;
}

.demo {
  background-color: #BFC;
  box-sizing: border-box;
  margin: 0;
  padding: 1em;
  position: relative;
  /* width: fit-content; // With this it works for Chrome or Safari, but not for Firefox or Edge. */
  /* word-break: break-all; // For some reason this sort of helps too, but of course messes up all word wrapping. */
  /* If I try to apply "word-break: normal" to <p> and <button> tags to compensate, the inner <div> leaks out again. */
}

.demo p:first-child {
  margin-top: 0;
}

.other-stuff {
  align-items: center;
  background-color: #AEB;
  display: flex;
}

button {
  margin-right: 1em;
}

.square {
  display: inline-block;
  background-color: #699;
  height: 80px;
  margin-right: 1em;
  min-width: 80px;
  width: 80px;
}

.circle {
  border-radius: 50px;
  display: inline-block;
  background-color: #969;
  height: 100px;
  margin-right: 1em;
  min-width: 100px;
  width: 100px;
}
<div class="demo">
  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
    in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
  <div class="other-stuff">
    <button>One&nbsp;button</button>
    <div class="square"></div>
    <button>Another&nbsp;button</button>
    <div class="circle"></div>
    <button>Don't&nbsp;click!</button>
  </div>
</div>
Expandir fragmento

kshetline avatar Aug 22 '19 07:08 kshetline
Aceptado

Lo que quieras se puede hacer usando una combinación de inline-blocky min-width:100%. Un elemento de bloque tiene su ancho definido en función de su elemento principal (bloque que contiene), mientras que inline-blocksu ancho estará definido por su contenido.

Agregar min-width:100%hará que se comporte como un elemento de bloque. No es obligatorio en este caso ya que ya tienes mucho contenido por lo que seguramente cubrirás todo el ancho:

Mostrar fragmento de código

Reduzca el texto en la parte superior y min-width:100%será obligatorio tener un comportamiento de ancho completo.

Ejecute el fragmento en página completa

Mostrar fragmento de código


De la especificación :

Elementos no reemplazados a nivel de bloque en flujo normal

Las siguientes restricciones deben cumplirse entre los valores utilizados de las otras propiedades:

'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' = width of containing block

Observe cómo el contenido no juega ningún papel en la definición del ancho.

'Bloque en línea', elementos no reemplazados en flujo normal

Si 'ancho' es 'automático', el valor utilizado es el ancho de reducción para ajustar

El cálculo del ancho de reducción para ajustar es similar al cálculo del ancho de una celda de una tabla utilizando el algoritmo de diseño de tabla automático. Aproximadamente: calcule el ancho preferido formateando el contenido sin dividir líneas excepto donde ocurren saltos de línea explícitos, y también calcule el ancho mínimo preferido, por ejemplo, probando todos los saltos de línea posibles. En tercer lugar, encuentre el ancho disponible: en este caso, este es el ancho del bloque contenedor menos los valores utilizados de 'margin-left', 'border-left-width', 'padding-left', 'padding-right', 'border-right-width', 'margin-right' y los anchos de las barras de desplazamiento relevantes

el ancho de contracción para ajustar es:min(max(preferred minimum width, available width), preferred width)

Observe cómo se utiliza el contenido para definir el ancho.


Lo mismo se aplica a cualquier tipo de valor de visualización ( ,,, gridetc. ) y el truco consiste flexen tablereemplazarlo con el inline-*equivalente ( inline-grid,,,, etc.)inline-flexinline-table

Temani Afif avatar Aug 22 '2019 00:08 Temani Afif