Solução pura de CSS
Use o código a seguir para anexar um primeiro filho sem conteúdo à div que se move sem querer:
.parent:before
{content: '';position: relative;height: 0px;width: 0px;overflow: hidden;white-space: pre;}
A vantagem desse método é que você não precisa alterar o CSS de nenhum elemento existente e, portanto, tem um impacto mínimo no design. Além disso, o elemento adicionado é um pseudo-elemento, que não está na árvore DOM.
O suporte a pseudo-elementos é amplo: Firefox 3+, Safari 3+, Chrome 3+, Opera 10+ e IE 8+. Isso funcionará em qualquer navegador moderno (tenha cuidado com o mais novo ::before
, que não é suportado no IE8).
Contexto
Se o primeiro filho de um elemento tiver um margin-top
, o pai ajustará sua posição como uma forma de recolher margens redundantes. Por quê? É assim mesmo.
Dado o seguinte 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>
Você pode corrigi-lo adicionando um filho com conteúdo, como um espaço simples. Mas todos nós odiamos adicionar espaços para o que é um problema apenas de design. Portanto, use a white-space
propriedade para falsificar conteúdo.
<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>
Onde position: relative;
garante o posicionamento correto da correção. E white-space: pre;
faz com que você não precise adicionar nenhum conteúdo - como um espaço em branco - à correção. E height: 0px;width: 0px;overflow: hidden;
garante que você nunca verá a correção.
Pode ser necessário adicionar line-height: 0px;
ou max-height: 0px;
garantir que a altura seja realmente zero nos navegadores IE antigos (não tenho certeza). E, opcionalmente, você pode adicioná <!--dummy-->
-lo em navegadores antigos do IE, se não funcionar.
Em resumo, você pode fazer tudo isso apenas com CSS (o que elimina a necessidade de adicionar um filho real à árvore 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>