HTML, CSS: шахматное поле
с помощью Flexbox
Веду ознакомительный курс для старшеклассников по HTML и CSS. Когда я начинал изучать HTML и CSS в нулевых, для размещения элементов на веб-странице в желаемом порядке часто использовали элемент table, который изначально создавался не для этого. В десятых появился ряд новых способов размещения элементов на веб-странице, в том числе Flexbox. Элемент table вернулся к своему первоначальному назначению — создание на веб-странице таблиц с данными.
Я сам не большой специалист по веб-разработке, поэтому мне тоже было интересно разбираться с Flexbox. Теория там несложная, прошли быстро. Но чтобы показать практическое значение этой технологии, требовался какой-то хороший пример, и в качестве такового я решил выбрать создание шахматного поля. Позже у нас планируется ознакомительный курс по JavaScript, при изучении которого пример с шахматным полем можно будет развить в полноценную игру.
Проектирование
Насколько я понимаю, название Flexbox по-русски дословно означает «гибкая коробка». Под «коробкой» подразумевается какой-либо блочный элемент веб-страницы, которому назначен стиль со свойством display: flex. Этот элемент еще называют «контейнером», так как он по задумке должен содержать элементы, расположение которых мы регулируем на веб-странице.
Эти вложенные элементы можем располагать внутри контейнера горизонтально или вертикально с помощью свойства flex-direction в стиле контейнера. По умолчанию вложенные элементы внутри контейнера располагаются горизонтально, в ряд (row).
Насколько я понимаю, слово flex в названии Flexbox значит, что и сама коробка (контейнер) является «гибкой», то есть подстраивается под вложенные элементы, и вложенные элементы гибко (адаптивно) располагаются внутри контейнера, пытаясь как можно лучше заполнить пространство внутри контейнера. Детали всего этого регулируются соответствующими свойствами стиля контейнера.
Расположение элементов по технологии Flexbox по умолчанию предполагается одномерным, то есть у нас есть либо только один ряд, либо только один столбец. С помощью свойства flex-wrap в стиле контейнера можно включить перенос вложенных элементов на следующую строку или в следующий столбец (в зависимости от значения свойства flex-direction), если они не помещаются в контейнер по ширине или высоте контейнера.
Но я решил для создания шахматного поля не использовать перенос вложенных элементов. Мы используем двойную вложенность. Для реализации шахматного поля используем только элементы div с указанием названия класса.
В случае необходимости выравнивание вложенных в контейнер со свойством display: flex элементов по горизонтали и вертикали можно выполнить с помощью свойств justify-content (основные значения left, center и right) и align-items (основные значения start, center и end) контейнера соответственно.
Обратите внимание, что в технологии Flexbox для крайних значений часто используют значения start и end, а не, к примеру, top и bottom (насколько я понимаю, это связано с тем, что по технологии Flexbox стороны элементов можно легко менять местами, поэтому авторы технологии постарались выбрать более нейтральные названия для значений).
Реализация
На первом уровне вложенности реализация шахматного поля в коде на языке HTML у меня выглядит так:
<div class="chess-field">
<!-- 8 ряд -->
<div class="chess-field-row">...</div>
<!-- 7 ряд -->
<div class="chess-field-row">...</div>
<!-- 6 ряд -->
<div class="chess-field-row">...</div>
<!-- 5 ряд -->
<div class="chess-field-row">...</div>
<!-- 4 ряд -->
<div class="chess-field-row">...</div>
<!-- 3 ряд -->
<div class="chess-field-row">...</div>
<!-- 2 ряд -->
<div class="chess-field-row">...</div>
<!-- 1 ряд -->
<div class="chess-field-row">...</div>
</div>
Мы не стали делать элемент <div class="chess-field"> контейнером по технологии Flexbox, так как в данном случае элементы <div class="chess-field-row"> в браузере по умолчанию располагаются в столбец, то есть так, как нам и требуется. Это происходит потому, что по умолчанию элемент div является блочным и занимает всю ширину родительского элемента.
Каждый элемент <div class="chess-field-row"> у нас является контейнером по технологии Flexbox и содержит 8 клеток шахматного поля. Вот как в коде на языке HTML выглядит первый ряд шахматного поля у меня:
<!-- 1 ряд -->
<div class="chess-field-row">
<!-- a1 -->
<div class="square black-square"></div>
<!-- b1 -->
<div class="square white-square"></div>
<!-- c1 -->
<div class="square black-square"></div>
<!-- d1 -->
<div class="square white-square"></div>
<!-- e1 -->
<div class="square black-square"></div>
<!-- f1 -->
<div class="square white-square"></div>
<!-- g1 -->
<div class="square black-square"></div>
<!-- h1 -->
<div class="square white-square"></div>
</div>
В нашем коде HTML ячейки расположены сверху вниз, в браузере будут отображены слева направо. Это обеспечивается следующими стилями:
.chess-field-row {
display: flex;
/* flex-direction: row; */
}
.square {
width: 100px;
height: 100px;
}
.white-square {
background-color: whitesmoke;
}
.black-square {
background-color: gray;
}
Свойство flex-direction в нашем случае указывать нет необходимости, так как по умолчанию оно имеет значение row, которое нам и требуется. Размер всего шахматного поля регулируем размером клеток шахматного поля: контейнер подстроится под размер содержимого. В нашем случае я выбрал размером клеток по ширине и высоте 100 пикселей.
Хотя шахматные клетки называют «черными» и «белыми», это не значит, что по правилам они должны быть именно такого цвета. Условно «черные» должны быть гораздо темнее условно «белых» клеток. Мы можем даже заменить свойство background-color на свойство background-image и назначить соответствующим клеткам шахматного поля какие-либо текстуры. В результате шахматное поле может стать деревянным, металлическим, стеклянным или принять какой-либо другой внешний вид.
Кроме этого, обратите внимание, что по шахматным правилам клетка a1 обязательно должна быть условно «черной». Отталкиваясь от этого и соблюдая принцип чередования цветов клеток, назначаем всем остальным клеткам шахматного поля соответствующие цвета. В интернете встречается довольно много иллюстраций шахматного поля с нарушением этого обязательного принципа. Будьте внимательны!
Вот пример такого неправильного назначения цветов шахматным клеткам, который мне выдала поисковая система «Яндекс» в начале списка результатов поиска по картинкам:

На этой иллюстрации еще неправильно пронумерованы ряды (нумерация рядов слева и справа шахматного поля должна совпадать, так как у одного и того же ряда не может быть разного номера, независимо от того, с какой стороны поля находится игрок). То же самое касается буквенных обозначений столбцов — они должны совпадать сверху и снизу поля. И такие примеры в интернете не редкость.
Выравнивание в окне браузера
В принципе, простейший вариант шахматного поля уже готов. По умолчанию шахматное поле в нашем случае размещено в левом верхнем углу окна браузера. Мы решили поместить шахматное поле в центр окна браузера. Для этого к описанным выше стилям добавили еще следующий:
body {
display: flex;
justify-content: center; /* в центр по горизонтали */
min-height: 100vh; /* растянуть body на высоту окна */
margin: 0; /* убрать лишние внешние отступы */
align-items: center; /* в центр по вертикали */
}
То есть элемент body тоже делаем контейнером по технологии Flexbox. Добавление свойства display: flex элементу body решает две задачи. Во-первых, это свойство меняет поведение рядов нашего шахматного поля: до этого при уменьшении ширины окна браузера шахматное поле «сплющивалось» по ширине, теперь — ширина клеток шахматного поля остается фиксированной и равной 100 пикселям. Во-вторых, это свойство дает возможность поместить шахматное поле в центр окна браузера с помощью свойств justify-content и align-items.
При выравнивании по вертикали следует учесть, что по умолчанию элемент body растягивается в высоту по своему содержимому. На моем экране высота описанного выше шахматного поля (а значит и элемента body) меньше высоты окна браузера. Таким образом, перед применением свойства align-items для выравнивания в центр окна браузера по высоте элемент body следует растянуть до высоты окна браузера. Это я делаю с помощью свойства min-height.
Также нужно убрать внешние отступы для элемента body, которые мой браузер расставляет по умолчанию. Это я делаю с помощью свойства margin: 0. Если эти отступы не убрать, мой браузер добавляет ненужный вертикальный ползунок.
Результат
Вот как полученное шахматное поле выглядит в окне моего браузера:

Можно посмотреть онлайн: https://textpub.neocities.org/my/chess-board/v1/.
Развитие проекта
Это простой вариант шахматного поля. Есть немало игроков, которым нравится вот такой минимализм. На занятиях мы добавили разные цвета и текстуры для ячеек, сделали настройки поля для пользователя. В том числе добавили номера рядов и буквенные обозначения столбцов поля. Добавили на поле шахматные фигуры разных стилей и с помощью скриптов на языке JavaScript реализовали передвижение фигур. Также реализовали выгрузку позиции и ходов в текстовый файл и загрузку из текстового файла.
Если выкрою время, то опишу это в одном или нескольких дополнительных постах.