<form>
<div class="board-wrapper">
<div class="board-outer">
<div class="board">
<div class="board-inner">
<input type="radio" name="pos11" id="pos11-blue" class="blue" required>
<input type="radio" name="pos11" id="pos11-red" class="red" required>
<div class="marque"></div>
<input type="radio" name="pos12" id="pos12-blue" class="blue" required>
<input type="radio" name="pos12" id="pos12-red" class="red" required>
<div class="marque"></div>
<input type="radio" name="pos13" id="pos13-blue" class="blue" required>
<input type="radio" name="pos13" id="pos13-red" class="red" required>
<div class="marque"></div>
<input type="radio" name="pos21" id="pos21-blue" class="blue" required>
<input type="radio" name="pos21" id="pos21-red" class="red" required>
<div class="marque"></div>
<input type="radio" name="pos22" id="pos22-blue" class="blue" required>
<input type="radio" name="pos22" id="pos22-red" class="red" required>
<div class="marque"></div>
<input type="radio" name="pos23" id="pos23-blue" class="blue" required>
<input type="radio" name="pos23" id="pos23-red" class="red" required>
<div class="marque"></div>
<input type="radio" name="pos31" id="pos31-blue" class="blue" required>
<input type="radio" name="pos31" id="pos31-red" class="red" required>
<div class="marque"></div>
<input type="radio" name="pos32" id="pos32-blue" class="blue" required>
<input type="radio" name="pos32" id="pos32-red" class="red" required>
<div class="marque"></div>
<input type="radio" name="pos33" id="pos33-blue" class="blue" required>
<input type="radio" name="pos33" id="pos33-red" class="red" required>
<div class="marque"></div>
<div id="win-blue" class="win-message"><div class="wrapper">Blue wins!</div></div>
<div id="win-red" class="win-message"><div class="wrapper">Red wins!</div></div>
<div id="no-winner" class="win-message"><div class="wrapper">It's a draw!</div></div>
</div>
</div>
</div>
</div>
<div class="actions">
<button type="reset">Restart</button>
</div>
</form>
* {
margin:0;
padding:0;
box-sizing:border-box;
}
html, body {
background:#000;
}
/*vars*/
$red:#c50878;
$redhover:rgba(197, 9, 120, .3);
$blue:#5039ff;
$bluehover:rgba(80, 57, 255, .3);
:root {
--blocksize:20vw;
--boardsize:60vw;
--spacing:45vw;
--winmsgsize:8vw;
}
@media (min-width: 750px) {
:root {
--blocksize:150px;
--boardsize:450px;
--spacing:400px;
--winmsgsize:3rem;
}
}
/*board*/
.board-wrapper {
overflow:hidden;
margin:3rem 0 0 calc( 50vw - var(--boardsize) / 2 );
width:var(--boardsize);
}
.board-outer {
width:100vw;
}
.board-inner {
width:var(--boardsize); height:var(--boardsize);
}
.board {
float:left;
position:relative;
&:before {
position:absolute;
left:-999px;
content:counter(player);
}
&:after {
content:counter(player, lower-roman);
display:inline-block;
height:0;
background:grey;
font-family:monospace;
letter-spacing:var(--spacing);
overflow:hidden;
}
}
/*input radio*/
.board input {
position:absolute;
width:var(--blocksize);
height:var(--blocksize);
cursor:pointer;
opacity:0;
-webkit-appearance:none;
&:indeterminate {
display:block;
}
&:checked,
&:checked + input {
display:none;
}
&.blue {
background:$blue;
}
&.red {
background:$red;
left:auto !important;
}
&[name="pos11"] {
top:0; left:0;
& + input { right:calc( 2 * var(--blocksize) ); }
}
&[name="pos12"] {
top:0; left:var(--blocksize);
& + input { right:var(--blocksize); }
}
&[name="pos13"] {
top:0; left:calc( 2 * var(--blocksize) );
& + input { right:0; }
}
&[name="pos21"] {
top:var(--blocksize); left:0;
& + input { right:calc( 2 * var(--blocksize) ); }
}
&[name="pos22"] {
top:var(--blocksize); left:var(--blocksize);
& + input { right:var(--blocksize); }
}
&[name="pos23"] {
top:var(--blocksize); left:calc( 2 * var(--blocksize) );
& + input { right:0; }
}
&[name="pos31"] {
top:calc( 2 * var(--blocksize) ); left:0;
& + input { right:calc( 2 * var(--blocksize) ); }
}
&[name="pos32"] {
top:calc( 2 * var(--blocksize) ); left:var(--blocksize);
& + input { right:var(--blocksize); }
}
&[name="pos33"] {
top:calc( 2 * var(--blocksize) ); left:calc( 2 * var(--blocksize) );
& + input { right:0; }
}
}
/*marque*/
.marque {
float:left;
display:flex;
padding:1px;
width:var(--blocksize); height:var(--blocksize);
justify-content:center;
align-items:center;
background:#1d1d1d;
background-clip:content-box;
&:before {
content:"";
position:static;
display:block;
width:50%; height:50%;
}
}
/* marque hover*/
.blue:hover + .red + .marque:before {
background:$bluehover;
border-radius:3px;
}
.blue + .red:hover + .marque:before {
background:$redhover;
border-radius:50%;
}
/* marque checked*/
.blue:checked + .red + .marque {
counter-increment:player 2;
position:relative;
z-index:100;
&:before {
background:$blue;
border-radius:3px;
}
}
.blue + .red:checked + .marque {
counter-increment:player -2;
position:relative;
z-index:100;
&:before {
background:$red;
border-radius:50%
}
}
/* results */
@mixin winners($val) {
//1st line
#pos11-#{$val}:checked ~ #pos12-#{$val}:checked ~ #pos13-#{$val}:checked ~ #win-#{$val},
//2nd line
#pos21-#{$val}:checked ~ #pos22-#{$val}:checked ~ #pos23-#{$val}:checked ~ #win-#{$val},
//3rd line
#pos31-#{$val}:checked ~ #pos32-#{$val}:checked ~ #pos33-#{$val}:checked ~ #win-#{$val},
//1st column
#pos11-#{$val}:checked ~ #pos21-#{$val}:checked ~ #pos31-#{$val}:checked ~ #win-#{$val},
//2nd column
#pos12-#{$val}:checked ~ #pos22-#{$val}:checked ~ #pos32-#{$val}:checked ~ #win-#{$val},
//3rd column
#pos13-#{$val}:checked ~ #pos23-#{$val}:checked ~ #pos33-#{$val}:checked ~ #win-#{$val},
//1st diagonal
#pos11-#{$val}:checked ~ #pos22-#{$val}:checked ~ #pos33-#{$val}:checked ~ #win-#{$val},
//2nd diagonal
#pos13-#{$val}:checked ~ #pos22-#{$val}:checked ~ #pos31-#{$val}:checked ~ #win-#{$val} {
display:block;
& ~ #no-winner {
display:none;
}
}
}
.win-message {
position:absolute;
top:0;
display:none;
height:100%; width:100%;
color:#FFF;
font-size:var(--winmsgsize);
font-weight:bold;
z-index:200;
.wrapper {
display:flex;
justify-content:center;
align-items:center;
width:var(--boardsize); height:var(--boardsize);
background:rgba(0,0,0,.6);
}
}
/*blue wins*/
@include winners(blue);
/*red wins*/
@include winners(red);
/**/
form:valid {
#no-winner {
display:block;
}
}
/* reset */
.actions {
clear:both;
margin-bottom:2rem;
text-align:center;
button {
margin-top:1rem;
padding:0.8rem 2rem;
border:1px solid #1d1d1d;
color:#555;
background:#000;
font-size:0.9rem;
cursor:pointer;
transition:background .3s ease-out, border .3s ease-out;
&:hover {
border-color:#303030;
background:#0a0a0a;
}
}
}
View Compiled
/*
Modern browsers that support vw units, css counter, and css variables only!
Highly inspired by Bence Szabó's Pure CSS Connect 4
https://codepen.io/finnhvman/pen/xXpzVN
https://css-tricks.com/roman-empire-made-pure-css-connect-4-possible/
*/
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.