Simple Tic-Tac-Toe Game using JavaScript
Last Updated :
06 Feb, 2025
Improve
This is a simple and interactive Tic Tac Toe game built using HTML, CSS, and JavaScript. Players take turns to mark X and O on the grid, with automatic win detection and the option to reset or start a new game.
What We’re Going to Create
- Players take turns marking X and O on a 3×3 grid, with real-time interaction.
- The game checks for a winner or a draw, displaying messages accordingly.
- The layout adapts to different screen sizes, with a reset button to start a new game.
Project Preview

Simple Tic-Tac-Toe Game using JavaScript
Simple Tic-Tac-Toe Game – HTML and CSS Code
This Tic Tac Toe game features a simple yet interactive design, allowing two players to take turns marking X and O on a 3×3 grid. The layout is responsive, with a reset button to restart the game.
<html>
<head>
<style>
* {
margin: 0;
padding: 0;
}
body {
background-color: lightcyan;
text-align: center;
}
.container {
height: 70vh;
display: flex;
justify-content: center;
align-items: center;
}
.game {
height: 60vmin;
width: 60vmin;
display: flex;
flex-wrap: wrap;
gap: 1.5vmin;
justify-content: center;
}
.box {
height: 18vmin;
width: 18vmin;
border-radius: 1rem;
border: none;
box-shadow: 0 0 1rem rgba(0, 0, 0, 0.3);
font-size: 8vmin;
color: red;
background-color: yellow;
}
#reset {
padding: 1rem;
font-size: 1.25rem;
background: #191913;
color: white;
border-radius: 1rem;
border: none;
}
.box:hover {
background-color: chocolate;
}
#new-btn {
padding: 1rem;
font-size: 1.25rem;
background: #191913;
color: white;
border-radius: 1rem;
border: none;
}
#msg {
font-size: 8vmin;
}
.msg-container {
height: 30vmin;
}
.hide {
display: none;
}
</style>
</head>
<body>
<div class="msg-container hide">
<p id="msg">Winner</p>
<button id="new-btn">New Game</button>
</div>
<main>
<h1>Tic Tac Toe</h1>
<div class="container">
<div class="game">
<button class="box"></button>
<button class="box"></button>
<button class="box"></button>
<button class="box"></button>
<button class="box"></button>
<button class="box"></button>
<button class="box"></button>
<button class="box"></button>
<button class="box"></button>
</div>
</div>
<button id="reset">Reset Game</button>
</main>
</body>
</html>
In this example
- The game board is a flexbox-based grid inside a .container, ensuring a centered and responsive design.
- Buttons for each cell have hover effects, rounded corners, and shadows, enhancing user experience.
- The winner message container (.msg-container) is hidden by default and appears when the game ends, with buttons to start a new game or reset.
Simple Tic-Tac-Toe Game – JavaScript code
The JavaScript code manages the gameplay of Tic Tac Toe, including alternating turns, detecting winners based on patterns, and handling game resets.
let boxes = document.querySelectorAll('.box');
let resetBtn = document.querySelector('#reset');
let turnO = true; // Player O starts
let newGameBtn = document.querySelector('#new-btn');
let msgContainer = document.querySelector('.msg-container');
let msg = document.querySelector('#msg');
const winPatterns = [
[0, 1, 2],
[0, 3, 6],
[0, 4, 8],
[1, 4, 7],
[2, 5, 8],
[2, 4, 6],
[3, 4, 5],
[6, 7, 8]
];
boxes.forEach((box) => {
box.addEventListener('click', function () {
if (turnO) {
box.innerText = 'O';
box.style.color = 'green';
turnO = false;
box.disabled = true;
checkWinner();
} else {
box.innerText = 'X';
box.style.color = 'black';
turnO = true;
box.disabled = true;
checkWinner();
}
});
});
const enableBoxes = () => {
for (let box of boxes) {
box.disabled = false;
box.innerText = "";
}
};
const disableBoxes = () => {
for (let box of boxes) {
box.disabled = true;
}
};
const showWinner = (winner) => {
msg.innerText = `Congratulations, Winner is ${winner}`;
msgContainer.classList.remove('hide');
disableBoxes();
};
const checkWinner = () => {
let hasWin = false;
for (let pattern of winPatterns) {
let pos1Val = boxes[pattern[0]].innerText;
let pos2Val = boxes[pattern[1]].innerText;
let pos3Val = boxes[pattern[2]].innerText;
if (pos1Val !== "" && pos2Val!=="" && pos3Val!==""
&& pos1Val === pos2Val && pos2Val === pos3Val) {
showWinner(pos1Val);
hasWin = true;
return;
}
}
if (!hasWin) {
const allBoxes = [...boxes].every((box) => box.innerText !== "");
if (allBoxes) {
msgContainer.classList.remove('hide');
msg.innerText = 'Match Drawn';
}
}
};
const resetGame = () => {
turnO = true;
enableBoxes();
msgContainer.classList.add('hide');
};
newGameBtn.addEventListener('click', resetGame);
resetBtn.addEventListener('click', resetGame);
In this example
- The turnO variable tracks the player, placing ‘X’ or ‘O’ on each button click and switching turns.
- box.addEventListener(‘click’, …) detects clicks, marks the cell, and checks for a winner after each move.
- checkWinner() scans predefined win patterns to see if any row, column, or diagonal has three identical marks.
- resetGame() clears the board, re-enables boxes, and hides the winner message for a fresh start.
- showWinner() reveals the winning message, disables all grid buttons, and stops further moves.
Simple Tic-Tac-Toe Game – Complete code
<html>
<head>
<style>
* {
margin: 0;
padding: 0;
}
body {
background-color: lightcyan;
text-align: center;
}
.container {
height: 70vh;
display: flex;
justify-content: center;
align-items: center;
}
.game {
height: 60vmin;
width: 60vmin;
display: flex;
flex-wrap: wrap;
gap: 1.5vmin;
justify-content: center;
}
.box {
height: 18vmin;
width: 18vmin;
border-radius: 1rem;
border: none;
box-shadow: 0 0 1rem rgba(0,0,0,0.3);
font-size: 8vmin;
color: red;
background-color: yellow;
}
#reset {
padding: 1rem;
font-size: 1.25rem;
background: #191913;
color: white;
border-radius: 1rem;
border: none;
}
.box:hover {
background-color: chocolate;
}
#new-btn {
padding: 1rem;
font-size: 1.25rem;
background: #191913;
color: white;
border-radius: 1rem;
border: none;
}
#msg {
font-size: 8vmin;
}
.msg-container {
height: 30vmin;
}
.hide {
display: none;
}
</style>
</head>
<body>
<div class="msg-container hide">
<p id="msg">Winner</p>
<button id="new-btn">New Game</button>
</div>
<main>
<h1>Tic Tac Toe</h1>
<div class="container">
<div class="game">
<button class="box"></button>
<button class="box"></button>
<button class="box"></button>
<button class="box"></button>
<button class="box"></button>
<button class="box"></button>
<button class="box"></button>
<button class="box"></button>
<button class="box"></button>
</div>
</div>
<button id="reset">Reset Game</button>
</main>
<script>
let boxes = document.querySelectorAll('.box');
let resetBtn = document.querySelector('#reset');
let turnO = true; // Player O starts
let newGameBtn = document.querySelector('#new-btn');
let msgContainer = document.querySelector('.msg-container');
let msg = document.querySelector('#msg');
const winPatterns = [
[0, 1, 2],
[0, 3, 6],
[0, 4, 8],
[1, 4, 7],
[2, 5, 8],
[2, 4, 6],
[3, 4, 5],
[6, 7, 8]
];
boxes.forEach((box) => {
box.addEventListener('click', function () {
if (turnO) {
box.innerText = 'O';
box.style.color = 'green';
turnO = false;
box.disabled = true;
checkWinner();
} else {
box.innerText = 'X';
box.style.color = 'black';
turnO = true;
box.disabled = true;
checkWinner();
}
});
});
const enableBoxes = () => {
for (let box of boxes) {
box.disabled = false;
box.innerText = "";
}
};
const disableBoxes = () => {
for (let box of boxes) {
box.disabled = true;
}
};
const showWinner = (winner) => {
msg.innerText = `Congratulations, Winner is ${winner}`;
msgContainer.classList.remove('hide');
disableBoxes();
};
const checkWinner = () => {
let hasWin = false;
for (let pattern of winPatterns) {
let pos1Val = boxes[pattern[0]].innerText;
let pos2Val = boxes[pattern[1]].innerText;
let pos3Val = boxes[pattern[2]].innerText;
if (pos1Val !== "" && pos2Val!=="" && pos3Val!=="" &&
pos1Val === pos2Val && pos2Val === pos3Val) {
showWinner(pos1Val);
hasWin = true;
return;
}
}
if (!hasWin) {
const allBoxes = [...boxes].every((box) => box.innerText !== "");
if (allBoxes) {
msgContainer.classList.remove('hide');
msg.innerText = 'Match Drawn';
}
}
};
const resetGame = () => {
turnO = true;
enableBoxes();
msgContainer.classList.add('hide');
};
newGameBtn.addEventListener('click', resetGame);
resetBtn.addEventListener('click', resetGame);
</script>
</body>
</html>