CSS - Expandir altura DIV filho flutuante para a altura dos pais


451

Eu tenho a estrutura da página como:

<div class="parent">
    <div class="child-left floatLeft">
    </div>

    <div class="child-right floatLeft">
    </div>
</div>

Agora, o child-leftDIV terá mais conteúdo, portanto a parentaltura do DIV aumenta conforme o DIV filho.

Mas o problema é que a child-rightaltura não está aumentando. Como posso fazer sua altura igual à sua mãe?


Respostas:


459

Para o parentelemento, adicione as seguintes propriedades:

.parent {
    overflow: hidden;
    position: relative;
    width: 100%;
}

então para .child-rightestes:

.child-right {
    background:green;
    height: 100%;
    width: 50%;
    position: absolute;
    right: 0;
    top: 0;
}

Encontre resultados mais detalhados com exemplos de CSS aqui e mais informações sobre colunas de altura igual aqui .


14
Seu CSS resulta em um comportamento indefinido - a altura dos pais depende da altura dos filhos, mas os filhos têm uma porcentagem de altura definida em termos dos pais: isso é inválido e provavelmente não funcionará de maneira cruzada no navegador.
Eamon Nerbonne

1
Vejo que você não está flutuando tudo - então isso é definido ao custo de não ser escalado, se a coluna da direita crescer mais do que a esquerda (o que de fato não é o caso na pergunta do OP).
Eamon Nerbonne

4
Sim, você precisa adicionar este: padding-bottom: 32768px; margem inferior: -32768 px; Para as crianças.
Michael

3
Isso funciona desde que a coluna da direita tenha menos conteúdo do que a esquerda ou será cortada. Também editei a resposta para omitir as declarações inúteis.
Christoph

3
@ MatthewBlackford: é um "hack", pois evita o colapso da margem. Você pode evitar o colapso da margem de outras maneiras, como o uso de uma borda transparente de 1px, mas em essência, mas o importante aqui é que você evite o colapso da margem. Eu não usaria essa solução, exceto como último recurso, uma vez que causa erros de layout estranhos e cortes inesperados (ou conteúdo sobreposto) quando suas suposições se mostram defeituosas. Em resumo: você não quer fazer isso, a menos que realmente precise.
Eamon Nerbonne

205

Uma solução comum para esse problema usa posicionamento absoluto ou flutuadores cortados, mas estes são complicados, pois exigem um ajuste extensivo se as colunas mudarem de número + tamanho e você precisa garantir que a coluna "principal" seja sempre a mais longa. Em vez disso, sugiro que você use uma das três soluções mais robustas:

  1. display: flex: de longe a solução mais simples e melhor e muito flexível - mas não suportada pelo IE9 e versões anteriores.
  2. tableou display: table: muito simples, muito compatível (praticamente todos os navegadores de todos os tempos), bastante flexível.
  3. display: inline-block; width:50% com um corte de margem negativo: bastante simples, mas as bordas na parte inferior da coluna são um pouco complicadas.

1 display:flex

Isso é realmente simples e fácil de se adaptar a layouts mais complexos ou mais detalhados - mas o flexbox é suportado apenas pelo IE10 ou posterior (além de outros navegadores modernos).

Exemplo: http://output.jsbin.com/hetunujuma/1

Html relevante:

<div class="parent"><div>column 1</div><div>column 2</div></div>

CSS relevante:

.parent { display: -ms-flex; display: -webkit-flex; display: flex; }
.parent>div { flex:1; }

O Flexbox oferece suporte para muito mais opções, mas para ter simplesmente qualquer número de colunas, as opções acima são suficientes!

2. <table>oudisplay: table

Uma maneira simples e extremamente compatível de fazer isso é usar um table- eu recomendo que você tente primeiro se precisar de suporte do IE antigo . Você está lidando com colunas; divs + floats simplesmente não são a melhor maneira de fazer isso (sem mencionar o fato de que vários níveis de divs aninhados apenas para contornar as limitações de css são dificilmente mais "semânticos" do que apenas usar uma tabela simples). Se você não deseja usar o tableelemento, considere cssdisplay: table (não suportado pelo IE7 e mais antigo).

Exemplo: http://jsfiddle.net/emn13/7FFp3/

HTML relevante: (mas considere usar um simples<table>)

<div class="parent"><div>column 1</div><div>column 2</div></div>

CSS relevante:

.parent { display: table; }
.parent > div {display: table-cell; width:50%; }
/*omit width:50% for auto-scaled column widths*/

Essa abordagem é muito mais robusta do que usar overflow:hiddencom flutuadores. Você pode adicionar praticamente qualquer número de colunas; você pode dimensioná- los automaticamente, se quiser; e você mantém a compatibilidade com navegadores antigos. Diferentemente da solução flutuante requer, você também não precisa saber de antemão qual coluna é mais longa; a altura escala muito bem.

BEIJO: não use hacks flutuantes, a menos que você precise especificamente. Se o IE7 for um problema, eu ainda escolheria uma tabela simples com colunas semânticas em vez de uma solução CSS de truque difícil de manter e menos flexível a qualquer dia.

A propósito, se você precisar que seu layout seja responsivo (por exemplo, sem colunas em telefones celulares pequenos), poderá usar uma @mediaconsulta para retornar ao layout de bloco simples para pequenas larguras de tela - isso funciona se você usa <table>ou qualquer outro display: tableelemento.

3. display:inline blockcom uma margem negativa hack.

Outra alternativa é usar display:inline block.

Exemplo: http://jsbin.com/ovuqes/2/edit

HTML relevante: (a ausência de espaços entre asdivtags é significativa!)

<div class="parent"><div><div>column 1</div></div><div><div>column 2</div></div></div>

CSS relevante:

.parent { 
    position: relative; width: 100%; white-space: nowrap; overflow: hidden; 
}

.parent>div { 
    display:inline-block; width:50%; white-space:normal; vertical-align:top; 
}

.parent>div>div {
    padding-bottom: 32768px; margin-bottom: -32768px; 
}

Isso é um pouco complicado, e a margem negativa significa que a parte inferior "verdadeira" das colunas está obscurecida. Por sua vez, isso significa que você não pode posicionar nada em relação à parte inferior dessas colunas, porque isso é cortado overflow: hidden. Observe que, além dos blocos embutidos, você pode obter um efeito semelhante com os flutuadores.


TL; DR : use flexbox se você puder ignorar o IE9 e mais antigo; caso contrário, tente uma tabela (css). Se nenhuma dessas opções funcionar para você, há invasões de margem negativa, mas elas podem causar problemas estranhos de exibição que são fáceis de serem perdidos durante o desenvolvimento e existem limitações de layout que você precisa conhecer.


1
Bom, mas vale a pena notar que você não pode usar margens entre essas células (o preenchimento não ajudará se você quiser que elas sejam estilizadas).
Wordpressor

3
border-spacing:10px;no elemento da tabela introduzirá espaçamento semelhante a margem. Como alternativa, você pode adicionar colunas extras (vazias) nas quais deseja espaço extra. E você também pode adicionar preenchimento dentro das células da tabela; esse preenchimento será incluído no plano de fundo, portanto, pode não ser o que você deseja. Mas você está certo que não é tão flexível quanto uma margem normal. E você não pode posicionar nada em relação às colunas, o que pode ser um problema.
Eamon Nerbonne

1
Então é melhor um layout sem tabela ou não?
dynamic

3
Devo dizer: concordo que, neste caso, uma tabela simples é mais que suficiente. O problema é que há uma visão comum de ignorar todos os layouts com mesa
dinâmica

3
O problema com a tabela é que, quando a tela é redimensionada para uma largura menor (design responsivo), as células da tabela ficam comprimidas em vez de colocar uma sobre a parte superior da próxima. O segundo método com fundo de preenchimento: 32768px; margem inferior: -32768 px; é bastante surpreendente e faz quase exatamente o que eu precisava ... obrigado por que um ... fundo fronteira é uma questão embora ...
Serj Sagan

23

Para o pai:

display: flex;

Para crianças:

align-items: stretch;

Você deve adicionar alguns prefixos, verifique caniuse.


2
Não recomendaria. IE9 ainda é uma coisa.

Obrigado pela sua resposta; isso funciona bem! "Você deve adicionar alguns prefixos, verifique caniuse." o que você quer dizer com essa linha? Você pode adicionar um pouco mais de informação para iniciantes?
Md Sifatul Islam

@MdSifatulIslam Acesse aqui: caniuse.com/#feat=flexbox Você pode ver se algum navegador necessário para suportar precisa de prefixo de recurso.
Aiphee

18

Encontrei muitas respostas, mas provavelmente a melhor solução para mim é

.parent { 
  overflow: hidden; 
}
.parent .floatLeft {
  # your other styles
  float: left;
  margin-bottom: -99999px;
  padding-bottom: 99999px;
}

Você pode verificar outras soluções aqui http://css-tricks.com/fluid-width-equal-height-columns/


Não tenho idéia do porquê desse trabalho, mas resolve meu problema como um encanto. Obrigado
Combinar

Funciona para mim também. Mesmo que não seja o caminho limpo. Obrigado!
Mark Anthony Uy

17
hacky como o inferno. Eu não recomendo isso para aplicativos de produção
FedericoCapaldo

isso é incrível haha. Eu não acho que isso seria realmente trabalhar
Tom McDonough

11

Por favor, defina div pai como overflow: hidden
divs filho. Você pode definir uma grande quantia para o fundo do preenchimento. por exemplo,
padding-bottom: 5000px
então margin-bottom: -5000px
e então todos os divs filhos terão a altura do pai.
Claro que isso não funcionará se você estiver tentando colocar conteúdo na div pai (fora de outras divs)

.parent{
    border: 1px solid black;
    overflow: hidden;
    height: auto;
}
.child{
    float: left;
    padding-bottom: 1500px;
    margin-bottom: -1500px;
}
.child1{
    background: red;
    padding-right: 10px;    
}
.child2{
    background: green;
    padding-left: 10px;
}
<div class="parent">
    <div class="child1 child">
        One line text in child1
    </div>
    <div class="child2 child">
        Three line text in child2<br />
        Three line text in child2<br />
        Three line text in child2
    </div>
</div>

Exemplo: http://jsfiddle.net/Tareqdhk/DAFEC/


parece um pouco sujo, mas funcionou para mim - a única solução para esta questão. Eu tentei isso usando o twitter bootstrap.
precisa saber é

8

Os pais têm altura? Se você definir a altura dos pais dessa forma.

div.parent { height: 300px };

Então você pode fazer a criança esticar até a altura máxima dessa maneira.

div.child-right { height: 100% };

EDITAR

Aqui está como você faria isso usando JavaScript.


pai não tem uma altura fixa. Ele está se expandindo conforme a altura da criança esquerda.
Veera

Ah, eu pensei isso, então você vai precisar de algum JavaScript, acrescentarei em um segundo.
Olical

O link do JSFiddle está quebrado. Remova-o ou atualize a resposta. Obrigado!
Itsmysterybox

1
O link para js agora fornece um 404
Chanoch 29/11

5

A exibição da tabela CSS é ideal para isso:

.parent {
  display: table;
  width: 100%;
}
.parent > div {
  display: table-cell;
}
.child-left {
  background: powderblue;
}
.child-right {
  background: papayawhip;
}
<div class="parent">
  <div class="child-left">Short</div>
  <div class="child-right">Tall<br>Tall</div>
</div>

Resposta original (supondo que qualquer coluna possa ser mais alta):

Você está tentando tornar a altura dos pais dependente da altura dos filhos e a altura dos filhos depende da altura dos pais. Não computará. As colunas CSS Faux são a melhor solução. Há mais de uma maneira de fazer isso. Prefiro não usar JavaScript.


Bom ponto. Que tal se a altura dos filhos depende da altura do irmão mais alto (seja determinado pela altura dos pais ou não), e não dos pais? Eu acho que isso não pode ser feito em CSS.
Mikato #

Não, irmãos não podem afetar a altura um do outro. No entanto, o layout display: table+ display: table-cellproduzirá o resultado desejado.
Salman A

Great update! No entanto, acabei tentando isso e queria ter uma separação de espaço em branco entre as divs / células e tive que fazer divs internas nas divs da célula da tabela para conseguir isso e, é claro, perdi a capacidade de fazê-las usar a altura total porque as divs internas não eram divs de célula de tabela - exatamente o mesmo problema. Alguma idéia para isso? Tipo de espaçamento entre células ausente agora.
Mikato 03/03

Ah, há espaçamento de borda no CSS! stackoverflow.com/questions/339923/… Consegui fazer com que meus divs parecidos com tabelas funcionassem bem com a separação de espaços em branco usando espaçamento entre bordas. Agora, tenho a capacidade de fazer com que as células da tabela (blocos de plano de fundo colorido) usem toda a altura do pai ou não com o uso inteligente dos divs da célula da tabela.
Mikato # 4/15

Apenas uma dica que eu encontrei: você não pode usá-lo com float: stackoverflow.com/questions/20110217/…
Joshua Pinter

4

Recentemente, fiz isso no meu site usando jQuery. O código calcula a altura da div mais alta e define as outras divs para a mesma altura. Aqui está a técnica:

http://www.broken-links.com/2009/01/20/very-quick-equal-height-columns-in-jquery/

Não acredito height:100%que funcione, portanto, se você não conhece explicitamente as alturas de div, não acho que exista uma solução CSS pura.


1
Você deve ativar isso pelo menos em pronto, redimensionar, alterar a orientação, redimensionar fontes.
netAction

4

Eu usei isso para uma seção de comentários:

.parent {
    display: flex;
    float: left;
    border-top:2px solid black;
    width:635px;
    margin:10px 0px 0px 0px;
    padding:0px 20px 0px 20px;
    background-color: rgba(255,255,255,0.5);
}
    
.child-left {
	align-items: stretch;
	float: left;
	width:135px;
	padding:10px 10px 10px 0px;
	height:inherit;
	border-right:2px solid black;
}

.child-right {
	align-items: stretch;
	float: left;
	width:468px;
	padding:10px;
}
<div class="parent">
  <div class="child-left">Short</div>
  <div class="child-right">Tall<br>Tall</div>
</div>

Você pode flutuar a criança-direita para a direita, mas, neste caso, calculei as larguras de cada div com precisão.


1
primeira coisa que veio a minha mente era altura: herdar não tenho certeza por que ninguém upvoted
Andreas

3

Se você está ciente do bootstrap, é possível fazê-lo facilmente usando a propriedade 'flex'. Tudo o que você precisa fazer é passar abaixo das propriedades css para parent div

.homepageSection {
  overflow: hidden;
  height: auto;
  display: flex;
  flex-flow: row;
}

Onde .homepageSectionestá o meu pai div? Agora adicione div filho no seu html como

<div class="abc col-md-6">
<div class="abc col-md-6">

onde abc é meu filho div. Você pode verificar a igualdade de altura em ambos filho div, independentemente da borda, apenas atribuindo borda ao filho div


0
<div class="parent" style="height:500px;">
<div class="child-left floatLeft" style="height:100%">
</div>

<div class="child-right floatLeft" style="height:100%">
</div>
</div>

Eu usei o estilo embutido apenas para dar uma idéia.


-2

Eu aprendi desse truque em uma entrevista de estágio. A pergunta original é como garantir que a altura de cada componente superior em três colunas tenha a mesma altura que mostra todo o conteúdo disponível. Basicamente, crie um componente filho invisível que renderize a altura máxima possível.

<div class="parent">
    <div class="assert-height invisible">
        <!-- content -->
    </div>
    <div class="shown">
        <!-- content -->
    </div>
</div>
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.