В этом уроке я предлагаю вам еще больше попрактиковаться в умении работать с Flexbox и создать с его помощью игральные кости. В ходе урока мы будем использовать:
- псевдоэлементы
- псевдоклассы
- и конечно же, непосредственно Flexbox
В первую очередь напишем базовую разметку для самого кубика. В качестве основы мы будем использовать список <ul>
, поскольку имеем дело с группой однотипных элементов. Дадим ему класс dice
(дайс), а его элементам класс dice__point
. Также мы добавим контейнеру класс-модификатор dice_one
, чтобы через него задать свойства первого кубика:
<!-- Первый кубик -->
<ul class="dice dice_one">
<li class="dice__point"></li>
</ul>
Базовое оформление
Теперь зададим нашим кубикам базовое оформление. В первую очередь скинем маркеры списка. Далее,
- пропишем его внутренние поля
- размеры содержимого
- а также видимую границу
- закруглим углы
- и изменим алгоритм блочной модели на значение
border-box
/* Базовое оформление */
.dice {
list-style: none;
padding: 20px;
width: 200px;
height: 200px;
border: solid 5px #000;
border-radius: 20px;
box-sizing: border-box;
}

Основа для наших кубиков готова, переходим к его элементам. Все что я сделаю, это добавлю им небольшую временную обводку, чтобы вы лучше понимали, что у нас происходит:
.dice__point {
outline: solid 2px #aaa;
}
Сами же точки мы реализуем с помощью псевдоэлементов ::before
, чтобы они не становились гибкими. В дальнейшем вы и сами поймете, для чего нам это нужно. Для отображения псевдоэлементов необходимо задать их контент. В нашем случае он будет пустым:
.dice__point::before {
content: "";
}
Также мы должны изменить их тип отображения, поскольку изначально он строчный и не позволит нам задать размеры. Например, на inline-block
. После чего мы уже можем установить ширину и высоту элемента в 40px
. Далее, добавим черную заливку и закругление углов на 50%
, чтобы получить окружности:
.dice__point::before {
content: "";
display: inline-block;
width: 40px;
height: 40px;
background-color: #000;
border-radius: 50%;
}

Наши элементы готовы. Переходим к их расположению.
Flex-контейнер
В первую очередь, сделаем наши кубы flex-контейнерами. Для этого изменим их тип отображения на inline-flex
, чтобы все они располагались рядом друг с другом. Кроме этого, зададим им вертикальное выравнивание и внешние отступы в 5px
.
.dice {
list-style: none;
padding: 20px;
width: 200px;
height: 200px;
border: solid 5px #000;
border-radius: 20px;
box-sizing: border-box;
display: inline-flex;
vertical-align: top;
margin: 5px;
}

Первый кубик
Переходим к оформлению первого кубика. На самом деле он довольно прост.Все что нам необходимо сделать, это расположить нашу точку по центру контейнера. Для этого мы используем свойство justify-content
в значении center
, чтобы выравнять элемент по центру главной оси. А также, свойство align-items
в значении center
, чтобы выравнять его по поперечной оси.
/* Первый кубик */
.dice_one {
justify-content: center;
align-items: center;
}

На этом наш первый кубик готов, переходим ко второму.
Второй куб
Второй кубик содержит уже две точки, которые должны располагаться в двух противоположных углах по диагонали:
<!-- Второй кубик -->
<ul class="dice dice_two">
<li class="dice__point"></li>
<li class="dice__point"></li>
</ul>
В первую очередь, давайте распределим наши элементы по главной оси с прижатием к ее концам. Для этого мы используем свойство justify-content
в значении space-between
:
/* Второй кубик */
.dice_two {
justify-content: space-between;
}
Теперь мы должны обратиться к одному из элементов, например, первому, и прижать его к концу поперечной оси. Для этого мы используем псевдокласс nth-child
(эн ти эйч чайлд). И применим к нему свойство align-self
в значении flex-end
:
.dice_two .dice__point:nth-child(1) {
align-self: flex-end;
}

Третий кубик
Третий кубик содержит три точки, также расположенных по диагонали:
<!-- Третий кубик -->
<ul class="dice dice_three">
<li class="dice__point"></li>
<li class="dice__point"></li>
<li class="dice__point"></li>
</ul>
Начало оформления мы можем взять из предыдущего примера. Распределяем элементы по главной оси и прижимаем первый из них к концу поперечной:
/* Третий кубик */
.dice_three {
justify-content: space-between;
}
.dice_three .dice__point:nth-child(1) {
align-self: flex-end;
}
Точно также обратимся ко второму элементу, только применим к нему значение center
:
.dice_three .dice__point:nth-child(2) {
align-self: center;
}

Четвертый кубик
Добавим разметку для четвертого кубика с модификатором dice_four
:
<!-- Четвертый кубик -->
<ul class="dice dice_four">
<li class="dice__point"></li>
<li class="dice__point"></li>
<li class="dice__point"></li>
<li class="dice__point"></li>
</ul>
Его элементы должны располагаться в два ряда. Поэтому, первым делом мы должны разрешить их перенос. Используем для этого свойство flex-wrap
в значении wrap
:
/* Четвертый кубик */
.dice_four {
flex-wrap: wrap;
}
Чтобы в один ряд помещалось только два элемента, зададим их ширину в размере 50%:
.dice_four .dice__point {
width: 50%;
}
Вернемся к контейнеру и распределим наши элементы по главной оси, используя значение space-between
. Используем это же значение и для свойства align-content
, чтобы прижать к краям поперечной оси и сами ряды:
.dice_four {
flex-wrap: wrap;
justify-content: space-between;
align-content: space-between;
}
Все что нам осталось сделать, это передвинуть вторую и четвертую точку к правому краю элемента. Используем псевдокласс nth-child
с ключевым словом even
, чтобы обратиться к четным элементам. После чего зададим им свойство text-align
в значении right
:
.dice_four .dice__point:nth-child(even) {
text-align: right;
}

Четвертый кубик готов, можем двигаться дальше.
Пятый кубик
Создание пятого кубика начинается аналогично:
<!-- Пятый кубик -->
<ul class="dice dice_five">
<li class="dice__point"></li>
<li class="dice__point"></li>
<li class="dice__point"></li>
<li class="dice__point"></li>
<li class="dice__point"></li>
</ul>
Разрешаем перенос элементов на новые ряды. Далее прижимаем элементы и ряды к краям осей:
/* Пятый кубик */
.dice_five {
flex-wrap: wrap;
justify-content: space-between;
align-content: space-between;
}
Теперь обратимся к третьему элементы и зададим ему ширину в 100%
, чтобы он полностью занял свой ряд. Последнее, что нам остается сделать, это выравнять точку пятого элемента по центру. Для этого мы используем свойство text-align
в значении center
:
.dice_five .dice__point:nth-child(3) {
width: 100%;
text-align: center;
}

Готово, переходим к последнему кубику.
Шестой кубик
Шестой кубик довольно прост. Начинаем с разметки:
<!-- Шестой кубик -->
<ul class="dice dice_six">
<li class="dice__point"></li>
<li class="dice__point"></li>
<li class="dice__point"></li>
<li class="dice__point"></li>
<li class="dice__point"></li>
<li class="dice__point"></li>
</ul>
В первую очередь разрешим нашим элементам перенос. Далее, прижмем наши элементы к краям главной оси, тоже самое сделаем и для рядов. И последнее, что нам остается сделать, это развернуть направление главной оси. Мы можем использовать для этого свойство flex-direction
. А можем объединить его со свойством flex-wrap
в виде общего свойства flex-flow
. Чтобы развернуть главную оси, используем значение column
:
/* Шестой кубик */
.dice_six {
flex-flow: wrap column;
justify-content: space-between;
align-content: space-between;
}

Вот и все. Можем вернуться к элементам и убрать вспомогательные линии. Посмотреть результат нашей работы можно в песочнице CodePen: