Snake game with only HTML, CSS, and JavaScript

February 22, 2025
This Snake game, built with HTML, CSS, and JavaScript, brings the classic arcade experience to the web. Players guide a lime-green snake across a 20x20 grid, gobbling up red food to grow longer and boost their score, while the pace quickens with each bite. A collision with the walls or the snake’s own body triggers an instant restart, keeping the challenge seamless and addictive in a sleek, retro-styled interface.

The Snake game, crafted using HTML, CSS, and JavaScript, delivers a modern take on the timeless arcade classic, blending simplicity with engaging mechanics. At its core, the game unfolds on a 20x20 grid—400 squares in total—rendered as a 400px by 400px black playfield within an HTML container. The snake, a vibrant lime-green entity, begins as a single square at the top-left corner and slithers across the grid under player control, driven by arrow key inputs. Red food squares appear randomly, tempting the snake to eat and grow, while a score display tracks progress. Styled with CSS, the game’s retro aesthetic is clean yet striking, with flexbox centering the layout on a light gray background, ensuring a focused and nostalgic gaming experience.

The game’s operation hinges on JavaScript’s dynamic logic, orchestrating movement, growth, and collision detection. The snake is represented as an array of grid indices, starting with [0], and moves by popping its tail and unshifting a new head based on the direction variable—set to 1 (right), -1 (left), -width (up), or width (down). A setInterval loop, initially ticking every 200 milliseconds, calls moveSnake() to update the snake’s position, clearing the tail’s square and coloring the new head lime-green via CSS class toggling. Arrow keys adjust the direction, with safeguards preventing reversal (e.g., no left turn while moving right), ensuring smooth control. When the snake’s head aligns with the food’s index, it grows by retaining the tail, the score jumps by 10, and the interval speeds up slightly (multiplying speed by 0.9), intensifying the challenge as the snake lengthens.

Collision detection is a critical mechanic, seamlessly integrated to maintain the game’s flow. The script checks each move for wall hits—using modulo operations and comparisons to detect edges (e.g., right wall at snake[0] % width === width - 1 with direction === 1)—and self-collision, where the next position already bears the snake class. Upon collision, rather than halting with a game-over screen, the game resets instantly: the grid clears, the snake shrinks back to its starting point, the score zeroes out, and a new food spawns, all triggered by a call to startGame(). This auto-restart feature keeps players in the action without pause, enhancing the addictive loop. Food generation uses a do-while loop to pick a random index, ensuring it doesn’t overlap with the snake, maintaining fairness and playability.

Behind the scenes, the code leverages the DOM efficiently. The grid’s 400 div elements are created once on page load and stored in an array, allowing rapid class manipulation instead of constant element creation. Event listeners for key presses are lightweight, updating direction only when valid, while console logs (optional for debugging) track movement and state changes. The interplay of HTML structure, CSS styling, and JavaScript logic creates a cohesive experience: a small, fast-loading webpage that delivers endless snake-chasing fun. This implementation not only recreates the essence of Snake but also serves as a practical showcase of web development fundamentals—DOM manipulation, event handling, and real-time updates—wrapped in a deceptively simple package.