margenes colapsados css margin grid-layout

colapsados - Se busca: sistema de cuadrícula CSS y márgenes de colapso.



margenes colapsados css (11)

Creo que esta es una pregunta difícil.

Yo uso un sistema de rejilla utilizando float:left . Podría reescribirlo con display:inline-block , pero eso no cambiaría nada.

Digamos que tenemos dos columnas:

<div class="row"> <div class="column"> <!-- some content here --> </div> <div class="column"> <!-- some content here --> </div> </div>

Si coloco un elemento de bloque con un margen superior (como <h1> ) obtengo márgenes no colapsables en el contenido anterior. Esto es normal, ya que siempre es así con elementos flotantes (o visualización: bloque en línea).

Pero quiero tener márgenes de colapso. Intenté mucho para que funcionara, pero parece que cada CSS que ponga dos elementos uno al lado del otro destruirá los márgenes de colapso de los contenidos anteriores.

Lo sé, podría usar CSS para obtener el primer hijo de un elemento para eliminar el margen superior. Pero en este caso no se aplicará, porque el contenido está creado con un CMS y podría haber un nivel arbitrario de profundidad de elemento hasta que llegue al elemento.

¿Hay alguna manera de hacer esto sin JavaScript?

Fiddle: http://jsfiddle.net/HerrSerker/ZSV3D/

Puede ver que el margen superior de h1 y el margen inferior de .header no se .header . Esto es por medio de float:left de .column .

.header { font-size: 24px; background: rgba(0,255,0,0.1); } h1 { background: silver; margin-bottom: 50px; font-size: 28px; } .column { float: left; width: 50%; background: rgba(255,0,0,0.1); } h2 { background: gold; margin-top: 50px; font-size: 24px; }

<div class="header"><h1>&lt;h1>Headerh1&lt;/h1></h1></div> <div class="row"> <div class="column"><h2>&lt;h2>Col 1, float: left&lt;/h2></h2></div> <div class="column"><h2>&lt;h2>Col 2, float: left&lt;/h2></h2></div> </div> <p>I want a 50 pixel margin between Header and the Cols, but the two margins don''t collapse and I end up with 50 + = 100 pixel gap. If it would work, you wouldn''t see the light red above col1 and col2</p>

Editar

Por supuesto, podría usar algún operador sucesor en CSS como header + .row .column h1 { margin-top: 0;} . Pero eso no es lo que quiero. Lo que quiero es una forma de elemento de configuración una junto a la otra que trabaje con el colapso del margen de los elementos contenidos.

Edit2

Así que la situación y la pregunta una vez más en breve.
El problema es bastante simple. Tengo algún código CSS, que me permite establecer dos o más divs uno al lado del otro como float: left; ancho: 50%. Dentro de estos divs hay elementos como h2 que tienen un margen superior. Si dentro de un div antes hay un h1 con margen inferior. Esta situación no permite que los márgenes de h1 y h2 se colapsen. ¿Hay alguna posibilidad de poner elementos uno al lado del otro con colapso de margen y sin establecer el margen a cero manualmente?

O de otro modo. ¿Existe alguna posibilidad de que los elementos de configuración estén uno junto al otro sin crear un nuevo contexto de formato de bloque?

Edit3:

------------------------------------------------------------- What it is: .header +---------------------+ .header | +-----------------+ | .header | | h1 | | .header | +-----------------+ | ----+--- .header +---------------------+ | | margin-bottom of h1 | -----------------------------+--- | | margin-top of h2 .row +---------------------+ | not collapsing .row | +-------+ +-------+ | ----+--- .row | | h2 | | h2 | | .row | | in | | in | | .row | | col 1 | | col 2 | | .row | +-------+ +-------+ | .row +---------------------+ ------------------------------------------------------------- What I want: .header +---------------------+ .header | +-----------------+ | .header | | h1 | | .header | +-----------------+ | ----+--- .header +---------------------+ | margin-bottom of h1 | and margin-top of h2 .row +---------------------+ | collapsing .row | +-------+ +-------+ | ----+--- .row | | h2 | | h2 | | .row | | in | | in | | .row | | col 1 | | col 2 | | .row | +-------+ +-------+ | .row +---------------------+ -------------------------------------------------------------


Como ya has escuchado varias veces ... Esto no parece ser posible ...

Sospecho que no desea utilizar un selector para no afectar a todos los h1 y resolver otros elementos (como quizás h2 , o incluso una p ) que pueden no ser h1 y pueden no ser hermanos adyacentes del elemento .header (tal vez solo h1 sin envoltura .header , o una p con margen inferior 70px ) ...

Suponiendo que tengo razón ... Puede usar este selector para resolver todos estos casos ...

.row .column > *:first-child { margin-top: 0; }

Esto establecerá top-margin del primer elemento en cada columna de cada fila en 0 .

Piensa que esto es lo más cercano que puedes llegar al comportamiento deseado ...

Déjame saber si eso ayuda.


Da *{margin:0;} estilo en tu css. Evitará todos los márgenes predeterminados en todos los navegadores.


Esto es imposible: o

Según la especificación ( https://www.w3.org/TR/CSS2/box.html#collapsing-margins )

Condición de colapso:

  • ambos pertenecen a cuadros de nivel de bloque en flujo que participan en el mismo contexto de formato de bloque
  • no hay casillas de línea, espacio libre, relleno ni borde que las separe (tenga en cuenta que ciertas casillas de línea de altura cero (ver 9.4.2) se ignoran para este propósito).
  • ambos pertenecen a bordes de caja adyacentes verticalmente, es decir, forman uno de los siguientes pares:
    • margen superior de una caja y margen superior de su primer elemento secundario en flujo
    • margen inferior de la caja y margen superior de su próximo flujo de entrada después del hermano
    • margen inferior de un último elemento secundario en flujo y margen inferior de su elemento primario si el principal tiene altura calculada "auto"
    • Márgenes superior e inferior de un cuadro que no establece un nuevo contexto de formato de bloque y que tiene cero ''altura mínima'' calculada, cero o ''auto'' ''altura'' calculada, y no hay elementos secundarios en flujo

contenedores de bloques (como bloques en línea, celdas de tabla y títulos de tabla) que no son cuadros de bloque

El colapso de los márgenes en esta situación romperá la regla:

  • Los márgenes entre una caja flotante y cualquier otra caja no se colapsan (ni siquiera entre una flotación y sus hijos en flujo).
  • Los márgenes de los elementos que establecen nuevos contextos de formato de bloque (como flotadores y elementos con ''desbordamiento'' que no sean ''visibles'') no se colapsan con sus elementos secundarios en flujo.
  • Los márgenes de las cajas con posición absoluta no se colapsan (ni siquiera con sus hijos en flujo).
  • Los márgenes de las cajas de bloque en línea no se colapsan (ni siquiera con sus hijos en flujo).
  • El margen inferior de un elemento de nivel de bloque en flujo siempre colapsa con el margen superior de su siguiente hermano de nivel de bloque en flujo, a menos que ese hermano tenga espacio libre.
  • El margen superior de un elemento de bloque de flujo colapsa con su primer margen superior de nivel de bloque de flujo de flujo si el elemento no tiene borde superior, sin relleno superior y el niño no tiene espacio libre.
  • El margen inferior de una caja de bloque de flujo con una ''altura'' de ''auto'' y una ''altura mínima'' de cero colapsa con su último margen inferior de nivel de bloque de flujo de niños si la caja no tiene relleno inferior ni ningún el borde inferior y el margen inferior del niño no se colapsan con un margen superior que tiene espacio libre.
  • Los márgenes de una caja se colapsan si la propiedad ''min-height'' es cero, y no tiene bordes superiores o inferiores ni relleno superior o inferior, y tiene una ''altura'' de 0 o ''auto'', y no contiene una caja de línea y todos sus márgenes de flujo de niños (si los hubiera) se colapsan.

flex box también ... ( https://www.w3.org/TR/css-flexbox-1/#item-margins )

Los márgenes de los elementos flexibles adyacentes no se colapsan.

grid también ... ( https://www.w3.org/TR/css-grid-1/#item-margins )

Los márgenes de los elementos de cuadrícula adyacentes no se colapsan.

Es imposible colapsar el margin-top: 50px; utilizando una de estas soluciones: inline-block , position: absolute , float , flex , grid .

Si no puede establecer el margen a cero, quizás pueda usar muchos otros métodos para interrumpir la función de margen

por ejemplo: deje que h1 esté en inline y que div tenga un fondo dorado para romper el margin-top: 50px; :

Según la especificación de margen ( https://www.w3.org/TR/CSS2/box.html#margin-properties ):

Las propiedades de margen especifican el ancho del área de margen de un cuadro. La propiedad abreviada ''margen'' establece el margen para los cuatro lados, mientras que las otras propiedades de margen solo establecen su lado respectivo. Estas propiedades se aplican a todos los elementos, pero los márgenes verticales no tendrán ningún efecto en los elementos en línea no reemplazados .


Hacer el elemento .row una flex , problema resuelto ...

¿Por qué quieres flotar?

.header { background: silver; height: 50px; margin-bottom: 50px; font-size: 24px; } .row { display: flex; } .column { width: 50%; } h1 { background: gold; font-size: 24px; } .firstcol { margin-top: 0; }

<div class="header">Header is normal div</div> <div class="row"> <div class="column"><h1 class="firstcol">Col 1 is float: left</h1></div> <div class="column"><h1 class="firstcol">Col 2 is float: left</h1></div> </div> <p>I want a 50 pixel margin between Header and the Cols, but the two margins don''t collapse and I end up with 50 + = 100 pixel gap.</p>


La única opción con la que realmente contrae los márgenes, sin algunos trucos de selección o JavaScript, es la siguiente:

No establezca un margin-top: 50px en su h1 , sino en .row

Ver este violín

HTML

<div class="header">Header is normal div</div> <div class="row"> <div class="column"><h1>Col 1 is float: left</h1></div> <div class="column"><h1>Col 2 is float: left</h1></div> </div> <p>I want a 50 pixel margin between Header and the Cols, but the two margins don''t collapse and I end up with 50 + = 100 pixel gap.</p>

CSS

.header { background: silver; height: 50px; margin-bottom: 50px; font-size: 24px; } .row { margin-top: 50px; } .column { float: left; width: 50%; } h1 { background: gold; font-size: 24px; }


La documentación sobre el colapso del margen es bastante clara ...

Los márgenes de elementos flotantes y absolutamente posicionados nunca colapsan.

https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Box_Model/Mastering_margin_collapsing

Incluso el uso de flexbox no ayudará, el comportamiento sigue siendo el mismo ...

Si sabe qué elementos tienen un margen superior, tal vez pueda sacar algo del selector de first-of-type ... Ver fragmentos:

.header { background: silver; height: 50px; margin-bottom: 50px; font-size: 24px; } .column { float: left; width: 50%; } h1 { background: gold; margin-top: 50px; font-size: 24px; } .column h1:first-of-type { margin-top: 0; }

<div class="header">Header is normal div</div> <div class="row"> <div class="column"><h1>Col 1 is float: left</h1></div> <div class="column"><h1>Col 2 is float: left</h1></div> </div> <p>I want a 50 pixel margin between Header and the Cols, but the two margins don''t collapse and I end up with 50 + = 100 pixel gap.</p>


No creo que puedas hacer eso. Probablemente el mejor método sería apuntar los márgenes en función de algunas condiciones y eliminarlo.

Si este problema solo ocurre cuando .column con elementos h1 sigue inmediatamente a .header , podría crear un poco más de una regla CSS específica. Esto anularía el margen y lo negaría.

.header + .row h1 { margin-top: 0; }

Sin embargo, hay bastantes "si" en esta respuesta y sin un poco más de información es bastante difícil de resolver.


Se display: table / table-row / table-cell como una opción?

.header { background: silver; height: 50px; margin-bottom: 50px; font-size: 24px; display: table-row; } .row { display: table-row; } .column { display: table-cell; width: 50%; } h1 { background: gold; margin-top: 50px; font-size: 24px; }

<div class="header">Header is normal div</div> <div class="row"> <div class="column"><h1>Col 1 is float: left</h1></div> <div class="column"><h1>Col 2 is float: left</h1></div> </div> <p>I want a 50 pixel margin between Header and the Cols, but the two margins don''t collapse and I end up with 50 + = 100 pixel gap.</p>


Según la Red de Desarrolladores de Mozzilla :

Los márgenes de elementos flotantes y absolutamente posicionados nunca colapsan.

Si se garantiza que el primer elemento necesita un colapso dentro de un número arbitrario de elementos, su mejor apuesta sería la siguiente CSS:

.header + * :first-child { margin-top: 0; }

Si entiendo la pregunta correctamente, esto es lo más cercano que obtendrás solo con CSS.

Manifestación:

.header { background: silver; height: 50px; margin-bottom: 50px; } .column { float: left; width: 50%; } h1 { background: gold; margin-top: 50px; } .header + * :first-child { margin-top: 0; }

<div class="header">Header</div> <div class="row"> <div class="column"><h1>Col 1</h1></div> <div class="column"><h1>Col 2</h1></div> </div>


Ver propiedad de visualización predeterminada de h1 es la siguiente,

h1{ margin-top: 0.67em;/* which is around 11px*/ margin-bottom: 0.67em;/* which is around 11px*/ margin-left: 0; margin-right: 0; }

Por lo tanto, en lugar de establecer el margen superior o inferior para su h1 o h2, puede establecer el margin-top para la fila, que le da el mismo resultado que h1 y h2. Ahora cuando cambia el tamaño de su navegador con esto como se menciona en los códigos a continuación. Puede notar que mientras se redimensiona el espacio, el espacio aumenta y disminuye. Pero en un punto se detendrá, ya que hemos asignado la parte superior del margen + ya tenemos el margen predeterminado h1 y h2 también.

.header { font-size: 24px; background: rgba(0,255,0,0.1); } h1 { background: silver; margin-bottom: 50px; font-size: 28px; } .column { float: left; width: 50%; background: rgba(255,0,0,0.1); } h2 { background: gold; margin-top: 50px; font-size: 24px; } .row{ margin-top:7.5%; }

Pero si eliminamos el valor predeterminado de h1 y h2, entonces el espacio entre .header y .column sería el espacio asignado a .row (en%) y eso disminuye a medida que redimensionamos el ancho de nuestro navegador. Ahora, para asignar un ancho del 100% a .column se puede hacer usando una consulta de medios al apuntar a dispositivos móviles particulares. Para que col 2 se coloquen debajo de col 1 con un ancho del 100%

body{ margin:0; } .header { font-size: 24px; background: rgba(0,255,0,0.1); } h1 { background: silver; font-size: 28px; margin:0; } .column { float: left; width: 50%; background: rgba(255,0,0,0.1); } h2 { background: gold; font-size: 24px; margin:0; } .row{ margin-top:7.5%; }


.header + *:last-child { h1{ margin-bottom:0px; } } .row + * :first-child{ h2{ margin-top:0px; } }