faça a altura da div se expandir com seu conteúdo


376

Eu tenho essas divs aninhadas e preciso que o contêiner principal seja expandido (em altura) para acomodar os DIVs internos

    <!-- head -->
    ...
    <!-- /head -->

    <body class="main">
      <div id="container">
        <div id="header">
          <!--series of divs in here, graphic banner etc. -->
        </div>

    <div id="main_content"> <!-- this DIV _should_ stretch to accommodate inner divs -->
      <div id="items_list" class="items_list ui-sortable">
        <div id="item_35" class="item_details">
        </div>
        <div id="item_36" class="item_details">
        </div>        
        <div id="item_37" class="item_details">
        </div>
        <!-- this list of DIVs "item_xx" goes on for a while
             each one representing a photo with name, caption etcetc -->
      </div>
    </div>
    <br class="clear"/>

    <div id="footer">
    </div>
  </body>
</html>

CSS é este:

* {
    padding: 0;
    margin: 0;
}

.main {
    font: 100% Verdana, Arial, Helvetica, sans-serif;
    background: #4c5462;
    margin: 0; 
    padding: 0;
    text-align: center; 
    color: #000000;
}
.main #container {
    height: auto;
    width: 46em;
    background: #4c5462;
    margin: 0 auto; 
    border: 0px solid #000000;
    text-align: left;       
}

.main #main_content {
    padding: 5px;
    margin: 0px;
}
#items_list {
    width: 400px;
    float: left;
}

.items_list {
    width: 400px;
    float: left;
}
.item_details {
    margin-top: 3px;
    margin-bottom: 3px;
    padding: 3px;
    float: left;
    border-bottom: 0.5px solid blue;
}

O problema que tenho é que #main_contentnão se estende para acomodar todos os divs internos, com o resultado de que eles continuam indo no fundo.

Como posso resolver esse problema considerando o cenário acima?


5
Gente, obrigado a todos pelas respostas! a melhor solução para o meu caso específico foi codificar um BR para limpar os dois lados (obrigado Jennyfofenny e também Ricebowl) De qualquer forma, também outras soluções funcionaram: colocar overflow: auto estava ok e flutuante #main_content também estava ok (embora ir reduziu a largura dessa div ao tamanho de divs filho). Agora, sendo um novato, estou me perguntando: essas soluções têm desvantagens ou posso usá-las indiferentemente? (. por exemplo, talvez um deles não funciona com o IE6, ou similar ...)
patrick

11
@Patrick, se você quiser desenvolver sua pergunta, clique no link 'editar' (abaixo do texto atual da pergunta) e adicione as perguntas adicionais. A Convenção sugere o uso de algo como <strong>Edited</strong>$Reason_for_revising_question...Você pode precisar alterar o título da pergunta para refletir as alterações, se houver uma grande alteração ou adição em seu foco. =)
David diz para reinstalar Monica

4
Você também nunca fechou a divtag com id='container'. Isso pode causar alguns problemas.
Batkins

@patrick, você também não tem o CSS da .clearclasse. Você esqueceu ou está no seu código original? A .clearaula sobre isso bré muito importante, como @jennyfofenny menciona em sua resposta.
Cannicide

Respostas:


281

Você precisa forçar a clear:bothantes que a #main_contentdiv seja fechada. Eu provavelmente moveria o <br class="clear" />;para a #main_contentdiv e definiria o CSS como:

.clear { clear: both; }

Atualização: Esta pergunta ainda recebe uma quantidade razoável de tráfego, então eu queria atualizar a resposta com uma alternativa moderna usando um novo modo de layout no CSS3 chamado Caixas flexíveis ou Flexbox :

body {
  margin: 0;
}

.flex-container {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

header {
  background-color: #3F51B5;
  color: #fff;
}

section.content {
  flex: 1;
}

footer {
  background-color: #FFC107;
  color: #333;
}
<div class="flex-container">
  <header>
    <h1>
     Header   
    </h1>
  </header>

  <section class="content">
    Content
  </section>

  <footer>
    <h4>
      Footer
    </h4>
  </footer>
</div>

Atualmente, a maioria dos navegadores modernos oferece suporte a unidades Flexbox e viewport , mas se você precisar manter o suporte a navegadores mais antigos, verifique a compatibilidade da versão específica do navegador.


4
Aqui está o artigo w3schools na propriedade CSS clear. Basicamente, clear significa que o elemento ao qual a clear é aplicada começa abaixo dos flutuadores em seu fluxo (apenas à esquerda, apenas à direita ou ambos).
precisa saber é o seguinte

230

Tente o seguinte: overflow: auto;

Funcionou para o meu problema ..


10
+1, esta solução é elegante e não adiciona uma tag invisível à sua página. Veja este violino: jsfiddle.net/XmKrm/1
Nabil Kadimi

5
auto overflow funcionou bem para mim. Para sua informação, isso adicionará uma barra de rolagem se a altura do contêiner automático de estouro for menor que o conteúdo interno. Dimensione-o também ou defina a altura: auto junto com o excesso.
Bryan Myers

@ Roozbeh15 adicionar display: block;com ele #
BadAtPHP

2
Melhor e mais fácil solução ... Você salvou o meu dia. Graças
Kashyap Kotak

Santo Deus, isso funcionou maravilhosamente. alguém se importa em explicar o mecanismo subjacente de por que isso funcionou?
Merkurial 13/01

86

adicione o seguinte:

overflow:hidden;
height:1%;

para sua div principal. Elimina a necessidade de extra <br />para limpar.


Uau! que fez exatamente o oposto do que eu esperava! estouro: oculto = expandir para caber no conteúdo! eu nunca teria imaginado isso!
precisa saber é o seguinte

Sim, isso funcionou para mim também e não faz totalmente sentido o porquê. Alguma explicação para o funcionamento da 'altura 1%' e do 'estouro oculto'?
Acarlon #

11
realmente como e mesmo por que funciona, se nenhuma altura é definida, por que o estouro oculto não apenas oculta tudo (a altura cos é 0), mas se expande, existe alguma explicação ou apenas acredite e seja feliz?
Max Yari

11
overflow: esconde as barras de rolagem escondido, mas mantém o tamanho do bloco
authentictech

funcionou para mim com apenas 'overflow: hidden' mas 'overflow: auto' também funcionou e não mostrou barras de rolagem.
precisa

60

como uma maneira alternativa, você também pode tentar isso que pode ser útil em algumas situações

display:table;

jsFiddle


24

Eu usaria apenas

height: auto;

na sua div. Sim, eu sei que estou um pouco atrasado, mas achei que isso poderia ajudar alguém como se tivesse me ajudado se estivesse aqui.


height: auto;faz com que todos os itens abaixo sejam movidos para o topo. Com essa propriedade na minha div principal de conteúdo, o rodapé da minha página se move para cima, de modo que toque o cabeçalho e se sobreponha à minha div de conteúdo.
Aaron Franke

11
Esta foi a solução para mim. Obrigado!
Nik Hammer-Ellis

14

O seguinte deve funcionar:

.main #main_content {
    padding: 5px;
    margin: 0px;
    overflow: auto;
    width: 100%; //for some explorer browsers to trigger hasLayout
}

adicionando overflow: trabalho automático, embora se eu adicionar também width: 100%, isso faça com que a div (#main_content) seja um pouco maior do que a div pai. Não entendi o porquê!
patrick

2
Isso porque as contagens de preenchimento, além da largura especificada, então a largura do seu elemento é 100% + preenchimento 5px 5px esquerda + direita estofamento
NickV

11
estouro: auto; trabalhou para mim, muito obrigado veddy.
Cosco Tech

9

Maneira muito simples

No DIV pai:

height: 100%;

Este trabalho para mim todas as vezes


8

Use a tag span com display:inline-blockcss anexado a ela. Você pode usar CSS e manipulá-lo como uma div de várias maneiras, mas se você não incluir uma widthou heightela se expande e se retrai com base em seu conteúdo.

Espero que ajude.


Sua esperança funcionou: pelo menos me ajudou! :) Aliás, deixei meu elemento como div(em vez de a span), mas display: inline-blockainda funcionava no meu caso (Chromium).
snapfractalpop

6

Normalmente, acho que isso pode ser resolvido forçando uma clear:bothregra no último elemento filho do#items_list .

Você pode usar:

#items_list:last-child {clear: both;}

Ou, se você estiver usando uma linguagem dinâmica, adicione uma classe adicional ao último elemento gerado em qualquer loop que criar a própria lista, para que você acabe com algo em seu html como:

<div id="list_item_20" class="last_list_item">

e css

.last_list_item {clear: both; }

6

Esse problema surge quando os elementos filho de uma div principal são flutuados. Aqui está a solução mais recente do problema:

No seu arquivo CSS, escreva a seguinte classe chamada .clearfix junto com o pseudo-seletor : depois

.clearfix:after {
    content: "";
    display: table;
    clear: both;
}

Em seguida, no seu HTML, adicione a classe .clearfix ao seu div. Por exemplo:

<div class="clearfix">
    <div></div>
    <div></div>
</div>

Deve funcionar sempre. Você pode chamar o nome da classe como .group vez de .clearfix , uma vez que irá tornar o código mais semântico. Observe que, não é necessário adicionar o ponto ou mesmo um espaço no valor do conteúdo entre aspas duplas "". Além disso, estouro: auto;pode resolver o problema, mas causa outros problemas, como mostrar a barra de rolagem, e não é recomendado.

Fonte: Blog de Lisa Catalano e Chris Coyier


5

adicione uma propriedade float à #main_contentdiv - ela será expandida para conter seu conteúdo flutuante


Obrigado Ray, isso funcionou, embora tenha diminuído a div para o tamanho do seu conteúdo (#items_list) que possui largura: 400px; Sua solução seria muito boa se eu pudesse fazer #main_content ficar em sua largura total - alguma sugestão?
patrick

@ Ray 2 e um pouco mais tarde, e isso me salvou de uma dor de cabeça em potencial com um problema semelhante. Obrigado!
John H,

4

Antes de fazer qualquer coisa, verifique as regras de css com:

{ position:absolute }

Remova se existir e não precisa deles.


2
Como "elementos posicionados absolutos são removidos do fluxo, sendo ignorados por outros elementos. Portanto, você não pode definir a altura dos pais de acordo com um elemento absolutamente posicionado". stackoverflow.com/questions/12070759/…
Federico

4

Elementos flutuantes não ocupam o espaço dentro do elemento pai, como o nome sugere, eles flutuam! Assim, se uma altura não for explicitamente fornecida a um elemento com seus elementos filhos flutuados, o elemento pai parecerá encolher e parecerá não aceitar as dimensões do elemento filho, também se overflow:hidden;seus filhos dados possam não aparecer na tela. Existem várias maneiras de lidar com esse problema:

  1. Insira outro elemento abaixo do elemento flutuante com a clear:both;propriedade ou use clear:both;on :afterdo elemento flutuante.

  2. Use display:inline-block;ou em flex-boxvez de float.


3

Parece que isso funciona

html {
 width:100%;
 height:auto;
 min-height:100%
} 

O tamanho da tela é mínimo e, se o conteúdo for expandido, ele aumentará.



2

Adicionei o Bootstrap a um projeto com sectiontags que eu havia definido como 100% da altura da tela. Funcionou bem até que eu fiz o projeto ágil, altura em que eu emprestado parte de jennyfofenny 's resposta para que o segundo plano da seção correspondesse ao segundo plano do conteúdo quando o tamanho da tela mudou em telas menores.

Meu novo sectionCSS fica assim:

section {
    // min-height so it looks good on big screen
    // but resizes on a small-screen
    min-height: 100%;
    min-height: 100vh;
    width:100%;
    width:100vh;
}

Digamos que você tenha uma seção com uma determinada cor. Ao usar min-height, se a largura da seção diminuir por causa de uma tela menor, a altura da seção será expandida, o conteúdo permanecerá dentro da seção e o plano de fundo permanecerá na cor desejada.


2

Você já tentou da maneira tradicional? dê a altura do recipiente principal: auto

#container{height:auto}

Eu usei isso e funcionou na maioria das vezes comigo.


1

Eu mesmo estou enfrentando isso em um projeto - eu tinha uma tabela dentro de uma div que estava saindo do fundo da div. Nenhuma das correções de altura que tentei funcionou, mas achei uma correção estranha para isso, e é colocar um parágrafo na parte inferior da div com apenas um ponto nela. Em seguida, estilize a "cor" do texto para ser a mesma do plano de fundo do contêiner. Trabalhou limpo como quiser e não é necessário javascript. Um espaço sem quebra não funcionará - nem uma imagem transparente.

Aparentemente, ele só precisava ver que havia algum conteúdo abaixo da tabela para esticar para contê-lo. Gostaria de saber se isso vai funcionar para mais alguém.

Esse é o tipo de coisa que faz os designers recorrerem a layouts baseados em tabelas - a quantidade de tempo que gastei descobrindo essas coisas e tornando-as compatíveis com vários navegadores está me deixando louco.


Deve haver alguma maneira de fazer isso com o css, mas não tenho idéia do que seria. Isso funcionou para mim, mas eu tive que adicionar largura: 100%; altura: auto; altura mínima: 100%; posição: relativa;
RationalRabbit

1

Eu tentei isso e funcionou

<div style=" position: absolute; direction: ltr;height:auto; min-height:100%">   </div>

0

Se você estiver usando a interface do usuário do jQuery, eles já terão uma classe. Funciona apenas como um charme. Adicione um <div>na parte inferior dentro da div com a qual você deseja expandirheight:auto; e adicione um nome de classe ui-helper-clearfix ou use esse atributo de estilo e adicione como abaixo :

<div style=" clear:both; overflow:hidden; height:1%; "></div>

adicione a classe da interface do usuário do jQuery à div clara, não à div que você deseja expandir.


0

Eu sei que esse é um tipo de discussão antiga, no entanto, isso pode ser alcançado com min-height propriedade CSS de uma maneira limpa, então deixarei isso aqui para futuras referências:

Eu fiz um violino com base no código publicado do OP aqui: http://jsfiddle.net/U5x4T/1/ , ao remover e adicionar divs dentro, você notará como o contêiner se expande ou reduz em tamanho

As únicas duas coisas que você precisa para conseguir isso, além do código OP, são:

* Estouro no contêiner principal (necessário para os divs flutuantes)

* propriedade css min-height, mais informações disponíveis aqui: http://www.w3schools.com/cssref/pr_dim_min-height.asp


0

Exibição adicionada: em linha com a div e ela cresceu automaticamente (e não o material de rolagem) quando o conteúdo da altura ficou maior que a altura da div definida de 200px


11
Esta não é uma resposta clara para a pergunta. Para observações, use a função de comentário.
ksbg

0

Você pode usar o CSS Grid Layout . O suporte é bastante amplo no momento: verifique em caniuse .

Aqui está o exemplo no jsfiddle. Também exemplo com toneladas de material de texto.

Código HTML:

<div class="container">
  <div class="header">
   Header
  </div>
  <div class="content">
   Content
  </div>
  <div class="footer">
   Footer
  </div>
</div>

Código CSS:

html, body {
  width: 100%;
  height: 100%;
  margin: 0;
}

.container {
  width: 100%;
  height: 100%;

  display: grid;
  grid-template-rows: 100px auto 150px;
  grid-template-columns: auto;
}
// style stuff

0

Tentei praticamente todas as sugestões listadas acima e nenhuma delas funcionou. No entanto, "display: table" fez o truque para mim.


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.