Использование margin: auto для вертикального выравнивания div

113

Итак, я знаю, что мы можем центрировать div по горизонтали, если будем использовать margin:0 auto;. Должно margin:auto auto;работать так, как я думаю? И по вертикали?

Почему тоже не vertical-align:middle;работает?

.black {
    position:absolute;
    top:0;
    bottom:0;
    left:0;
    right:0;
    background:rgba(0,0,0,.5);
}
.message {
    background:yellow;
    width:200px;
    margin:auto auto;
    padding:10px;
}
<div class="black">
    <div class="message">
        This is a popup message.
    </div>
</div>

JSFiddle

спасатель
источник
1
Настоятельно рекомендуем прочитать и реализовать ответ @ zpr ниже относительно Flexbox. На сегодняшний день он довольно хорошо поддерживается, и ваш CSS будет намного чище.
Говинд Рай
если ((новая Дата ()). getFullYear ()> 2017) useFlexBox = true;
Brandito

Ответы:

174

Обновить август 2020

Хотя ниже все еще стоит прочитать полезную информацию, у нас уже некоторое время есть Flexbox, поэтому просто используйте его в соответствии с этим ответом .


Вы не можете использовать:

vertical-align:middleпотому что это не применимо к элементам уровня блока

margin-top:autoи margin-bottom:autoпоскольку их используемые значения будут вычисляться как ноль

margin-top:-50%поскольку процентные значения маржи рассчитываются относительно ширины содержащего блока

Фактически, характер документооборота и алгоритмы расчета высоты элемента делают невозможным использование полей для центрирования элемента по вертикали внутри его родительского элемента. Всякий раз, когда значение вертикального поля изменяется, это вызывает повторный расчет высоты родительского элемента (повторный поток), который, в свою очередь, запускает повторное центрирование исходного элемента ... что делает его бесконечным циклом.

Ты можешь использовать:

Несколько подобных обходных путей, которые работают для вашего сценария; три элемента должны быть вложены следующим образом:

.container {
    display: table;
    height: 100%;
    position: absolute;
    overflow: hidden;
    width: 100%;
}
.helper {
    #position: absolute;
    #top: 50%;
    display: table-cell;
    vertical-align: middle;
}
.content {
    #position: relative;
    #top: -50%;
    margin: 0 auto;
    width: 200px;
    border: 1px solid orange;
}
<div class="container">
    <div class="helper">
        <div class="content">
            <p>stuff</p>
        </div>
    </div>
</div

JSFiddle отлично работает согласно Browsershot .

ов
источник
10
#- это хитрость, при которой правило с префиксом интерпретируется только IE7 и ниже. Вместо этого вы можете предпочесть включить эти правила в таблицу стилей для IE , используя условные комментарии и т. Д.
ov
2
+1 за указание причин, почему это так, расчет процентной маржи на основе ширины очень открыл глаза.
ricosrealm 09
2
Я сомневаюсь в утверждении «бесконечного цикла».
Barun
105
человечество уже побывало на Луне много лет назад, и нам все еще приходится иметь дело с этой ерундой. вертикальное выравнивание вещей в браузере,
Иисус
3
В эпоху> = IE9 position: absolute; top: 50%; transform: translateY(-50%);это тоже возможно и довольно популярно ... (в отличие от top:50%;margin: - $halfHeightтого, что вам не нужно знать высоту заранее ...)
Фрэнк
112

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

Если отображается ваш родительский контейнер flex, то да , margin: auto auto(также известный как margin: auto) будет работать, чтобы центрировать его как по горизонтали, так и по вертикали, независимо от того, является ли он элементом inlineили block.

#parent {
    width: 50vw;
    height: 50vh;
    background-color: gray;
    display: flex;
}
#child {
    margin: auto auto;
}
<div id="parent">
    <div id="child">hello world</div>
</div>

Обратите внимание, что ширину / высоту необязательно указывать абсолютно, как в этом примере jfiddle, который использует размер относительно области просмотра.

Хотя браузерная поддержка флексбоксов находится на рекордно высоком уровне на момент публикации, многие браузеры по-прежнему не поддерживают ее или требуют префиксов поставщика. Посетите http://caniuse.com/flexbox для получения обновленной информации о поддержке браузера.

Обновить

Поскольку этому ответу было уделено немного внимания, я также хотел бы указать, что вам вообще не нужно указывать, используете marginли вы и хотите ли вы центрировать display: flexвсе элементы в контейнере:

#parent {
    width: 50vw;
    height: 50vh;
    background-color: gray;
    display: flex;
    align-items: center; /* horizontal */
    justify-content: center; /* vertical */
}
<div id="parent">
    <div>hello world</div>
</div>

ZPR
источник
4
родительский {дисплей: гибкий; } дочерний {маржа: авто 0; } просто великолепен.
Арек Костржеба 01
О боже, чувак, ты рок-звезда, черт возьми, я не могу проголосовать за тебя больше одного раза !!!
PirateApp
Это хороший ответ, когда вас также может смутить проблема соответствия содержимому. Устанавливая гибкость контейнера, div содержимого не требует установки каких-либо свойств.
Эрик
1
Это, безусловно, лучшее и элегантное решение для работы в 2018 году, спасибо.
SilverSurfer
Я хотел бы добавить, что по состоянию на май 2018 года в этом решении текст не выравнивается по вертикали посередине в IE 11.
Ефу
62

Вот лучшее решение, которое я нашел: http://jsfiddle.net/yWnZ2/446/ Работает в Chrome, Firefox, Safari, IE8-11 и Edge.

Если объявленная height( height: 1em, height: 50%и т.д.) , или это элемент , где браузер знает высоту ( img, svgили canvas, например), то все , что вам нужно для вертикального центрирования заключается в следующем:

.message {
    position: absolute;
    top: 0; bottom: 0; left: 0; right: 0;
    margin: auto;
}

Вы обычно хотите , чтобы указать widthили max-widthтак что содержание не растягивается на всю длину экрана / контейнера.

Если вы используете это для модального окна, которое вы хотите всегда центрировать в области просмотра, перекрывая другой контент, используйте position: fixed;для обоих элементов вместо position: absolute. http://jsfiddle.net/yWnZ2/445/

Вот более полная запись: http://codepen.io/shshaw/pen/gEiDt

шшоу
источник
3
Это не обязательно центрирует его в родительском элементе. Хороший хак, если вы просто хотите, чтобы он был в центре страницы.
Джоэл Меллон
2
Просто добавьте position: relativeк родительскому элементу, и элемент будет центрирован внутри родительского элемента. Если вы хотите узнать больше, я написал
shshaw
Иногда абсолютное значение основано на одном или двух родителях (по сравнению с телом), а родственник может быть прародителем или прадедом (по сравнению с родителем). Может быть, те, кто знает, когда и почему это происходит, могли бы лучше контролировать эту технику - я никогда особо не разбирался в этих проблемах, но я знаю, что переключение с абсолютного на относительное само по себе не является решением для этой работы. Я прочитал небольшую часть вашей статьи, и похоже, что абсолютное и относительное восходят к первому абсолютному или относительному предку, это правильно?
Джоэл Меллон
Я немного медленный. Я просто перечитал ваш комментарий выше. Я не заметил, что вы сказали добавить это к… parentпонял. Спасибо!
Джоэл Меллон
1
@commonpike Единственная проблема IE8 / 9 заключается в том, что вы используете display: tableдля содержимого переменной высоты. В противном случае этот метод должен работать должным образом. Прочтите рецензию для получения более подробной информации в целом. Вы также должны иметь возможность протестировать полный вид в IE8 / 9, чтобы увидеть, есть ли какие-либо проблемы.
shshaw
22

Изменить: это 2020 год, вместо этого я бы использовал гибкую коробку.

Оригинальный ответ:

Html

<body>
  <div class="centered">
  </div>
</body>

CSS

.centered {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
Гал Маргалит
источник
не будет работать с IE 8 и более ранними версиями ie. Поскольку свойства преобразования поддерживаются (с префиксом -ms-) начиная с версии 9.0 и выше. (т.е. 10 больше не нужен префикс).
DevWL 01
5
Правда, мне плевать на IE8
Гал Маргалит
И писатель отметил html5 в своем вопросе ☺
Гал Маргалит
9

Я знаю, что это вопрос 2012 года, но я нашел самый простой способ и хотел поделиться.

HTML:

<div id="parent">
     <div id="child">Content here</div>
</div>

и CSS:

#parent{
     height: 100%;
     display: table;
}    
#child {
     display: table-cell;
     vertical-align: middle; 
}
Паула Флек
источник
7

Если вам известна высота блока div, который вы хотите центрировать , вы можете разместить его абсолютно внутри его родительского элемента, а затем установить topзначение 50%. Это поместит верхнюю часть дочернего div на 50% вниз от его родительского элемента, то есть слишком низко. Поднимите его, установив margin-topна половину высоты. Итак, теперь у вас есть вертикальная средняя точка дочернего div, сидящая в вертикальной средней точке родительского элемента - вертикально по центру!

Пример:

.black {
    position:absolute;
    top:0;
    bottom:0;
    left:0;
    right:0;
    background:rgba(0,0,0,.5);
}
.message {
    background:yellow;
    width:200px;
    margin:auto auto;
    padding:10px;
    position: absolute;
    top: 50%;
    margin-top: -25px;
    height: 50px;
}
<div class="black">
    <div class="message">
        This is a popup message.
    </div>
</div>

http://jsfiddle.net/yWnZ2/2/

туф
источник
1
margin-topне может быть установлена в% относительно высоты элемента, так что вы будете в конечном итоге с размерами зависимой затруднительного
OV
1
Что ... именно то, что я сказал в своем ответе? «Если вы знаете высоту div, которую хотите центрировать». И я не говорил, что OP должен использовать% in margin-top.
туф
Я не согласен с решением, поскольку оно фиксирует вас на заранее определенной высоте элемента, но ваш комментарий имеет смысл. Вы можете отразить это в
своем
3
Хорошо, я выделил жирным шрифтом ту часть, которую вы упустили, надеюсь, теперь она стала яснее.
туф
1
@ov: Если элемент не имеет фиксированной высоты, вы можете просто использовать JS для получения вычисленной высоты, а затем соответственно установить отрицательное верхнее поле. На мой взгляд, это по-прежнему лучший метод вертикального центрирования.
daGUY
3

Эти два решения требуют только двух вложенных элементов.
Первый - относительное и абсолютное позиционирование, если контент статичен (ручной центр).

.black {
    position:relative;
    min-height:500px;
    background:rgba(0,0,0,.5);

}
.message {
    position:absolute;
    margin: 0 auto;
    width: 180px;
    top: 45%; bottom:45%;  left: 0%; right: 0%;
}

https://jsfiddle.net/GlupiJas/5mv3j171/

или для гибкого дизайна - вместо этого для точного информационного центра используйте следующий пример:

.message {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

https://jsfiddle.net/GlupiJas/w3jnjuv0/

Вам нужно установить min-height, если содержимое превышает 50% высоты окна. Этой высотой также можно управлять с помощью медиа-запроса для мобильных и планшетных устройств. Но только если Вы играете с адаптивным дизайном.

Я думаю, вы могли бы пойти дальше и использовать простой скрипт JavaScript / JQuery для управления минимальной или фиксированной высотой, если по какой-то причине в этом есть необходимость.

Во- вторых - если содержание жидкости у может также использовать таблицы и таблицы ячейки CSS свойства с вертикальным выравниванием и выравнивания текста по центру:

/*in a wrapper*/  
display:table;   

и

/*in the element inside the wrapper*/
display:table-cell;
vertical-align: middle;
text-align: center;

Отлично работает и масштабируется, часто используется в качестве адаптивного решения для веб-дизайна с макетами сетки и медиа-запросами, которые управляют шириной объекта.

.black {
    display:table;
    height:500px;
    width:100%;
    background:rgba(0,0,0,.5);

}
.message {
    display:table-cell;
    vertical-align: middle;
    text-align: center;
}

https://jsfiddle.net/GlupiJas/4daf2v36/

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

DevWL
источник
2

.black {
    display:flex;
    flex-direction: column;
    height: 200px;
    background:grey
}
.message {
    background:yellow;
    width:200px;
    padding:10px;
    margin: auto auto;
}
<div class="black">
    <div class="message">
        This is a popup message.
    </div>
</div>

Seetpal Singh
источник
Не могли бы вы поделиться с нами, каково это решение? Кроме того, я вижу ваше «всплывающее сообщение» внизу не по центру
Alex
Я кое-что пропустил, но теперь он доработан, чтобы div оставался посередине по вертикали. Вы можете проверить сейчас.
Seetpal Singh
0

Не существует одного простого способа центрировать div по вертикали, который помогал бы в любой ситуации.

Однако есть множество способов сделать это в зависимости от ситуации.

Вот несколько из них:

  • Установите верхний и нижний отступ родительского элемента, например padding: 20px 0px 20px 0px
  • Используйте таблицу, ячейка таблицы центрирует свое содержимое по вертикали
  • Установите относительную позицию родительского элемента, а div, который вы хотите центрировать по вертикали, на absolute и задайте стиль как top: 50px; внизу: 50 пикселей; например

Вы также можете найти в Google "вертикальное центрирование css"

Хасу
источник
0

переменная высота, верхнее и нижнее поле автоматически

.black {background:rgba(0,0,0,.5);
width: 300px;
height: 100px;
display: -webkit-flex; /* Safari */
display: flex;}
.message{
background:tomato;
margin:auto;
padding:5%;
width:auto;
}
<div class="black">
<div class="message">
    This is a popup message.
</div>

переменная высота, верхнее и нижнее поле автоматически

пользователь3668456
источник
0

Использование Flexbox:

HTML:

<div class="container">
  <img src="http://lorempixel.com/400/200" />
</div>

CSS:

.container {
  height: 500px;
  display: flex;
  justify-content: center; /* horizontal center */
  align-items: center;     /* vertical center */
}

Посмотреть результат

Даниэль Бласкес
источник
0
.black {
    position:absolute;
    top:0;
    bottom:0;
    left:0;
    right:0;
    background:rgba(0,0,0,.5);
}
.message {
    position: absolute;
    top:50%;
    left: 50%;
    transform: translate(-50%, -50%);
    background:yellow;
    width:200px;
    padding:10px;
}

 - 


----------


<div class="black">
<div class="message">
    This is a popup message.
</div>
Судипто Чакраборти
источник