Как вертикально центрировать контент с переменной высотой в div?

Каков наилучший способ вертикального центрирования содержимого div, когда высота содержимого является переменной. В моем конкретном случае высота контейнера div фиксирована, но было бы здорово, если бы существовало решение, которое работало бы и в тех случаях, когда контейнер также имеет переменную высоту. Кроме того, мне бы понравилось решение без или с очень небольшим использованием CSS-хаков и / или несемантической разметки.

Как вертикально центрировать контент с переменной высотой в div?

метод в этой статье разваливается в Safari (4.0.5): S

user349440 25.05.2010 03:38

@ ripper234 Не совсем так, поскольку этот вопрос касается div переменной высоты

Rauli Rajande 29.09.2013 04:01

Также этот вопрос был задан первым.

Gui Imamura 02.05.2014 23:42

Возможный дубликат Как вертикально центрировать div для всех браузеров?

sandyJoshi 12.12.2017 09:10
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Введение в CSS
Введение в CSS
CSS является неотъемлемой частью трех основных составляющих front-end веб-разработки.
Как выровнять Div по центру?
Как выровнять Div по центру?
Чтобы выровнять элемент <div>по горизонтали и вертикали с помощью CSS, можно использовать комбинацию свойств и значений CSS. Вот несколько методов,...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
CSS: FlexBox
CSS: FlexBox
Ранее разработчики использовали макеты с помощью Position и Float. После появления flexbox сценарий полностью изменился.
163
4
155 177
9
Перейти к ответу Данный вопрос помечен как решенный

Ответы 9

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

Для лучшего объяснения метода вы можете посмотреть статья, которую я адаптировал из, но в основном он включает добавление дополнительного элемента и применение различных стилей в IE и браузерах, поддерживающих position:table\table-cell, для элементов, не являющихся таблицами.

<div class = "valign-outer">
    <div class = "valign-middle">
        <div class = "valign-inner">
            Excuse me. What did you sleep in your clothes again last night. Really. You're gonna be in the car with her. Hey, not too early I sleep in on Saturday. Oh, McFly, your shoe's untied. Don't be so gullible, McFly. You got the place fixed up nice, McFly. I have you're car towed all the way to your house and all you've got for me is light beer. What are you looking at, butthead. Say hi to your mom for me.
        </div>
    </div>
</div>

<style>
    /* Non-structural styling */
    .valign-outer { height: 400px; border: 1px solid red; }
    .valign-inner { border: 1px solid blue; }
</style>

<!--[if lte IE 7]>
<style>
    /* For IE7 and earlier */
    .valign-outer { position: relative; overflow: hidden; }
    .valign-middle { position: absolute; top: 50%; }
    .valign-inner { position: relative; top: -50% }
</style>
<![endif]-->
<!--[if gt IE 7]> -->
<style>
    /* For other browsers */
    .valign-outer { position: static; display: table; overflow: hidden; }
    .valign-middle { position: static; display: table-cell; vertical-align: middle; width: 100%; }
</style>

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

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

Обновлять: Мы начинаем улучшать поддержку CSS3 браузерами, предлагая гибкий блок и преобразования в качестве альтернативных методов для получения вертикального центрирования (среди других эффектов). См. этот другой вопрос для получения дополнительной информации о современных методах, но имейте в виду, что поддержка CSS3 браузерами по-прежнему отрывочна.

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

jessegavin 12.09.2008 19:39

Возможно, вы можете опубликовать код, который вы используете, который не работает?

Chris Marasti-Georg 12.09.2008 19:40

Это все еще лучшее решение этой проблемы?

ripper234 03.01.2012 12:59

Эта статья, похоже, не работает в Chrome 23, Firefox 16 и IE 9. Этот ответ кажется лучшим решением.

Fernando Correia 19.11.2012 01:24

Нет, эта статья все еще работает в последних версиях Chrome и Firefox по состоянию на 24 февраля 2013 г.

OMA 24.02.2013 17:16

@KatieK, я не люблю копировать код прямо из рукописей других людей, и если я каким-то образом не добавлю ценности, я обычно этого не делаю. Однако этот пост определенно был готов к обновлению, поэтому я добавил код. Спасибо, что снова обратили на это мое внимание!

Prestaul 24.07.2013 20:11

Похоже, это лучшее решение, которое я нашел для этой проблемы, если ваш браузер поддерживает псевдоэлемент ::before: CSS-уловки: центрирование в неизвестном.

Он не требует дополнительной разметки и работает очень хорошо. Я не мог использовать метод display: table, потому что элементы table не подчиняются свойству max-height.

.block {
  height: 300px;
  text-align: center;
  background: #c0c0c0;
  border: #a0a0a0 solid 1px;
  margin: 20px;
}

.block::before {
  content: '';
  display: inline-block;
  height: 100%; 
  vertical-align: middle;
  margin-right: -0.25em; /* Adjusts for spacing */

  /* For visualization 
  background: #808080; width: 5px;
  */
}

.centered {
  display: inline-block;
  vertical-align: middle;
  width: 300px;
  padding: 10px 15px;
  border: #a0a0a0 solid 1px;
  background: #f5f5f5;
}
<div class = "block">
    <div class = "centered">
        <h1>Some text</h1>
        <p>But he stole up to us again, and suddenly clapping his hand on my
           shoulder, said&mdash;"Did ye see anything looking like men going
           towards that ship a while ago?"</p>
    </div>
</div>

Теперь -это- решение -BRILLIANT-. Большое спасибо за размещение этого!

Troy Alford 25.10.2012 23:42

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

KatieK 23.07.2013 23:30

+1, решение действительно гениальное! Кстати, вы можете добавить .block { white-space: nowrap; font-size: 0; line-height: 0; } и оставить отрицательное правое поле на псевдоэлементе, вам просто нужно сбросить fs и lh на .centered ... таким образом вы гарантируете, что элемент будет правильно позиционирован, даже если он шире, чем область просмотра (и не нужно использовать imo немного грязный отрицательный запас).

Simon 16.08.2013 14:26

@jessegavin - по вашему мнению ... как следующий подход соотносится с изложенным вами подходом: stackoverflow.com/questions/396145/…

pulkitsinghal 21.08.2013 00:37

Это решение не поддерживает IE6. И поэтому НАМНОГО проще. Так что это немного похоже на сравнение яблок с апельсинами.

jessegavin 21.08.2013 00:52

Работает как шарм. Спасибо, что разместили это решение!

MikeTedeschi 06.09.2013 00:15

В моем случае .block - это position:absolute, что вызывает проблемы с Fire Fox и IE8. Однако, похоже, это можно исправить, удалив margin-right из .block:before и установив .block { letter-spacing: -0.25em }.center { letter-spacing: normal }. Спасибо, @Fadi!

gyo 26.09.2013 23:09

Это нормально для IE12, Chrome и Firefox. Но в стандартном браузере Android он отображается некорректно ...

Emaborsa 18.01.2014 02:59

Кроме того, это не работает, когда внешний контейнер .block имеет минимальную высоту вместо высоты.

Lincoln B 30.07.2014 20:04

Вы красотка. Я искал это решение годами

Adam Moore 24.09.2014 18:49

Это работает даже с переменной высотой контейнера, это великолепно! Спасибо!

Pluc 18.08.2015 18:05

Используя дочерний селектор, я взял Невероятный ответ Фади выше и свел его к одному правилу CSS, которое я могу применить. Теперь все, что мне нужно сделать, это добавить имя класса contentCentered к элементам, которые я хочу центрировать:

.contentCentered {
  text-align: center;
}

.contentCentered::before {
  content: '';
  display: inline-block;
  height: 100%; 
  vertical-align: middle;
  margin-right: -.25em; /* Adjusts for spacing */
}

.contentCentered > * {
  display: inline-block;
  vertical-align: middle;
}
<div class = "contentCentered">
  <div>
    <h1>Some text</h1>
    <p>But he stole up to us again, and suddenly clapping his hand on my
      shoulder, said&mdash;"Did ye see anything looking like men going
      towards that ship a while ago?"</p>
  </div>
</div>

Разветвленный CodePen: http://codepen.io/dougli/pen/Eeysg

Круто. Спасибо, что поделился. Одно предупреждение заключается в том, что селектор * будет работать хуже, чем принятый ответ. Возможно, это не проблема, но стоит отметить. stevesouders.com/blog/2009/06/18/simplifying-css-selectors

jessegavin 07.12.2013 02:12

Спасибо. Да, это, вероятно, будет работать хуже, но в настоящее время правила CSS, вероятно, не сильно влияют на вещи. Мы, вероятно, сможем улучшить это, выбрав вместо этого > div. calendar.perfplanet.com/2011/…

dougli 14.12.2013 02:40

Просто и здорово. У меня отлично работает.

Lovro 06.01.2018 17:46

Это отличное решение для div с динамической (процентной) высотой.

CSS

.vertical_placer{
  background:red;
  position:absolute; 
  height:43%; 
  width:100%;
  display: table;
}

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

.inner_placer svg{
  position:relative;
  color:#fff;
  background:blue;
  width:30%;
  min-height:20px;
  max-height:60px;
  height:20%;
}

HTML

<div class = "footer">
    <div class = "vertical_placer">
        <div class = "inner_placer">
            <svg> some Text here</svg>
        </div>
    </div>
</div>  

Попробуйте сами.

Ответ принят как подходящий

Просто добавь

position: relative;
top: 50%;
transform: translateY(-50%);

во внутренний div.

Он перемещает верхнюю границу внутреннего div на половину высоты внешнего div (top: 50%;), а затем внутренний div вверх на половину его высоты (transform: translateY(-50%)). Это будет работать с position: absolute или relative.

Имейте в виду, что transform и translate имеют префиксы поставщиков, которые не включены для простоты.

Кодовое отверстие: http://codepen.io/anon/pen/ZYprdb

Просто интересно, почему это работает в Chrome и Firefox, но не в Safari. Затем я заметил, что большинство вещей, связанных с transform, имеют префикс -webkit-, и теперь он работает. Напоминаем: не забудьте также добавить префикс -webkit-.

miho 06.03.2015 22:20

Используйте такой инструмент, как github.com/postcss/autoprefixer, чтобы обработать префиксы за вас.

Jamie Chong 25.03.2015 22:45

Этот ответ должен быть вверху.

Jose Faeti 21.08.2015 14:51

У этого должно быть намного больше голосов! Кстати, с position: absolute тоже работает?

caw 03.02.2016 08:40

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

Daniel M. 25.03.2016 16:30

Используя 100% width и height для html и body, он также очень хорошо работает в Chrome без необходимости устанавливать внешний элемент. Просто использовать корпус как внешний элемент с позицией fixed! Большой!

evsar3 05.04.2016 09:00

У этого метода есть неприятный побочный эффект в Chrome - если ваша оболочка имеет нечетное количество пикселей, translate будет отображать все размыто, поскольку он пытается обрабатывать высоту 0,5 пикселей для всего.

Keith 27.06.2016 14:21

согласен с @JoseFaeti. Это должно быть наверху.

Janith Chinthana 21.09.2016 16:52

Проблема в том, что он предотвращает динамический рост div более чем на 50% от родительского / области просмотра: jsfiddle.net/9h838uaw

user2145184 08.12.2016 20:30

@BlackCetha Вот как это выглядит в Chrome 55.0.2883.75: i.imgur.com/fNp97jX.png - И это ближе к тому, что я хотел бы (используйте ширину до 100%): i.imgur.com/ynA6uJA.png

user2145184 08.12.2016 20:43

@ user2145184 На первом снимке экрана похоже, что полоса прокрутки взята из jsfiddle, а не из CSS. Не могли бы вы подробнее объяснить вашу проблему или опубликовать скриншоты, отображающие всю страницу?

BlackCetha 08.12.2016 20:45

@BlackCetha Я только что понял, что это решение для вертикального центрирования. Моя проблема связана с горизонтальным расположением, извините за это.

user2145184 08.12.2016 20:47

Буквально кричал "БОМБА МАТЬ УБИРАЙСЯ", когда я реализовал это

user1380540 21.12.2017 23:51

Если содержимое внутри div не является другим div, например svg, ему также потребуется display: block; в теме

Travis J 09.04.2019 06:48

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

dbx 06.03.2020 10:51

Вы можете использовать маржу автоматически. При использовании flex кажется, что div тоже центрирован по вертикали.

body,
html {
  height: 100%;
  margin: 0;
}
.site {
  height: 100%;
  display: flex;
}
.site .box {
  background: #0ff;
  max-width: 20vw;
  margin: auto;
}
<div class = "site">
  <div class = "box">
    <h1>blabla</h1>
    <p>blabla</p>
    <p>blablabla</p>
    <p>lbibdfvkdlvfdks</p>
  </div>
</div>

display: flex по-прежнему практически экспериментальная функция; ни один браузер еще не поддерживает это правильно

andreszs 06.10.2016 14:49

Лучший результат для меня на данный момент:

div для центрирования:

position: absolute;
top: 50%;
transform: translateY(-50%);
margin: 0 auto;
right: 0;
left: 0;

Работал как шарм

m4heshd 15.08.2018 00:42

Для меня лучший способ сделать это:

.container{
  position: relative;
}

.element{
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
}

Преимущество заключается в том, что высота не указывается явно.

вы можете использовать гибкий дисплей, например, код ниже:

.example{
  background-color:red;
  height:90px;
  width:90px;
  display:flex;
  align-items:center; /*for vertically center*/
  justify-content:center; /*for horizontally center*/
}
<div class = "example">
    <h6>Some text</h6>
</div>

Другие вопросы по теме