Texte d'alignement vertical CSS à l'intérieur de li

100

J'affiche le nombre de boîtes d'affilée avec une hauteur et une largeur fixes, générées à partir des balises <li>. maintenant, je dois aligner le texte au centre vertical. L'alignement vertical CSS n'a aucun impact, il me manque peut-être quelque chose ???

Je ne cherche pas d'astuces utilisant (marge, remplissage, hauteur de ligne), elles ne fonctionneront pas car certains textes sont longs et se diviseront en deux lignes.

Veuillez trouver le code actuel:

Code CSS

ul.catBlock{
  width:960px; 
  height: 270px; 
  border:1px solid #ccc; 
}

ul.catBlock li{
  list-style: none; 
  float:left; 
  display:block; 
  text-align: center; 
  width:160px; 
  height: 100px;
}

ul.catBlock li a{ 
  display: block;  
  padding: 30px 10px 5px 10px; 
  height:60px;
}

Code HTML

<ul class="catBlock">
 <li><a href="#">IP Phone</a></li>
 <li><a href="#">Dual SIM Switch Server</a></li>
 <li><a href="#">IP PBX</a></li>
</ul>
AK4668
la source
2
vous devrez peut-être fournir plus d'informations. Les boîtes ont-elles la même hauteur? Alignez-vous le texte à l'intérieur des cases du li? "parce que certains textes sont longs ... deux lignes" ??? Peut-être une capture d'écran ou un violon aiderait.
KMC
1
J'ai juste essayé de poster une capture d'écran mais cela ne me permet pas, car mon compte est nouveau.
AK4668

Réponses:

100

Définissez le parent avec display: tableet l'élément lui-même avec vertical-align: middleet display: table-cell.

Asaf Chertkoff
la source
4
+1 pour l'utilisation de la table / cellule de tableau d'affichage. Il semble que peu de gens connaissent leur existence.
powerbuoy
5
Ceci est de W3CSchool ... Remarque: Les valeurs "inline-table", "run-in", "table", "table-caption", "table-cell", "table-column", "table-column- group "," table-row "," table-row-group "et" inherit "ne sont pas pris en charge dans IE7 et les versions antérieures. IE8 nécessite un! DOCTYPE. IE9 prend en charge les valeurs.
AK4668
20
cette solution est nul car elle supprime complètement tout effet de marge. La seule solution à cela est de créer des tonnes de pseudo éléments. Pourquoi le css est-il si nul.
Muhammad Umer
Pourquoi ne pas <li>entrer dans une seule ligne?
polkovnikov.ph
1
De plus, ce n'est pas conforme à l'accessibilité CATO si vous n'affichez PAS de données tabulaires.
Stevo Perisic
59

line-heightest la façon dont vous alignez verticalement le texte. C'est assez standard et je ne le considère pas comme un "hack". Ajoutez simplement line-height: 100pxà votre ul.catBlock liet tout ira bien.

Dans ce cas, vous devrez peut-être l'ajouter à la ul.catBlock li aplace car tout le texte à l'intérieur du liest également à l'intérieur d'un fichier a. J'ai vu des choses étranges se produire lorsque vous faites cela, alors essayez les deux et voyez laquelle fonctionne.

Logan Serman
la source
21
J'ai d'abord utilisé la hauteur de ligne, mais lorsque le contenu est long, il se divisera en 2 lignes et disons un écart de 100 pixels par ligne et le rendra pire. Est-ce qu'il y a un autre moyen?
AK4668
2
Je pense qu'il y a un moyen d'avoir vertical-align: middlesi vous avez display: table-cell. Cependant, je ne l'ai jamais utilisé. Jetez un œil ici: phrogz.net/css/vertical-align/index.html
Logan Serman
Excellente solution - j'ai défini la hauteur de la ligne de li pour qu'elle soit la même que ma hauteur min, et le texte est aligné verticalement - au moins assez près pour une inspection visuelle. La solution «table» ci-dessus n'est certainement pas sémantique et est de nature hackish. Chaque fois que nous faisons cela, nous augmentons les chances d'affichages cassés ou de comportement décalé quelque part dans le paysage réactif.
CodeFinity
Merci! Fonctionne très bien sur l'élément <a>! Quelle solution simple :-) Il suffit de le modifier pour corriger la valeur et il centre verticalement parfait!
Asle
45

Quel que soit le retard de cette réponse, quiconque rencontrera ce problème voudra peut-être essayer

li {
    display: flex;
    flex-direction: row;
    align-items: center;
}

La prise en charge de la flexbox par le navigateur est bien meilleure qu'elle ne l'était lorsque @scottjoudry a publié sa réponse ci-dessus, mais vous pouvez toujours envisager le préfixe ou d'autres options si vous essayez de prendre en charge des navigateurs beaucoup plus anciens. caniuse: flex

volant
la source
Cela ne fonctionne pas bien avec list-style-imageChrome - l'image disparaît
Benjineer
1
Je l'ai utilisé sur l'élément de navigation bootstrap 4 et cela a fonctionné parfaitement. THX.
010110110101
Flex box enregistre en direct comme toujours
Arthur Medeiros
16

Étonnamment (ou non), l' vertical-alignoutil fonctionne le mieux pour ce travail. Mieux encore, aucun Javascript n'est requis.

Dans l'exemple suivant, je place la outerclasse au milieu du corps et la innerclasse au milieu duouter classe.

Aperçu: http://jsfiddle.net/tLkSV/513/

HTML:

<div id="container">
    <span></span><div class="outer">
        <span></span><div class="inner">

        </div>
    </div>
</div>

CSS:

html, body {
    height: 100%;
    margin: 0;
    padding: 0; }
#container {
    text-align: center;
    height: 100%; }
span { 
    height: 100%;
    vertical-align: middle;
    display: inline-block; }
.outer {
    width: 100px;
    height: 200px;
    padding: 0;
    border: 1px solid #000;
    vertical-align: middle;
    display: inline-block; }
.inner {
    background: red;
    width: 30px;
    height: 20px;    
    vertical-align: middle;
    display: inline-block; }

L'alignement vertical fonctionne en alignant les centres des éléments les uns à côté des autres. L'application de l'alignement vertical à un seul élément ne fait absolument rien. Si vous ajoutez un deuxième élément qui n'a pas de largeur mais qui est la hauteur du conteneur, votre élément unique se déplacera pour se centrer verticalement avec cet élément sans largeur, le centrant ainsi verticalement. Les seules conditions requises sont que vous définissiez les deux éléments sur inline (ou inline-block) et que leur attribut vertical-align survertical-align: middle .

Remarque: vous remarquerez peut-être dans mon code ci-dessous que mon <span>tag et mon <div>tag se touchent. Comme ce sont tous les deux des éléments en ligne, un espace ajoutera en fait un espace entre l'élément sans largeur et votre div, alors assurez-vous de le laisser de côté.

Wex
la source
1
Fantastique, ça a du bon sens. // Je ne peux pas voter pour votre réponse maintenant car ma réputation
minimale
1
Pour ceux d'entre vous qui recherchent cette technique appliquée directement à la question - jsfiddle.net/utGVt/385
Wex
15

À l'avenir, ce problème sera résolu par flexbox. À l'heure actuelle, la prise en charge du navigateur est lamentable, mais elle est prise en charge sous une forme ou une autre dans tous les navigateurs actuels.

Prise en charge du navigateur: http://caniuse.com/flexbox

.vertically_aligned {

    /* older webkit */
    display: -webkit-box;
    -webkit-box-align: center;
    -webkit-justify-content: center;

    /* older firefox */
    display: -moz-box;
    -moz-box-align: center;
    -moz-box-pack: center;

    /* IE10*/
    display: -ms-flexbox;
    -ms-flex-align: center;
    -ms-flex-pack: center;

    /* newer webkit */
    display: -webkit-flex;
    -webkit-align-items: center;
    -webkit-box-pack: center;

    /* Standard Form - IE 11+, FF 22+, Chrome 29+, Opera 17+ */
    display: flex;
    align-items: center;
    justify-content: center;
}

Contexte sur Flexbox: http://css-tricks.com/snippets/css/a-guide-to-flexbox/

Scott Joudry
la source
1
Au moment où cette question a été posée, je ne suis pas sûr que cela aurait été une bonne réponse, mais aujourd'hui, nous voyons ~ 95% de support préfixé, donc je pense certainement que c'est une option viable.
Wex
Si vous souhaitez que les éléments <li> s'enroulent (au lieu d'être réduits), ajoutez flex-wrap: wrap; au niveau <ul>
Thierry
Quel élément dois-je également ajouter à cette classe?
Matt M.
6

Il n'y a pas de réponses parfaites fournies ici à l'exception de la réponse d'Asaf qui ne fournit aucun code ni aucun exemple, alors j'aimerais contribuer à la mienne ...

Afin de faire vertical-align: middle;fonctionner, vous devez utiliser display: table;pour votre ulélément et display: table-cell;pour les liéléments et que vous pouvez utiliser vertical-align: middle;pour les liéléments.

Vous n'avez pas besoin de fournir une explicite margins, paddingspour rendre votre texte verticalement milieu.

Démo

ul.catBlock{
    display: table;
    width:960px; 
    height: 270px; 
    border:1px solid #ccc; 
}

ul.catBlock li {
    list-style: none;
    display: table-cell; 
    text-align: center; 
    width:160px; 
    vertical-align: middle;
}

ul.catBlock li a { 
    display: block;
}
M. Alien
la source
Cela n'aide pas puisque la seule raison pour laquelle il a été aligné verticalement est parce que vous l'avez forcé vers le bas avec un rembourrage sur la balise a
str11
@ Mr.Alien Je répète cependant que le seul problème avec cette solution est que les règles de marge sont ignorées.
Thomas
4

Comme expliqué ici: https://css-tricks.com/centering-in-the-unknown/ .

Comme testé dans la pratique réelle, la solution la plus fiable et la plus élégante consiste à insérer un élément assistant en ligne dans l' <li />élément en tant que 1er enfant, dont la hauteur doit être réglée à 100% (de la hauteur de son parent, le <li />), et sa valeur vertical-alignau milieu. . Pour y parvenir, vous pouvez mettre un <span />, mais le moyen le plus pratique est d'utiliser une li:afterpseudo classe.

Capture d'écran: entrez la description de l'image ici

ul.menu-horizontal {
    list-style-type: none;
    margin: 0;
    padding: 0;
    display: inline-block;
    vertical-align: middle;
}

ul.menu-horizontal:after {
    content: '';
    clear: both;
    float: none;
    display: block;
}

ul.menu-horizontal li {
    padding: 5px 10px;
    box-sizing: border-box;
    height: 100%;
    cursor: pointer;
    display: inline-block;
    vertical-align: middle;
    float: left;
}

/* The magic happens here! */
ul.menu-horizontal li:before {
    content: '';
    display: inline;
    height: 100%;
    vertical-align: middle;
}
Jeff Tian
la source
1

Essayez cette solution

Fonctionne mieux dans la plupart des cas

vous devrez peut-être utiliser div au lieu de li pour cela

.DivParent {
    height: 100px;
    border: 1px solid lime;
    white-space: nowrap;
}
.verticallyAlignedDiv {
    display: inline-block;
    vertical-align: middle;
    white-space: normal;
}
.DivHelper {
    display: inline-block;
    vertical-align: middle;
    height:100%;
}
<div class="DivParent">
    <div class="verticallyAlignedDiv">
        <p>Isnt it good!</p>
     
    </div><div class="DivHelper"></div>
</div>

keshav
la source
1
Pourquoi cela a-t-il besoin d'un divHelper pour s'aligner verticalement? Je l'ai vu sur un autre sujet, mais je ne comprends pas pourquoi il ne s'aligne pas sans une autre div ..
Sasha Chirico
0

Solution simple pour aligner verticalement le milieu ... pour moi, cela fonctionne comme un charme

ul{display:table; text-align:center; margin:0 auto;}
li{display:inline-block; text-align:center;}
li.items_inside_li{display:inline-block; vertical-align:middle;}
Fahad Ali
la source