Сверстать вот так
если вдруг, то тут три строчки и у каждой колонки в строчке фиксированная ширина и высота, то есть flex-grow колонкам не ставим.
Сегодня будем учится верстать в столбик. В строчку вроде как уже умеем.
В строчку обычно как? Например, вот так
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.1/css/all.min.css" />
</head>
<body>
<div class="row">
<div class="block">
тут собачка живет
<i class="fas fa-2x fa-dog"></i>
</div>
<div class="block">
<i class="fas fa-2x fa-cat"></i>
</div>
<div class="block">
<i class="fas fa-2x fa-kiwi-bird"></i>
</div>
</div>
<style>
.row {
display: flex;
}
.block {
border: 1px solid black;
margin: 0.25em;
padding: 0.5em;
}
</style>
</body>
</html>
и по умолчанию все зверики занимают ровно столько сколько им надо
если я хочу, чтобы каждый занимал какое-то специфическое пространство я стало быть добавляю свойство flex-grow: 1
<div class="row">
<div class="block" style="flex-grow: 1;">
тут собачка живет
<i class="fas fa-2x fa-dog"></i>
</div>
<div class="block" style="flex-grow: 1;">
<i class="fas fa-2x fa-cat"></i>
</div>
<div class="block" style="flex-grow: 1;">
<i class="fas fa-2x fa-kiwi-bird"></i>
</div>
</div>
в этом случае как ты помнишь идет равномерное распределение пустого пространства
то есть, если я хочу, чтобы равномерными были именно размеры, то я добавляю flex-basis: 0
<div class="row">
<div class="block" style="flex-basis: 0; flex-grow: 1;">
тут собачка живет
<i class="fas fa-2x fa-dog"></i>
</div>
<div class="block" style="flex-basis: 0; flex-grow: 1;">
<i class="fas fa-2x fa-cat"></i>
</div>
<div class="block" style="flex-basis: 0; flex-grow: 1;">
<i class="fas fa-2x fa-kiwi-bird"></i>
</div>
</div>
и все ровно встает:
А теперь посмотрим, как все это работает, когда я делаю верстку в столбик.
Чтобы сделать верстку в столбик надо добавить свойство flex-direction: column
, вот так
<style>
.block {
/* ... */
}
.column { /* переименовал в column, не забудь переименовать выше, где class="row" */
display: flex;
flex-direction: column; /* добавил */
}
</style>
и тут же все превращается в колонку
Попробую-ка я сделать, чтобы кошечка в два раза больше места занимала:
<div class="column">
<div class="block" style="flex-basis: 0; flex-grow: 1;">
тут собачка живет
<i class="fas fa-2x fa-dog"></i>
</div>
<div class="block" style="flex-basis: 0; flex-grow: 2;"> <!-- заменил тут на flex-grow: 2; -->
<i class="fas fa-2x fa-cat"></i>
</div>
<div class="block" style="flex-basis: 0; flex-grow: 1;">
<i class="fas fa-2x fa-kiwi-bird"></i>
</div>
</div>
проверяем:
Хм, шо за ерунда?
А дело в том, что у вертикальной верстки есть мини проблема, которая заключается в том, что у браузера нет по сути чёткого понятия высоты.
То есть 100% ширины — это всегда понятно сколько, от левого края до правого. А вот 100% высоты — это не понятно, как считать. Это от верха видимого куска страницы до низа видимого куска страницы, или до низа если проскроллить, или еще как? Неясно в общем.
Поэтому при вертикальной верстке всегда важно указывать высоту колонки. Например, я укажу что высота моей колонки 300px
<div class="column" style="height: 300px"> <!-- добавил height: 300px -->
<div class="block" style="flex-basis: 0; flex-grow: 1;">
тут собачка живет
<i class="fas fa-2x fa-dog"></i>
</div>
<div class="block" style="flex-basis: 0; flex-grow: 2;">
<i class="fas fa-2x fa-cat"></i>
</div>
<div class="block" style="flex-basis: 0; flex-grow: 1;">
<i class="fas fa-2x fa-kiwi-bird"></i>
</div>
</div>
о, и сразу все заработало
flex-basis: 0;
ведет себя точно так же как и в горизонтальной верстке, то есть без него будет попытка распределить пустое пространство:
тут не сильно разницу видно, но она есть.
На самом деле наличие резиновых блоков по вертикали не очень часто нужно. То есть сейчас у нас, и собачка и кошка и киви все находятся в резиновых блоках. Но резина весьма условная, так как высота родительского блока у нас фиксированная
Уберу-ка я у блоков flex-grow и flex-basis и добавлю цвет колонке
<div class="column" style="height:300px; background-color: rgb(167, 242, 255);">
<div class="block" style="">
тут собачка живет
<i class="fas fa-2x fa-dog"></i>
</div>
<div class="block" style="">
<i class="fas fa-2x fa-cat"></i>
</div>
<div class="block" style="">
<i class="fas fa-2x fa-kiwi-bird"></i>
</div>
</div>
получится так
и теперь воспользуюсь невероятной возможностью выравнивать содержимое внутри блока. Для этого есть свойство, которое именуется align-items
, для блока-колонки она определяет, как выравниваются блоки внутри по горизонтали.
По умолчанию оно имеет значение stretch (что переводится как растянуть)
.column {
align-items: stretch; /* добавил, прописал значение по умолчанию*/
display: flex;
flex-direction: column;
}
и соответственно меняя его я могу менять то, как будут выравниваться блоки по горизонтали внутри:
Например align-items: flex-start;
или align-items: center;
или в конец если хочу загнать align-items: flex-end;
но самая радость появляется что мы можем управлять положением блоков не только по горизонтали, но и по вертикали. Для этого используется свойство justify-content
. По умолчанию оно имеет значение flex-start, то есть выравнивать по верху блока
.column {
justify-content: flex-start; /* добавил */
align-items: flex-end;
display: flex;
flex-direction: column;
}
но я могу так же попросить его выравнивать по центру
.column {
justify-content: center; /* поменял на center */
align-items: flex-end;
display: flex;
flex-direction: column;
}
а если еще и align-items: center;
сделать:
можно и вниз опустить
.column {
justify-content: flex-end; /* поменял на flex-end */
align-items: center;
/* ... */
}
еще есть интересный режим который равномерно распределяет расстояние между блоками, почти как flex-grow только блоки занимают ровно столько места сколько им надо:
.column {
justify-content: space-between; /* поменял на space-between */
align-items: center;
/* ... */
}
есть еще такой:
.column {
justify-content: space-around; /* поменял на space-around */
align-items: center;
/* ... */
}
и такой:
.column {
justify-content: space-evenly; /* поменял на space-evenly */
align-items: center;
/* ... */
}
используя эти свойства можно быстро и красиво выровнять содержимое любого блока.
Естественно одна колонка — это не очень интересно, и намного интереснее объединять колонки в строчки. Используя уже знакомый нам горизонтальный флекс.
Допустим хочу я три колонки в ряд, сначала я просто скопирую блок с колонкой три раза:
<div class="column" style="height:300px; background-color: rgb(167, 242, 255);">
<!-- ... -->
</div>
<div class="column" style="height:300px; background-color: rgb(167, 242, 255);">
<!-- ... -->
</div>
<div class="column" style="height:300px; background-color: rgb(167, 242, 255);">
<!-- ... -->
</div>
он мне все три колонки положит в одну мега колонк (то есть каждая колонка окажется под следующей), потому что это стандартное поведение div блоков, и по сути я получу колонку в три раза выше.
Чтобы поставить колонки в строчку я оберну все в обыкновенный flex блок, вот так
<div style="display: flex;">
<div class="column" style="height:300px; background-color: rgb(167, 242, 255);">
<!-- ... -->
</div>
<div class="column" style="height:300px; background-color: rgb(167, 242, 255);">
<!-- ... -->
</div>
<div class="column" style="height:300px; background-color: rgb(167, 242, 255);">
<!-- ... -->
</div>
</div>
и ура, теперь три колонки в ряд:
каждой колонке я могу указать как размещать блоки в ней
<div style="display: flex;">
<div class="column" style="justify-content: flex-start; height:300px; background-color: rgb(167, 242, 255);">
<!-- ... -->
</div>
<div class="column" style="align-items: stretch; justify-content: space-evenly; height:300px; background-color: rgb(167, 242, 255);">
<!-- ... -->
</div>
<div class="column" style="align-items: flex-end; justify-content: flex-end; height:300px; background-color: rgb(167, 242, 255);">
<!-- ... -->
</div>
</div>
вот так получится
на большом экране они скорее всего займут не всю строчку
если ты хочешь, чтобы они растягивались на всю ширину, просто добавь свойство flex-grow: 1
каждой колонке. Я еще цвет каждой поменял тут чтобы лучше видно было
<div style="display: flex;">
<div class="column" style="flex-grow:1; justify-content: flex-start; height:300px; background-color: rgb(167, 242, 255);">
<!-- ... -->
</div>
<div class="column" style="flex-grow:1; align-items: stretch; justify-content: space-evenly; height:300px; background-color: rgb(126, 171, 255);">
<!-- ... -->
</div>
<div class="column" style="flex-grow:1; align-items: flex-end; justify-content: flex-end; height:300px; background-color: rgb(171, 147, 255);">
<!-- ... -->
</div>
</div>
колонки ведут себя так же как обыкновенные блоки. То есть я могу попросить вторую колонку стать в два раза толще других, если укажу ей flex-grow: 2
<div style="display: flex;">
<div class="column" style="...">
<!-- ... -->
</div>
<div class="column" style="flex-grow:2; align-items: stretch; justify-content: space-evenly; height:300px; background-color: rgb(126, 171, 255);">
<!-- ... -->
</div>
<div class="column" style="...">
<!-- ... -->
</div>
</div>
тут опять распределится именно пустое пространство, если хочешь чтобы было четко, то добавляешь flex-basis: 0
<div style="display: flex;">
<div class="column" style="flex-basis: 0; ...">
<!-- ... -->
</div>
<div class="column" style="flex-basis: 0; flex-grow:2; ...">
<!-- ... -->
</div>
<div class="column" style="flex-basis: 0; ...">
<!-- ... -->
</div>
</div>
хошь конкретные размеры, прописываешь в пикселях в свойство flex-basis, попутно убирая flex-grow:
<div style="display: flex;">
<div class="column" style="flex-basis: 100px; justify-content: flex-start; height:300px; background-color: rgb(167, 242, 255);">
<!-- ... -->
</div>
<div class="column" style="...">
<!-- ... -->
</div>
<div class="column" style="...">
<!-- ... -->
</div>
</div>
в общем все как обычно, прямо как в прошлой задачке. Ну все можно пилить задачку =)
Сверстать вот так
если вдруг, то тут три строчки и у каждой колонки в строчке фиксированная ширина и высота, то есть flex-grow колонкам не ставим.