Как вертикально центрировать контент с переменной высотой внутри div? - PullRequest
152 голосов
/ 12 сентября 2008

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

alt text

Ответы [ 7 ]

157 голосов
/ 25 октября 2012

Это лучшее решение, которое я нашел для этой проблемы, если ваш браузер поддерживает псевдоэлемент ::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>
132 голосов
/ 27 декабря 2014

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

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

до внутреннего деления.

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

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

Codepen: http://codepen.io/anon/pen/ZYprdb

16 голосов
/ 12 сентября 2008

Это то, что мне нужно было сделать много раз, и последовательное решение все еще требует, чтобы вы добавили небольшую несемантическую разметку и некоторые специфичные для браузера хаки. Когда мы получим поддержку браузера для 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, предлагая как flex-box, так и transforms в качестве альтернативных методов для получения вертикального центрирования (среди прочих эффектов). См. этот другой вопрос для получения дополнительной информации о современных методах, но имейте в виду, что поддержка браузеров для CSS3 все еще схематична.

9 голосов
/ 07 декабря 2013

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

Forked CodePen: http://codepen.io/dougli/pen/Eeysg

4 голосов
/ 21 ноября 2016

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

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

position: absolute;
top: 50%;
transform: translateY(-50%);
margin: 0 auto;
right: 0;
left: 0;
2 голосов
/ 18 мая 2016

Вы можете использовать маржу авто. С 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>
0 голосов
/ 30 сентября 2014

Это мое замечательное решение для 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>  

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

...