Вертикальное выравнивание div (без таблиц)

Я могу выровнять div по горизонтали, и все содержимое выглядит красиво. Требуется вертикальное выравнивание div, не содержащего таблиц. Я попытался установить позиции полей на некоторые отрицательные значения внутри #container, но это сработало. Я знаю, что CSS еще не поддерживает это?

Вот моя разметка:

body
{
    background: #777; /* gray */
    text-align: center;
}

#container 
{ 
    margin: 0 auto;
    width: 968px;
    text-align: left;
}

#toptab
{
    background: #f77; /* red */
    height: 14px;
    width: 968px;
}

#middletab
{
    background: #7f7; /* green */
    width: 968px;
}

#data
{
    width: 948px; /* 948 for the box plus we need 20 more px to handle the padding */
    padding-left: 10px; 
    padding-right 10px;
}

#bottomtab
{
    background: #77f; /* blue */
    height: 14px;
    width: 968px;
}
<div id="container">
    <div id="toptab"></div>
    <div id="middletab">
        <div id="data">
            The quick brown fox jumped over the big red bear.
            The quick brown fox jumped over the big red bear.
            The quick brown fox jumped over the big red bear.
            The quick brown fox jumped over the big red bear.
            The quick brown fox jumped over the big red bear.
            The quick brown fox jumped over the big red bear.
            The quick brown fox jumped over the big red bear.
            The quick brown fox jumped over the big red bear.
            The quick brown fox jumped over the big red bear.
            The quick brown fox jumped over the big red bear.
            The quick brown fox jumped over the big red bear.
            The quick brown fox jumped over the big red bear.
        </div>
    </div>
    <div id="bottomtab"></div>
</div>

Запустите приведенный выше фрагмент и нажмите «Полная страница», чтобы увидеть, как он выглядит в настоящее время. В принципе, он отлично смотрится по горизонтали, но теперь мне нужно, чтобы он также находился по центру по вертикали на странице.

Элемент, который я хочу выровнять по вертикали, - это div #container. Эффект заставит весь div и все под div не только выровняться по горизонтали, но и по вертикали. Я знаю, что это возможно, и я знаю, что Энди Бадд опубликовал такое решение, но, похоже, оно не работает для меня.


person JonH    schedule 15.12.2009    source источник
comment
Вы имеете в виду вертикальное распределение / выравнивание или просто центрирование того, что отображается на странице по вертикали?   -  person Eric Wendelin    schedule 15.12.2009
comment
@Eric: конечный результат - круглая рамка с содержимым, которая должна быть посередине страницы. На данный момент, как вы видите, контент центрирован, но центрирован только вверху. Мне нужно центрировать его прямо посередине страницы.   -  person JonH    schedule 15.12.2009
comment
Насколько я знаю, вам нужно немного написать javascript, если вам не нужна страница с фиксированной высотой, в чем я сомневаюсь.   -  person Eric Wendelin    schedule 15.12.2009


Ответы (8)


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

Использование таблицы вполне возможно, но вы заметили, что это невозможно.

Если можно использовать javascript, мы можем легко исправить это за вас. Плагин jQuery уже существует для вертикального выравнивания контейнера.

(function ($) {
    // VERTICALLY ALIGN FUNCTION
    $.fn.vAlign = function() {
        return this.each(function(i){
            var ah = $(this).height();
            var ph = $(this).parent().height();
            var mh = (ph - ah) / 2;
            $(this).css('margin-top', mh);
        });
    };
})(jQuery);

И вы должны вертикально выровнять блок DIV следующим образом:

$('#example').vAlign();

Взято из плагина простого вертикального выравнивания.

person Corey Ballou    schedule 15.12.2009
comment
@cballou Я никак не могу определить высоту контейнера, она может варьироваться :(. Но если я предполагаю, что максимум будет, скажем, 500 пикселей. Используя предоставленную разметку, что я могу сделать? - person JonH; 15.12.2009
comment
Я пробовал это безуспешно #container {margin: 0 auto; ширина: 968 пикселей; выравнивание текста: слева; позиция: абсолютная; верх: 50%; осталось: 50%; высота: 484 пикселей; маржа сверху: -9em; / * установлено отрицательное число 1/2 вашего роста * / margin-left: -15em; / * установить отрицательное число 1/2 вашей ширины * /} - person JonH; 15.12.2009
comment
@JonH: Если у него нет фиксированной высоты, вы не сможете сделать его вертикально по центру без javascript. - person Tatu Ulmanen; 15.12.2009
comment
@cballou +1 за это! Мой единственный вопрос: я мало работал с JQuery. Я понимаю, что функция должна находиться в теге заголовка, и могу ли я просто включить jquery.js? - person JonH; 15.12.2009
comment
Разве нельзя было реализовать вертикальный выравниватель с помощью ванильного Javascript без необходимости использования jQuery? Или это просто упрощает использование jQuery? - person JAB; 31.05.2012
comment
это не всегда сработает, поскольку порой до рендеринга родительский элемент будет равен нулю - person mmm; 25.08.2016

Взгляните на Вертикальное центрирование с помощью CSS или Вертикально центрируйте контент с помощью CSS или Вертикальное центрирование CSS. Метод 3 первой ссылки аналогичен вертикальному центру CSS с использованием float и clear.

И, безусловно, неплохо проверить результат с помощью такой службы, как browsershots.org.


РЕДАКТИРОВАТЬ: я изменил ваш CSS и разметку для реализации метода 3:

css:

* {
  margin:0;
  padding:0;
}

html,
body {
  height: 100%;
}

body {
  text-align:center;
}

#floater {
  float: left;
  height:50%;
  margin-bottom: -100px;
}

#container
{
  clear:both;
  position: relative;
  margin: 0 auto;
  width:968px;
  text-align: left;
  height: 200px;
}

...

разметка:

<body>
<div id="floater"></div>
<div id="container">

...

Недостаток, который я вижу в этом методе, заключается в том, что с помощью CSS вы должны заранее знать высоту вашего контента, чтобы вы могли применить к плавающему положению отрицательный запас, равный половине этой высоты. В примере я выбрал 200px.

Посмотрите на это в действии.

person Gregory Pakosz    schedule 15.12.2009
comment
Мне не нужны статьи, которые я много читал. Кажется, я не могу заставить его работать с отрицательными значениями маржи. - person JonH; 15.12.2009
comment
Если themeforest когда-либо будет недоступен, этот ответ будет неадекватным. Не могли бы вы перенести инструкции в свой ответ и отдать должное первоначальным авторам. Таким образом, людям не придется прыгать со страницы на страницу, чтобы взвесить ценность вашего ответа? - person Sampson; 15.12.2009
comment
@Jonathan ›хороший момент, хотя я не люблю копировать чужие вещи: / - person Gregory Pakosz; 15.12.2009
comment
как ни странно, я получил голосование @JohnH за ссылки, и пока я был занят реализацией одного из связанных методов, я получил голосование против - person Gregory Pakosz; 15.12.2009
comment
Не мной, Григорий !!! Я благодарю вас за ваше время и усилия .. Я хотел бы принять 2 ответа! - person JonH; 15.12.2009
comment
Это не так уж важно. Просто я сам не голосую против ответа, если в нем явно нет ничего плохого. Если я считаю, что это недостаточно хорошо, я просто не голосую. Удачи с вашим сайтом - person Gregory Pakosz; 15.12.2009
comment
Я согласен, мне всегда хотелось, чтобы у SO был раздел в профиле человека, чтобы показать вам, кто голосовал последними, будь то голоса за или против. Было бы полезно получить обратную связь при голосовании против. Например, заставьте пользователя оставить комментарий, если он / она голосует против. - person JonH; 15.12.2009
comment
и по иронии судьбы моей первой мыслью было предложить использовать jQuery: D - person Gregory Pakosz; 16.12.2009

Есть несколько способов сделать это, все с компромиссами.

  • Используйте position:absolute, фиксированную высоту и overflow:auto.
  • Используйте display:table, display:table-cell и vertical-align:middle
  • Использовать javascript

Думаю, вариант №2 очень хорош.

edit: Я не думаю, что вариант 2 будет работать в IE. Вы можете застрять в javascript, если хотите сохранить динамическую высоту.

person Peter Di Cecco    schedule 15.12.2009
comment
Компромисс кроссбраузерной совместимости: если быть точным, все семейство IE. - person Corey Ballou; 15.12.2009
comment
@cballou, я просто подумал об этом и редактировал свой пост, когда вы оставляли свой комментарий: P - person Peter Di Cecco; 15.12.2009

В чистом CSS это только возможно, если у div есть фиксированный height. Затем вы можете position это absolute и установить его top и left на 50%, а margin-top и margin-left на отрицательную половину его width и height соответственно.

Вот SSCCE, просто скопируйте'n'paste'n'run. Граница чисто презентационная, остальные стили обязательны.

<!doctype html>
<html lang="en">
    <head>
        <title>SO question 1909753</title>
    </head>
    <style>
        #content {
            position: absolute;
            width: 300px;
            height: 200px;
            top: 50%;
            left: 50%;
            margin-left: -150px; /* Negative half of width. */
            margin-top: -100px; /* Negative half of height. */
            border: 1px solid #000;
        }
    </style>
    <body>
        <div id="content">
            content
        </div>
    </body>
</html>

Если нет средств фиксированной высоты, тогда вам нужно понять Javascript и смириться с тем фактом, что клиент увидит, что div быстро перемещается в середину во время загрузки страницы, что может вызвать «wtf?» опыт.

person BalusC    schedule 15.12.2009

Создайте контейнер div со стилем display: table и используйте стиль vertical-align: top для внутренних элементов, которые display: inline-block

Рабочая демонстрация на http://jsfiddle.net/uzcrt/

person andy magoon    schedule 30.05.2012

Если высота вашего основного контейнера невелика, ваш единственный надежный выбор - использовать JavaScript ("надежный" здесь, конечно, спорный). В JavaScript вы должны сначала найти высоту контейнера, затем высоту окна и соответствующим образом отрегулировать верхнее смещение. Вот как это сделать в jQuery:

$(function() {
    $(window).resize(function() {
        var top = $(window).height() / 2 - $('#content').height() / 2;
        top = top < 0 ? 0 : top;
        $('#content').css('top', top);
    });
    $(window).resize();
});

И CSS, чтобы заставить его работать:

#content {
    position: absolute;
    /* Everything else is optional: */
    width: 960px;
    margin: 0 auto;
}

И HTML:

...
<body>
    <div id="#content">Content here</div>
</body>
</html>

Это все еще довольно просто и будет работать, если у пользователя включен JavaScript.

person Tatu Ulmanen    schedule 15.12.2009
comment
Моя единственная проблема с этой функцией заключается в том, что она будет правильно работать только в том случае, если элемент является прямым потомком тега BODY. Плагин, который я опубликовал, использует свой родительский контейнер для вычисления центрированного положения. - person Corey Ballou; 15.12.2009

Я думаю, что можно обойтись без display: table.

вот пример:

HTML:

<div class="notificationArea">
    something
</div>

CSS:

.notificationArea
{
    position: absolute;
    top: 50%;
    bottom: 50%;
    right: 50%;
    left: 50%
}
person Rasto    schedule 04.03.2011
comment
Что ты имеешь в виду? В вашем CSS есть display: table правило, и div все равно не центрируется по вертикали ... - person Marcel Korpel; 06.03.2011
comment
Демо почему-то показывало другой пример. Я заменил его настоящим кодом. - person Rasto; 07.03.2011

Класс CSS для выравнивания элемента по центру экрана:

.middle{
    position: absolute;
    top: 50%; /*50% from top*/
    left: 50%; /*50% from left*/ 

    /*remove 50% of element width and height to align the element center in the position*/
    transform: translateY(-50%) translateX(-50%); 
}

Теперь добавьте этот класс в элемент HTML.

person Gabriel Consalter    schedule 22.03.2017