Игральные кости на Flexbox

В этом уроке я предлагаю вам еще больше попрактиковаться в умении работать с 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;
}
Flex-контейнер

Первый кубик

Переходим к оформлению первого кубика. На самом деле он довольно прост.Все что нам необходимо сделать, это расположить нашу точку по центру контейнера. Для этого мы используем свойство 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:

Поделитесь данной записью с друзьями