" Pure CSS Connect 4 "
Bootstrap 3.0.0 Snippet by harunpehlivan

<link href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css"> <script src="//netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script> <script src="//code.jquery.com/jquery-1.11.1.min.js"></script> <!------ Include the above in your HEAD tag ----------> <h1>Pure CSS Connect 4</h1> <form> <div class="board"> <div class="field"> <div class="grid column"> <input type="radio" name="slot11" tabindex="-1" required> <input type="radio" name="slot11" tabindex="-1" required> <div class="disc"></div> <input type="radio" name="slot12" tabindex="-1" required> <input type="radio" name="slot12" tabindex="-1" required> <div class="disc"></div> <input type="radio" name="slot13" tabindex="-1" required> <input type="radio" name="slot13" tabindex="-1" required> <div class="disc"></div> <input type="radio" name="slot14" tabindex="-1" required> <input type="radio" name="slot14" tabindex="-1" required> <div class="disc"></div> <input type="radio" name="slot15" tabindex="-1" required> <input type="radio" name="slot15" tabindex="-1" required> <div class="disc"></div> <input type="radio" name="slot16" tabindex="-1" required> <input type="radio" name="slot16" tabindex="-1" required> <div class="disc"></div> <!--Column 1 after--> <div class="column"> <input type="radio" name="slot21" tabindex="-1" required> <input type="radio" name="slot21" tabindex="-1" required> <div class="disc"></div> <input type="radio" name="slot22" tabindex="-1" required> <input type="radio" name="slot22" tabindex="-1" required> <div class="disc"></div> <input type="radio" name="slot23" tabindex="-1" required> <input type="radio" name="slot23" tabindex="-1" required> <div class="disc"></div> <input type="radio" name="slot24" tabindex="-1" required> <input type="radio" name="slot24" tabindex="-1" required> <div class="disc"></div> <input type="radio" name="slot25" tabindex="-1" required> <input type="radio" name="slot25" tabindex="-1" required> <div class="disc"></div> <input type="radio" name="slot26" tabindex="-1" required> <input type="radio" name="slot26" tabindex="-1" required> <div class="disc"></div> <!--Column 2 after--> <div class="column"> <input type="radio" name="slot31" tabindex="-1" required> <input type="radio" name="slot31" tabindex="-1" required> <div class="disc"></div> <input type="radio" name="slot32" tabindex="-1" required> <input type="radio" name="slot32" tabindex="-1" required> <div class="disc"></div> <input type="radio" name="slot33" tabindex="-1" required> <input type="radio" name="slot33" tabindex="-1" required> <div class="disc"></div> <input type="radio" name="slot34" tabindex="-1" required> <input type="radio" name="slot34" tabindex="-1" required> <div class="disc"></div> <input type="radio" name="slot35" tabindex="-1" required> <input type="radio" name="slot35" tabindex="-1" required> <div class="disc"></div> <input type="radio" name="slot36" tabindex="-1" required> <input type="radio" name="slot36" tabindex="-1" required> <div class="disc"></div> <!--Column 3 after--> <div class="column"> <input type="radio" name="slot41" tabindex="-1" required> <input type="radio" name="slot41" tabindex="-1" required> <div class="disc"></div> <input type="radio" name="slot42" tabindex="-1" required> <input type="radio" name="slot42" tabindex="-1" required> <div class="disc"></div> <input type="radio" name="slot43" tabindex="-1" required> <input type="radio" name="slot43" tabindex="-1" required> <div class="disc"></div> <input type="radio" name="slot44" tabindex="-1" required> <input type="radio" name="slot44" tabindex="-1" required> <div class="disc"></div> <input type="radio" name="slot45" tabindex="-1" required> <input type="radio" name="slot45" tabindex="-1" required> <div class="disc"></div> <input type="radio" name="slot46" tabindex="-1" required> <input type="radio" name="slot46" tabindex="-1" required> <div class="disc"></div> <!--Column 4 after--> <div class="column"> <input type="radio" name="slot51" tabindex="-1" required> <input type="radio" name="slot51" tabindex="-1" required> <div class="disc"></div> <input type="radio" name="slot52" tabindex="-1" required> <input type="radio" name="slot52" tabindex="-1" required> <div class="disc"></div> <input type="radio" name="slot53" tabindex="-1" required> <input type="radio" name="slot53" tabindex="-1" required> <div class="disc"></div> <input type="radio" name="slot54" tabindex="-1" required> <input type="radio" name="slot54" tabindex="-1" required> <div class="disc"></div> <input type="radio" name="slot55" tabindex="-1" required> <input type="radio" name="slot55" tabindex="-1" required> <div class="disc"></div> <input type="radio" name="slot56" tabindex="-1" required> <input type="radio" name="slot56" tabindex="-1" required> <div class="disc"></div> <!--Column 5 after--> <div class="column"> <input type="radio" name="slot61" tabindex="-1" required> <input type="radio" name="slot61" tabindex="-1" required> <div class="disc"></div> <input type="radio" name="slot62" tabindex="-1" required> <input type="radio" name="slot62" tabindex="-1" required> <div class="disc"></div> <input type="radio" name="slot63" tabindex="-1" required> <input type="radio" name="slot63" tabindex="-1" required> <div class="disc"></div> <input type="radio" name="slot64" tabindex="-1" required> <input type="radio" name="slot64" tabindex="-1" required> <div class="disc"></div> <input type="radio" name="slot65" tabindex="-1" required> <input type="radio" name="slot65" tabindex="-1" required> <div class="disc"></div> <input type="radio" name="slot66" tabindex="-1" required> <input type="radio" name="slot66" tabindex="-1" required> <div class="disc"></div> <!--Column 6 after--> <div class="column"> <input type="radio" name="slot71" tabindex="-1" required> <input type="radio" name="slot71" tabindex="-1" required> <div class="disc"></div> <input type="radio" name="slot72" tabindex="-1" required> <input type="radio" name="slot72" tabindex="-1" required> <div class="disc"></div> <input type="radio" name="slot73" tabindex="-1" required> <input type="radio" name="slot73" tabindex="-1" required> <div class="disc"></div> <input type="radio" name="slot74" tabindex="-1" required> <input type="radio" name="slot74" tabindex="-1" required> <div class="disc"></div> <input type="radio" name="slot75" tabindex="-1" required> <input type="radio" name="slot75" tabindex="-1" required> <div class="disc"></div> <input type="radio" name="slot76" tabindex="-1" required> <input type="radio" name="slot76" tabindex="-1" required> <div class="disc"></div> <!--Column 7 after--> <div class="column"></div> </div> </div> </div> </div> </div> </div> </div> </div> <div class="front"></div> </div> <button type="reset">New Game</button> </form>
body { margin: 0; font-family: "Helvetica", "Verdana", "Roboto", sans-serif; } h1 { margin: 0 0 15px; padding: 15px; color: #fff; font-size: 40px; font-weight: normal; text-align: center; background-color: #1f90ff; } form { display: flex; flex-flow: column nowrap; align-items: center; } .board { position: relative; width: 450px; height: 450px; } .field { position: absolute; top: 0; left: 15px; padding: 75px 0 0 0; box-sizing: border-box; width: 420px; height: 435px; overflow: hidden; cursor: not-allowed; } .grid { display: inline-flex; flex-flow: column wrap; position: relative; min-width: 420px; height: 360px; counter-reset: player 1; } .column { display: inline-flex; flex-flow: column wrap; height: 360px; } .front { position: absolute; top: 60px; border: 15px solid #007fff; border-radius: 4px; box-sizing: border-box; width: 450px; height: 390px; pointer-events: none; background: radial-gradient(circle, transparent, transparent 18px, #007fff 20px, #007fff 23px, #1f90ff 23px, #1f90ff 36px, #007fff) center top/60px 60px; } /* Invisible inputs */ input { display: none; position: absolute; top: -90px; margin: 0; width: 60px; height: 450px; cursor: pointer; opacity: 0; } input:indeterminate { display: initial; } /* Inputs for red */ .column > input:nth-of-type(2n) { right: 360px; } .column > .column > input:nth-of-type(2n) { right: 300px; } .column > .column > .column > input:nth-of-type(2n) { right: 240px; } .column > .column > .column > .column > input:nth-of-type(2n) { right: 180px; } .column > .column > .column > .column > .column > input:nth-of-type(2n) { right: 120px; } .column > .column > .column > .column > .column > .column > input:nth-of-type(2n) { right: 60px; } .column > .column > .column > .column > .column > .column > .column > input:nth-of-type(2n) { right: 0; } /* Inputs for yellow */ .column > input:nth-of-type(2n+1) { left: 0; } .column > .column > input:nth-of-type(2n+1) { left: 60px; } .column > .column > .column > input:nth-of-type(2n+1) { left: 120px; } .column > .column > .column > .column > input:nth-of-type(2n+1) { left: 180px; } .column > .column > .column > .column > .column > input:nth-of-type(2n+1) { left: 240px; } .column > .column > .column > .column > .column > .column > input:nth-of-type(2n+1) { left: 300px; } .column > .column > .column > .column > .column > .column > .column > input:nth-of-type(2n+1) { left: 360px; } /* Disc */ .disc { position: relative; top: 0; width: 60px; height: 60px; color: #fff; background: radial-gradient(circle, currentcolor 12px, #666 13px, currentcolor 14px, currentcolor 21px, #666 22px, transparent 23px, transparent) center/60px; opacity: 0; pointer-events: none; transition: opacity 0.2s, top 0s 0.2s, color 0s 0.2s; } /* Red's turn */ input:hover + .disc { color: #ff010b; opacity: 1; transition: opacity 0.2s, top 0s; } input:checked + .disc { color: #ff010b; opacity: 1; } /* Yellow's turn */ input:hover + input + .disc { color: #ffd918; opacity: 1; transition: opacity 0.2s, top 0s; } input:checked + input + .disc { color: #ffd918; opacity: 1; } /* Height and time of disc fall per row */ input:hover + .disc:nth-of-type(1), input:hover + input + .disc:nth-of-type(1){ top: -75px; } input:checked + .disc:nth-of-type(1), input:checked + input + .disc:nth-of-type(1){ transition: top 0.14s cubic-bezier(0.56, 0, 1, 1); } input:hover + .disc:nth-of-type(2), input:hover + input + .disc:nth-of-type(6n+2) { top: -135px; } input:checked + .disc:nth-of-type(2), input:checked + input + .disc:nth-of-type(2){ transition: top 0.19s cubic-bezier(0.56, 0, 1, 1); } input:hover + .disc:nth-of-type(3), input:hover + input + .disc:nth-of-type(3) { top: -195px; } input:checked + .disc:nth-of-type(3), input:checked + input + .disc:nth-of-type(3) { transition: top 0.23s cubic-bezier(0.56, 0, 1, 1); } input:hover + .disc:nth-of-type(4), input:hover + input + .disc:nth-of-type(4) { top: -255px; } input:checked + .disc:nth-of-type(4), input:checked + input + .disc:nth-of-type(4) { transition: top 0.26s cubic-bezier(0.56, 0, 1, 1); } input:hover + .disc:nth-of-type(5), input:hover + input + .disc:nth-of-type(5){ top: -315px; } input:checked + .disc:nth-of-type(5), input:checked + input + .disc:nth-of-type(5){ transition: top 0.29s cubic-bezier(0.56, 0, 1, 1); } input:hover + .disc:nth-of-type(6n), input:hover + input + .disc:nth-of-type(6n) { top: -375px; } input:checked + .disc:nth-of-type(6n), input:checked + input + .disc:nth-of-type(6n) { transition: top 0.32s cubic-bezier(0.56, 0, 1, 1); } /* Tracking turns */ input:checked + .disc { counter-increment: player 2; } input:checked + input + .disc { counter-increment: player -2; } .grid::after { content: counter(player, lower-roman); display: inline-block; max-width: 840px; min-width: 420px; letter-spacing: 375px; font-family: monospace; font-size: 1px; overflow: hidden; } /* Draw outcome */ form:valid .column > .column > .column > .column > .column > .column > .column > .column::after { content: "It's a draw!"; z-index: 1; position: absolute; left: 0; top: -75px; width: 420px; height: 435px; visibility: visible; color: #1f90ff; font-size: 30px; text-align: center; line-height: 60px; cursor: initial; pointer-events: auto; animation: outcome 1.5s; } /* Red column win */ input:checked + .disc + input + input:checked + .disc + input + input:checked + .disc + input + input:checked ~ .column::after, /* Red row win */ input:nth-of-type(2):checked ~ .column > input:nth-of-type(2):checked ~ .column > input:nth-of-type(2):checked ~ .column > input:nth-of-type(2):checked ~ .column::after, input:nth-of-type(4):checked ~ .column > input:nth-of-type(4):checked ~ .column > input:nth-of-type(4):checked ~ .column > input:nth-of-type(4):checked ~ .column::after, input:nth-of-type(6):checked ~ .column > input:nth-of-type(6):checked ~ .column > input:nth-of-type(6):checked ~ .column > input:nth-of-type(6):checked ~ .column::after, input:nth-of-type(8):checked ~ .column > input:nth-of-type(8):checked ~ .column > input:nth-of-type(8):checked ~ .column > input:nth-of-type(8):checked ~ .column::after, input:nth-of-type(10):checked ~ .column > input:nth-of-type(10):checked ~ .column > input:nth-of-type(10):checked ~ .column > input:nth-of-type(10):checked ~ .column::after, input:nth-of-type(12):checked ~ .column > input:nth-of-type(12):checked ~ .column > input:nth-of-type(12):checked ~ .column > input:nth-of-type(12):checked ~ .column::after, /* Red diagonal win */ input:nth-of-type(2):checked ~ .column > input:nth-of-type(4):checked ~ .column > input:nth-of-type(6):checked ~ .column > input:nth-of-type(8):checked ~ .column::after, input:nth-of-type(4):checked ~ .column > input:nth-of-type(6):checked ~ .column > input:nth-of-type(8):checked ~ .column > input:nth-of-type(10):checked ~ .column::after, input:nth-of-type(6):checked ~ .column > input:nth-of-type(8):checked ~ .column > input:nth-of-type(10):checked ~ .column > input:nth-of-type(12):checked ~ .column::after, input:nth-of-type(8):checked ~ .column > input:nth-of-type(6):checked ~ .column > input:nth-of-type(4):checked ~ .column > input:nth-of-type(2):checked ~ .column::after, input:nth-of-type(10):checked ~ .column > input:nth-of-type(8):checked ~ .column > input:nth-of-type(6):checked ~ .column > input:nth-of-type(4):checked ~ .column::after, input:nth-of-type(12):checked ~ .column > input:nth-of-type(10):checked ~ .column > input:nth-of-type(8):checked ~ .column > input:nth-of-type(6):checked ~ .column::after { content: "Red wins! :)"; z-index: 2; position: absolute; left: 0; top: -75px; width: 420px; height: 435px; visibility: visible; color: #ff010b; font-size: 30px; text-align: center; line-height: 60px; cursor: initial; pointer-events: auto; animation: outcome 1s; } /* Yellow column win */ input:checked + input + .disc + input:checked + input + .disc + input:checked + input + .disc + input:checked ~ .column::after, /* Yellow row win */ input:nth-of-type(1):checked ~ .column > input:nth-of-type(1):checked ~ .column > input:nth-of-type(1):checked ~ .column > input:nth-of-type(1):checked ~ .column::after, input:nth-of-type(3):checked ~ .column > input:nth-of-type(3):checked ~ .column > input:nth-of-type(3):checked ~ .column > input:nth-of-type(3):checked ~ .column::after, input:nth-of-type(5):checked ~ .column > input:nth-of-type(5):checked ~ .column > input:nth-of-type(5):checked ~ .column > input:nth-of-type(5):checked ~ .column::after, input:nth-of-type(7):checked ~ .column > input:nth-of-type(7):checked ~ .column > input:nth-of-type(7):checked ~ .column > input:nth-of-type(7):checked ~ .column::after, input:nth-of-type(9):checked ~ .column > input:nth-of-type(9):checked ~ .column > input:nth-of-type(9):checked ~ .column > input:nth-of-type(9):checked ~ .column::after, input:nth-of-type(11):checked ~ .column > input:nth-of-type(11):checked ~ .column > input:nth-of-type(11):checked ~ .column > input:nth-of-type(11):checked ~ .column::after, /* Yellow diagonal win */ input:nth-of-type(1):checked ~ .column > input:nth-of-type(3):checked ~ .column > input:nth-of-type(5):checked ~ .column > input:nth-of-type(7):checked ~ .column::after, input:nth-of-type(3):checked ~ .column > input:nth-of-type(5):checked ~ .column > input:nth-of-type(7):checked ~ .column > input:nth-of-type(9):checked ~ .column::after, input:nth-of-type(5):checked ~ .column > input:nth-of-type(7):checked ~ .column > input:nth-of-type(9):checked ~ .column > input:nth-of-type(11):checked ~ .column::after, input:nth-of-type(7):checked ~ .column > input:nth-of-type(5):checked ~ .column > input:nth-of-type(3):checked ~ .column > input:nth-of-type(1):checked ~ .column::after, input:nth-of-type(9):checked ~ .column > input:nth-of-type(7):checked ~ .column > input:nth-of-type(5):checked ~ .column > input:nth-of-type(3):checked ~ .column::after, input:nth-of-type(11):checked ~ .column > input:nth-of-type(9):checked ~ .column > input:nth-of-type(7):checked ~ .column > input:nth-of-type(5):checked ~ .column::after { content: "Yellow wins! :)"; z-index: 2; position: absolute; left: 0; top: -75px; width: 420px; height: 435px; visibility: visible; color: #ffd918; font-size: 30px; text-align: center; line-height: 60px; background: linear-gradient(#fff 60px, transparent 60px, transparent); cursor: initial; pointer-events: auto; animation: outcome 1s; } /* Button style */ button { margin: 20px auto; border: none; border-radius: 2px; padding: 12px 18px; font-size: 16px; text-transform: uppercase; cursor: pointer; color: #fff; background: #2196f3 center; box-shadow: 0 0 4px #999; outline: none; transition: background 0.5s; } button:hover { background: #47a7f5 radial-gradient(circle, transparent 1%, #47a7f5 1%) center/15000%; } button:active { background-color: #6eb9f7; background-size: 100%; transition: background 0s; } @keyframes outcome { 0% { opacity: 0; } 35% { opacity: 0; } 100% { opacity: 1; } }

Related: See More


Questions / Comments: