Disposition div 2 colonnes: colonne de droite avec largeur fixe, fluide gauche

158

Mon exigence est simple: 2 colonnes où la bonne a une taille fixe . Malheureusement, je n'ai pas trouvé de solution fonctionnelle, ni sur stackoverflow ni sur Google. Chaque solution qui y est décrite échoue si je l'implémente dans mon propre contexte. La solution actuelle est:

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>

J'obtiens ce qui suit avec le code ci-dessus:

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

S'il vous plaît donnez votre avis. Merci beaucoup!

MrG
la source

Réponses:

268

Retirez le flotteur de la colonne de gauche.

Au niveau du code HTML, la colonne de droite doit venir avant celle de gauche.

Si la droite a un float (et une largeur), et si la colonne de gauche n'a pas de largeur et pas de float, elle sera flexible :)

Appliquez également un overflow: hiddenet une certaine hauteur (peut être automatique) à la division externe, de sorte qu'elle entoure les deux div internes.

Enfin, dans la colonne de gauche, ajoutez un width: autoet overflow: hidden, cela rend la colonne de gauche indépendante de la colonne de droite (par exemple, si vous avez redimensionné la fenêtre du navigateur et que la colonne de droite a touché celle de gauche, sans ces propriétés, la colonne de gauche fonctionnerait autour de la droite, avec ces propriétés il reste dans son espace).

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

Exemple ici: http://jsfiddle.net/jackJoe/fxWg7/

jackJoe
la source
2
@Mir A clear: both à l' intérieur de l' une des colonnes n'affectera pas les flotteurs extérieurs. Ce n'est pas "fragile" sauf si vous placez le clair au même niveau des colonnes entre les colonnes, si vous le placez à la fin aucun mal n'est fait.
jackJoe
6
J'envisagerais d'utiliser l'exemple d'Adam. Je ne pense pas que ce soit une bonne idée de mettre la colonne de droite avant la colonne de gauche dans votre balisage html.
Danny_Joris
1
@Danny_Joris Je suis d'accord. De plus, si vous utilisez des requêtes multimédias, il est maintenant difficile de pousser la colonne de droite sous la colonne de gauche
andrewtweber
2
Pour ceux qui sont curieux de savoir comment cela fonctionne, une explication peut être trouvée ici: stackoverflow.com/questions/25475822/…
Hashem Qolami
1
Je me demande s'il existe un moyen d'avoir la colonne de droite APRÈS la gauche, pour qu'elle s'empile correctement (sans utiliser flexbox)
Dominic
71

Voir http://www.alistapart.com/articles/negativemargins/ , c'est exactement ce dont vous avez besoin ( exemple 4 ici).

<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;
Adam
la source
1
Solution fantastique et simple qui conserve également le bon ordre HTML!
user1794295
3
C'est mieux que la solution acceptée car le balisage est dans le bon ordre.
Petri Lehtinen
Je ne savais pas. Comment n'ai-je pas su cela. Parfait! J'ai essayé de faire tout "l'entrée fluide, le bouton de recherche à largeur fixe", et évidemment l'ordre des sources est vraiment important ici. Cela cloue. Merci!
Malabar Front
J'aime cette solution car à l'heure du point d'arrêt mobile, les colonnes / la barre latérale de droite apparaîtront en dessous et non au-dessus du contenu de la colonne de gauche.
dougtesting.net
Je n'ai pas pu obtenir la bonne colonne pour aller en haut avec cette méthode.
mulllhausen
29

Il est préférable d'éviter de placer la colonne de droite avant la gauche, utilisez simplement une marge droite négative.

Et soyez «réactif» en incluant un paramètre @media pour que la colonne de droite tombe sous la gauche sur les écrans étroits.

<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
la source
1
Excellente solution. Garder la droite en dessous de la gauche en HTML est crucial pour les mises en page telles que les blogs, où la gauche a un contenu plus important.
Jake
3
Excellente réponse! Voici un exemple de travail sur Codepen: codepen.io/martinkrulltott/pen/yNxezM
Martin
11

Solution la plus simple et la plus flexible à ce jour à utiliser table display:

HTML, le div de gauche vient en premier, le div de droite vient en second ... nous lisons et écrivons de gauche à droite, donc cela n'a aucun sens de placer les divs de droite à gauche

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

Exemples de cas:

// 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
la source
Nice, a bien fonctionné merci. Parfois, il y a un moment et un lieu pour les tables où flexbox n'est pas une alternative viable. Plutôt que de mettre le bon contenu avant dans le DOM qui ne s'empile pas correctement ..
Dominic
1
J'aime le fait que ce soit une solution «propre». Cependant, le seul problème avec la mise en mode table-cellule de vos divs est que vous pourriez aussi bien utiliser Tables & Tds. Et vous
finirez
C'est injuste, car cette solution est au moins sémantiquement correcte et conviviale pour les techniques RWD simplement, alors que l'utilisation de a tableavec tds ne l'est certainement pas!
ianp
Cette méthode permet facilement à une requête multimédia de supprimer la table pour un div normal si les colonnes deviennent trop étroites. Agréable et propre. J'aime.
AnthonyVO
6

Je voudrais suggérer une solution encore non mentionnée: utilisez CSS3 calc()pour mélanger %et pxunités. calc()a un excellent support nos jours, et il permet la construction rapide de mises en page assez complexes.

Voici un lien JSFiddle pour le code ci-dessous.

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

Et voici un autre JSFiddle démontrant ce concept appliqué à une mise en page plus complexe. J'ai utilisé SCSS ici car ses variables permettent un code flexible et auto-descriptif, mais la mise en page peut être facilement recréée en CSS pur si le fait d'avoir des valeurs "codées en dur" n'est pas un problème.

Illya Moskvin
la source
2

Il s'agit d'une solution générique commandée à la source HTML où:

  • La première colonne dans l'ordre source est fluide
  • La deuxième colonne dans l'ordre source est fixe
    • Cette colonne peut être flottante à gauche ou à droite en utilisant CSS

Colonne fixe / deuxième à droite

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

Colonne fixe / deuxième à gauche

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

Une autre solution consiste à utiliser display: table-cell ; ce qui donne des colonnes de hauteur égale.

Salman A
la source
la deuxième colonne à droite ne fonctionnera pas. si la colonne de gauche est pleine de texte, votre colonne de droite s'affichera comme une nouvelle ligne.
TomSawyer
avez-vous déjà essayé de mettre plus de contenu et de redimensionner. vient de tester votre code et n'a pas fonctionné.
TomSawyer
@TomSawyer Je ne sais pas de quoi vous parlez. Me voici en train d'essayer de mettre plus de contenu: jsfiddle.net/salman/mva6cnxL et jsfiddle.net/salman/mva6cnxL/1 . Fonctionne parfaitement.
Salman A
Juste ce que j'ai recherché. Merci
0

Hé, ce que vous pouvez faire, c'est appliquer une largeur fixe aux deux conteneurs, puis utiliser une autre classe div où clear: both, comme

div#left {

width: 600px;
float: left;
}

div#right {

width: 240px;
float: right;

}

div.clear {

clear:both;

}

placez un div transparent sous le récipient gauche et droit.

tigerstyle
la source
-3

Je l'ai simplifié: j'ai édité la réponse de Jackjoe. La hauteur auto etc pas obligatoire je pense.

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>
Service de référencement RiG
la source
La question d'origine veut une colonne de droite avec une taille fixe.
Dr Aaron Dishno