Центрирование элементов

Мы уже изучили достаточно материла, который поможет нам реализовать наш проект. Сейчас, я хочу поделиться с тобой несколькими практическими приемами, которые встречаются в практике. Также я помечу некоторые из них меткой "Устарело". Я делаю это по нескольким причинам.

Во-первых, эти решения использовались довольно давно, но они до сих пор работают, но есть более современные. Во-вторых, хоть они являются устаревшими, но их польза заключается в том, что они помогают настроить мышление на нужны лад для работы верстальщиком.

Центрирование блочных элементов по-горизонтали

Начнем мы с горизонтальное центрирование блока, которая является самой частой задачей. Для ее решения используют margin со значением auto, которое рассчитывает браузером автоматически.

Создадим один блок с контентом и попробуем отцентрировать.

<div class="parent">
    <div class="block">Дочерний блок</div>
</div>
body{
    margin: 0;
}

.parent{
    border: 2px solid black;
    margin-left: auto;
    margin-right: auto;    
}

Как ты уже знаешь, блочные элементы по-умолчанию растягиваются на всю ширину своего родителя, и поэтому ширина элемента .parent будет равняться ширине body, и, соответственно, браузер не может рассчитать значения для внешних отступов.

Зададим значение ширины, которое будет меньше чем у body. Например, 400px.

.parent{
    border: 2px solid #000;
    margin-left: auto;
    margin-right: auto;    
    width: 400px;
}

Браузер добавил 253,333px слева и справа, и давай попробуем понять, как он рассчитал эти значения.

Для этого нам пригодиться блочная модель. Я еще раз напишу ее.

Ш.Б = width + padding-right + padding-left + border-right + border-left + margin-right + margin-left

Но мы можем использовать ее не только для расчета размера бокса, но и для свойств width, padding, border и margin. Например, для margin формула изменится следующим образом:

margin = (Ш.Б - width - padding-right - padding-left - border-right - border-left) / 2

Из-за того, что мы используем значение auto, то margin-left и margin-right равны друг друге, и поэтому я делаю на два. Также из-за того, что у блока нет padding мы можем упростить формулу.

margin = (Ш.Б - width - border-right - border-left) / 2

Из всех значений мы не знаем ширину бокса, в которой находится элемент. Хм, как же быть? Тьфу, да все просто! Так как элемент .parent находится в body, то он и будет является боксом. Соответственно, мне нужно было посмотреть ширину body. Когда я делал скриншот экрана она равнялась 910,667px

margin = (910,667 - 400 - 0 - 0 - 2 - 2) / 2 = 253,333

Получилось точно такое же значение, как и в веб-инспекторе, и теперь мы точно знаем как же браузер обрабатывает значение auto для свойства margin.

Центрирование блока с position: absolute и position: fixed по горизонтали

Для изучения приема создадим следующий пример:

<div class="parent">
    <div class="block">Дочерний блок</div>
</div>
.parent{
    width: 500px;
    height: 200px;
    border: 2px solid #000;

    margin-left: auto;
    margin-right: auto;       
    position: relative;  
}

.block{
    width: 100px;
    height: 100px;
    background-color: tomato;

    position: absolute;
    top: 0;
    left: 50%;    
}

Из-за того, что координата элемента рассчитывается относительно левой стороны родителя, получается то, что браузер сдвигает на 50% левую сторону самого элемента, и поэтому блок находится чуть правее. Но нас это не устраивает!

Для исправления нужно сдвинуть элемент .block влево на половину его ширины. Например, мы можем сделать при помощи margin-left с отрицательным значением.

.block{
    width: 100px;
    height: 100px;
    background-color: tomato;

    position: absolute;
    top: 0;
    left: 50%;    
    margin-left: -50px;
}

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

Мы будем использовать свойство transform. Пока, что мы не будем подробно разбирать принцип работы свойства. Скажу только то, что мы будем использовать функцию translate, с помощью которой можно двигает элемент по осям X и Y.

Зададим в качестве первого аргумента значение -50%, а вторым — 0.

.block{
    width: 100px;
    height: 100px;
    background-color: tomato;

    position: absolute;
    top: 0;
    left: 50%;    
    transform: translate(-50%, 0);
}

Значением 50% рассчитывается от ширины элемента. Это то, что нужно!

Мы рассмотрели основные способы центрирования абсолютного блока, но что же с фиксированным позиционированием? Да, все хорошо! Все рассмотренные приемы отличное работают для элементов, которые позиционируются с помощью fixed.

Центрирование блока с position: absolute и position: fixed по вертикали

В предыдущем способе мы использовали функцию transform со значениями -50% и 0, но я не рассказал, почему во второй аргумент я передал такое число. Исправлю этот недочет и раскрою заветную тайну!

Да, на самом деле нет никакой тайны. Значение во втором аргументе отвечает за смещение по оси Y, а так как мы прижали блок к верху родителя, то и смещать его не нужно было.

Но, у меня есть один пример, в котором это как раз потребуется. Допустим, что центрирование нужно сделать сразу по осям X и Y, одновременно. Для этого нам нужно изменить в предыдущем примере значение для свойства top и для функции translate.

.block{
    width: 100px;
    height: 100px;
    background-color: tomato;

    position: absolute;
    top: 50%;
    left: 50%;    
    transform: translate(-50%, -50%);
}

Вот и все! Мы сверстали элемент так, что при любых его размерах, он всегда будет по центру.

Кроме приема с использованием transform мы также могли использовать отрицательный margin, но как и в случаи с шириной, нам нужно было бы знать высоту блока. А это еще более редкое явление, поэтому данную технику мы рассматривать не будем.

Центрирование строчно-блочных элементов по горизонтали

А теперь перейдем к строчно-блочным элементам. И начнем мы с позиционирования по горизонтали. Для решения мы будем использовать свойство text-align.

<body>
    <div class="parent">
        <div class="block">Дочерний блок</div>
    </div>
</body>
.parent{
    width: 1000px;
    height: 500px;
    border: 2px solid #000;    
    text-align: center;    
}

.block{
    display: inline-block;
    width: 100px;
    height: 100px;
    background: tomato;
}

Центрирование строчно-блочных элементов по вертикали

И наконец то мы с тобой дошли до вертикального центрирования. Существует несколько техник решения этой задачи. Рассмотрим каждую по порядку.

С псевдоэлементом :before

Первый метод основывается на свойстве vertical-align.

<body>
    <div class="parent">
        <div class="block">
            Дочерний блок
        </div>
    </div>
</body>
.parent{
    width: 400px;
    height: 500px;
    border: 2px solid #000;    
}

.parent:before{
    content: "";
    display: inline-block;
    vertical-align: middle;
    height: 100%;
}

.block{
    display: inline-block;
    vertical-align: middle;
}

Свойство vertical-align выравнивает элементы по вертикали. Но так, как у нас только один блок, то нам нужно добавить еще один. Для этого мы используем псевдоэлемент :before. Далее мы растягиваем его на всю высоту родителя, и теперь vertical-align: middle сможет отцентрировать соседний элемент по высоте псевдоэлемента, а тем самым и по высоте родительского блока.

Но давай теперь добавим больше текста, чтобы он занял как минимум 2 строки.

<body>
    <div class="parent">
        <div class="block">
            Дочерний блок с длинным очень длинным текстом так, чтобы было очень длинно
        </div>
    </div>
</body>

Как видишь текст спрыгнул под блок. Ты же помнишь, что между строчно-блочными элементами создается отступ? Вот именно из-за текст и спрыгнул, потому что блоку с ним просто не хватило места.

results matching ""

    No results matching ""