Почему выравнивание по вертикали: середина не работает на моем 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

user1782556
источник
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>

kornieff
источник
На самом деле это наиболее удачное решение, тем более что большинству проектов, которые я видел до сих пор, требуется совместимость с 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%. Это позволит расположить содержимое в центре контейнера из верхнего левого угла содержимого.

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

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

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

Timbergus
источник
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 !

RizonBarns
источник
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, но с половиной пространства в начале и конце потока.

Downhillski
источник
Идеальное решение. Несовместимые браузеры могут выводить содержимое без выравнивания, и пользователь должен разобраться с ним или обновить свой браузер.
дважды
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>

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

Smig
источник
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;
}

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

Кингсли Гима
источник