• Home
  • /
  • Colorful Neumorphism Tic Tac Toe Game using HTML CSS JS

Colorful Neumorphism Tic Tac Toe Game using HTML CSS JS | Beautiful UI Design

HTML

				
					<!DOCTYPE html>
<html lang="en">
<head>

<meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
  <title>Tic Tac Toe - Neumorphism</title>
  <link rel="stylesheet" href="style.css" />
</head>
<body>
  <div class="game-container">
    <h1>Tic Tac Toe</h1>
    <div class="board" id="board">
      <div class="cell" data-cell></div>
      <div class="cell" data-cell></div>
      <div class="cell" data-cell></div>
      <div class="cell" data-cell></div>
      <div class="cell" data-cell></div>
      <div class="cell" data-cell></div>
      <div class="cell" data-cell></div>
      <div class="cell" data-cell></div>
      <div class="cell" data-cell></div>
    </div>
    <h2 id="statusText">Player X's Turn</h2>
    <button id="restartBtn">Restart</button>
  </div>

  <template id="GNSvhnLiEhN4JprfV0X3"></template>
</body>
</html>

				
			

CSS

				
					:root {
  --bg: #f1f6ff;
  --shadow-light: #ffffff;
  --shadow-dark: #cfd9ea;
  --primary: #2b2d42;

  --x-color: linear-gradient(135deg, #ff416c, #ff4b2b); /* pink/red */
  --o-color: linear-gradient(135deg, #56ccf2, #2f80ed); /* cyan/blue */

  --status-x: #ff4b5c;
  --status-o: #3b82f6;
  --status-draw: #666;
}

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  font-family: 'Segoe UI', sans-serif;
}

body {
  background: var(--bg);
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
}

.game-container {
  background: var(--bg);
  padding: 40px;
  border-radius: 20px;
  box-shadow: 20px 20px 60px var(--shadow-dark),
              -20px -20px 60px var(--shadow-light);
  text-align: center;
}

h1 {
  margin-bottom: 20px;
  font-size: 2.2rem;
  letter-spacing: 1px;
  background: linear-gradient(90deg, #5f72bd, #9b23ea);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}

.board {
  display: grid;
  grid-template-columns: repeat(3, 100px);
  grid-template-rows: repeat(3, 100px);
  gap: 15px;
  margin: 20px 0;
}

.cell {
  background: var(--bg);
  box-shadow: 6px 6px 12px var(--shadow-dark),
              -6px -6px 12px var(--shadow-light);
  border-radius: 16px;
  font-size: 2.8rem;
  font-weight: bold;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  user-select: none;
  transition: 0.3s ease-in-out;
  position: relative;
  color: var(--primary);
}

.cell.x {
  background: var(--x-color);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}

.cell.o {
  background: var(--o-color);
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}

.cell:hover {
  transform: scale(1.07);
  background-color: #eaf2ff;
}

#statusText {
  margin: 15px 0;
  font-weight: 700;
  font-size: 1.25rem;
  transition: 0.3s;
}

.status-x {
  color: var(--status-x);
}

.status-o {
  color: var(--status-o);
}

.status-draw {
  color: var(--status-draw);
}

#restartBtn {
  padding: 10px 25px;
  font-size: 1rem;
  border: none;
  border-radius: 12px;
  background: var(--bg);
  box-shadow: 4px 4px 10px var(--shadow-dark),
              -4px -4px 10px var(--shadow-light);
  cursor: pointer;
  transition: 0.3s ease;
  color: var(--primary);
}

#restartBtn:hover {
  transform: scale(1.05);
  background-color: #d4e4ff;
}

				
			

JavaScript

				
					const cells = document.querySelectorAll('[data-cell]');
const board = document.getElementById('board');
const statusText = document.getElementById('statusText');
const restartBtn = document.getElementById('restartBtn');

let currentPlayer = 'X';
let gameActive = true;
let gameState = Array(9).fill("");

const winningCombinations = [
  [0,1,2], [3,4,5], [6,7,8],
  [0,3,6], [1,4,7], [2,5,8],
  [0,4,8], [2,4,6]
];

cells.forEach(cell => {
  cell.addEventListener('click', handleClick, { once: true });
});

restartBtn.addEventListener('click', restartGame);

function handleClick(e) {
  const cell = e.target;
  const index = [...cells].indexOf(cell);

  if (!gameActive || gameState[index] !== "") return;

  gameState[index] = currentPlayer;
  cell.textContent = currentPlayer;
  cell.classList.add(currentPlayer.toLowerCase());

  if (checkWin()) {
    statusText.textContent = `Player ${currentPlayer} Wins!`;
    statusText.className = currentPlayer === 'X' ? 'status-x' : 'status-o';
    gameActive = false;
  } else if (gameState.every(cell => cell !== "")) {
    statusText.textContent = "It's a Draw!";
    statusText.className = 'status-draw';
    gameActive = false;
  } else {
    currentPlayer = currentPlayer === 'X' ? 'O' : 'X';
    statusText.textContent = `Player ${currentPlayer}'s Turn`;
    statusText.className = currentPlayer === 'X' ? 'status-x' : 'status-o';
  }
}

function checkWin() {
  return winningCombinations.some(combination => {
    return combination.every(index => {
      return gameState[index] === currentPlayer;
    });
  });
}

function restartGame() {
  currentPlayer = 'X';
  gameActive = true;
  gameState = Array(9).fill("");
  statusText.textContent = `Player ${currentPlayer}'s Turn`;
  statusText.className = 'status-x';
  cells.forEach(cell => {
    cell.textContent = "";
    cell.classList.remove('x', 'o');
    cell.removeEventListener('click', handleClick);
    cell.addEventListener('click', handleClick, { once: true });
  });
}

				
			

Share this post

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

Your email address will not be published. Required fields are marked *

Scroll to Top