CSS: Comment aligner verticalement une «étiquette» et une «entrée» à l'intérieur d'un «div»?

92

Considérez le code suivant :

HTML:

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

CSS:

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

Quelle serait la méthode la plus simple pour placer le labelet le inputau milieu du div(verticalement)?

Misha Moroshko
la source
1
À ma connaissance, l'essentiel est "vous ne pouvez pas", et la manière la plus paresseuse de contourner cela est d'utiliser un simple <table>et de l'appliquer valign='middle'à ses <td>s.
BeemerGuy

Réponses:

97

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>

Les avantages de cette méthode sont que vous pouvez changer la hauteur du div, changer la hauteur du champ de texte et changer la taille de la police et tout restera toujours au milieu.

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

Marc-François
la source
1
semble élégant :) est-ce que quelqu'un sait à quel point cette méthode est compatible avec le navigateur?
Zaven Nahapetyan
1
Pour IE, je pense que cela ne fonctionne que sur IE8 ou mieux. Pour les autres navigateurs Web, c'est bien.
Marc-François
1
Je ne savais pas pour le display: table-cell. Est-ce pris en charge sur certains navigateurs?
BeemerGuy
7
@Misha vous auriez dû préciser le fait que votre entrée / étiquette était absolument positionnée. Cela change totalement les circonstances de la question. Je donne un +1 à Marc. Très bonne réponse.
jessegavin
2
Je suis assez certain que le point que jenson essayait de faire valoir (et aurait dû articuler) est que l'utilisation display: table-cellfait que les divs se comportent d'une manière dans laquelle ils ne sont pas censés se comporter, comme les divs suivants rendus sur la même ligne / etc.
taswyn
74

une approche plus moderne consisterait à utiliser 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>

un exemple plus complexe ... si vous avez des éléments multi-éléments dans le flux flexible, vous pouvez utiliser align-self pour aligner des éléments individuels différemment sur l'alignement spécifié ...

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>

c'est aussi super facile à centrer horizontalement et verticalement:

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
la source
Je souhaite que cela fonctionne quand il y a une image et du texte enveloppés dans l'étiquette. J'ai une petite icône suivie d'un texte, mais le texte ne bouge pas.
Kevin Scharnhorst
cela fonctionne si l'étiquette et le texte sont des éléments séparés, ou si vous faites de votre étiquette une boîte flexible aussi ...
Holger Will
display:flexa moins de compatibilité, fonctionne sur chrome 29+
14

Cela fonctionne entre les navigateurs, offre plus d'accessibilité et est livré avec moins de balisage. abandonner le div. Enveloppez l'étiquette

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
la source
3
Cela ne fonctionnera évidemment pas pour une étiquette à deux lignes. Et si vous êtes sûr que l'étiquette est toujours sur une seule ligne, il existe des millions d'autres alternatives.
Lashae
16
la question portait sur une étiquette à une seule ligne, et j'ai répondu en conséquence. Je ne sais pas trop sur vos points ou vos intentions ici, mais si x est si évident, vous devriez en faire un million d'exemples. à tout le moins pour que vous puissiez vous réjouir de ma réponse et ressentir la puissance de vos millions de victoires. Bravo.
albert
2
C'est la meilleure réponse pour les étiquettes à une seule ligne. La spécification dit: "Si l'attribut for n'est pas spécifié, mais que l'élément label a un descendant d'élément associé au formulaire étiquetable, le premier de ces descendants dans l'ordre arborescent est le contrôle étiqueté de l'élément label." C'est donc la seule approche où vous pouvez omettre les attributs foret idpour une simplicité maximale.
parlement
8

Je sais que cette question a été posée il y a plus de deux ans, mais pour les téléspectateurs récents, voici une solution alternative, qui présente quelques avantages par rapport à la solution de Marc-François:

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

Ici, nous ajoutons simplement un line-heightégal à celui de la hauteur du div. L'avantage étant que vous pouvez maintenant changer la propriété d'affichage du div comme bon vous semble, inline-blockpar exemple, et son contenu restera centré verticalement. La solution acceptée nécessite que vous traitiez le div comme une cellule de tableau. Cela devrait fonctionner parfaitement, multi-navigateur.

Le seul autre avantage étant qu'il ne s'agit que d'une règle CSS de plus au lieu de deux :)

À votre santé!

MusikAnimal
la source
6

Utiliser paddingsur le div( haut et bas ) et vertical-align:middlesur le labelet input.

exemple sur http://jsfiddle.net/VLFeV/1/

Gabriele Petrioli
la source
Cela ne fonctionne pas sur jsfiddle. J'ai changé la hauteur du divet le contenu à l'intérieur ne bougeait pas du tout. Est-ce que je manque quelque chose?
BeemerGuy
À mon avis, les mises en page ne devraient pas avoir des hauteurs de pixels fixes… Les mises en page devraient circuler de manière fluide autour du contenu. Cependant, je viens d'un jour et d'une heure où les navigateurs redimensionnaient la taille du texte lors d'un zoom avant et arrière. Les navigateurs récents mettent à l'échelle la page entière, donc la définition de la hauteur des pixels fonctionne un peu mieux. Cependant, il existe de toutes nouvelles raisons d'éviter de définir des hauteurs de pixels… par exemple, des techniques de mise en page réactive. C'est pourquoi ce serait ma méthode préférée.
Thirdender
3

Enveloppez l'étiquette et entrez dans un autre div avec une hauteur définie. Cela peut ne pas fonctionner dans les versions IE inférieures à 8.

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

Vous pouvez utiliser la display: table-cellpropriété comme dans le code suivant:

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