Pull to refresh

Выравниваем блок по центру страницы

Reading time5 min
Views967K
Очень часто стоит задача выровнять блок по центру страницы / экрана, да ещё и так, чтобы без ява-скрипта, без задания жёстких размеров или отрицательных отступов, ещё чтобы и скроллбары работали у родителя, если блок превышает его размеры. В сети ходят достаточно много однообразных примеров как выровнять блок по центру экрана. Как правило большинство из них основаны на одних принципах.

Ниже представлены основные способы решения задачи, их плюсы и минусы. Чтобы понимать суть примеров, рекомендую уменьшить высоту / ширину окошка Result в примерах по указанным ссылкам.

Вариант 1. Отрицательный отступ.


Позиционируем блок атрибутами top и left на 50%, и заранее зная высоту и ширину блока, задаём отрицательный margin, который равен половине размера блока. Огромным минусом данного варианта является то, что нужно подсчитывать отрицательные отступы. Так же блок не совсем корректно ведёт себя в окружении скроллбаров — он попросту обрезается так как имеет отрицательные отступы.

Пример: jsfiddle.net/serdidg/pphzjh25.

<div class="parent">
    <div class="block">
        <img src="1450829233933958453855" alt="">
    </div>
</div>


.parent {
    width: 100%;
    height: 100%;
    position: absolute;
    top: 0;
    left: 0;
    overflow: auto;
}

.block {
    width: 250px;
    height: 250px;
    position: absolute;
    top: 50%;
    left: 50%;
    margin: -125px 0 0 -125px;
    
    img {
        max-width: 100%;
        height: auto;
        display: block;
        margin: 0 auto;
        border: none;
    }
}


Вариант 2. Автоматический отступ.


Менее распространённый, но схожий с первым. Для блока задаём ширину и высоту, позиционируем атрибутами top right bottom left на 0, и задаём margin auto. Плюсом данного варианта являются рабочие скроллбары у родителя, если у последнего задана 100% ширина и высота. Минусом данного способ является жёсткое задание размеров.

Пример: jsfiddle.net/serdidg/sg0xbw88.

<div class="parent">
    <div class="block">
        <img src="1450829233933958453855" alt="">
    </div>
</div>


.parent {
    width: 100%;
    height: 100%;
    position: absolute;
    top: 0;
    left: 0;
    overflow: auto;
}

.block {
    width: 250px;
    height: 250px;
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    margin: auto;
    
    img {
        max-width: 100%;
        height: auto;
        display: block;
        margin: 0 auto;
        border: none;
    }
}


Вариант 3. Таблица.


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

Пример: jsfiddle.net/serdidg/fk5nqh52.

<div class="parent">
    <div class="inner">
        <div class="block">
            <img src="1450829233933958453855" alt="">
        </div>
    </div>
</div>


.parent {
    width: 100%;
    height: 100%;
    display: table;
    position: absolute;
    top: 0;
    left: 0;
    
    .inner {
        display: table-cell;
        text-align: center;
        vertical-align: middle;
    }
}

.block {
    display: inline-block;
    
    img {
        display: block;
        border: none;
    }
}


Чтобы добавить скролл в данный пример, придётся добавить в конструкцию ещё один элемент.
Пример: jsfiddle.net/serdidg/xkb615mu.

Вариант 4. Псевдо-элемент.


Данный вариант лишён всех проблем, перечисленных у предыдущих способов, а так же решает первоначально поставленные задачи. Суть состоит в том, чтобы у родителя задать стили псевдо-элементу before, а именно 100% высоту, выравнивание по центру и модель строчного блока. Так же само и у блока ставится модель строчного блока, выравнивание по центру. Чтобы блок не «падал» под псевдо-элемент, когда размеры первого больше чем родителя, указываем родителю white-space: nowrap и font-size: 0, после чего у блока отменяем эти стили следующими — white-space: normal. В данном примере font-size: 0 нужен для того, чтобы убрать образовавшийся пробел между родителем и блоком в связи с форматированием кода. Пробел можно убрать и иными способами, но лучшим считается просто его не допускать.

Пример: jsfiddle.net/serdidg/nfqg9rza.
Примеры без нулевого font-size: jsfiddle.net/serdidg/gw5dq4pv, jsfiddle.net/serdidg/91784mfw.

<div class="parent">
    <div class="block">
        <img src="1450829233933958453855" alt="">
    </div>
</div>


.parent {
    width: 100%;
    height: 100%;
    position: absolute;
    top: 0;
    left: 0;
    overflow: auto;
    white-space: nowrap;
    text-align: center;
    font-size: 0;
    
    &::before {
        height: 100%;
        display: inline-block;
        vertical-align: middle;
        content: '';
    }
}

.block {
    display: inline-block;
    white-space: normal;
    vertical-align: middle;
    text-align: left;
    
    img {
        display: block;
        border: none;
    }
}


либо, если вам нужно, чтобы родитель занимал только высоту и ширину окна, а не всей страницы:

.parent {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    overflow: auto;
    white-space: nowrap;
    text-align: center;
    font-size: 0;
    
    &::before {
        height: 100%;
        display: inline-block;
        vertical-align: middle;
        content: '';
    }
}

.block {
    display: inline-block;
    white-space: normal;
    vertical-align: middle;
    text-align: left;
    
    img {
        display: block;
        border: none;
    }
}


Вариант 5. Flexbox.


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

Пример: jsfiddle.net/serdidg/zyzvsk9d.

<div class="parent">
    <div class="block">
        <img src="1450829233933958453855" alt="">
    </div>
</div>


.parent {
    width: 100%;
    height: 100%;
    position: fixed;
    top: 0;
    left: 0;
    display: flex;
    align-items: center;
    align-content: center;
    justify-content: center;
    overflow: auto;
}

.block {
    background: #60a839;
    
    img {
        display: block;
        border: none;
    }
}


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

Пример: jsfiddle.net/serdidg/2zqe1m3j.

.parent {
    width: 100%;
    height: 100%;
    position: fixed;
    top: 0;
    left: 0;
    display: flex;
    overflow: auto;   
}

.block {
    margin: auto;
    background: #60a839;
    
    img {
        display: block;
        border: none;
    }
}


Вариант 6. Transform.


Подходит в случае если мы ограничены структурой, и нет возможности манипулировать родительским элементом, а блок выровнять как-то нужно. На помощь придёт css функция translate(). При значение 50% абсолютное позиционирование расположит верхний левый угол блока точно по центру, затем отрицательное значение translate сдвинет блок относительно своих собственных размеров. Учтите, что могут всплыть негативные эффекты в виде размытых граней или начертания шрифта. Также подобный способ может привести к проблемах с вычислением положения блока с помощью java-script'а. Иногда для компенсации потери 50% ширины из-за использования css свойства left может помочь заданное у блока правило: margin-right: -50%;.

Пример. jsfiddle.net/serdidg/vjxxo7ua.

<div class="parent">
    <div class="block">
        <img src="1450829233933958453855" alt="">
    </div>
</div>


.parent {
    width: 100%;
    height: 100%;
    position: fixed;
    top: 0;
    left: 0;
    overflow: auto;   
}

.block {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    
    img {
        display: block;
    }
}


Вариант 7. Кнопка.


Пользователь azproduction предложил вариант, где блок обрамляется в тег button. Кнопка имеет свойство центрировать всё, что находится у неё внутри, а именно элементы строчной и блочно-строчной (inline-block) модели. На практике использовать не рекомендую.

Пример: jsfiddle.net/serdidg/0bn8wg38.

<button class="parent">
    <div class="block">
        <img src="1450829233933958453855" alt="">
    </div>
</button>


.parent {
    width: 100%;
    height: 100%;
    position: absolute;
    top: 0;
    left: 0;
    overflow: auto;
    background: none;
    border: none;
    outline: none;
    appearance: none;
}

.block {
    display: inline-block;
    
    img {
        display: block;
        border: none;
    }
}


Бонус


Используя идею 4-го варианта, можно задавать внешние отступы для блока, и при этом последний будет адекватно отображаться в окружении скроллбаров.
Пример: jsfiddle.net/serdidg/ugnp8ry7.

Так же можно выравнивать картинку по центру, и в случае если картинка больше родителя, масштабировать её по размеру родителя.
Пример: jsfiddle.net/serdidg/Lhpa1s70.
Пример с большой картинкой: jsfiddle.net/serdidg/tor2yudn.
Tags:
Hubs:
+33
Comments49

Articles

Change theme settings