I have seen demos of pure CSS Tic-tac-toe games, but I was unable to find a version that truly works. If I have missed it, please send me link, so I can see how another dev has created it.
A Pen by Žiga Miklič on CodePen.
| .tic-tac-toe | |
| - for (var turn = 1; turn <= 9; turn++) | |
| - for (var row = 1; row <= 3; row++) | |
| - for (var column = 1; column <= 3; column++) | |
| - var player = "1" | |
| - var positionHorizontal = "" | |
| - var positionVertical = "" | |
| - var positionDiagonal = "" | |
| if( turn % 2 == 0 ) | |
| - var player = "2" | |
| if( column == 1 ) | |
| - var positionHorizontal = " left first-column" | |
| else if( column == 2 ) | |
| - var positionHorizontal = " middle second-column" | |
| else if( column == 3 ) | |
| - var positionHorizontal = " right third-column" | |
| if( row == 1 ) | |
| - var positionVertical = " top first-row" | |
| else if( row == 2 ) | |
| - var positionVertical = " center second-row" | |
| else if( row == 3 ) | |
| - var positionVertical = " bottom third-row" | |
| if( row == 1 && column == 1 ) | |
| - var positionDiagonal = " first-diagonal" | |
| else if( row == 1 && column == 3 ) | |
| - var positionDiagonal = " second-diagonal" | |
| else if( row == 2 && column == 2 ) | |
| - var positionDiagonal = " first-diagonal second-diagonal" | |
| else if( row == 3 && column == 1 ) | |
| - var positionDiagonal = " second-diagonal" | |
| else if( row == 3 && column == 3 ) | |
| - var positionDiagonal = " first-diagonal" | |
| input(id="block" + turn + "-" + row + "-" + column type="radio" class="player-" + player + positionHorizontal + positionVertical + positionDiagonal + " turn-" + turn) | |
| label(for="block" + turn + "-" + row + "-" + column class="turn-" + turn) | |
| .end | |
| h3 | |
| a(href="") Restart | |
| h5 Note: use the Full Page view for the best experience. |
I have seen demos of pure CSS Tic-tac-toe games, but I was unable to find a version that truly works. If I have missed it, please send me link, so I can see how another dev has created it.
A Pen by Žiga Miklič on CodePen.
| // Look ma' no JS! :) | |
| /* | |
| I have seen demos of pure CSS Tic-tac-toe games, but I was unable to find a version that truly works. If I have missed it, please send me link, so I can see how another dev has created it. | |
| My version works as any normal Tic-tac-toe game would: 2 players can play against each other, it can result in either a win or a tie. Players can also restart the game. | |
| In my CodePen example, I used Jade and SASS, so that my code looks much cleaner and simpler to understand. | |
| */ | |
| // How it works: http://codepen.io/ziga-miklic/blog/pure-css-tic-tac-toe/ |
| @import "compass/css3"; | |
| /* Variables | |
| -------------------------------------------------------------- */ | |
| $size-sm: 90px; | |
| $size: 140px; | |
| $spacing: 5px; | |
| $player-1-icon: "\f00d"; | |
| $player-2-icon: "\f10c"; | |
| $player-1-color: #dc685a; | |
| $player-2-color: #ecaf4f; | |
| $hover-color: #3d4250; | |
| /* Body and Notice styling | |
| -------------------------------------------------------------- */ | |
| body { | |
| color: #b6b5ca; | |
| font-family: 'Arial', sans-serif; | |
| margin: 0; | |
| text-align: center; | |
| } | |
| h5 { | |
| font-weight: 400; | |
| padding: 0 20px; | |
| } | |
| /* Tic-tac-toe game | |
| -------------------------------------------------------------- */ | |
| .tic-tac-toe { | |
| font-family: 'Open Sans', sans-serif; | |
| height: ($size-sm + $spacing*2)*3; | |
| overflow: hidden; | |
| margin: 50px auto 30px auto; | |
| position: relative; | |
| width: ($size-sm + $spacing*2)*3; | |
| @media(min-width: 450px) { | |
| height: ($size + $spacing*2)*3; | |
| width: ($size + $spacing*2)*3; | |
| } | |
| input[type="radio"] { | |
| // Hide radio buttons | |
| display: none; | |
| // Put the label above the rest, when checked | |
| &:checked + label { | |
| cursor: default; | |
| z-index: 10 !important; | |
| } | |
| // Player 1 icon | |
| &.player-1 + label:after { content: $player-1-icon; } | |
| // Player 2 icon | |
| &.player-2 + label:after { content: $player-2-icon; } | |
| // Show icon when checked | |
| &.player-1:checked + label:after, | |
| &.player-2:checked + label:after { opacity: 1; } | |
| // Player 1 color | |
| &.player-1:checked + label { background-color: $player-1-color; } | |
| // Player 2 color | |
| &.player-2:checked + label { background-color: $player-2-color; } | |
| // Stack each turn on top of another | |
| @for $i from 1 through 9 { | |
| &.turn-#{$i} + label { | |
| z-index: $i; | |
| } | |
| } | |
| // Display the first turn | |
| &.turn-1 + label { display: block; } | |
| // Show next turn, once the current label has been :checked | |
| @for $i from 1 through 8 { | |
| &.turn-#{$i}:checked ~ .turn-#{$i+1} + label { display: block; } | |
| } | |
| // Label positioning | |
| &.left + label { left: 0; } | |
| &.top + label { top: 0; } | |
| &.middle + label { left: ($size-sm + $spacing*2); } | |
| &.right + label { left: ($size-sm + $spacing*2)*2; } | |
| &.center + label { top: ($size-sm + $spacing*2); } | |
| &.bottom + label { top: ($size-sm + $spacing*2)*2; } | |
| @media(min-width: 450px) { | |
| &.middle + label { left: ($size + $spacing*2); } | |
| &.right + label { left: ($size + $spacing*2)*2; } | |
| &.center + label { top: ($size + $spacing*2); } | |
| &.bottom + label { top: ($size + $spacing*2)*2; } | |
| } | |
| } | |
| // If all 9 turns have been played, show the end pop-up and set the text to "It is a tie!" | |
| input[type="radio"]:checked ~ input[type="radio"]:checked ~ input[type="radio"]:checked ~ | |
| input[type="radio"]:checked ~ input[type="radio"]:checked ~ input[type="radio"]:checked ~ | |
| input[type="radio"]:checked ~ input[type="radio"]:checked ~ input[type="radio"]:checked ~ .end { | |
| display: block; | |
| > h3:before { content: "It is a tie!"; } | |
| } | |
| // Check for all posibble victories, for both players individually | |
| @for $i from 1 through 2 { | |
| .player-#{$i}.first-column:checked ~ .player-#{$i}.first-column:checked ~ .player-#{$i}.first-column:checked ~ .end, | |
| .player-#{$i}.second-column:checked ~ .player-#{$i}.second-column:checked ~ .player-#{$i}.second-column:checked ~ .end, | |
| .player-#{$i}.third-column:checked ~ .player-#{$i}.third-column:checked ~ .player-#{$i}.third-column:checked ~ .end, | |
| .player-#{$i}.first-row:checked ~ .player-#{$i}.first-row:checked ~ .player-#{$i}.first-row:checked ~ .end, | |
| .player-#{$i}.second-row:checked ~ .player-#{$i}.second-row:checked ~ .player-#{$i}.second-row:checked ~ .end, | |
| .player-#{$i}.third-row:checked ~ .player-#{$i}.third-row:checked ~ .player-#{$i}.third-row:checked ~ .end, | |
| .player-#{$i}.first-diagonal:checked ~ .player-#{$i}.first-diagonal:checked ~ .player-#{$i}.first-diagonal:checked ~ .end, | |
| .player-#{$i}.second-diagonal:checked ~ .player-#{$i}.second-diagonal:checked ~ .player-#{$i}.second-diagonal:checked ~ .end { | |
| display: block; | |
| h3:before { content: "Player #{$i} wins!" !important; } | |
| } | |
| } | |
| // Label style | |
| label { | |
| background-color: #78bec5; | |
| border-radius: 14px; | |
| cursor: pointer; | |
| color: #fff; | |
| display: none; | |
| height: $size-sm; | |
| margin: $spacing; | |
| position: absolute; | |
| width: $size-sm; | |
| @include transition(background-color .3s); | |
| @media(min-width: 450px) { | |
| height: $size; | |
| width: $size; | |
| } | |
| // Label hover effect | |
| &:hover { | |
| background-color: $hover-color; | |
| &:after { opacity: .4; } | |
| } | |
| // Icon style | |
| &:after { | |
| left: 0; | |
| font-family: "FontAwesome"; | |
| font-size: $size-sm*0.5; | |
| margin-top: -($size-sm*0.5)/2; | |
| opacity: 0; | |
| position: absolute; | |
| text-align: center; | |
| text-shadow: 2px 2px 4px rgba(0, 0, 0, .2); | |
| top: 50%; | |
| width: 100%; | |
| @media(min-width: 450px) { | |
| font-size: $size*0.5; | |
| margin-top: -($size*0.5)/2; | |
| } | |
| } | |
| } | |
| // End screen style | |
| .end { | |
| background: rgba(255, 255, 255, .8); | |
| bottom: 5px; | |
| color: #3d4250; | |
| display: none; | |
| left: 5px; | |
| padding-top: 55px; | |
| position: absolute; | |
| right: 5px; | |
| top: 5px; | |
| text-align: center; | |
| z-index: 11; | |
| @media(min-width: 450px) { | |
| padding-top: 110px; | |
| } | |
| h3 { | |
| font-size: 30px; | |
| font-weight: 300; | |
| @media(min-width: 450px) { font-size: 40px; } | |
| } | |
| a { | |
| background-color: #3d4250; | |
| border-radius: 4px; | |
| color: #fff; | |
| padding: 14px 45px; | |
| text-decoration: none; | |
| @include transition(background-color .2s); | |
| &:hover { | |
| background-color: #262934; | |
| cursor: pointer; | |
| } | |
| } | |
| } | |
| } |