Por que a altura de um elemento contêiner não aumenta se ele contém elementos flutuantes?

210

Gostaria de perguntar como a altura e a flutuação funcionam. Eu tenho uma div externa e uma div interna que tem conteúdo nela. Sua altura pode variar dependendo do conteúdo da div interna, mas parece que minha div interna transbordará da div externa. Qual seria a maneira correta de fazer isso?

 <html>
    <body>
        <div style="margin:0 auto;width: 960px; min-height: 100px; background-color:orange">
    	    <div style="width:500px; height:200px; background-color:black; float:right"></div>
        </div>
    </body>
</html>

Boy Pasmo
fonte
muito bom e muito obrigado!
Bassam Alugili

Respostas:

581

Os elementos flutuantes não aumentam a altura do elemento do contêiner e, portanto, se você não os limpar, a altura do contêiner não aumentará ...

Eu vou te mostrar visualmente:

insira a descrição da imagem aqui

insira a descrição da imagem aqui

insira a descrição da imagem aqui

Mais explicações:

<div>
  <div style="float: left;"></div>
  <div style="width: 15px;"></div> <!-- This will shift 
                                        besides the top div. Why? Because of the top div 
                                        is floated left, making the 
                                        rest of the space blank -->

  <div style="clear: both;"></div> 
  <!-- Now in order to prevent the next div from floating beside the top ones, 
       we use `clear: both;`. This is like a wall, so now none of the div's 
       will be floated after this point. The container height will now also include the 
       height of these floated divs -->
  <div></div>
</div>

Você também pode adicionar overflow: hidden;elementos de contêiner, mas eu sugiro que você use clear: both;.

Além disso, se você quiser limpar um elemento automaticamente, poderá usar

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

Como funciona o CSS Float?

O que é float exatamente e o que ele faz?

  • A floatpropriedade é incompreendida pela maioria dos iniciantes. Bem, o que exatamente faz float? Inicialmente, a floatpropriedade foi introduzida para fluir o texto em torno das imagens, que são flutuadas leftou right. Aqui está outra explicação de @Madara Uchicha.

    Então, é errado usar a floatpropriedade para colocar caixas lado a lado? A resposta é não ; não há problema se você usar a floatpropriedade para definir caixas lado a lado.

  • A flutuação de um elemento inlineou blocklevel fará com que ele se comporte como um inline-blockelemento.

    Demo

  • Se você flutuar um elemento leftou right, o widthelemento será limitado ao conteúdo que ele contém, a menos que widthseja definido explicitamente ...

  • Você não pode floatum elemento center. Esse é o maior problema que eu sempre vi com iniciantes, usando float: center;, que não é um valor válido para a floatpropriedade. floatgeralmente é usado para float/ mover o conteúdo para a esquerda ou para a direita . Existem apenas quatro valores válidos para a floatpropriedade left, ou seja right, none(padrão) e inherit.

  • O elemento pai entra em colapso, quando ele contém elementos filhos flutuantes, para evitar isso, usamos a clear: both;propriedade para limpar os elementos flutuantes em ambos os lados, o que impedirá o colapso do elemento pai. Para mais informações, você pode consultar minha outra resposta aqui .

  • (Importante) Pense nisso onde temos uma pilha de vários elementos. Quando usamos float: left;ou float: right;o elemento se move acima da pilha por um. Portanto, os elementos no fluxo normal de documentos se ocultam atrás dos elementos flutuantes porque estão no nível da pilha acima dos elementos flutuantes normais. (Por favor, não relacione isso z-indexcomo isso é completamente diferente.)


Tomando um caso como exemplo para explicar como as flutuações CSS funcionam, supondo que precisamos de um layout simples de 2 colunas com cabeçalho, rodapé e 2 colunas, então aqui está a aparência do blueprint ...

insira a descrição da imagem aqui

No exemplo acima, nós estaremos flutuante apenas as caixas vermelhas, ou você pode floattanto à left, ou você pode floatpara left, e outro para rightassim, depende do layout, se é 3 colunas, você pode float2 colunas para leftonde outro um rightdepende, embora neste exemplo, tenhamos um layout simplificado de 2 colunas, assim como floatum lefte outro right.

Marcação e estilos para criar o layout explicados mais adiante ...

<div class="main_wrap">
    <header>Header</header>
    <div class="wrapper clear">
        <div class="floated_left">
            This<br />
            is<br />
            just<br />
            a<br />
            left<br />
            floated<br />
            column<br />
        </div>
        <div class="floated_right">
            This<br />
            is<br />
            just<br />
            a<br />
            right<br />
            floated<br />
            column<br />
        </div>
    </div>
    <footer>Footer</footer>
</div>

* {
    -moz-box-sizing: border-box;       /* Just for demo purpose */
    -webkkit-box-sizing: border-box;   /* Just for demo purpose */
    box-sizing: border-box;            /* Just for demo purpose */
    margin: 0;
    padding: 0;
}

.main_wrap {
    margin: 20px;
    border: 3px solid black;
    width: 520px;
}

header, footer {
    height: 50px;
    border: 3px solid silver;
    text-align: center;
    line-height: 50px;
}

.wrapper {
    border: 3px solid green;
}

.floated_left {
    float: left;
    width: 200px;
    border: 3px solid red;
}

.floated_right {
    float: right;
    width: 300px;
    border: 3px solid red;
}

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

Vamos passo a passo com o layout e ver como o float funciona.

Primeiro de tudo, nós usamos o elemento envoltório principal, você pode simplesmente assumir que é a sua janela, então usamos headere atribuir um heightde 50pxmodo nada extravagante lá. É apenas um elemento normal de nível de bloco não flutuante que ocupará 100%espaço horizontal, a menos que seja flutuado ou que atribuímos inline-blocka ele.

O primeiro valor válido para floaté leftassim em nosso exemplo, usamos float: left;for .floated_left, então pretendemos flutuar um bloco no leftelemento do nosso container.

Coluna flutuada para a esquerda

E sim, se você vê, o elemento pai, que está .wrapperrecolhido, o que você vê com uma borda verde não se expandiu, mas deveria estar certo? Voltaremos a isso em um tempo, por enquanto, temos uma coluna flutuada para left.

Chegando à segunda coluna, deixa esta floataqui para oright

Outra coluna flutuou para a direita

Aqui, temos uma 300pxcoluna ampla na qual vamos floatpara right, que fica ao lado da primeira coluna à medida que flutua para o lefte, desde que flutuou para o left, ele criou uma calha vazia para o right, e como havia um amplo espaço no right, nosso righto elemento flutuado estava perfeitamente ao lado do leftoutro.

Ainda assim, o elemento pai está recolhido, bem, vamos corrigir isso agora. Existem várias maneiras de impedir que o elemento pai seja recolhido.

  • Adicione um elemento de nível de bloco vazio e use clear: both;antes que o elemento pai termine, que contém elementos flutuantes. Agora, essa é uma solução barata para clearseus elementos flutuantes, que fará o trabalho por você, mas eu recomendo não usá-lo.

Adicione, <div style="clear: both;"></div>antes do .wrapper divfinal, como

<div class="wrapper clear">
    <!-- Floated columns -->
    <div style="clear: both;"></div>
</div>

Demo

Bem, isso corrige muito bem, não há mais pai recolhido, mas adiciona marcação desnecessária ao DOM, sugerem alguns, para usar overflow: hidden;no elemento pai que contém elementos filhos flutuantes que funcionam como pretendido.

Use overflow: hidden;em.wrapper

.wrapper {
    border: 3px solid green;
    overflow: hidden;
}

Demo

Isso nos poupa de um elemento toda vez que precisamos, clear floatmas ao testar vários casos com isso, ele falhou em um deles, que é usado box-shadownos elementos filhos.

Demo (Não é possível ver a sombra nos quatro lados,overflow: hidden;causa esse problema)

E agora? Salve um elemento, não overflow: hidden;faça uma correção clara, use o trecho abaixo em seu CSS e, assim como você usa overflow: hidden;para o elemento pai, chame o elemento classabaixo no elemento pai para limpar automaticamente.

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

<div class="wrapper clear">
    <!-- Floated Elements -->
</div>

Demo

Aqui, a sombra funciona como pretendido e também limpa automaticamente o elemento pai que impede o colapso.

E, finalmente, usamos o rodapé depois cleardos elementos flutuantes.

Demo


Quando é float: none;usado de qualquer maneira, como é o padrão, então qualquer uso para declarar float: none;?

Bem, depende, se você estiver buscando um design responsivo, usará esse valor várias vezes quando desejar que seus elementos flutuantes sejam renderizados um abaixo do outro em uma determinada resolução. Para essa float: none;propriedade desempenha um papel importante lá.


Poucos exemplos reais de como floaté útil.

  • O primeiro exemplo que já vimos é criar um ou mais de um layout de coluna.
  • O uso de imgfloat inside pque permitirá que nosso conteúdo flua.

Demonstração (sem flutuaçãoimg)

Demo 2 (imgflutuou para oleft)

  • Usando floatpara criar o menu horizontal - Demo

Flutue o segundo elemento também, ou use `margin`

Por último, mas não menos importante, quero explicar esse caso específico em que você floatapenas um elemento para o leftmas não floato outro, então o que acontece?

Suponha que, se removermos float: right;do nosso .floated_right class, o divserá processado do extremo, leftpois não é flutuado.

Demo

Portanto, neste caso, seja possível floato para o leftbem

OU

Você pode usar o margin-leftque será igual ao tamanho da coluna flutuante esquerda, ou seja, 200pxlarga .

Mr. Alien
fonte
3
O fato de os flutuadores não contribuírem para a altura de um pai no nível de bloco é explicitamente declarado aqui na especificação: w3.org/TR/CSS21/visudet.html#normal-block A razão pela qual a adição de um clearfix funciona é porque 1) o clearfix está (normalmente) no fluxo normal 2) a limpeza de flutuadores requer que o clearfix seja colocado na parte inferior dos flutuadores 3) o contêiner deve ser esticado para conter esse clearfix.
BoltClock
@BoltClock, seria melhor se você reverter a edição do título, pois isso afetará gravemente o SEO dos usuários que descobrirem como o float funciona. Você pode escrever esses termos no google e verificar. Caso contrário, essa resposta canônica não será útil se as pessoas estiverem não é capaz de encontrar o que eles estão procurando.
Sr. Estrangeiro
"Como o CSS float funciona?" é um título extremamente amplo, e também engana as pessoas a votar para fechar qualquer questão flutuante como uma bobagem dessa. A questão aqui abrange apenas um aspecto: os contêineres embalados (ou não embalados) flutuam.
BoltClock
@BoltClock De qualquer forma, o tecnicismo continua o mesmo que o explicado clear: both;, mas tudo bem se você achar que a edição justifica, então vamos continuar assim
Sr. Alien
1
resposta brilhante. "Flutuando qualquer elemento para a esquerda ou para a direita, a largura do elemento será limitada ao conteúdo que contém, a menos que a largura seja definida explicitamente" - observei a mesma coisa e estava apenas procurando que isso fosse confirmado. Obrigado
Deen John
38

Você precisa adicionar overflow:autoao seu div principal para que ele abranja o div flutuante interno:

<div style="margin:0 auto;width: 960px; min-height: 100px; background-color:orange;overflow:auto">
    <div style="width:500px; height:200px; background-color:black; float:right">
    </div>
</div>

Exemplo de jsFiddle

j08691
fonte
6
isso não é uma solução, você está ocultando o conteúdo que sai dos limites da div externa.
Alejandro Ruiz Arias
@AlejandroRuizArias - Exatamente como algo está sendo escondido?
J08691
3
Neste exemplo, nada, mas se você introduzir conteúdo suficiente na div interna, sim.
Alejandro Ruiz Arias
Isso não faz o que o OP estava procurando:
Bifurcada
1
Impressionante. A solução de um atributo que eu estava procurando, se tudo o mais fosse assim tão fácil, não haveria necessidade de redução.
YK
10

Você está encontrando o erro de flutuação (embora eu não tenha certeza se é tecnicamente um erro devido a quantos navegadores exibem esse comportamento). Eis aqui o que está acontecendo:

Em circunstâncias normais, assumindo que nenhuma altura explícita foi definida, um elemento no nível do bloco, como uma div, definirá sua altura com base em seu conteúdo. A parte inferior da div principal se estenderá além do último elemento. Infelizmente, flutuar um elemento impede que o pai leve em consideração o elemento flutuante ao determinar sua altura. Isso significa que, se seu último elemento for flutuado, ele não "esticará" o pai da mesma maneira que um elemento normal faria.

Compensação

Existem duas maneiras comuns de corrigir isso. O primeiro é adicionar um elemento "clearing"; ou seja, outro elemento abaixo do flutuante que forçará o pai a se esticar. Portanto, adicione o seguinte html como o último filho:

<div style="clear:both"></div>

Ele não deve estar visível e, usando clear: ambos, você garante que ele não fique ao lado do elemento flutuado, mas depois dele.

Transbordar:

O segundo método, que é preferido pela maioria das pessoas (eu acho), é alterar o CSS do elemento pai para que o estouro seja tudo menos "visível". Portanto, definir o estouro como "oculto" forçará o pai a esticar além da parte inferior do filho flutuante. Isso só é verdade se você não tiver definido uma altura no pai, é claro.

Como eu disse, o segundo método é preferido, pois não requer que você adicione elementos semanticamente sem sentido à sua marcação, mas há momentos em que você precisa overflowestar visível; nesse caso, adicionar um elemento de limpeza é mais do que aceitável .

Maloric
fonte
3

É por causa do flutuador da div. Adicione overflow: hiddeno elemento externo.

<div style="overflow:hidden; margin:0 auto;width: 960px; min-height: 100px; background-color:orange;">
    <div style="width:500px; height:200px; background-color:black; float:right">
    </div>
</div>

Demo

Starx
fonte
3

Você confunde como os navegadores renderizam os elementos quando existem elementos flutuantes. Se um elemento de bloco estiver flutuando (sua div interna no seu caso), outros elementos de bloco o ignorarão porque o navegador remove elementos flutuantes do fluxo normal da página da web. Então, como a div flutuante foi removida do fluxo normal, a div externa é preenchida, como se a div interna não estivesse lá. No entanto, os elementos embutidos (imagens, links, texto, citações em preto) respeitarão os limites do elemento flutuante. Se você introduzir texto na div externa, o texto será colocado ao redor da div interna.

Em outras palavras, os elementos do bloco (cabeçalhos, parágrafos, divs, etc) ignoram os elementos flutuantes e preenchem, e os elementos embutidos (imagens, links, texto, etc) respeitam os limites dos elementos flutuantes.

Um exemplo de violino aqui

<body>
    <div style="float:right; background-color:blue;width:200px;min-height:400px;margin-right:20px">
           floating element
    </div>
    <h1 style="background-color:red;"> this is a big header</h1>
    <p style="background-color:green"> this is a parragraph with text and a big image. The text places arrounds the floating element. Because of the image is wider than space between paragrah and floating element places down the floating element. Try to make wider the viewport and see what happens :D
        <img src="http://2.bp.blogspot.com/_nKxzQGcCLtQ/TBYPAJ6xM4I/AAAAAAAAAC8/lG6XemOXosU/s1600/css.png">
     </p>
Alejandro Ruiz Arias
fonte
3
Não destaque o texto e compartilhe links de violino, códigos postais na sua resposta da próxima vez, porque se o link de violão estiver morto, o usuário futuro não receberá ajuda aqui e sua resposta não terá significado
Sr. Alien
2

Tente este

.parent_div{
    display: flex;
}
Yusufbek
fonte
1

você pode usar a propriedade overflow na div do contêiner se não tiver nenhuma div para mostrar sobre o contêiner, por exemplo:

<div class="cointainer">
    <div class="one">Content One</div>
    <div class="two">Content Two</div>
</div>

Aqui está o seguinte css:

.container{
    width:100%;/* As per your requirment */
    height:auto;
    float:left;
    overflow:hidden;
}
.one{
    width:200px;/* As per your requirment */
    height:auto;
    float:left;
}

.two{
    width:200px;/* As per your requirment */
    height:auto;
    float:left;
}

-----------------------OU-------------------------- ----

    <div class="cointainer">
        <div class="one">Content One</div>
        <div class="two">Content Two</div>
        <div class="clearfix"></div>
    </div>

Aqui está o seguinte css:

    .container{
        width:100%;/* As per your requirment */
        height:auto;
        float:left;
        overflow:hidden;
    }
    .one{
        width:200px;/* As per your requirment */
        height:auto;
        float:left;
    }

    .two{
        width:200px;/* As per your requirment */
        height:auto;
        float:left;
    }
    .clearfix:before,
    .clearfix:after{
        display: table;
        content: " ";
    }
    .clearfix:after{
        clear: both;
    }
Nishant Rana
fonte