Layout div de 2 colunas: coluna direita com largura fixa, fluido esquerdo


158

Minha exigência é simples: 2 colunas onde a correta tem um tamanho fixo . Infelizmente, não consegui encontrar uma solução funcional, nem no stackoverflow nem no Google. Cada solução descrita lá falha se eu implementar no meu próprio contexto. A solução atual é:

div.container {
    position: fixed;
    float: left;
    top: 100px;
    width: 100%;
    clear: both;
}

#content {
    margin-right: 265px;
}

#right {
    float: right;
    width: 225px;
    margin-left: -225px;
}

#right, #content {
    height: 1%; /* fixed for IE, although doesn't seem to work */
    padding: 20px;
}
<div class="container">
    <div id="content">
        fooburg content
    </div>
    <div id="right">
        test right
    </div>
</div>

Eu recebo o seguinte com o código acima:

|----------------------- -------|
| fooburg content  |            |
|-------------------------------|
|                  | test right | 
|----------------------- -------|

Por favor informar. Muito Obrigado!

Respostas:


268

Remova a bóia na coluna da esquerda.

No código HTML, a coluna da direita precisa vir antes da esquerda.

Se a direita tiver uma bóia (e uma largura), e se a coluna esquerda não tiver uma largura e nenhuma bóia, será flexível :)

Aplique também uma overflow: hiddene alguma altura (pode ser automática) à div externa, para que ela envolva as divs internas.

Finalmente, na coluna da esquerda, adicionar um width: autoe overflow: hidden, o que torna o independente coluna da esquerda da direita (por exemplo, se você redimensionado janela do navegador, e a coluna da direita tocou o esquerdo, sem estas propriedades, a coluna da esquerda seria executado ao redor o caminho certo, com essas propriedades, ele permanece em seu espaço).

Exemplo de HTML:

<div class="container">
    <div class="right">
        right content fixed width
    </div>
    <div class="left">
        left content flexible width
    </div>
</div>

CSS:

.container {
   height: auto;
   overflow: hidden;
}

.right {
    width: 180px;
    float: right;
    background: #aafed6;
}

.left {
    float: none; /* not needed, just for clarification */
    background: #e8f6fe;
    /* the next props are meant to keep this block independent from the other floated one */
    width: auto;
    overflow: hidden;
}​​

Exemplo aqui: http://jsfiddle.net/jackJoe/fxWg7/


2
@ Mir A clear: both dentro de qualquer uma das colunas não afetará os flutuadores externos. Isso não é "frágil", a menos que você coloque o espaço livre no mesmo nível das colunas entre as colunas; se você colocar no final, nenhum dano será causado.
precisa

6
Eu consideraria usar o exemplo de Adam. Não acho uma boa ideia colocar a coluna da direita antes da coluna da esquerda na sua marcação html.
Danny_Joris

1
@Danny_Joris Eu concordo. Além disso, se você usar consultas de mídia, é difícil agora para empurrar a coluna da direita abaixo da coluna da esquerda
andrewtweber

2
Para aqueles que estão curiosos sobre como ele funciona, uma explicação pode ser encontrada aqui: stackoverflow.com/questions/25475822/...
Hashem Qolami

1
Gostaria de saber se existe uma maneira de ter a coluna logo após a esquerda, de modo a que-lo corretamente pilhas (sem usar flexbox)
Dominic

71

Consulte http://www.alistapart.com/articles/negativemargins/ , isto é exatamente o que você precisa ( exemplo 4 lá).

<div id="container">
    <div id="content">
        <h1>content</h1>
        <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.  Phasellus varius eleifend tellus. Suspendisse potenti. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Nulla facilisi. Sed wisi lectus, placerat nec, mollis quis, posuere eget, arcu.</p>
        <p class="last">Donec euismod. Praesent mauris mi, adipiscing non, mollis eget, adipiscing ac, erat. Integer nonummy mauris sit amet metus. In adipiscing, ligula ultrices dictum vehicula, eros turpis lacinia libero, sed aliquet urna diam sed tellus. Etiam semper sapien eget metus.</p>
    </div>
</div>

<div id="sidebar">
    <h1>sidebar</h1>
    <ul>
        <li>link one</li>
        <li>link two</li>
    </ul>
</div>

#container {
    width: 100%;
    background: #f1f2ea url(background.gif) repeat-y right;
    float: left;
    margin-right: -200px;
}
#content {
    background: #f1f2ea;
    margin-right: 200px;
}
#sidebar {
    width: 200px;
    float: right;

1
Solução fantástica e simples e mantém a ordem HTML correta também!
user1794295

3
Isso é melhor que a solução aceita, porque a marcação está na ordem correta.
Petri Lehtinen

Eu não sabia sobre isso. Como eu não sabia disso? Perfeito! Eu tenho tentado fazer toda a "entrada fluida, botão de pesquisa de largura fixa" e, obviamente, a ordem da fonte é realmente importante aqui. Isso acertou em cheio. Obrigado!
Front Malabar

Eu gosto dessa solução porque, no momento do ponto de interrupção móvel, as colunas / barra lateral direita aparecerão abaixo e não acima do conteúdo da coluna esquerda.
Dougtesting.net

Não consegui obter a coluna certa para ir ao topo com este método.
mulllhausen

29

É melhor evitar colocar a coluna da direita antes da esquerda, basta usar uma margem direita negativa.

E seja "responsivo" incluindo uma configuração @media para que a coluna da direita fique abaixo da esquerda em telas estreitas.

<div style="background: #f1f2ea;">
  <div id="container">
    <div id="content">
        <strong>Column 1 - content</strong>
    </div>
  </div>
  <div id="sidebar">
    <strong>Column 2 - sidebar</strong>
  </div>
<div style="clear:both"></div>

<style type="text/css">
#container {
    margin-right: -300px;
    float:left;
    width:100%;
}
#content {
    margin-right: 320px; /* 20px added for center margin */
}
#sidebar {
    width:300px;
    float:left
}
@media (max-width: 480px) {
    #container {
        margin-right:0px;
        margin-bottom:20px;
    }
    #content {
        margin-right:0px;
        width:100%;
    }
    #sidebar {
        clear:left;
    }
}
</style>

1
Ótima solução. Manter a direita abaixo da esquerda em HTML é crucial para layouts como blogs, onde a esquerda tem conteúdo mais importante.
Jake

3
Excelente resposta! Aqui está um exemplo de trabalho em Codepen: codepen.io/martinkrulltott/pen/yNxezM
Martin

11

Solução mais simples e flexível até agora utilizada table display:

HTML, div esquerdo aparece em primeiro lugar, div direito aparece em segundo ... lemos e escrevemos da esquerda para a direita, para que não faça sentido colocar os divs da direita para a esquerda

<div class="container">
    <div class="left">
        left content flexible width
    </div>
    <div class="right">
        right content fixed width
    </div>
</div>

CSS:

.container {
  display: table;
  width: 100%;
}

.left {
  display: table-cell;
  width: (whatever you want: 100%, 150px, auto)
}​​

.right {
  display: table-cell;
  width: (whatever you want: 100%, 150px, auto)
}

Exemplos de casos:

// One div is 150px fixed width ; the other takes the rest of the width
.left {width: 150px} .right {width: 100%}

// One div is auto to its inner width ; the other takes the rest of the width
.left {width: 100%} .right {width: auto}

Bom, funcionou bem, obrigado. Às vezes, há um tempo e um local para as mesas quando o flexbox não é uma alternativa viável. Em vez de colocar o conteúdo certo antes no DOM que não pilha corretamente ..
Dominic

1
Eu gosto que esta seja uma solução 'limpa'. No entanto, o único problema ao colocar suas divs no modo de célula de tabela é que você também pode usar Tabelas e Tds. E você vai acabar perdendo recursos como estouro de rolagem etc.
MarzSocks

Isso é injusto, porque esta solução é pelo menos semanticamente correta e amigável em relação às técnicas simplesmente de RWD, enquanto usar a tablecom tds certamente não é!
IanP

Esse método permite facilmente que uma consulta de mídia elimine a tabela para divs regulares se as colunas forem reduzidas. Legal e Limpo. Eu gosto.
AnthonyVO 14/05

5

Gostaria de sugerir uma solução ainda não mencionada: use CSS3 calc()para misturar %e pxunidades. calc()tem excelente suporteAtualmente, e permite a construção rápida de layouts bastante complexos.

Aqui está um link do JSFiddle para o código abaixo.

HTML:

<div class="sidebar">
  sidebar fixed width
</div>
<div class="content">
  content flexible width
</div>

CSS:

.sidebar {
    width: 180px;
    float: right;
    background: green;
}

.content {
    width: calc(100% - 180px);
    background: orange;
}

E aqui está outro JSFiddle demonstrando esse conceito aplicado a um layout mais complexo. Eu usei o SCSS aqui, pois suas variáveis ​​permitem código flexível e auto-descritivo, mas o layout pode ser facilmente recriado em CSS puro, se não houver problema em ter valores "codificados".


2

Esta é uma solução genérica, ordenada por fonte HTML, em que:

  • A primeira coluna na ordem de origem é fluida
  • A segunda coluna na ordem de origem é corrigida
    • Esta coluna pode ser lançada para a esquerda ou direita usando CSS

Coluna fixa / segunda à direita

#wrapper {
  margin-right: 200px;
}
#content {
  float: left;
  width: 100%;
  background-color: powderblue;
}
#sidebar {
  float: right;
  width: 200px;
  margin-right: -200px;
  background-color: palevioletred;
}
#cleared {
  clear: both;
}
<div id="wrapper">
  <div id="content">Column 1 (fluid)</div>
  <div id="sidebar">Column 2 (fixed)</div>
  <div id="cleared"></div>
</div>

Coluna fixa / segunda à esquerda

#wrapper {
  margin-left: 200px;
}
#content {
  float: right;
  width: 100%;
  background-color: powderblue;
}
#sidebar {
  float: left;
  width: 200px;
  margin-left: -200px;
  background-color: palevioletred;
}
#cleared {
  clear: both;
}
<div id="wrapper">
  <div id="content">Column 1 (fluid)</div>
  <div id="sidebar">Column 2 (fixed)</div>
  <div id="cleared"></div>
</div>

A solução alternativa é usar display: table-cell ; o que resulta em colunas de altura igual.


segunda coluna à direita não funcionará. se a coluna da esquerda estiver cheia de texto, sua coluna da direita será exibida como uma nova linha.
TomSawyer

você já tentou colocar mais conteúdo e redimensionar. acabou de testar seu código e não funcionou.
TomSawyer

@ TomSawyer Não sei ao certo o que você está falando. Aqui estou eu tentando colocar mais conteúdo: jsfiddle.net/salman/mva6cnxL e jsfiddle.net/salman/mva6cnxL/1 . Funciona perfeitamente.
Salman A

Apenas o que eu procurei. Graças

0

Ei, o que você pode fazer é aplicar uma largura fixa aos dois contêineres e, em seguida, usar outra classe div, onde estiver claro: ambos, como

div#left {

width: 600px;
float: left;
}

div#right {

width: 240px;
float: right;

}

div.clear {

clear:both;

}

coloque uma div clara sob o recipiente esquerdo e direito.


-3

Simplifiquei: editei a resposta de jackjoe. A altura auto etc não é necessário, eu acho.

CSS:

#container {
position: relative;
margin:0 auto;
width: 1000px;
background: #C63;
padding: 10px;
}

#leftCol {
background: #e8f6fe;
width: auto;
}

#rightCol {
float:right;
width:30%;
background: #aafed6;
}

.box {
position:relative;
clear:both;
background:#F39;
 }
</style>

HTML:

<div id="container">

  <div id="rightCol"> 
   <p>Lorem ipsum dolor sit amet,consectetuer adipiscing elit. Phasellus varius eleifend. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.Phasellus varius eleifend.</p>

  <p>Lorem ipsum dolor sit amet,consectetuer adipiscing elit. Phasellus varius eleifend. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.Phasellus varius eleifend.</p>
 </div>

 <div id="leftCol">

   <p>Lorem ipsum dolor sit amet,consectetuer adipiscing elit. Phasellus varius eleifend. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.Phasellus varius eleifend.</p>

  <p>Lorem ipsum dolor sit amet,consectetuer adipiscing elit. Phasellus varius eleifend. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.Phasellus varius eleifend.</p>
  <p>Lorem ipsum dolor sit amet,consectetuer adipiscing elit. Phasellus varius eleifend. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.Phasellus varius eleifend.</p>

Lorem ipsum dolor sente-se entre os elites consectetuer adipiscing. Phasellus varius eleifend. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.Phasellus varius eleifend.

</div>

</div>

<div class="box">
  <p>Lorem ipsum dolor sit amet,consectetuer adipiscing elit. Phasellus varius eleifend. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.Phasellus varius eleifend.</p>

  <p>Lorem ipsum dolor sit amet,consectetuer adipiscing elit. Phasellus varius eleifend. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.Phasellus varius eleifend.</p>
  <p>Lorem ipsum dolor sit amet,consectetuer adipiscing elit. Phasellus varius eleifend. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.Phasellus varius eleifend.</p>
</div>

A pergunta original quer uma coluna da direita com tamanho fixo.
Dr. Aaron Dishno
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.