Margen en el elemento hijo mueve el elemento padre
Tengo un div
(padre) que contiene otro div
(niño). Padre es el primer elemento en body
sin un estilo CSS particular. Cuando establezco
.child
{
margin-top: 10px;
}
El resultado final es que top of my child sigue alineado con parent. En lugar de desplazar al niño por 10px hacia abajo, mi padre mueve 10px hacia abajo.
Mi DOCTYPE
se establece en XHTML Transitional
.
¿Qué me estoy perdiendo aquí?
editar 1
Mi padre necesita haber definido estrictamente dimensiones porque tiene un fondo que tiene que mostrarse debajo de él de arriba a abajo (pixel perfecto). Así que establecer márgenes verticales en él es un no go.
editar 2
Este comportamiento es el mismo en FF, IE y CR.
14 answers
Encontró una alternativa en Elementos secundarios con márgenes dentro de DIVs También puede agregar:
.parent { overflow: auto; }
O:
.parent { overflow: hidden; }
Esto evita que los márgenes se contraigan . El borde y el relleno hacen lo mismo. Por lo tanto, también puede usar lo siguiente para evitar un colapso del margen superior:
.parent {
padding-top: 1px;
margin-top: -1px;
}
Actualización por petición popular: El objetivo de colapsar los márgenes es manejar el contenido textual. Por ejemplo:
<style type="text/css">
h1, h2, p, ul {
margin-top: 1em;
margin-bottom: 1em;
}
</style>
<h1>Title!</h1>
<div class="text">
<h2>Title!</h2>
<p>Paragraph</p>
</div>
<div class="text">
<h2>Title!</h2>
<p>Paragraph</p>
<ul>
<li>list item</li>
</ul>
</div>
Porque el navegador colapsa márgenes, el texto aparecerá como es de esperar, y las etiquetas <div>
wrapper no influyen en los márgenes. Cada elemento se asegura de que tenga espacio a su alrededor, pero el espacio no se duplicará. Los márgenes de <h2>
y <p>
no se suman, sino que se deslizan entre sí (se colapsan). Lo mismo sucede con los elementos <p>
y <ul>
.
Tristemente, con diseños modernos esta idea puede morderte cuando quieres explícitamente un contenedor. Esto se llama un nuevo contexto de formato de bloque en lenguaje CSS. El overflow
o truco de margen te dará eso.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:10:43
Este es un comportamiento normal (al menos entre las implementaciones del navegador). El margen no afecta la posición del hijo en relación con su padre, a menos que el padre tenga relleno, en cuyo caso la mayoría de los navegadores agregarán el margen del hijo al relleno del padre.
Para obtener el comportamiento que desea, necesita:
.child {
margin-top: 0;
}
.parent {
padding-top: 10px;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-11-19 11:10:31
Aunque todas las respuestas solucionan el problema, pero vienen con compensaciones / ajustes / compromisos como
-
floats
, Usted tiene para flotar elementos -
border-top
, Esto empuja al padre al menos 1px hacia abajo, que luego debe ajustarse introduciendo-1px
margen al propio elemento padre. Esto puede crear problemas cuando el padre ya tienemargin-top
en unidades relativas. -
padding-top
, el mismo efecto que usarborder-top
-
overflow: hidden
, No se puede usar cuando el padre debe mostrar contenido desbordante, como un menú desplegable -
overflow: auto
, Introduce barras de desplazamiento para el elemento padre que tiene (intencionalmente) contenido desbordante (como sombras o triángulo de punta de herramienta)
El problema se puede resolver usando pseudo elementos CSS3 de la siguiente manera
.parent::before {
clear: both;
content: "";
display: table;
margin-top: -1px;
height: 0;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-06-15 14:22:06
Añadir estilo display:inline-block
al elemento secundario
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-04-08 11:09:47
El elemento padre no tiene que estar vacío al menos pon
antes del elemento hijo.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-07-23 09:00:13
Esto es lo que funcionó para mí
.parent {
padding-top: 1px;
margin-top: -1px;
}
.child {
margin-top:260px;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-09-26 18:34:32
Me entero de que, dentro de tu .css > si establece la propiedad display de un elemento div en inline-block soluciona el problema. y el margen funcionará como se espera.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-05-13 22:29:47
El margin
de los elementos contenidos dentro de .child
se están colapsando.
<html>
<style type="text/css" media="screen">
#parent {background:#dadada;}
#child {background:red; margin-top:17px;}
</style>
<body>
<div id="parent">
<p>&</p>
<div id="child">
<p>&</p>
</div>
</div>
</body>
</html>
En este ejemplo, p
está recibiendo un margin
de los estilos predeterminados del navegador. El valor predeterminado del navegador font-size
es típicamente 16px. Al tener un margin-top
de más de 16px en #child
comienzas a notar su movimiento de posición.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-11-19 11:45:40
También tuve este problema, pero preferí evitar hacks de márgenes negativos, así que puse un
<div class="supercontainer"></div>
Alrededor de todo lo que tiene rellenos en lugar de márgenes. Por supuesto, esto significa más divitis, pero es probablemente la forma más limpia de hacerlo correctamente.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-04-07 15:03:51
Curiosamente, mi solución favorita para este problema aún no se menciona aquí: el uso de flotadores.
Html:
<div class="parent">
<div class="child"></div>
</div>
Css:
.parent{width:100px; height:100px;}
.child{float:left; margin-top:20px; width:50px; height:50px;}
Véalo aquí: http://codepen.io/anon/pen/Iphol
Tenga en cuenta que en caso de que necesite altura dinámica en el padre, también tiene que flotar, así que simplemente reemplace height:100px;
por float:left;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-07-14 20:13:54
Una solución alternativa que encontré antes de saber la respuesta correcta fue agregar un borde transparente al elemento padre.
Sin embargo, su caja usará píxeles adicionales...
.parent {
border:1px solid transparent;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-01-08 09:09:07
Solución solo CSS ordenada
Use el siguiente código para anteponer un primer hijo sin contenido al div que se mueve involuntariamente:
.parent:before
{content: '';position: relative;height: 0px;width: 0px;overflow: hidden;white-space: pre;}
La ventaja de este método es que no necesita cambiar el CSS de ningún elemento existente, y por lo tanto tiene un impacto mínimo en el diseño. Junto a esto, el elemento que se agrega es un pseudo-elemento, que es no en el árbol DOM.
El soporte para pseudo-elementos está muy extendido: Firefox 3+, Safari 3+, Chrome 3+, Opera 10+, e IE 8+. Esto funcionará en cualquier navegador moderno (tenga cuidado con el nuevo ::before
, que no es compatible con IE8).
Contexto
Si el primer hijo de un elemento tiene un margin-top
, el padre ajustará su posición como una forma de contraer márgenes redundantes. ¿Por qué? Es así de simple.
Dado el siguiente problema:
<style type="text/css">
div {position: relative;}
.parent {background-color: #ccc;}
.child {margin-top: 40px;}
</style>
<div class="parent"><!--This div moves 40px too-->
<div class="child">Hello world!</div>
</div>
Puede arreglarlo agregando un hijo con contenido, como un espacio simple. Pero todos odiamos agregar espacios para lo que es un problema solo de diseño. Por lo tanto, utilice la propiedad white-space
para falsificar contenido.
<style type="text/css">
div {position: relative;}
.parent {background-color: #ccc;}
.child {margin-top: 40px;}
.fix {position: relative;white-space: pre;height: 0px;width: 0px;overflow: hidden;}
</style>
<div class="parent"><!--This div won't move anymore-->
<div class="fix"></div>
<div class="child">Hello world!</div>
</div>
Donde position: relative;
asegura el posicionamiento correcto de la solución. Y white-space: pre;
hace que no tenga que agregar ningún contenido, como un espacio en blanco, a la solución. Y height: 0px;width: 0px;overflow: hidden;
se asegura de que nunca verás la solución.
Es posible que deba agregar line-height: 0px;
o max-height: 0px;
para asegurarse de que la altura es realmente cero en los navegadores IE antiguos (no estoy seguro). Y opcionalmente se puede añadir <!--dummy-->
en los navegadores IE antiguos, si no funciona.
En resumen, puedes hacer todo esto con solo CSS (que elimina la necesidad de agregar un hijo real al árbol DOM HTML):
<style type="text/css">
div {position: relative;}
.parent {background-color: #ccc;}
.child {margin-top: 40px;}
.parent:before {content: '';position: relative;height: 0px;width: 0px;overflow: hidden;white-space: pre;}
</style>
<div class="parent"><!--This div won't move anymore-->
<div class="child">Hello world!</div>
</div>
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-13 09:39:00
Usar top
en lugar de margin-top
es otra solución posible, si es apropiado.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-11-20 10:57:32
Para evitar que "Div parent" use el margen de " div child":
En el padre use estas css:
- Float
- Relleno
- Frontera
- Desbordamiento
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-11 06:00:47