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

Итак, я знаю, что мы можем центрировать 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


person savinger    schedule 13.09.2012    source источник
comment
Настоятельно рекомендуем прочитать и реализовать приведенный ниже ответ @zpr относительно Flexbox. На сегодняшний день он довольно хорошо поддерживается, и ваш css будет намного чище.   -  person Govind Rai    schedule 01.01.2017
comment
if((new Date()).getFullYear() › 2017) useFlexBox = true;   -  person brandito    schedule 05.04.2018


Ответы (12)


Обновление, август 2020 г.

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


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

vertical-align:middle потому что это не< /em> применимо к блочным элементам

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

Согласно Browsershot, JSFiddle работает нормально.

person Oleg    schedule 14.09.2012
comment
Спасибо! Три верхние ноты очень полезно знать. Быстрый вопрос ... знаки фунта в вашем css просто комментарии? - person savinger; 14.09.2012
comment
# — это хак, позволяющий префиксу правила интерпретировать его только в IE7 и ниже. Вместо этого вы можете включить эти правила в специфичную для IE таблицу стилей с помощью условных комментариев. и т.п. - person Oleg; 15.09.2012
comment
+1 за указание причин, по которым это так, расчет процента маржи на основе ширины был очень поучительным. - person ricosrealm; 10.03.2013
comment
Отлично, как раз то, что мне было нужно. Возвращаясь к старой доброй таблице, но в стиле CSS. Я просто пытался сделать то же самое с flex box, я это сделал, но его поддержка настолько нестабильна, что мне пришлось прибегнуть к другому подходу. - person JorgeeFG; 17.04.2013
comment
Я сомневаюсь в утверждении «бесконечный цикл». - person Barun; 11.06.2014
comment
Существует более новый и короткий ответ. - person Qwerty; 09.04.2015
comment
человечество уже побывало на Луне много лет назад, и нам до сих пор приходится иметь дело с этой чушью. вертикальное выравнивание в браузере, господи - person user151496; 11.05.2015
comment
ИСПРАВЛЕНИЕ: .content нужно display: table; центрировать .. спасибо .. работает - person KingRider; 23.10.2015
comment
@KingRider Не используйте таблицы для макета. - person TylerH; 11.08.2016
comment
@TylerH проблема с моей загрузкой, конфликт. Ну бывает. - person KingRider; 11.08.2016
comment
В эпоху ›= IE9 position: absolute; top: 50%; transform: translateY(-50%); также возможен и весьма популярен... (в отличие от top:50%;margin: - $halfHeight вам не нужно заранее знать высоту...) - person Frank Nocke; 09.04.2017
comment
Если вы подходите к этому вопросу после 2019 года, посмотрите ниже лучший ответ, который касается FlexBox как способа сделать это. - person clayRay; 03.07.2020

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

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

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

Обновлять

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

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

person zpr    schedule 27.09.2014
comment
родитель { дисплей: гибкий; } ребенок { поле: авто 0; } просто великолепно. - person Arek Kostrzeba; 02.12.2016
comment
OMG чувак, ты рок-звезда, блин, я не могу проголосовать за тебя больше одного раза!!! - person PirateApp; 15.12.2017
comment
Это хороший ответ, когда вы также можете быть сбиты с толку проблемой соответствия содержимого. Установив flex для контейнера, div содержимого не требует установки каких-либо свойств. - person Eric; 09.02.2018
comment
Это, безусловно, лучшее и элегантное решение для работы в 2018 году, спасибо. - person SilverSurfer; 24.02.2018
comment
Я хотел бы добавить, что по состоянию на май 2018 года с этим решением текст не выравнивается по вертикали посередине в IE 11. - person Yefu; 31.05.2018
comment
Лучшее решение 2020 года, в том числе кроссбраузерное - person scravy; 20.07.2020

Вот лучшее решение, которое я нашел: 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.

person shshaw    schedule 07.08.2013
comment
Это не обязательно центрирует его в родительском элементе. Хороший хак, если вы просто хотите, чтобы он был в центре страницы. - person Joel Mellon; 24.01.2014
comment
Просто добавьте position: relative к родителю, и элемент будет центрирован внутри родителя. Я сделал гораздо большую статью об этой технике в Smashing Magazine, если вы хотите прочитать больше: coding.smashingmagazine.com/2013/08/09/ - person shshaw; 24.01.2014
comment
Иногда абсолютным является родитель или два (по сравнению с телом), а относительный может быть дедушкой или прадедушкой (по сравнению с родителем). Возможно, те, кто знает, когда и почему это происходит, могли бы лучше контролировать эту технику - я никогда не изучал эти проблемы, но я знаю, что переключение с абсолютного на относительное само по себе не является решением, чтобы заставить эту работу работать. Я прочитал немного вашей статьи, и похоже, что абсолютный и относительный предки восходят к первому абсолютному или относительному предку, это правильно? - person Joel Mellon; 24.01.2014
comment
Я немного медленный. Я только что перечитал ваш комментарий выше. Я не заметил, что вы сказали добавить его в parent — понял. Большое спасибо! - person Joel Mellon; 24.01.2014
comment
Ага, вот оно! Элементы position: absolute всегда позиционируются на основе ближайшего родителя position: relative. - person shshaw; 25.01.2014
comment
Определенно лучший способ. - person APAD1; 06.08.2014
comment
Может ли кто-нибудь рассказать нам о предостережениях для ie8/9 или дать ссылку на документ, описывающий их? - person commonpike; 18.03.2016
comment
@commonpike Единственная проблема с IE8/9 заключается в том, что вы используете display: table для содержимого переменной высоты. В противном случае этот метод должен работать должным образом. Прочтите заметку, чтобы получить более подробную информацию. Вы также должны иметь возможность протестировать полное представление в IE8/9, чтобы увидеть, есть ли любые вопросы. - person shshaw; 18.03.2016
comment
2017. Этот подход не работает в IE10+ (без вертикального или горизонтального выравнивания) или Firefox 52 (только горизонтальное выравнивание), эмуляция IE9 не поддерживает jsfiddle, поэтому не удалось протестировать более ранние версии, если IE. Работает в Chrome 57 (как по вертикали, так и по горизонтали). - person Neolisk; 18.04.2017
comment
@Neolisk Этот метод надежно работает с IE8/9, если вы объявляете высоту ( height: 50%, height: 100px, height: 0; padding-top: 50% ) или высота автоматически известна браузеру (элементы img, svg и canvas и т. д.). Хак display: table не работает в кроссбраузерном режиме, но установка высоты должна работать без проблем. Ознакомьтесь с полной рецензией для получения дополнительной информации: codepen.io/shshaw/pen/gEiDt. - person shshaw; 18.04.2017
comment
@shshaw: Да, ваш последний пример работает во всех браузерах, но он довольно сложен. У jsfiddle в ответе есть проблемы, не могли бы вы обновить его, чтобы он работал во всех браузерах? Пожалуйста, делайте это как можно проще. Для демонстрации достаточно одного пустого div, заполненного сплошным цветом. - person Neolisk; 18.04.2017
comment
@Neolisk Оригинальный Fiddle был основан на точных потребностях оригинального спрашивающего. Единственные необходимые части для центрирования — это position: absolute; top: 0; right: 0; bottom: 0; left: 0; margin: auto; и height. Я обновил FIddle, сделав его более простым: jsfiddle.net/yWnZ2/445 - person shshaw; 18.04.2017

Редактировать: это 2020 год, вместо этого я бы использовал flex box.

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

HTML

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

CSS

.centered {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
person Gal Margalit    schedule 19.07.2015
comment
не будет работать для IE 8 и более старых версий ie. Так как свойство преобразования поддерживается (с префиксом -ms-) начиная с версии 9.0 и выше. (т.е. 10 больше не нужен префикс). - person DevWL; 01.09.2015
comment
Правда мне плевать на IE8 - person Gal Margalit; 01.09.2015
comment
И автор отметил html5 для своего вопроса ☺ - person Gal Margalit; 06.09.2015

Я знаю, что вопрос из 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; 
}
person Paula Fleck    schedule 17.09.2014

Если вы знаете высоту элемента 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/

person tuff    schedule 13.09.2012
comment
margin-top нельзя установить в % относительно высоты элемента, поэтому вы получите исправление, зависящее от размеров - person Oleg; 14.09.2012
comment
Что... именно то, что я сказал в своем ответе? Если вы знаете высоту div, которую хотите центрировать. И я не говорил, что ОП должен использовать% в margin-top. - person tuff; 14.09.2012
comment
Я не согласен с решением, поскольку оно привязывает вас к заранее определенной высоте элемента, но ваш комментарий имеет смысл. Вы можете отразить это в ответе - person Oleg; 14.09.2012
comment
Хорошо, я выделил жирным шрифтом ту часть, которую вы упустили из виду, надеюсь, теперь это понятнее. - person tuff; 14.09.2012
comment
@o.v.: Если элемент не имеет фиксированной высоты, вы можете просто использовать JS, чтобы получить вычисленную высоту, а затем соответствующим образом установить отрицательное верхнее поле. На мой взгляд, это все еще лучший метод вертикального центрирования. - person daGUY; 14.09.2012
comment
+1 — у нас уже есть div, который мы используем в качестве ограничительной рамки для img с заданной высотой - person Izkata; 04.06.2013

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

.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-свойства table и table-cell с вертикальным выравниванием и выравниванием текста по центру:

/*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/

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

person DevWL    schedule 01.09.2015

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

Тем не менее, есть много способов сделать это в зависимости от ситуации.

Вот некоторые из них:

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

Вы также можете поискать в Google «вертикальное центрирование css».

person hasu    schedule 13.09.2012

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

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

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

person user3668456    schedule 07.04.2017

Использование флексбокса:

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 */
}

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

person DanielBlazquez    schedule 09.08.2016

Я думаю, вы можете исправить это с помощью Flexbox.

.black {
  height : 200px;
  width : 200px;
  background-color : teal;
  border: 5px solid rgb(0, 53, 53);
  /* This is the important part */
  display : flex;
  justify-content: center;
  align-items: center;
}

.message {
  background-color :  rgb(119, 128, 0);
  border: 5px solid rgb(0, 53, 53);
  height : 50%;
  width : 50%;
  padding : 5px;
}
<div class="black">
    <div class="message">
        This is a popup message.
    </div>
</div>

person Younes Belaabda    schedule 06.10.2020

person    schedule
comment
Не могли бы вы поделиться с нами, каково это решение? Кроме того, я вижу ваше всплывающее сообщение внизу не по центру - person Alex; 21.09.2017
comment
Я что-то пропустил, но теперь он усовершенствован, чтобы держать div посередине по вертикали. вы можете проверить сейчас. - person Seetpal singh; 25.09.2017