Почему выравнивание по вертикали: середина не работает на моем span или div?


247

Я пытаюсь вертикально центрировать элемент spanили divэлемент внутри другого divэлемента. Однако, когда я ставлю vertical-align: middle, ничего не происходит. Я попытался изменить displayсвойства обоих элементов, но ничего не работает.

Вот что я сейчас делаю на своей веб-странице:

.main {
  height: 72px;
  vertical-align: middle;
  border: 1px solid black;
  padding: 2px;
}
    
.inner {
  vertical-align: middle;
  border: 1px solid red;    
}
    
.second {
  border: 1px solid blue; 
}
<div class="main">
  <div class="inner">
    This box should be centered in the larger box
    <div class="second">Another box in here</div>
  </div>
</div>

Вот jsfiddle реализации, показывающий, что она не работает: http://jsfiddle.net/gZXWC/

Ответы:


207

Это, кажется, лучший способ - прошло некоторое время с момента моего первоначального поста, и это то, что должно быть сделано сейчас: http://jsfiddle.net/m3ykdyds/200

/* CSS file */

.main {
    display: table;
}

.inner {
    border: 1px solid #000000;
    display: table-cell;
    vertical-align: middle;
}

/* HTML File */
<div class="main">
    <div class="inner"> This </div>
</div>

2
Так как же кто-то делает то, что хочет сделать ОП?
— Райан Мортенсен

Есть идеи по изменяющимся абзацам? то есть. если нет способа узнать, будет ли это одна или две строки. Нужно ли тогда пользователю jQuery?
— Foochow

Что, если высота должна быть динамической, каково решение?
— Murhaf Sousli

не должен быть принятым ответом, полагается на знание высоты '.inner', поэтому не совсем то, о чем просил ОП, и некоторые гораздо лучшие ответы ниже, см. ответы @timbergus или Тима Перкинса внизу внизу.
— майк-источник

@ mike-source зная высоту inner, возможно на 100%, даже если высота является динамической, так как немного javascript может понять это и динамически изменить правило CSS для этого объекта DOM.
— Чарльз Аддис

143

Используя CSS3:

<div class="outer">
   <div class="inner"/>
</div>

Css:

.outer {
  display : flex;
  align-items : center;
  justify-content: center;
}

Примечание: это может не работать в старых IE


16
Это поддерживается всеми основными современными браузерами и самым простым и чистым решением.
— Сэм

2
Также имейте в виду, inline-flexчто внутри внутреннего элемента должно быть несколько элементов подряд.
— Дан Ниссенбаум,

1
В моем случае, поскольку я тоже хотел центрировать содержимое .inner по горизонтали, мне пришлось добавить .inner { width: 100%; }. Таким образом, это похоже на работу, .outer { display: table; } .inner { display: table-cell; vertical-align: middle; }но без принудительной минимальной ширины.
— Барт S

Раньше я justify-content: center;выравнивал по горизонтали, что прекрасно работало
— Рут Янг

140

Попробуйте это, у меня работает очень хорошо:

/* Internet Explorer 10 */
display:-ms-flexbox;
-ms-flex-pack:center;
-ms-flex-align:center;

/* Firefox */
display:-moz-box;
-moz-box-pack:center;
-moz-box-align:center;

/* Safari, Opera, and Chrome */
display:-webkit-box;
-webkit-box-pack:center;
-webkit-box-align:center;

/* W3C */
display:box;
box-pack:center;
box-align:center;

4
отличный ответ, это дало мне полностью работоспособное решение, которое не вызвало других проблем с зацепкой (приложение, использующее jquerymobile + phonegap и все другие решения, привело к проблемам css и div sizing). Просто чтобы указать, что эти параметры должны быть добавлены в блок CSS, специфичный для элементов, которые должны быть центрированы / размещены, например: #element span {height:100%;display:-webkit-box;-webkit-box-pack:center;-webkit-box-align:center;}- обратите внимание, высота важна, чтобы гарантировать, что span наследует полную высоту своего контейнера (возможно, div), в противном случае Вы все еще не получите вертикальное центрирование!
— Энди Лоренц

Кстати, вы можете написать стандартный код flexbox без префиксов браузера, а затем получить браузер с префиксом autoprefixer github.com/postcss/autoprefixer или через онлайн-демонстрацию simevidas.jsbin.com/gufoko/quiet
— starikovs

2
недопустимое значение свойства boxвdisplay
— Joaquinglezsantos

Кроме того, ответ @ user1782556 работает лучше, когда внешнее поле имеет отступ.
— Iautomation

34

Установка высоты строки на ту же высоту, что и содержащая div, также будет работать

ДЕМО http://jsfiddle.net/kevinPHPkevin/gZXWC/7/

.inner {
    line-height:72px;
    border: 1px solid #000000;
}

1
Я разместил ссылку, которая объясняет этот метод, а также. Не мой предпочтительный метод, хотя, если остальная часть макета не является фиксированной по размеру - я столкнулся с проблемами в окнах разных размеров с этим методом.
— Чарльз Аддис

2
да, техника высоты строки работает хорошо, но ТОЛЬКО ЕСЛИ у вас есть однострочный контент. Дополнительные строки будут потеряны / выльются за пределы контейнера, и вам нужно будет начать заново!
— Энди Лоренц,

а) line-heightтакже изменит высоту внутреннего элемента. б) Внутренний элемент все еще не точно отцентрирован по вертикали. c) Он не работает с элементами, которые не содержат текст, например <img>, или с элементами с фиксированной высотой.
— Alph.Dev

Он также может
— давать

1
Это очень непредсказуемо и часто приводит к увеличению высоты контейнера.
— Undistraction

25

Если вы не можете положиться на flexbox ... Поместите .childв .parentцентр. Работает, когда размеры пикселей неизвестны (другими словами, всегда), и нет проблем с IE9 + тоже.

.parent { position: relative; }

.child {
    position: absolute;
    top : 50%;
    left: 50%;
    -ms-transform: translate(-50%, -50%);
    transform    : translate(-50%, -50%);    
}
<div class="parent" style="background:lightyellow; padding:6em"> 
  <div class="child" style="background:gold; padding:1em">&mdash;</div> 
</div>


На самом деле это наиболее удачное решение, тем более что большинству проектов, которые я видел до сих пор, требуется совместимость с IE9
— Jabberwocky

21

Вы должны надеть vertical-align: middleвнутренний элемент, а не внешний элемент. Установите line-heightсвойство на внешнем элементе, чтобы соответствовать heightвнешнему элементу. Затем установите display: inline-blockи line-height: normalна внутренний элемент. При этом текст на внутреннем элементе будет перенесен с обычной высотой строки. Работает в Chrome, Firefox, Safari и IE 8+

.main {
    height: 72px;
    line-height:72px;
    border: 1px solid black;
}
.inner {
    display: inline-block;
    vertical-align: middle;
    line-height: normal;
}
<div class="main">
    <div class="inner">Vertically centered text</div>
</div>

скрипка


Это, вероятно, самый простой способ ... все остальные ответы на этой странице излишне неуклюжи / хакерские ИЛИ не поддерживаются в старых браузерах ИЛИ полагаются на знание высоты внутреннего элемента. Вам на самом деле не нужно line-height: normal;и display:inline;работает тоже. Преимущество этого метода в том, что он не мешает text-align:center;, а использование display: table-cell;может создавать проблемы. Довольно часто мы хотим выровнять как горизонтально, так и вертикально. Смотрите эту отредактированную скрипку: jsfiddle.net/br090prs/36
— mike-source

2
@ mike-source причина использования line-height: normalи display: inline-blockтак, чтобы внутренний текст был перенесен правильно. Если вы уверены, что текст во внутреннем div никогда не будет перенесен, эти свойства не понадобятся.
— Тим Перкинс

С тех пор, как Microsoft прекратила поддержку старых версий IE, я использовал flexbox для такого рода вещей (как предложил @ user1782556). Мой оригинальный ответ - путь, если вам все еще нужно поддерживать IE 10 или старше.
— Тим Перкинс

100% согласны, но я бы пока не стал использовать flex box, только 76% браузеров полностью поддерживают его по состоянию на май 2016 года (94%, если вы включите частичную поддержку), см .: caniuse.com/#search=f Flexible% 20box . Тем не менее, это очень близко к тому, чтобы быть наиболее разумным вариантом, в зависимости от вашей пользовательской базы.
— майк-источник

10

Я использовал это, чтобы выровнять все по центру div-оболочки, на случай, если это кому-нибудь поможет - я нашел это проще всего:

div.wrapper {
  /* --- This works --- */
  display: flex;
  /* Align Vertically */
  align-items: center;
  /* Align Horizontally */
  justify-content: center;
  /* --- ---------- ----- */
  width: 100%;
  height:100px;
  background-color: blue;
}
div.inner {
  width: 50px;
  height: 50px;
  background-color: orange;
}
<div class="wrapper">
  <div class="inner">
  </div>
</div>


7

Здесь у вас есть пример двух способов сделать вертикальное выравнивание. Я использую их, и они работают довольно хорошо. Один использует абсолютное позиционирование, а другой использует flexbox .

Пример вертикального выравнивания

Используя flexbox, вы можете выровнять элемент внутри другого элемента с display: flex;помощью align-self. Если вам нужно выровнять его также по горизонтали, вы можете использовать align-itemsи justify-contentв контейнере.

Если вы не хотите использовать flexbox, вы можете использовать свойство position. Если вы сделаете контейнер относительным, а содержимое - абсолютным, содержимое сможет свободно перемещаться внутри контейнера. Так что если вы используете top: 0;и left: 0;в контенте, он будет расположен в верхнем левом углу контейнера.

Абсолютное позиционирование

Затем, чтобы выровнять его, вам просто нужно изменить верхнюю и левую ссылки на 50%. Это позволит расположить содержимое в центре контейнера из верхнего левого угла содержимого.

Выровняйте посередине контейнера

Так что вам нужно исправить это, переведя содержимое на половину его размера слева и сверху.

Абсолютно центрированный


5

Вот отличная статья о том, как выровнять по вертикали. Мне нравится способ с плавающей точкой.

http://www.vanseodesign.com/css/vertical-centering/

HTML:

<div id="main">
    <div id="floater"></div>
    <div id="inner">Content here</div>
</div>

И соответствующий стиль:

#main {
   height: 250px;
}

#floater {
   float: left;
   height: 50%;
   width: 100%;
   margin-bottom: -50px;
}

#inner {
   clear: both;
   height: 100px;
}

3
Я думаю, что если вы определите высоту блока #inner, это лишит законной силы правильное вертикальное центрирование. OPS просил сделать его автоматическим, поэтому я предполагаю, что это означает, что высота внутренней коробки не известна во время зачатия.
— Алексис Вилке

5

HTML

<div id="myparent">
  <div id="mychild">Test Content here</div>
</div>

CSS

#myparent {
  display: table;
}
#mychild {
  display: table-cell;
  vertical-align: middle;
}

Мы устанавливаем родительский div для отображения в виде таблицы, а дочерний div для отображения в качестве ячейки таблицы. Затем мы можем использовать вертикальное выравнивание на дочернем элементе div и установить его значение на середину. Все внутри этого дочернего элемента div будет вертикально центрировано.


4

Это просто. Просто добавьте display:table-cellв свой основной класс.

.main {
  height: 72px;
  vertical-align: middle;
  display:table-cell;
  border: 1px solid #000000;
}

Проверьте это jsfiddle !


4

Вот последнее простейшее решение - не нужно ничего менять, просто добавьте три строки правил CSS в свой контейнер div, в котором вы хотите сосредоточиться. Я люблю Flex Box#LoveFlexBox

.main {
  /* I changed height to 200px to make it easy to see the alignment. */
  height: 200px;
  vertical-align: middle;
  border: 1px solid #000000;
  padding: 2px;
  
  /* Just add the following three rules to the container of which you want to center at. */
  display: flex;
  flex-direction: column;
  justify-content: center;
  /* This is true vertical center, no math needed. */
}
.inner {
  border: 1px solid #000000;
}
.second {
  border: 1px solid #000000;
}
<div class="main">
  <div class="inner">This box should be centered in the larger box
    <div class="second">Another box in here</div>
  </div>
  <div class="inner">This box should be centered in the larger box
    <div class="second">Another box in here</div>
  </div>
</div>

бонус

В качестве justify-contentзначения можно указать следующие несколько параметров:

  • flex-start, который выровняет дочерний элемент div в том месте, где поток flex начинается в его родительском контейнере. В этом случае он останется на вершине.

  • center, который выровняет дочерний элемент div по центру его родительского контейнера. Это действительно аккуратно, потому что вам не нужно добавлять дополнительный div для обтекания всех дочерних элементов, чтобы поместить обертку в родительский контейнер для центрирования дочерних элементов. Из-за этого это истинный вертикальный центр ( column flex-directionаналогично, если вы измените его flow-directionна row, он станет горизонтально центрированным).

  • flex-end, который выровняет дочерний элемент div в том месте, где поток flex заканчивается в его родительском контейнере. В этом случае он переместится вниз.

  • space-between, который распространит все дочерние элементы от начала потока до конца потока. Если демо, я добавил еще один дочерний div, чтобы показать, что они разложены.

  • space-aroundАналогично space-between, но с половиной пространства в начале и конце потока.


Идеальное решение. Несовместимые браузеры могут выводить содержимое без выравнивания, и пользователь должен разобраться с ним или обновить свой браузер.
— дважды

0

Поскольку он vertical-alignработает, как и ожидалось td, вы можете поместить один элемент tableв, divчтобы выровнять его содержимое.

<div>
    <table style="width: 100%; height: 100%;"><tr><td style="vertical-align: middle; text-align: center">
        Aligned content here...
    </td></tr></table>
</div>

Неуклюжий, но работает, насколько я могу судить. Это может не иметь недостатков других обходных путей.


5
Нет, пожалуйста, больше нет столов. CSS может сделать это чистым способом. В этом случае нет необходимости использовать <table>.
— enguerranws

0

Просто поместите содержимое в таблицу с высотой 100% и установите высоту для основного div

<div style="height:80px;border: 1px solid #000000;">
<table style="height:100%">
<tr><td style="vertical-align: middle;">
  This paragraph should be centered in the larger box
</td></tr>
</table>
</div>

0

Для вертикального центрирования элемента span или div в другом div, добавьте позицию относительно родительского div и абсолютную позицию по отношению к дочернему div. Теперь дочерний div можно расположить в любом месте внутри div. Пример ниже центров как по горизонтали, так и по вертикали.

<div class="parent">
    <div class="child">Vertically and horizontally centered child div</div>
</div>

CSS:

.parent{
    position: relative;
}
.child{
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    margin: auto;
}

0

Это современный подход, использующий функциональность CSS Flexbox. Теперь вы можете выровнять содержимое в родительском контейнере по вертикали, просто добавив эти стили в .mainконтейнер.

.main {
        display: flex;
        flex-direction: column;
        justify-content: center;
}

И вам хорошо идти!

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.