Как центрировать div по вертикали внутри абсолютно позиционированного родительского div

157

Я пытаюсь поместить синий контейнер посередине розового, но, похоже vertical-align: middle;, в этом случае не работает.

<div style="display: block; position: absolute; left: 50px; top: 50px;">
    <div style="text-align: left; position: absolute;height: 56px;vertical-align: middle;background-color: pink;">
        <div style="background-color: lightblue;">test</div>
    </div>
</div>

Результат:

введите описание изображения здесь

Ожидание:

введите описание изображения здесь

Пожалуйста, подскажите, как я могу этого добиться.

Jsfiddle

Владимира
источник
2
Есть ли причина, по которой вы используете position: absoluteвезде?
Vucko
то vertical-align: middle;работает с display: inline-blockили сервировки стола
ctf0
проверьте эту ссылку: vanseodesign.com/css/vertical-centering ;)
Хорди Кастилья
@Vucko да - это обязательное условие, поскольку это просто упрощенная версия очень сложной компоновки, но абсолютное положение в обоих верхних div является ключевым моментом.
Владимирс
@Vladimirs я могу думать только margin-top: calc((56px - 16px) / 2), где 56px - parent height, 16px - element height/font-size- JSFiddle
Vučko

Ответы:

348

Прежде всего обратите внимание, что vertical-alignэто применимо только к ячейкам таблицы и элементам встроенного уровня.

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

1. Использование transformиtop

.valign {
    position: relative;
    top: 50%;
    transform: translateY(-50%);
    /* vendor prefixes omitted due to brevity */
}
<div style="position: absolute; left: 50px; top: 50px;">
    <div style="text-align: left; position: absolute;height: 56px;background-color: pink;">
        <div class="valign" style="background-color: lightblue;">test</div>
    </div>
</div>

Ключевым моментом является то, что процентное значение on topотносится к heightсодержанию блока; В то время как процентное значение transforms относится к размеру самого поля (ограничивающего прямоугольника).

Если вы испытываете проблемы с отображением шрифта (размытый шрифт), исправьте это, добавив perspective(1px)в transformобъявление, чтобы оно стало:

transform: perspective(1px) translateY(-50%);

Стоит отметить, что CSS transform поддерживается в IE9 + .

2. Использование inline-block(псевдо) элементов

В этом методе у нас есть два родственных inline-blockэлемента, которые выровнены по вертикали посередине посредством vertical-align: middleобъявления.

Один из них имеет heightот 100%своего родителя , а другой наш искомый элемент которого мы хотели , чтобы выровнять его по центру.

.parent {
    text-align: left;
    position: absolute;
    height: 56px;
    background-color: pink;
    white-space: nowrap;
    font-size: 0; /* remove the gap between inline level elements */
}

.dummy-child { height: 100%; }

.valign {
    font-size: 16px; /* re-set the font-size */
}

.dummy-child, .valign {
    display: inline-block;
    vertical-align: middle;
}
<div style="position: absolute; left: 50px; top: 50px;">
    <div class="parent">
        <div class="dummy-child"></div>
        <div class="valign" style="background-color: lightblue;">test</div>
    </div>
</div>

Наконец, мы должны использовать один из доступных методов для устранения разрыва между элементами встроенного уровня .

Хашем Колами
источник
Спасибо за полезные советы. Это сработало для моего проекта. Хорошая работа.
Sedat Kumcu 01
Для первого метода valignэлемент должен бытьdisplay: block
Олег
transform: translateY(-50%);Никогда раньше такого не видел, но работает безупречно. Спасатель реальной жизни.
Бенни Боттема,
62

использовать это :

.Absolute-Center {
    margin: auto;
    position: absolute;
    top: 0; left: 0; bottom: 0; right: 0;
}

обратитесь по этой ссылке: https://www.smashingmagazine.com/2013/08/absolute-horizontal-vertical-centering-css/

Iển Trương
источник
1
Как это не главное решение? Так просто, и это работает!
Мейсон
23
Имейте в виду, что heightсвойство должно быть определено (в пикселях, em и т. Д.), Чтобы это работало.
Vaidas
Что, если у меня есть несколько div внутри родительского элемента? Разве все не будут размещены друг на друге?
psykid
это не сработает, если есть еще один ребенок на том же уровне с «абсолютным центром»
Паскут
20

Используйте flex blox в своем абсолютно позиционированном div, чтобы центрировать его содержимое.

См. Пример https://plnkr.co/edit/wJIX2NpbNhO34X68ZyoY?p=preview

.some-absolute-div {    
  display: -webkit-box;
  display: -webkit-flex;
  display: -moz-box;
  display: -moz-flex;
  display: -ms-flexbox;
  display: flex;

  -webkit-box-pack: center;
  -ms-flex-pack: center;
  -webkit-justify-content: center;
  -moz-justify-content: center;
  justify-content: center;

  -webkit-box-align: center;
  -ms-flex-align: center;
  -webkit-align-items: center;
  -moz-align-items: center;
  align-items: center;
}
Крис Эльбрехт
источник
15

По центру по вертикали и горизонтали:

.parent{
  height: 100%;
  position: absolute;
  width: 100%;
  top: 0;
  left: 0;
}
.c{
  position: absolute;
  top: 50%;
  left: 0;
  right: 0;
  transform: translateY(-50%);
}
Хуан Анхель
источник
4

Вы можете использовать display:table/table-cell;

.a{
   position: absolute; 
  left: 50px; 
  top: 50px;
  display:table;
}
.b{
  text-align: left; 
  display:table-cell;
  height: 56px;
  vertical-align: middle;
  background-color: pink;
}
.c {
  background-color: lightblue;
}
<div class="a">
  <div  class="b">
    <div class="c" >test</div>
  </div>
</div>

G-Cyrillus
источник
Спасибо, ваш пример работает отлично, но .bотсутствует, position: absolute;что важно для отображения других вещей, которые я не включил, чтобы код был более понятным. Я знаю , что не имеет никакого смысла , имеющую настольную ячейки с абсолютным позиционированием , но может быть , есть другой подход , который позволит сохранить position: absolute;в обоих .aи .bклассах?
Владимирс
если a является абсолютной позицией, а b (дочерний элемент), определяющим его размер, b сам находится в абсолютной позиции по отношению к остальному содержимому. если не предполагается, что он останется без размера, я не понимаю цель абсолютного внутри абсолютного?
G-Cyrillus
2

Вот простой способ использования объекта Top.

например: Если абсолютный размер элемента составляет 60 пикселей.

.absolute-element { 
    position:absolute; 
    height:60px; 
    top: calc(50% - 60px);
}
Сайнул Абид
источник
2
Использование calcполезно, хотя это должно быть top: calc(50% - 30px)для фактического центрирования.
brainbag
2

Дополнительное простое решение

HTML:

<div id="d1">
    <div id="d2">
        Text
    </div>
</div>

CSS:

#d1{
    position:absolute;
    top:100px;left:100px;
}

#d2{
    border:1px solid black;
    height:50px; width:50px;
    display:table-cell;
    vertical-align:middle;
    text-align:center;  
}
Hicham
источник
1

Вы можете сделать это, используя display:table;родительский div и display: table-cell; vertical-align: middle;дочерний div

<div style="display:table;">
      <div style="text-align: left;  height: 56px;  background-color: pink; display: table-cell; vertical-align: middle;">
          <div style="background-color: lightblue; ">test</div>
      </div>
  </div>

Ариндам Саркар
источник
3
возможно, ваш ответ хорош, но вы можете значительно улучшить его, добавив некоторое описание того, что делает ваш код ...
DaFois
-1

Только для вертикального центра

    <div style="text-align: left; position: relative;height: 56px;background-color: pink;">
        <div style="background-color: lightblue;position:absolute;top:50%;    transform: translateY(-50%);">test</div>
    </div>

Мне всегда это нравится, это очень короткий и простой код для центрирования как по горизонтали, так и по вертикали

.center{
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}
<div class="center">Hello Centered World!</div>

Каран Гоял
источник
Этот ответ уже был дан в принятом ответе.
TylerH
Это означает, что я не могу добавить сюда ничего нового @TaylerH
Каран
Каждый день вам задают множество других вопросов в html или css, на которые вы можете попытаться ответить. Вы должны публиковать ответ только в том случае, если вы можете добавить что-то новое к существующим ответам. Повторение содержания никому не помогает.
TylerH