Expanda div para largura máxima quando float: left estiver definido


115

Eu tenho algo assim:

<div style="width:100px;float:left">menu</div>
<div style="float:left">content</div>

ambos os flutuadores são necessários. Quero que o div de conteúdo preencha toda a tela, menos os 100px do menu. Se eu não usar float, o div se expande exatamente como deveria. Mas como faço para definir isso quando float está definido? Se eu usar algo como

style=width:100%

então, o div de conteúdo obtém o tamanho do pai, que é o corpo ou outro div que também experimentei e, portanto, é claro que não se encaixa direito no menu e é mostrado abaixo.

Respostas:


138

Espero ter entendido corretamente, dê uma olhada nisto: http://jsfiddle.net/EAEKc/

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <title>Content with Menu</title>
  <style>
    .content .left {
      float: left;
      width: 100px;
      background-color: green;
    }
    
    .content .right {
      margin-left: 100px;
      background-color: red;
    }
  </style>
</head>

<body>
  <div class="content">
    <div class="left">
      <p>Hi, Flo!</p>
    </div>
    <div class="right">
      <p>is</p>
      <p>this</p>
      <p>what</p>
      <p>you are looking for?</p>
    </div>
  </div>
</body>

</html>


5
A questão afirma que "ambos os flutuadores são necessários".
Crescent Fresh

8
Sim, você está certo e eu concordo. No entanto, acho que Flo apenas mencionou isso, porque ele pensa que são os dois! precisava obter o layout desejado e, portanto, minha solução alternativa.
merkuro

@merkuro: bom ponto. Eu concordo, ".right" não precisa ser flutuado para obter o efeito desejado. @Flo: você pode confirmar, o div de conteúdo deve ser flutuado? Por outros motivos?
Crescent Fresh de

pode funcionar, vou tentar um pouco com isso, você entendeu bem o motivo e o flutuador é melhor, mas acho que não vai funcionar
Flo

2
Ahh jeah e eu novamente vejo a razão pela qual eu mudei para float: Ie7 e Firefox funcionam bem, mas isto é 5.5 e ie 6 começam a margem na borda direita da div esquerda, então tem 236 px (a largura real, 100 foi um exemplo) intervalo entre os dois divs
Flo

100

A maneira com mais compatibilidade cruzada que encontrei de fazer isso não é muito óbvia. Você precisa remover o flutuador da segunda coluna e aplicar overflow:hiddena ele. Embora isso pareça estar ocultando qualquer conteúdo que saia do div, ele realmente força o div a permanecer dentro de seu pai.

Usando seu código, este é um exemplo de como isso poderia ser feito:

<div style="width: 100px; float: left;">menu</div>
<div style="overflow: hidden;">content</div>

Espero que isso seja útil para alguém com esse problema, é o que eu achei que funciona melhor para o site que eu estava construindo, depois de tentar ajustá-lo a outras resoluções. Infelizmente, isso não funcionará se você incluir um flutuante à direita divapós o conteúdo também, se alguém souber uma boa maneira de fazer isso funcionar, com boa compatibilidade com o IE, ficaria muito feliz em saber.

Nova e melhor opção usando display: flex;

Agora que o modelo Flexbox está amplamente implementado, eu realmente recomendo usá-lo, pois permite muito mais flexflexibilidade com o layout. Aqui está uma coluna simples de duas colunas como a original:

<div style="display: flex;">
    <div style="width: 100px;">menu</div>
    <div style="flex: 1;">content</div>
</div>

E aqui está uma coluna de três colunas com uma coluna central de largura flexível!

<div style="display: flex;">
    <div style="width: 100px;">menu</div>
    <div style="flex:1;">content</div>
    <div style="width: 100px;">sidebar</div>
</div>

Depois de mais alguns testes, parece que você não precisa acionar o hasLayout com "position: relative" para que funcione no IE 6, não tenho certeza sobre o IE 5, mas geralmente não é um problema incluí-lo de qualquer maneira, apenas para estar seguro.
alanaktion de

1
Esta resposta parece pouco apreciada, mas é muito bom saber. Este permite que você flutue, mesmo com um elemento flutuante dentro do div. Sou um "contexto de formatação de bloco" do google. agora mesmo.
Carlos Gil

A melhor maneira é usar uma tabela simples de 2 cols em vez de perder tempo adicionando toneladas de truques CSS não compatíveis com navegadores diferentes
Marco Demaio

@Marco Eu precisei usar CSS para isso porque meu design é responsivo. Tamanhos de tela diferentes precisavam de layouts diferentes, então uma tabela não funcionaria. Além disso, esse método parece funcionar basicamente em qualquer navegador que ainda seja usado.
alanaktion

1
@MarcoDemaio, meu ponto era que em um tamanho de tela em que a coluna fixa menor fosse quase tão grande quanto a coluna principal, como em um dispositivo móvel, eu queria que as duas colunas se tornassem linhas de largura total, o que não poderia ser feito com tabelas, a menos que eu realmente queira mover o conteúdo com JavaScript.
alanaktion

31

Solução sem fixar o tamanho em sua margem

.content .right{
    overflow: auto; 
    background-color: red;
}

+1 para Merkuro, mas se o tamanho do flutuador mudar, sua margem fixa falhará. Se você usar o CSS acima à direita, divele mudará de tamanho com a mudança de tamanho no flutuador esquerdo. É um pouco mais flexível assim. Verifique o violino aqui: http://jsfiddle.net/9ZHBK/144/


2
@alanaktion Retirei o automóvel desnecessário. A diferença está no valor de estouro. Aparentemente overflow: hiddene overflow autoresultam no mesmo comportamento. Eu também acho que as pessoas apreciam o Fiddle.
Wilt

Se alguém quiser saber por que isso funciona, veja aqui: stackoverflow.com/a/1767270/2756409
TylerH

Eu acho que isso é melhor do que a solução do merkuro.
SkuraZZ de

6

Os elementos flutuantes são retirados do layout de fluxo normal e os elementos de bloco, como DIVs, não ocupam mais a largura de seu pai. As regras mudam nesta situação. Em vez de reinventar a roda, verifique este site para obter algumas soluções possíveis para criar o layout de duas colunas que você procura: http://www.maxdesign.com.au/presentation/page_layouts/

Especificamente, o "Layout de duas colunas líquidas".

Felicidades!


4

Esta é uma solução atualizada para HTML 5 se alguém estiver interessado e não gostar de "flutuar".

A tabela funciona muito bem neste caso, pois você pode definir a largura fixa da tabela e da célula da tabela.

.content-container{
    display: table;
    width: 300px;
}

.content .right{
    display: table-cell;   
    background-color:green;
    width: 100px;
}

http://jsfiddle.net/EAEKc/596/ código-fonte original de @merkuro


+1 finalmente algo que funciona com o elemento de largura fixa à direita, mesmo que tecnicamente não use float.
Karthik T

1 tão totalmente sim. depois de anos lutando com carros alegóricos, posições e tabelas, esta é a solução certa. a solução aceita propaga css inseguro.
Horace

4

este uso pode resolver seu problema.

width: calc(100% - 100px);

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <title>Content with Menu</title>
  <style>
    .content .left {
      float: left;
      width: 100px;
      background-color: green;
    }
    
    .content .right {
      float: left;
      width: calc(100% - 100px);
      background-color: red;
    }
  </style>
</head>

<body>
  <div class="content">
    <div class="left">
      <p>Hi, Flo!</p>
    </div>
    <div class="right">
      <p>is</p>
      <p>this</p>
      <p>what</p>
      <p>you are looking for?</p>
    </div>
  </div>
</body>

</html>


Bem-vindo ao SO. Você poderia adicionar uma explicação de como isso funciona?
yacc de

3

E com base na merkurosolução de, se quiser maximizar o da esquerda, você deve usar:

<!DOCTYPE html>   
<html lang="en">     
    <head>              
        <meta "charset="UTF-8" />   
        <title>Content with Menu</title>                 
        <style>
            .content .left {
                margin-right: 100px;
                background-color: green;
            }
            .content .right {
                float: right;
                width: 100px;
                background-color: red;
            }
        </style>              
    </head>
    <body>        
        <div class="content">
            <div class="right">  
                <p>is</p>
                <p>this</p>
                <p>what</p>
                <p>you are looking for?</p>
            </div>
            <div class="left">
                <p>Hi, Flo!</p>
            </div>
        </div>
    </body>
</html>

Não foi testado no IE, então pode parecer quebrado no IE.


1

A resposta aceita pode funcionar, mas não gosto da ideia de margens sobrepostas. Em HTML5, você faria isso com display: flex;. É uma solução limpa. Basta definir a largura de um elemento e flex-grow: 1;do elemento dinâmico. Uma versão editada do fiddle merkuros: https://jsfiddle.net/EAEKc/1499/


0

Olá, há uma maneira fácil com o método oculto de estouro no elemento certo.

    .content .left {
        float:left;
        width:100px;
        background-color:green;
      }
      .content .right {
        overflow: hidden;
        background-color:red;
      }
<!DOCTYPE html>   
<html lang="en">     
    <head>      
           
        <title>Content Menu</title>         
          
    </head>
    <body>    
    <div class="content">
      <div class="left">
        <p>Hi, Flo! I am Left</p>
      </div>
      <div class="right">  
        <p>is</p>
        <p>this</p>
        <p>what</p>
        <p>you are looking for?</p>
        <p> It done with overflow hidden and result is same.</p>
      </div>
    </div>
    </body>
</html> 


-1

Isso pode funcionar:

    div{
    display:inline-block;
    width:100%;
    float:left;
    }
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.