Яндекс.Метрика

Дизайн-журнал №1. Актуальная информация для дизайнеров, веб дизайнеров, программистов и разработчиков сайтов.

Создание игры крестики-нолики с использованием только CSS

30 ноября 2015 | Опубликовано в css | Нет комментариев »

В этом уроке мы познакомимся с интересными возможностями CSS и создадим игру крестики-нолики на чистом CSS. Эта игра предназначена для двух игроков, играющих поочередно, для крестика нужно нажать один раз, для нолика — два раза. 

 

 


Основные особенности:

  • Для состояний ячеек используются скрытые переключатели-флажки и подписи. Неопределенное состояние означает пустую клетку, отмеченное — крестик, неотмеченное — нолик.
  • При запуске небольшой скрипт, единственный JavaScript в этом примере, задает всем переключателям-флажкам неопределенное состояние.
  • Используются псевдоклассы :checked (отмеченный) и :indeterminate (неопределенный) и родственные и соседние селекторы для изменения состояний ячеек и вывода информации о победителе.
  • Когда кто-то нажимает на переключатель-флажок или в этом случае на его подпись, меняется состояние с неопределенного или на отмеченное, или на неотмеченное, в зависимости от того, сколько раз было нажато.

Как дополнительное преимущество в эти крестики-нолики можно играть с клавиатуры, выбирая клеточку табуляцией и используя пробел для нажатия, хотя, вероятно, эта игра не подойдет для программы — экранного диктора.

Для разметки гораздо лучше подошел бы элемент таблицы, но мы решили пожертвовать в этом случае структурой, чтобы пример стал проще.

Все современные версии браузеров поддерживают неопределенное состояние, но в некоторых старых версиях браузеров наш пример не работает, например, в некоторых старых  браузерах на движке Webkit из-за неправильной работы с родственными и соседними селекторами. Эта демонстрация должна работать даже в браузере Internet Explorer версии 9, хотя мы не проверяли.

В некоторых современных браузерах с некоторыми настройками при однократном нажатии появляется не крестик, а нолик, а при двукратном — не нолик, а крестик, но это не ухудшает функциональность игры.

Демонстрация работы

Код HTML

<input type="checkbox" id="a11" /><label for="a11">Top left</label>
<input type="checkbox" id="a12" /><label for="a12">Top center</label>
<input type="checkbox" id="a13" /><label for="a13">Top right</label>

<input type="checkbox" id="a21" /><label for="a21">Middle left</label>
<input type="checkbox" id="a22" /><label for="a22">Middle center</label>
<input type="checkbox" id="a23" /><label for="a23">Middle right</label>

<input type="checkbox" id="a31" /><label for="a31">Bottom left</label>
<input type="checkbox" id="a32" /><label for="a32">Bottom center</label>
<input type="checkbox" id="a33" /><label for="a33">Bottom right</label>
<p>State: </p>

Код  JavaScript

var checkboxes = document.getElementsByTagName('input');
for(var i=0; i<checkboxes.length; i++) {
    checkboxes[i].indeterminate = true;
}

Код CSS

input {
    position:absolute;
    clip: rect(0,0,0,0);
}

label {
    display:block;
    width:30px;
    height:50px;
    padding:10px 20px;
    outline:1px solid #bbb;
    background:white;
    float:left;
    color:transparent;
    font-size:50px;
    line-height:1;
    overflow:hidden;
}

input:focus + label {
    background:#ffd;
}

label:nth-of-type(3n + 1) {
    clear:left
}

label:before {
    color:black;
}

input:checked + label:before {
    content: '×';
    color: green;
}

input:not(:checked) + label:before {
    content: '○';
    color: blue;
}

input:indeterminate + label:before {
    content: ' ';
}

p {
    clear:both;
    padding:10px 0;
    font:150% sans-serif;
}

p:after {
    content: 'Tie';
    font-weight:bold;
}

input:indeterminate + label ~ p:after {
    content: 'Still playing';
}

input:nth-of-type(3n+1):checked + label + input:checked + label + input:checked ~ p:after,
#a11:checked ~ #a21:checked ~ #a31:checked ~ p:after,
#a12:checked ~ #a22:checked ~ #a32:checked ~ p:after,
#a13:checked ~ #a23:checked ~ #a33:checked ~ p:after,
#a11:checked ~ #a22:checked ~ #a33:checked ~ p:after,
#a13:checked ~ #a22:checked ~ #a31:checked ~ p:after {
    content: 'X won';
    color:green;
}
input:nth-of-type(3n+1):not(:checked):not(:indeterminate) + label + input:not(:checked):not(:indeterminate) + label + input:not(:checked):not(:indeterminate) ~ p:after,
#a11:not(:checked):not(:indeterminate) ~ #a21:not(:checked):not(:indeterminate) ~ #a31:not(:checked):not(:indeterminate) ~ p:after,
#a12:not(:checked):not(:indeterminate) ~ #a22:not(:checked):not(:indeterminate) ~ #a32:not(:checked):not(:indeterminate) ~ p:after,
#a13:not(:checked):not(:indeterminate) ~ #a23:not(:checked):not(:indeterminate) ~ #a33:not(:checked):not(:indeterminate) ~ p:after,
#a11:not(:checked):not(:indeterminate) ~ #a22:not(:checked):not(:indeterminate) ~ #a33:not(:checked):not(:indeterminate) ~ p:after,
#a13:not(:checked):not(:indeterminate) ~ #a22:not(:checked):not(:indeterminate) ~ #a31:not(:checked):not(:indeterminate) ~ p:after{
    content: 'O won';
    color:blue;
}

Автор урока Lea Verou

Перевод — Дежурка

Смотрите также:




Коментарии запрещены.

[an error occurred while processing the directive]


[an error occurred while processing the directive]