CSS: Como alinhar verticalmente um “rótulo” e “entrada” dentro de um “div”?

89

Considere o seguinte código :

HTML:

<div>
    <label for='name'>Name:</label>
    <input type='text' id='name' />
</div>

CSS:

div {
    height: 50px;
    border: 1px solid blue;
}

Qual seria o método mais fácil de colocar o labele o inputno meio do div(verticalmente)?

Misha Moroshko
fonte
1
Que eu saiba, o resultado final é "você não pode", e a maneira mais preguiçosa de contornar isso é usar um simples <table>e aplicar valign='middle'aos seus <td>.
BeemerGuy

Respostas:

94

div {
    display: table-cell;
    vertical-align: middle;
    height: 50px;
    border: 1px solid red;
}
<div>
    <label for='name'>Name:</label>
    <input type='text' id='name' />
</div>

As vantagens deste método são que você pode alterar a altura do div, alterar a altura do campo de texto e alterar o tamanho da fonte e tudo ficará sempre no meio.

http://jsfiddle.net/53ALd/6/

Marc-François
fonte
1
parece elegante :) Alguém sabe como este método é compatível com o navegador?
Zaven Nahapetyan
1
Para o IE, acho que só funciona no IE8 ou melhor. Para os outros navegadores da Web está bom.
Marc-François
1
Eu não sabia sobre o display: table-cell. Isso é compatível com alguns navegadores?
BeemerGuy
6
@Misha você deve ter especificado o fato de que sua entrada / etiqueta estava absolutamente posicionada. Isso muda totalmente as circunstâncias da questão. Estou dando a Marc um +1. Ótima resposta.
jessegavin
2
Tenho quase certeza de que o ponto que jenson estava tentando fazer (e deveria ter articulado) é que o uso de display: table-celltorna os divs se comportam de maneiras que não deveriam se comportar, como subsequente renderização de divs na mesma linha / etc.
taswyn 01 de
72

uma abordagem mais moderna seria usar css flex-box.

div {
  height: 50px;
  background: grey;
  display: flex;
  align-items: center
}
<div>
  <label for='name'>Name:</label>
  <input type='text' id='name' />
</div>

um exemplo mais complexo ... se você tiver vários elementos no fluxo flexível, você pode usar o alinhamento próprio para alinhar elementos únicos de maneira diferente do alinhamento especificado ...

div {
  display: flex;
  align-items: center
}

* {
  margin: 10px
}

label {
  align-self: flex-start
}
<div>
  <img src="https://de.gravatar.com/userimage/95932142/195b7f5651ad2d4662c3c0e0dccd003b.png?size=50" />
  <label>Text</label>
  <input placeholder="Text" type="text" />
</div>

também é super fácil de centralizar horizontal e verticalmente:

div {
  position:absolute;
  top:0;left:0;right:0;bottom:0;
  background: grey;
  display: flex;
  align-items: center;
  justify-content:center
}
<div>
  <label for='name'>Name:</label>
  <input type='text' id='name' />
</div>

Holger Will
fonte
Eu gostaria que isso funcionasse quando há uma imagem e um texto embrulhados no rótulo. Tenho um pequeno ícone seguido de texto, mas o texto não se move.
Kevin Scharnhorst,
funciona se o rótulo e o texto forem elementos separados, ou se você fizer seu rótulo um flexbox também ...
Holger Will
display:flextem menos compatibilidade, funciona no Chrome 29+
14

Isso funciona em vários navegadores, fornece mais acessibilidade e vem com menos marcação. vala o div. Embrulhe o rótulo

label{
     display: block; 
     height: 35px; 
     line-height: 35px; 
     border: 1px solid #000; 
}

input{margin-top:15px; height:20px}

<label for="name">Name: <input type="text" id="name" /></label>
Albert
fonte
3
Isso obviamente não funcionará para uma etiqueta de duas linhas. E se você tem certeza de que o rótulo é sempre uma linha, então existem milhões de outras alternativas.
Lashae
14
a pergunta era em relação a uma etiqueta de linha única, e eu respondi de acordo. não tenho certeza sobre seu (s) ponto (s) ou intenções aqui, mas se x for tão óbvio, você deve dar um milhão de exemplos disso. no mínimo, para que você possa se gabar de minha resposta e sentir o poder de seus milhões de vitórias. bravo.
Albert,
2
Esta é a melhor resposta para rótulos de linha única. A especificação diz: "Se o atributo for não for especificado, mas o elemento label tiver um descendente de elemento associado ao formulário rotulável, então o primeiro descendente na ordem da árvore é o controle rotulado do elemento label." Portanto, esta é a única abordagem em que você pode omitir os atributos fore idpara obter o máximo de simplicidade.
parlamento em
8

Estou ciente de que essa pergunta foi feita há mais de dois anos, mas para qualquer espectador recente, aqui está uma solução alternativa, que tem algumas vantagens sobre a solução de Marc-François:

div {
    height: 50px;
    border: 1px solid blue;
    line-height: 50px;
}

Aqui, simplesmente adicionamos um line-heightigual à altura do div. A vantagem é que agora você pode alterar a propriedade de exibição da div conforme desejar, para, inline-blockpor exemplo, e seu conteúdo permanecerá centralizado verticalmente. A solução aceita requer que você trate o div como uma célula de tabela. Isso deve funcionar perfeitamente, em vários navegadores.

A única outra vantagem é que é apenas mais uma regra CSS em vez de duas :)

Felicidades!

MusikAnimal
fonte
6

Use paddingna div( superior e inferior ) e vertical-align:middlena labele input.

exemplo em http://jsfiddle.net/VLFeV/1/

Gabriele Petrioli
fonte
Isso não funciona no jsfiddle. Mudei a altura do dive o conteúdo interno não se moveu. Estou esquecendo de algo?
BeemerGuy
Na minha opinião, os layouts não devem ter alturas de pixel fixas ... Os layouts devem fluir fluidamente em torno do conteúdo. No entanto, venho de uma época e um dia em que os navegadores dimensionavam o tamanho do texto ao aumentar e diminuir o zoom. Navegadores recentes dimensionam a página inteira, portanto, definir a altura dos pixels funciona um pouco melhor. No entanto, existem novos motivos para evitar definir alturas de pixel ... por exemplo, técnicas de layout responsivo. É por isso que esse seria meu método preferido.
terceiro jogador de
3

Envolva o rótulo e insira em outro div com uma altura definida. Isso pode não funcionar em versões do IE anteriores a 8.

position:absolute; 
top:0; bottom:0; left:0; right:0;
margin:auto;
Trevor
fonte
0

Você pode usar a display: table-cellpropriedade como no seguinte código:

div {
     height: 100%;
     display: table-cell; 
     vertical-align: middle;
    }
abahet
fonte