CSS alinha verticalmente divs flutuantes

90

Eu tenho um div (#wrapper) contendo 2 divs lado a lado.

Eu gostaria que a div direita fosse alinhada verticalmente. Tentei o alinhamento vertical: meio no meu wrapper principal, mas não está funcionando. Isso está me deixando louco!

Espero que alguém possa ajudar.

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
fonte

Respostas:

67

Você não tem sorte com elementos flutuantes. Eles não obedecem ao alinhamento vertical,

você precisa, em display:inline-blockvez disso:

http://cssdesk.com/2VMg8

CUIDADO


Tenha cuidado, display: inline-block;pois ele interpreta o espaço em branco entre os elementos como um espaço em branco real. Não o ignora como o display: blockfaz.

Eu recomendo isto:

Defina o font-sizedo elemento que o contém para 0(zero) e redefina o font-sizepara o valor necessário nos elementos como este

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

Veja uma demonstração aqui: 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
fonte
Isso não funcionará se a #wrapper height for fixa. O # right-div é centralizado em relação ao # left-div , não em relação ao elemento wrapper. ( inline-blockfaz com que se comporte como um inline imgque tem o alignatributo definido)
Costa
@Costa Acho que é assim que deve ser.
yunzen de
não importa como deveria ser, existem muitos casos onde você DEVE usar um elemento flutuante, e sempre HÁ uma maneira de fazer coisas em CSS. sempre. no caso mais simples, um alinhamento vertical de texto flutuante
vsync
11
mas sua solução também não funcionará, porque você não pode simplesmente decidir NÃO usar flutuadores ... o objetivo é alinhar verticalmente de alguma forma ao usar flutuadores.
vsync
2
Tudo o que quero dizer é que às vezes o inline-block não era uma opção e dava um caso de uso para ajudar outras pessoas que poderiam acabar nesta página do Google. Não havia necessidade de ser rude.
Jamie Barker de
21

Você pode fazer isso facilmente com display table e display table-cell.

#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: Na verdade, mexeu rapidamente no CSS Desk para você - http://cssdesk.com/RXghg

OUTRA EDIÇÃO: Use o Flexbox. Isso funcionará, mas está bastante desatualizado - 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;
}
SpaceBeers
fonte
1
Olá, SpaceBeers. Sua sugestão não está funcionando para mim, pois estou escondendo o estouro de right-div (acabei de adicionar o código na mesa css). Com sua solução, o estouro não fica oculto, a div expande sua largura ...
Marc
11

Sei que essa é uma questão antiga, mas achei que seria útil postar uma solução para o problema do alinhamento vertical do flutuador.

Ao criar um invólucro em torno do conteúdo que deseja flutuar, você pode usar os pseudo seletores :: after ou :: before para alinhar verticalmente seu conteúdo dentro do invólucro. Você pode ajustar o tamanho desse conteúdo o quanto quiser, sem afetar o alinhamento. O único problema é que a embalagem deve preencher 100% da altura de seu recipiente.

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
fonte
Não tenho certeza do que você está fazendo, mas depois de excluir a centeredclasse e limpar muitas coisas redundantes daquele CSS, ele ainda faz o alinhamento vertical muito bem, com apenas (desculpe a perda de formatação! ...):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.
3

Eu faço o meu melhor para evitar o uso de flutuadores ... mas - quando necessário, eu alinho verticalmente ao meio usando as seguintes linhas:

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

A única queda das minhas modificações é que você tem uma altura div definida ... Não sei se isso é um problema para você ou não.

http://cssdesk.com/kyPhC

Sean Carruthers
fonte
1
Olá Sean. Obrigado, mas estou tentando usar uma solução flexível e, portanto, espero evitar esse tipo de solução ...
Marc