Diseño div de 2 columnas: columna derecha con ancho fijo, fluido izquierdo

158

Mi requisito es simple: 2 columnas donde la correcta tiene un tamaño fijo . Lamentablemente, no pude encontrar una solución que funcione, ni en stackoverflow ni en Google. Cada solución descrita allí falla si la implemento en mi propio contexto. La solución actual es:

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>

Me sale lo siguiente con el código anterior:

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

Por favor avise. ¡Muchas gracias!

MrG
fuente

Respuestas:

268

Retire el flotador en la columna izquierda.

En el código HTML, la columna derecha debe aparecer antes que la izquierda.

Si la derecha tiene un flotador (y un ancho), y si la columna izquierda no tiene un ancho y no flota, será flexible :)

También aplique una overflow: hiddenaltura y un poco (puede ser automática) al div externo, de modo que rodee a ambos div internos.

Finalmente, en la columna izquierda, agregue un width: autoyoverflow: hidden , esto hace que la columna independiente izquierda desde el más adecuado (por ejemplo, si cambia el tamaño de la ventana del navegador, y la columna de la derecha tocó el de la izquierda, sin estas propiedades, la columna de la izquierda correría alrededor de la derecha, con estas propiedades permanece en su espacio).

HTML de ejemplo:

<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;
}​​

Ejemplo aquí: http://jsfiddle.net/jackJoe/fxWg7/

jackJoe
fuente
2
@Mir A clear: both dentro de cualquiera de las columnas no afectará a los flotadores exteriores. Esto no es "frágil" a menos que coloque el borrado en el mismo nivel de las columnas entre las columnas, si lo coloca al final no se hace daño.
jackJoe
66
Consideraría usar el ejemplo de Adam. No creo que sea una buena idea poner la columna derecha antes de la columna izquierda en su marcado html.
Danny_Joris
1
@Danny_Joris Estoy de acuerdo. Además, si usa consultas de medios, ahora es difícil empujar la columna derecha debajo de la columna izquierda
andrewtweber
2
Para aquellos que tienen curiosidad acerca de cómo funciona, puede encontrar una explicación aquí: stackoverflow.com/questions/25475822/…
Hashem Qolami
1
Me pregunto si hay una manera de tener la columna derecha DESPUÉS de la izquierda, para que se apile correctamente (sin usar flexbox)
Dominic
71

Consulte http://www.alistapart.com/articles/negativemargins/ , esto es exactamente lo que necesita ( ejemplo 4 allí).

<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;
Adán
fuente
1
¡Solución fantástica, simple y mantiene el orden HTML correcto también!
user1794295
3
Esto es mejor que la solución aceptada porque el marcado está en el orden correcto.
Petri Lehtinen
Yo no sabía sobre esto. ¿Cómo no supe de esto? ¡Perfecto! He estado tratando de hacer todo el 'botón de entrada de fluido, búsqueda de ancho fijo', y obviamente el orden de origen es realmente importante aquí. Esto lo clava. ¡Gracias!
Malabar Front
Me gusta esta solución porque cuando llegue el punto de interrupción móvil, las columnas / barras laterales correctas aparecerán debajo, no encima del contenido de la columna izquierda.
dougtesting.net
No pude obtener la columna correcta para ir a la cima con este método.
mulllhausen
29

Es mejor evitar colocar la columna derecha antes que la izquierda, simplemente use un margen derecho negativo.

Y sea "receptivo" al incluir una configuración @media para que la columna derecha quede debajo de la izquierda en pantallas estrechas.

<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>
Loren
fuente
1
Gran solución Mantener la derecha debajo de la izquierda en HTML es crucial para diseños como blogs, donde la izquierda tiene contenido más importante.
Jake
3
Excelente respuesta! Aquí hay un ejemplo de trabajo en Codepen: codepen.io/martinkrulltott/pen/yNxezM
Martin
11

La solución más simple y flexible hasta ahora para usar table display:

HTML, el div izquierdo es el primero, el div derecho es el segundo ... leemos y escribimos de izquierda a derecha, por lo que no tiene sentido colocar los divs de derecha a izquierda

<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)
}

Ejemplos 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}
Benj
fuente
Bien, funcionó bien, gracias. A veces hay un momento y un lugar para las tablas cuando flexbox no es una alternativa viable. En lugar de poner el contenido correcto antes en el DOM que no se apila correctamente ...
Dominic
1
Me gusta que esta sea una solución 'limpia'. Sin embargo, el único problema con poner sus divs en modo de celda de tabla es que también podría usar Tablas y Tds. Y terminará perdiendo funciones como el desplazamiento de desbordamiento, etc.
MarzSocks
Eso es injusto, porque esta solución es al menos semánticamente correcta y amigable con las técnicas simples de RWD, mientras que el uso de a tablecon tds no lo es.
ianp
Este método permite fácilmente que una consulta de medios descarte la tabla para una división regular si las columnas se estrechan. Bonito y limpio. Me gusta.
AnthonyVO
6

Me gustaría sugerir una solución aún no mencionada: use CSS3 calc()para mezclar %y pxunidades. calc()tiene un excelente soporte hoy en día, y permite la construcción rápida de diseños bastante complejos.

Aquí hay un enlace JSFiddle para el código a continuación.

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;
}

Y aquí hay otro JSFiddle que demuestra este concepto aplicado a un diseño más complejo. Usé SCSS aquí ya que sus variables permiten un código flexible y autodescriptivo, pero el diseño se puede volver a crear fácilmente en CSS puro si tener valores "codificados" no es un problema.

Illya Moskvin
fuente
2

Esta es una solución ordenada genérica de origen HTML donde:

  • La primera columna en orden de origen es fluida
  • La segunda columna en orden de origen es fija
    • Esta columna se puede flotar hacia la izquierda o hacia la derecha usando CSS

Fijo / Segunda columna a la derecha

#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>

Fijo / Segunda columna a la izquierda

#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>

La solución alternativa es usar display: table-cell ; que da como resultado columnas de igual altura.

Salman A
fuente
La segunda columna de la derecha no funcionará. Si la columna izquierda tiene texto completo, la columna derecha se mostrará como una nueva fila.
TomSawyer
¿Alguna vez has tratado de poner más contenido y cambiar el tamaño? acabo de probar tu código y no funcionó.
TomSawyer
@ TomSawyer No estoy seguro de lo que estás hablando. Aquí estoy tratando de poner más contenido: jsfiddle.net/salman/mva6cnxL y jsfiddle.net/salman/mva6cnxL/1 . Funciona perfectamente.
Salman A
Justo lo que buscaba. Gracias
0

Oye, lo que puedes hacer es aplicar un ancho fijo a ambos contenedores y luego usar otra clase div donde sea claro: ambos, como

div#left {

width: 600px;
float: left;
}

div#right {

width: 240px;
float: right;

}

div.clear {

clear:both;

}

coloque el div transparente debajo del contenedor izquierdo y derecho.

tigerstyle
fuente
-3

Lo he simplificado: he editado la respuesta de jackjoe. La altura automática, etc. no se requiere, creo.

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 sit amet, consectetuer adipiscing elit. 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>
Servicio de SEO RiG
fuente
La pregunta original quiere una columna derecha con tamaño fijo.
Dr. Aaron Dishno