CSS вертикальное выравнивание текста внутри li

101

Я показываю количество ящиков в строке с фиксированной высотой и шириной, сгенерированных из тегов <li>. теперь мне нужно выровнять текст по вертикали по центру. CSS vertical-align не влияет, может я что-то упускаю ???

Я не ищу трюков с использованием (margin, padding, line-height), они не будут работать, потому что некоторые тексты длинные и разбиваются на две строки.

Найдите актуальный код:

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;
}

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
источник
3
вам может потребоваться дополнительная информация. Ящики одинаковой высоты? Вы выравниваете текст внутри полей в li? "потому что какой-то текст длинный ... две строки" ??? Может, поможет скриншот или скрипка.
KMC
1
Я просто попытался опубликовать снимок экрана, но это не позволяет мне, так как моя учетная запись новая.
AK4668

Ответы:

101

Определите родительский display: tableэлемент с помощью, vertical-align: middleа сам элемент с помощью и display: table-cell.

Асаф Чертков
источник
4
+1 для использования отображения таблицы / таблицы-ячейки. Кажется, не многие люди знают об их существовании.
powerbuoy
5
Это из W3CSchool ... Примечание. Значения «inline-table», «run-in», «table», «table-caption», «table-cell», «table-column», «table-column-» group »,« table-row »,« table-row-group »и« наследование »не поддерживаются в IE7 и более ранних версиях. IE8 требует! DOCTYPE. IE9 поддерживает значения.
AK4668
21
это решение отстой, поскольку оно полностью исключает любой эффект маржи. Единственное решение этой проблемы - создать тонны псевдоэлементов. Почему css так отстой.
Мухаммад Умер
Как насчет того, <li>чтобы попасть в одну строку?
polkovnikov.ph 08
1
Кроме того, это не соответствует требованиям CATO, если вы на самом деле НЕ показываете табличные данные.
Стево Перишич
59

line-heightкак вы выравниваете текст по вертикали. Это довольно стандартно, и я не считаю это "взломом". Просто добавьте line-height: 100pxв свой ul.catBlock liи все будет хорошо.

В этом случае вам, возможно, придется добавить его ul.catBlock li aвместо этого, поскольку весь текст внутри также liнаходится внутри a. Я видел, как при этом происходили странные вещи, поэтому попробуйте оба и посмотрите, какой из них работает.

Логан Серман
источник
22
Изначально я использовал line-height, но когда контент длинный, он разбивается на 2 строки и, скажем, 100 пикселей на каждую строку, и это ухудшит вид. Есть ли другой путь?
AK4668
2
Думаю, есть способ, vertical-align: middleесли да display: table-cell. Но я никогда им не пользовался. Взгляните здесь: phrogz.net/css/vertical-align/index.html
Логан Серман
Отличное решение - я установил li 'line height' таким же, как моя min-height, а текст выровнен по вертикали - по крайней мере, достаточно близко для визуального осмотра. Приведенное выше «табличное» решение определенно не является семантическим и по своей природе является хакерским. Каждый раз, когда мы это делаем, мы увеличиваем вероятность поломки дисплеев или странного поведения где-нибудь в отзывчивой среде.
CodeFinity,
Спасибо! Отлично работает с элементом <a>! Какое простое решение :-) Просто настройте его на правильное значение, и он будет идеально центрирован по вертикали!
Asle
46

Каким бы опозданием ни был этот ответ на много лет, любой, кто столкнется с этим, может просто захотеть попробовать

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

Браузерная поддержка flexbox намного лучше, чем когда @scottjoudry опубликовал свой ответ выше, но вы все равно можете рассмотреть вопрос о префиксе или других вариантах, если вы пытаетесь поддерживать гораздо более старые браузеры. caniuse: flex

летающий
источник
1
Это не очень хорошо с list-style-imageChrome - изображение исчезает
Benjineer
1
Я использовал это в навигационном элементе bootstrap 4, и он работал отлично. Спасибо.
010110110101
flex box сохраняет вживую, как всегда
Артур Медейрос,
16

Удивительно (или нет), но vertical-alignинструмент действительно лучше всего подходит для этой работы. Лучше всего то, что Javascript не требуется.

В следующем примере я размещаю outerкласс посередине тела, а innerкласс - посередине outerкласса.

Предварительный просмотр: 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; }

Вертикальное выравнивание работает путем выравнивания центров элементов, расположенных рядом друг с другом. Применение vertical-align к отдельному элементу абсолютно ничего не дает. Если вы добавите второй элемент, который не имеет ширины, но является высотой контейнера, ваш единственный элемент переместится в центр по вертикали с этим элементом без ширины, таким образом центрируя его по вертикали. Единственное требование состоит в том, что вы установите оба элемента как inline (или inline-block) и установите для их атрибута vertical-align значение vertical-align: middle.

Примечание. В моем коде ниже вы можете заметить, что мой <span>тег и <div>тег соприкасаются. Поскольку они оба являются встроенными элементами, пробел фактически добавит пробел между элементом без ширины и вашим div, поэтому не забудьте оставить его.

Wex
источник
1
Потрясающе, в этом есть смысл. // Я не могу проголосовать за ваш ответ сейчас, потому что моя минимальная репутация должна быть 15.
AK4668
1
Для тех из вас, кто ищет эту технику, применимую непосредственно к вопросу - jsfiddle.net/utGVt/385
Wex
16

В будущем эту проблему решит flexbox. На данный момент поддержка браузеров мрачна, но она поддерживается в той или иной форме во всех текущих браузерах.

Поддержка браузера: 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;
}

Справочная информация о Flexbox: http://css-tricks.com/snippets/css/a-guide-to-flexbox/

Скотт Джоудри
источник
2
В то время, когда задавался этот вопрос, я не уверен, что это был бы хороший ответ, но сегодня мы видим поддержку с префиксом ~ 95%, поэтому я, безусловно, думаю, что это жизнеспособный вариант.
Wex
Если вы хотите, чтобы элементы <li> обертывались (а не сжимались), добавьте flex-wrap: wrap; на уровне <ul>
Тьерри
Какой элемент мне добавить и этот класс?
Мэтт М.
6

Здесь нет идеальных ответов, кроме ответа Асафа, который не содержит ни кода, ни примеров, поэтому я хотел бы внести свой вклад ...

Чтобы заставить vertical-align: middle;работать, вам нужно использовать display: table;для своего ulэлемента и display: table-cell;для liэлементов, а затем вы можете использовать vertical-align: middle;для liэлементов.

Вам не нужно давать никаких явных указаний margins, paddingsчтобы сделать ваш текст вертикально посередине.

Демо

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;
}
Г-н Чужой
источник
Это не помогает, поскольку единственная причина, по которой он был выровнен по вертикали, заключается в том, что вы принудительно опускали его с помощью отступа в теге a
str11
@ Mr.Alien Я повторю, что единственная проблема с этим решением заключается в том, что правила маржи игнорируются.
Thomas
4

Как объясняется здесь: https://css-tricks.com/centering-in-the-unknown/ .

Как было проверено на практике, наиболее надежным, но элегантным решением является вставка вспомогательного встроенного элемента в <li />элемент в качестве 1-го дочернего элемента, высота которого должна быть установлена ​​на 100% (от высоты его родительского элемента <li />), а его высота - vertical-alignна середину. . Для этого вы можете поставить a <span />, но наиболее удобный способ - использовать li:afterпсевдокласс.

Скриншот: введите описание изображения здесь

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;
}
Джефф Тиан
источник
1

Попробуйте это решение

Лучше всего работает в большинстве случаев

вам может потребоваться использовать div вместо li для этого

.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>

кешав
источник
1
Зачем нужен divHelper для вертикального выравнивания? Я видел это по другой теме, но я не могу понять, почему он не выравнивается без другого div ..
Саша Кирико
0

Простое решение для вертикального выравнивания по центру ... для меня это работает как шарм

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;}
Фахад Али
источник