Позиционирование в CSS и Flexbox — объяснение с примерами

0
656
views

Перевод статьи «How CSS Positioning and Flexbox Work – Explained with Examples».

Image by NickyPe from Pixabay

Если вам когда-либо приходилось использовать CSS, вы знаете, как тяжело располагать элементы. Но к концу этого руководства вы будете знать куда больше о позиционировании в CSS и о Flexbox, и сможете мастерски расположить элементы в своем любимом проекте.

Для начала давайте разберем основы.

CSS-свойство position

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

В CSS есть пять типов позиционирования:

  1. Статическое
  2. Относительное
  3. Абсолютное
  4. Фиксированное
  5. Липкое

Давайте разберем каждый тип.

Статическое позиционирование в CSS

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

Вот как выглядит код:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CSS Position and Flexbox</title>
    <link rel="stylesheet" href="./index.css">
</head>
<body>
    <div class="parent">Parent
        <div class="child-one">One</div>
        <div class="child-two">Two</div>
        <div class="child-three">Three</div>
    </div>
</body>
</html>
/* Static Positioning */
.parent {
    padding: 5px;
    position: static;
    background-color: #00AAFF;
    width: 40%;
  }

  .child-one {
    position: static;
    background-color: rgb(116, 255, 116);
  }
  
  .child-two {
    position: static;
    background-color: rgb(248, 117, 117);
  }
  
  .child-three {
    position: static;
    background-color: rgb(255, 116, 232);
  }

В этом примере у нас есть родительский элемент (parent), а затем по порядку идут элементы-потомки (child-one, child-two, child-three). Все они имеют статическое позиционирование, совпадающее с нормальным потоком страницы.

Относительное позиционирование в CSS

Относительное позиционирование работает почти так же, как статическое. Но все же не в точности так же.

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

Чтобы разобраться, давайте обратимся к примеру.

/* Relative Positioning */
.parent {
    padding: 5px;
    background-color: #00AAFF;
    width: 40%;
  }

  .child-one {
    position: relative;
    background-color: rgb(116, 255, 116);
  }
  
  .child-two {
    background-color: rgb(248, 117, 117);
  }
  
  .child-three {
    background-color: rgb(255, 116, 232);
  }

Если мы запустим наше приложение, мы не заметим никакой разницы в выводе. То есть, статическое и относительное позиционирование одинаковы, если не применять свойства top, bottom, left и right.

Теперь давайте попробуем добавить эти свойства.

/* Relative Positioning with Top, Bottom, Left and Right */
.parent {
    padding: 5px;
    background-color: #00AAFF;
    width: 40%;
  }

  .child-one {
    position: relative;
    top: 10px;
    background-color: rgb(116, 255, 116);
  }
  
  .child-two {
    background-color: rgb(248, 117, 117);
  }
  
  .child-three {
    background-color: rgb(255, 116, 232);
  }

Здесь мы используем относительное позиционирование и свойство top для child-one.

Это «выбрасывает» элемент child-one из нормального потока документа, и он смещается на 10px вниз относительно своего «нормального» места (т. е. того места, которое у него было бы без этого смещения).

Вы видите, что при сдвиге этот элемент перекрывает элемент child-two.

Если задать свойства left, right или bottom, поведение будет таким же, сменится только направление сдвига.

Основная причина, по которой элемент child-one накладывается на child-two, состоит в том, что child-one больше не является частью нормального потока документа, а элементы child-two и child-three остались в этом потоке.

Абсолютное позиционирование в CSS

Следующий способ расположения элементов — абсолютное позиционирование. Оно полностью удаляет элемент из потока документа. Если у элемента свойство position имеет значение absolute, все другие элементы будут игнорировать этот элемент.

Если не использовать свойства top, bottom, left или right, элемент останется на прежнем месте. При использовании этих свойств элемент сдвигается относительно первого позиционированного родительского элемента. Если позиционированных родительских элементов нет, элемент с абсолютным позиционированием будет привязываться к элементу body вашей страницы.

/* Absolute Positioning */
.parent {
    padding: 5px;
    background-color: #00AAFF;
    width: 40%;
    position: static;
  }

  .child-one {
    position: absolute;
    top: 0px;
    background-color: rgb(116, 255, 116);
  }
  
  .child-two {
    background-color: rgb(248, 117, 117);
  }
  
  .child-three {
    background-color: rgb(255, 116, 232);
  }

Здесь элемент child-one выпадает из нормального потока, потому что ему задано свойство top: 0px. Обратите внимание, что сам элемент позиционирован абсолютно, но его родительский элемент — статический. Поэтому child-one позиционируется относительно элемента body.

А что если установить абсолютное позиционирование для parent и указать top: 0px?

/* Absolute Positioning */
.parent {
    padding: 5px;
    background-color: #00AAFF;
    width: 40%;
    position: absolute;
    top: 0px;
  }

  .child-one {
    position: absolute;
    top: 0px;
    background-color: rgb(116, 255, 116);
  }
  
  .child-two {
    background-color: rgb(248, 117, 117);
  }
  
  .child-three {
    background-color: rgb(255, 116, 232);
  }

Вы видите, что child-one перекрывает parent, и оба они прижаты кверху всего документа. parent позиционировался относительно body, а child-one — относительно parent.

Есть и третий вариант использования. Мы можем установить для parent относительное позиционирование, и для child-one — абсолютное.

/* Absolute Positioning */
.parent {
    padding: 5px;
    background-color: #00AAFF;
    width: 40%;
    position: relative;
    top: 0px;
  }

  .child-one {
    position: absolute;
    top: 0px;
    background-color: rgb(116, 255, 116);
  }
  
  .child-two {
    background-color: rgb(248, 117, 117);
  }
  
  .child-three {
    background-color: rgb(255, 116, 232);
  }

Использование абсолютного позиционирования в связке с относительным — самый полезный способ. Вы видите, что child-one позиционирован абсолютно, но в привязке к родительскому элементу, а не ко всему документу.

Проще говоря, если вы зададите родительскому элементу относительное позиционирование, а потомку — абсолютное, родительский станет как бы контейнером для потомка.

Фиксированное позиционирование в CSS

Если при абсолютном позиционировании вы указываете положение элемента относительно родительского, то при фиксированном родительский элемент игнорируется.

Фиксированное позиционирование — это позиционирование относительно всего HTML-документа. Положение родительского элемента не учитывается, даже если родитель позиционирован.

Есть еще одна особенность: если задать элементу фиксированное позиционирование, он останется на своем месте даже при прокрутке страницы.

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

/* Fixed Positioning */
.parent {
    padding: 5px;
    background-color: #00AAFF;
    width: 40%;
    position: relative;
    top: 0px;
    height: 1000px;
  }

  .child-one {
    position: fixed;
    top: 0px;
    background-color: rgb(116, 255, 116);
  }
  
  .child-two {
    background-color: rgb(248, 117, 117);
  }
  
  .child-three {
    background-color: rgb(255, 116, 232);
  }

Этот пример показывает, что элемент-потомок совершенно оторван от родительского, несмотря на то, что для родительского установлено относительное позиционирование.

И если мы прокрутим страницу, все остальные элементы-потомки прокрутятся согласно потоку документа, но фиксированный останется на том же месте.

Липкое позиционирование в CSS

Липкое позиционирование — это комбинация относительного и фиксированного.

/* Sticky Positioning */
.parent {
    padding: 5px;
    background-color: #00AAFF;
    width: 40%;
    position: relative;
    top: 0px;
    height: 1000px;
  }

  .child-one {
    position: sticky;
    top: 0px;
    background-color: rgb(116, 255, 116);
  }
  
  .child-two {
    background-color: rgb(248, 117, 117);
  }
  
  .child-three {
    background-color: rgb(255, 116, 232);
  }

Если мы зададим элементу-потомку липкое позиционирование, его вид не изменится (как в случае с относительным позиционированием). Но когда мы начнем скроллить, «липкий» потомок приклеится к верху и его позиция зафиксируется.

Липкое позиционирование используется, главным образом, для создания панелей навигации.

Теперь, разобравшись с видами позиционирования, давайте сосредоточимся на Flexbox.

Как использовать Flexbox

(О выборе между Grid и Flexbox можно почитать в статье «Grid — для макетов, Flexbox — для компонентов», — прим. ред. Techrocks).

Допустим, у нас есть документ, в котором по порядку идут три одинаковых элемента-потомка какого-нибудь родительского блока. Они располагаются друг за другом вертикально.

Но что, если нам нужно расположить их в ряд?

Здесь нам на помощь приходит Flexbox. Этот функционал CSS позволяет располагать элементы с учетом строк и столбцов, а также задавать промежутки между ними (пространство вокруг них).

Для начала давайте создадим родительский блок div с тремя элементами-потомками внутри него.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CSS Position and Flexbox</title>
    <link rel="stylesheet" href="./index.css">
</head>
<body>
    <div class="parent">
        <div class="child-one"></div>
        <div class="child-two"></div>
        <div class="child-three"></div>
    </div>
</body>
</html>

CSS:

/* Flexbox container */
.parent {
    background-color: #00AAFF;
    width: 300px;
    height: 300px;
    display: flex;
  }

  .child-one {
    background-color: rgb(116, 255, 116);
    width: 300px;
    height: 300px;
  }
  
  .child-two {
    background-color: rgb(248, 117, 117);
    width: 300px;
    height: 300px;
  }
  
  .child-three {
    background-color: rgb(255, 116, 232);
    width: 300px;
    height: 300px;
  }

Обратите внимание, что для класса .parent установлено свойство display: flex. Благодаря этому наши элементы-потомки расположились в ряд. Это расположение, принятое во Flexbox по умолчанию.

Давайте посмотрим другие варианты расположений.

Как располагать элементы при помощи Flexbox

flex-direction

Свойство flex-direction служит для указания главной оси, по которой будут располагаться элементы. То есть, оно определяет, как элементы будут отображаться на экране: горизонтально или вертикально.

Свойству flex-direction назначают значение row, если элементы нужно расположить в ряд, слева направо (это значение по умолчанию):

Значение column позволяет расположить элементы в виде столбцов, т. е. вертикально:

Значение row-reverse работает так же, как row, но порядок элементов будет обратным. Первый элемент станет последним, а последний — первым. расположение элементов будет противоположным тому, что было бы при значении flex-direction: row:

Аналогично, значение column-reverse служит для расположения элементов вертикально, но в обратном порядке.

justify-content

Это свойство определяет выравнивание элементов вдоль горизонтальной оси контейнера.

Если задано значение center, элементы будут располагаться по центру контейнера.

При значении start — в начале страницы.

При значении end — в конце страницы.

Значение space-around позволяет распределить элементы по ширине flex-блока. Элементы будут разделены промежутками. Расстояния между каждой парой соседних элементов будут одинаковыми, а пустые пространства перед первым элементом и после последнего элемента будут равны половине пространства между парами элементов.

Вы видите, что пространства между child-one, child-two и child-three одинаковые, а пространства перед child-one и после child-three — меньше.

Значение space-between максимизирует пространство между элементами, прижимая первый и последний к началу и концу контейнера по главной оси.

Значение space-evenly дает эффекта, похожий на эффект от значения space-around, с той разницей, что пространство от краев контейнера до первого и последнего элементов будет таким же, как и пространство между элементами.

align-items

Свойство align-items аналогично свойству justify-content, но служит для выравнивания элементов по вертикали. Работает только с фиксированной высотой контейнера.

Значение center позволяет центрировать элементы по вертикали.

При значении flex-start элементы выравниваются по верхнему краю страницы.

При значении flex-end — выравниваются по нижнему краю.

Теперь вы знаете основы Flexbox.

Как выравнивать элементы по центру экрана

Свойства Flexbox можно использовать вместе. Например, если мы хотим расположить элементы по центру и по горизонтали, и по вертикали, мы можем задать и align-items: center, и justify-content: center.

verstka logo

Хочешь знать больше про веб?

Подпишись на наш телеграм-канал TechRocks WEB-разработка?

×

ОСТАВЬТЕ ОТВЕТ

Please enter your comment!
Please enter your name here