HTML, CSS: шахматное поле
с помощью Flexbox, часть 2
В одном из предыдущих постов я описал создание веб-страницы с минималистичной версией шахматного поля. Проект писали со старшеклассниками, потом расширяли в течение нескольких занятий. Пока используем HTML и CSS, включая технологию Flexbox. JavaScript добавим позже. Вот как выглядел результат, скриншот (можно посмотреть и онлайн):

В этом посте я буду делать из минималистичной версии шахматного поля более яркую версию, с добавлением ряда деталей.
Фоновые текстуры для клеток
Моя любимая версия шахматного поля — деревянная, поэтому я выбирал фоны шахматных клеток из текстур дерева. Подходящие я выбрал быстро, но после добавления шахматных фигур изначально выбранные текстуры для черных клеток пришлось поменять, так как на них шахматные фигуры были видны плохо, не контрастно. Вот что получилось в результате:

Изменение стилей:
.white-square {
background-image: url("images/white-wood.webp");
}
.black-square {
background-image: url("images/black-wood.webp");
}
Обозначение рядов цифрами и столбцов буквами
Как-то раз я купил книжку для начинающих шахматистов, и в ее начале довольно много внимания уделялось изучению само́й шахматной доски, без фигур. Предполагалось, что еще до изучения ходов фигурами вы должны научиться представлять шахматное поле в уме, не глядя на доску.
Я некоторое время потратил на поиск каких-нибудь тренировочных веб-игр в интернете, посвященных этой теме, но почти ничего не нашел. Когда я купил себе настоящую деревянную шахматную доску, то специально стер с нее все обозначения для рядов и столбцов, чтобы заставить себя запомнить координаты клеток. Но настоящей доской я в итоге пользовался очень редко, виртуальная доска оказалась гораздо удобнее: не нужно возиться с расстановкой фигур.
В конце концов я понял, что специально насильно запоминать координаты клеток не нужно, они постепенно запомнятся сами, если постоянно играть в шахматы и разбирать разные партии. Я так и не стал особым любителем игры в шахматы, играю редко, но люблю смотреть разборы интересных партий и этюдов от шахматных видеоблогеров.
Обозначение рядов цифрами и столбцов буквами я всё же решил добавить к разрабатываемому шахматному полю. В крайнем случае можно позже сделать настройку с включением/отключением этих обозначений по желанию пользователя.
Эти обозначения можно реализовать множеством способов. Я выбрал следующий. В HTML добавил ряд клеток сверху от восьмого ряда и ряд клеток снизу от первого ряда для обозначений столбцов. Для обозначений рядов я добавил по одной клетке слева и справа к каждому из восьми главных рядов шахматного поля.
Код шахматного поля с добавлением рядов с обозначениями столбцов:
<div class="chess-field">
<!-- ряд с обозначениями столбцов -->
<div class="chess-field-row">...</div>
<!-- 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 class="chess-field-row">...</div>
</div>
Про обычные ряды шахматного поля я подробно писал в предыдущем посте. Вот как у меня выглядит в коде ряд с обозначениями столбцов, который находится над восьмым рядом шахматного поля:
<!-- ряд с обозначениями столбцов -->
<div class="chess-field-row">
<div class="border-cell corner"></div>
<div class="border-cell letter top-letter">a</div>
<div class="border-cell letter top-letter">b</div>
<div class="border-cell letter top-letter">c</div>
<div class="border-cell letter top-letter">d</div>
<div class="border-cell letter top-letter">e</div>
<div class="border-cell letter top-letter">f</div>
<div class="border-cell letter top-letter">g</div>
<div class="border-cell letter top-letter">h</div>
<div class="border-cell corner"></div>
</div>
Обратите внимание, что ряду элементов здесь назначено одновременно несколько классов (в этом случае названия классов отделяются друг от друга пробелом). Это сделано для того, чтобы при описании стилей можно было поместить повторяющиеся описания в одно место. Например, свойства стилей, одинаковые для всех ячеек с буквами и цифрами, можно поместить в стиль по селектору .border-cell. Свойства стилей, одинаковые для всех ячеек с буквами, поместим в стиль по селектору .letter. И так далее.
Код ряда с обозначениями столбцов, который находится под первым рядом шахматного поля, аналогичен вышеприведенному коду для ряда с обозначениями столбцов, находящегося над восьмым рядом шахматного поля. Единственное отличие состоит в том, что вместо класса top-letter используется класс bottom-letter.
Кроме этого, добавлены пустые квадратные ячейки с классом corner, которые находятся в углах шахматной доски. Они нужны, так как слева и справа от шахматного поля добавятся столбцы с цифрами, обозначающими номера рядов шахматного поля. То есть если без буквенно-цифровых обозначений мое шахматное поле содержало 8 рядов и 8 столбцов, то с этими обозначениями оно содержит 10 рядов и 10 столбцов.
Код ряда шахматного поля на примере 8 ряда шахматного поля, с добавлением цифровых обозначений:
<!-- 8 ряд -->
<div class="chess-field-row">
<div class="border-cell digit left-digit">8</div>
<!-- a8 -->
<div class="square white-square"></div>
<!-- b8 -->
<div class="square black-square"></div>
<!-- c8 -->
<div class="square white-square"></div>
<!-- d8 -->
<div class="square black-square"></div>
<!-- e8 -->
<div class="square white-square"></div>
<!-- f8 -->
<div class="square black-square"></div>
<!-- g8 -->
<div class="square white-square"></div>
<!-- h8 -->
<div class="square black-square"></div>
<div class="border-cell digit right-digit">8</div>
</div>
Ячейкам с цифровым обозначением рядов тоже назначено одновременно несколько классов по тем же причинам, которые изложены выше.
Перейдем к описанию стилей:
/* обозначения рядов и столбцов */
body {
font-size: 30px;
/* переменные */
--chess-border-size: 50px;
--cell-size: 100px;
}
.border-cell {
display: flex;
background-color: rgb(240, 224, 248);
box-sizing: border-box; /* размер ячейки включает внутренние отступы */
padding: 5px; /* внутренние отступы */
}
.corner {
width: var(--chess-border-size);
height: var(--chess-border-size);
}
.letter {
justify-content: center;
align-items: start;
width: var(--cell-size);
height: var(--chess-border-size);
}
.digit {
justify-content: end;
align-items: center;
width: var(--chess-border-size);
height: var(--cell-size);
}
.top-letter {
transform: rotate(180deg);
}
.right-digit {
transform: rotate(180deg);
}
Этот код просто добавляется в конец файла со стилями из предыдущего поста. В предыдущем посте уже был стиль по селектору body. В таких случаях работает правило «каскада» (наличие этого правила отражено в названии языка описания стилей CSS — Cascading Style Sheets, по-русски «каскадные списки стилей»), то есть если в списке стилей есть стили с одинаковыми селекторами, то эти стили объединяются.
При этом если в объединяемых стилях есть свойства с одинаковыми именами, то в действие вступает свойство, определенное ниже (позже) в списке. Название «каскад» произошло от аналогии с каскадным водопадом, в котором вода стекает по уступам вниз, а уступы не дают воде течь вверх. В списке стилей приоритетность свойств стилей повышается сверху вниз, как вода в каскадном водопаде течет сверху вниз.
В нашем случае происходит только добавление свойств к стилю по селектору body, повторяющихся свойств для этого стиля у нас нет.
Кроме этого, я использовал переменные, чтобы свести указание размеров ячеек шахматного поля в одно место. Это удобно, особенно если придется менять эти размеры. Переменные можно определить в стиле родительского элемента, их имена начинают с двух дефисов. В данном случае переменные для размеров ячеек шахматного поля я определил в стиле элемента body, который является родительским для любых элементов, отображаемых браузером. Для получения значений переменных использована функция var.
Размер шрифта для буквенно-цифровых обозначений определен в стиле по селектору body с помощью свойства font-size.
По умолчанию размеры, указываемые для элементов div, относятся к содержимому этих элементов, то есть не включают внутренние отступы и толщину границ. Мне было удобнее, чтобы эти размеры относились ко всей ячейке, то есть чтобы эти размеры включали внутренние отступы и толщину границ. Для этого я использовал свойство box-sizing: border-box в стиле по селектору .border-cell.
Буквенные обозначения над восьмым рядом шахматного поля и цифровые обозначения справа от шахматного поля мы решили перевернуть вверх ногами. Для этого использовано свойство transform: rotate(180deg) для стилей по селекторам .top-letter и .right-digit. На реальных шахматных досках так делают, чтобы игроку, выступающему за черных, было удобнее смотреть на эти обозначения. В нашем случае, с нашей виртуальной доской, в этом нет необходимости, но мы хотели поэкспериментировать с этим интересным свойством.
Кстати, если убрать эти две трансформации, то будет немного сложнее работать с выравниванием обозначений в ячейках. По технологии Flexbox при вращении содержимого ячеек меняются положения главной и поперечной осей. Сейчас выравнивание левых и правых цифровых обозначений и нижних и верхних буквенных обозначений совпадает, поэтому стало возможным объединить их выравнивание в стили с селекторами .letter и .digit. В противном случае (если убрать вращение transform: rotate(180deg)) придется разносить выравнивание в стили с селекторами .top-letter, .bottom-letter, .left-digit и .right-digit.
Результат
Вот как полученное шахматное поле выглядит в окне моего браузера:

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