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

@ ripper234 Не совсем так, поскольку этот вопрос касается div переменной высоты
Также этот вопрос был задан первым.
Возможный дубликат Как вертикально центрировать div для всех браузеров?






Это то, что мне приходилось делать много раз, и последовательное решение по-прежнему требует, чтобы вы добавили небольшую несемантическую разметку и некоторые хаки, специфичные для браузера. Когда мы получим поддержку 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 браузерами по-прежнему отрывочна.
Да, я нашел эту статью сегодня и не смог заставить ее работать в моей конкретной ситуации. Возможно, мне нужно разобраться в этом подробнее.
Возможно, вы можете опубликовать код, который вы используете, который не работает?
Это все еще лучшее решение этой проблемы?
Эта статья, похоже, не работает в Chrome 23, Firefox 16 и IE 9. Этот ответ кажется лучшим решением.
Нет, эта статья все еще работает в последних версиях Chrome и Firefox по состоянию на 24 февраля 2013 г.
@KatieK, я не люблю копировать код прямо из рукописей других людей, и если я каким-то образом не добавлю ценности, я обычно этого не делаю. Однако этот пост определенно был готов к обновлению, поэтому я добавил код. Спасибо, что снова обратили на это мое внимание!
Похоже, это лучшее решение, которое я нашел для этой проблемы, если ваш браузер поддерживает псевдоэлемент ::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—"Did ye see anything looking like men going
towards that ship a while ago?"</p>
</div>
</div>Теперь -это- решение -BRILLIANT-. Большое спасибо за размещение этого!
Как и в случае с другим ответом, этот был бы намного лучше, если бы он описывал подход и включал код из ссылки.
+1, решение действительно гениальное! Кстати, вы можете добавить .block { white-space: nowrap; font-size: 0; line-height: 0; } и оставить отрицательное правое поле на псевдоэлементе, вам просто нужно сбросить fs и lh на .centered ... таким образом вы гарантируете, что элемент будет правильно позиционирован, даже если он шире, чем область просмотра (и не нужно использовать imo немного грязный отрицательный запас).
@jessegavin - по вашему мнению ... как следующий подход соотносится с изложенным вами подходом: stackoverflow.com/questions/396145/…
Это решение не поддерживает IE6. И поэтому НАМНОГО проще. Так что это немного похоже на сравнение яблок с апельсинами.
Работает как шарм. Спасибо, что разместили это решение!
В моем случае .block - это position:absolute, что вызывает проблемы с Fire Fox и IE8. Однако, похоже, это можно исправить, удалив margin-right из .block:before и установив .block { letter-spacing: -0.25em }.center { letter-spacing: normal }. Спасибо, @Fadi!
Это нормально для IE12, Chrome и Firefox. Но в стандартном браузере Android он отображается некорректно ...
Кроме того, это не работает, когда внешний контейнер .block имеет минимальную высоту вместо высоты.
Вы красотка. Я искал это решение годами
Это работает даже с переменной высотой контейнера, это великолепно! Спасибо!
Используя дочерний селектор, я взял Невероятный ответ Фади выше и свел его к одному правилу 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—"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
Спасибо. Да, это, вероятно, будет работать хуже, но в настоящее время правила CSS, вероятно, не сильно влияют на вещи. Мы, вероятно, сможем улучшить это, выбрав вместо этого > div. calendar.perfplanet.com/2011/…
Просто и здорово. У меня отлично работает.
Это отличное решение для 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-.
Используйте такой инструмент, как github.com/postcss/autoprefixer, чтобы обработать префиксы за вас.
Этот ответ должен быть вверху.
У этого должно быть намного больше голосов! Кстати, с position: absolute тоже работает?
Мне нравится этот метод, но я не думаю, что он работает с несколькими «внутренними» div разной высоты, кажется, что в качестве эталона используется самый высокий div, более короткие не выровнены должным образом.
Используя 100% width и height для html и body, он также очень хорошо работает в Chrome без необходимости устанавливать внешний элемент. Просто использовать корпус как внешний элемент с позицией fixed! Большой!
У этого метода есть неприятный побочный эффект в Chrome - если ваша оболочка имеет нечетное количество пикселей, translate будет отображать все размыто, поскольку он пытается обрабатывать высоту 0,5 пикселей для всего.
согласен с @JoseFaeti. Это должно быть наверху.
Проблема в том, что он предотвращает динамический рост div более чем на 50% от родительского / области просмотра: jsfiddle.net/9h838uaw
@BlackCetha Вот как это выглядит в Chrome 55.0.2883.75: i.imgur.com/fNp97jX.png - И это ближе к тому, что я хотел бы (используйте ширину до 100%): i.imgur.com/ynA6uJA.png
@ user2145184 На первом снимке экрана похоже, что полоса прокрутки взята из jsfiddle, а не из CSS. Не могли бы вы подробнее объяснить вашу проблему или опубликовать скриншоты, отображающие всю страницу?
@BlackCetha Я только что понял, что это решение для вертикального центрирования. Моя проблема связана с горизонтальным расположением, извините за это.
Буквально кричал "БОМБА МАТЬ УБИРАЙСЯ", когда я реализовал это
Если содержимое внутри div не является другим div, например svg, ему также потребуется display: block; в теме
Проблема возникает, когда контент загружается динамически, а иногда внутренний больше, чем внешний
Вы можете использовать маржу автоматически. При использовании 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 по-прежнему практически экспериментальная функция; ни один браузер еще не поддерживает это правильно
Лучший результат для меня на данный момент:
div для центрирования:
position: absolute;
top: 50%;
transform: translateY(-50%);
margin: 0 auto;
right: 0;
left: 0;
Работал как шарм
Для меня лучший способ сделать это:
.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>
метод в этой статье разваливается в Safari (4.0.5): S