CSS aligner verticalement les div flottants

89

J'ai un div (#wrapper) contenant 2 divs côte à côte.

Je voudrais que le div-droit soit aligné verticalement. J'ai essayé vertical-align: middle sur mon wrapper principal mais cela ne fonctionne pas. Ça me rend fou!

J'espère que quelqu'un pourra vous aider.

http://cssdesk.com/LWFhW

HTML:

<div id="wrapper">
  <div id="left-div">
    <ul>
      <li>One</li>
      <li>Two</li>
    </ul>
  </div>  
  <div id="right-div">
    Here some text...
  </div>
</div>

CSS:

#wrapper{
  width:400px;
  float:left;
  height:auto;
  border:1px solid purple;}

#left-div{
  width:40px;
  border:1px solid blue;
  float:left;}

#right-div{
  width:350px;
  border:1px solid red;
  float:left;}

ul{
  list-style-type: none;
  padding:0;
  margin:0;}
Marc
la source

Réponses:

67

Vous n'avez pas de chance avec les éléments flottants. Ils n'obéissent pas à l'alignement vertical,

vous avez besoin, à la display:inline-blockplace:

http://cssdesk.com/2VMg8

IL FAUT SE MÉFIER


Soyez prudent display: inline-block;car il interprète l'espace blanc entre les éléments comme un véritable espace blanc. Il ne l'ignore pas comme le display: blockfait.

Je recommande ceci:

Définissez l' font-sizeélément contenant sur 0(zéro) et réinitialisez le font-sizeà la valeur requise dans les éléments comme suit

ul {
    margin: 0;
    padding: 0;
    list-style: none;
    font-size: 0;
}
ul > li {
    font-size: 12px;
}

Voir une démonstration ici: http://codepen.io/HerrSerker/pen/mslay


CSS

#wrapper{
  width:400px;
  height:auto;
  border:1px solid green;
  vertical-align: middle;
  font-size: 0;
}

#left-div{
  width:40px;
  border:1px solid blue;
  display: inline-block;
  font-size: initial;
  /* IE 7 hack */
  *zoom:1;
  *display: inline;
  vertical-align: middle;
}

#right-div{
  width:336px;
  border:1px solid red;
  display: inline-block;  
  font-size: initial;
  /* IE 7 hack */
  *zoom:1;
  *display: inline;
  vertical-align: middle;
}
  
yunzen
la source
Cela ne fonctionnera pas si la hauteur #wrapper est fixe. Le # right-div est centré par rapport au # left-div , et non par rapport à l'élément wrapper. (le inline-blockfait se comporter comme un inline imgdont l' alignattribut est défini)
Costa
@Costa C'est comme ça que ça devrait être, je pense.
yunzen
peu importe de quelle manière cela devrait être, il y a de nombreux cas où vous DEVEZ utiliser un élément flottant, et il y a toujours un moyen de faire des choses en CSS. toujours. dans le cas le plus simple, un alignement vertical du texte flottant: jsbin.com/UWeB/1/edit
vsync
11
mais votre solution ne fonctionnera pas non plus, car vous ne pouvez pas simplement décider de NE PAS utiliser de flotteurs ... le but est de s'aligner verticalement en utilisant des flotteurs.
vsync
2
Tout ce que je voulais dire, c'était que parfois le blocage en ligne n'était pas une option et donnait un cas d'utilisation pour aider d'autres personnes susceptibles de se retrouver sur cette page de Google. Il n'y avait aucun besoin d'être impoli.
Jamie Barker
21

Vous pouvez le faire assez facilement avec la table d'affichage et la cellule-table d'affichage.

#wrapper {
    width: 400px;
    float: left;
    height: auto;
    display: table;
    border: 1px solid green;
}

#right-div {
    width: 356px;
    border: 1px solid red;
    display: table-cell;
    vertical-align: middle;
}

EDIT: En fait, rapidement déconné sur CSS Desk pour vous - http://cssdesk.com/RXghg

UNE AUTRE MODIFICATION: utilisez Flexbox. Cela fonctionnera mais c'est assez obsolète - http://www.cssdesk.com/davf5

#wrapper {
    display: flex;
    align-items: center;
    border:1px solid green;
}

#left-div {
    border:1px solid blue;
}

#right-div {
    border:1px solid red;
}
SpaceBières
la source
1
Bonjour SpaceBeers. Votre suggestion ne fonctionne pas pour moi car je cache le débordement de right-div (je viens d'ajouter le code dans le bureau css). Avec votre solution le débordement n'est pas masqué, la div étend sa largeur ...
Marc
11

Je me rends compte que c'est une question ancienne, mais j'ai pensé qu'il serait utile de publier une solution au problème de l'alignement vertical des flotteurs.

En créant un wrapper autour du contenu que vous souhaitez flotter, vous pouvez ensuite utiliser les pseudo sélecteurs :: after ou :: before pour aligner verticalement votre contenu dans le wrapper. Vous pouvez ajuster la taille de ce contenu à votre guise sans que cela affecte l'alignement. Le seul hic, c'est que l'emballage doit remplir 100% de la hauteur de son conteneur.

http://jsfiddle.net/jmdrury/J53SJ/

HTML

<div class="container">
    <span class="floater">
        <span class="centered">floated</span>
    </span>
    <h1>some text</h1>
</div>

CSS

div {
    border:1px solid red;
    height:100px;
    width:100%;
    vertical-align:middle;
    display:inline-block;
    box-sizing: border-box;
}
.floater {
    float:right;
    display:inline-block;
    height:100%;
    box-sizing: border-box;
}
.centered {
    border:1px solid blue;
    height: 30px;
    vertical-align:middle;
    display:inline-block;
    box-sizing: border-box;
}
h1 {
    margin:0;
    vertical-align:middle;
    display:inline-block;
    box-sizing: border-box;
}
.container:after, .floater:after, .centered:after, h1:after {
    height:100%;
    content:'';
    font-size:0;
    vertical-align:middle;
    display:inline-block;
    box-sizing: border-box;
}
Justin Drury
la source
Je ne suis pas sûr de ce que vous faites, mais après avoir supprimé la centeredclasse et nettoyé beaucoup de choses redondantes de ce CSS, l'alignement vertical est toujours parfait, avec juste (désolé pour la perte de formatage! ...):div { border:1px solid red; height:100px; } .floater { float:right; height:100%; } h1 { vertical-align:middle; } .container:after, .floater:after, .centered:after { height:100%; content:''; font-size:0; vertical-align:middle; display:inline-block; }
Sz.
2

Je fais de mon mieux pour éviter d'utiliser des flotteurs ... mais - si nécessaire, je m'aligne verticalement au milieu en utilisant les lignes suivantes:

position: relative;
top: 50%;
transform: translateY(-50%);
Maoritzio
la source
-1

Le seul inconvénient de mes modifications est que vous avez une hauteur de div définie ... Je ne sais pas si c'est un problème pour vous ou non.

http://cssdesk.com/kyPhC

Sean Carruthers
la source
1
Bonjour Sean. Merci mais j'essaye d'utiliser une solution flexible et espère donc éviter ce genre de solution ...
Marc