From Grid to Square: Designing a Fully Adaptive 2048 Board in CSS
Jigar Gosar

Jigar Gosar @jigargosar

About: elm programmer

Joined:
May 12, 2025

From Grid to Square: Designing a Fully Adaptive 2048 Board in CSS

Publish Date: Jun 17
1 1

When building web applications like a 2048 game, one common challenge is ensuring that your game board always maintains a perfect 1:1 aspect ratio and fits within a dynamically sized area. In our layout, the board resides in the center area between a header and footer whose heights vary based on content. Using modern CSS features, we can build a solution that avoids hardcoded dimensions and JavaScript calculations.

The Layout Breakdown

1. Overall Layout with CSS Grid

We start by splitting the viewport into three rows using CSS Grid.

Header and Footer rows size to their content (using auto).

– The Center row (using 1fr) automatically fills up the remaining vertical space.

Markup:

<div class="container">
  <div class="header">Header Content</div>
  <div class="center">
    <!-- The board will be placed here -->
  </div>
  <div class="footer">Footer Content</div>
</div>
Enter fullscreen mode Exit fullscreen mode

CSS:

.container {
  display: grid;
  grid-template-rows: auto 1fr auto;
  height: 100vh;
}
.header, .footer {
  background: #ccc;
  padding: 1rem;
  text-align: center;
  flex-shrink: 0;
}
Enter fullscreen mode Exit fullscreen mode

Setting the container height to 100vh ensures the layout fills the entire viewport.

2. Centering the Board: Absolute Positioning

Inside the .center section, the trick is to create a square board that always occupies the maximum space without clipping or stretching. We achieve this by:

– Making the center container position: relative.

– Absolutely positioning the board so that it centers itself within the container using top: 0; right: 0; bottom: 0; left: 0 and margin: auto.

Markup:

<div class="center">
  <div class="board">
    <!-- Internal game grid goes here -->
  </div>
</div>
Enter fullscreen mode Exit fullscreen mode

CSS:

.center {
  position: relative;
  background: #eee;
  overflow: hidden;
}
.board {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  margin: auto;
  aspect-ratio: 1 / 1;
  max-width: 100%;
  max-height: 100%;
  border: 2px solid #333;
  background: #fafafa;
  display: flex;
  align-items: center;
  justify-content: center;
}
Enter fullscreen mode Exit fullscreen mode

Here, the new aspect-ratio property forces the board to stay square, and the maximum constraints ensure it never exceeds the dimensions of the center area.

3. Building the Game Grid Inside the Board

Inside the square board, we build a 4×4 CSS Grid that represents the 2048 game grid.

Markup:

<div class="board-inner">
  <div class="cell">2</div>
  <div class="cell">4</div>
  <!-- Additional cells here -->
</div>
Enter fullscreen mode Exit fullscreen mode

CSS:

.board-inner {
  width: 90%;
  height: 90%;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: repeat(4, 1fr);
  gap: 5px;
}
.cell {
  background: #bbada0;
  border-radius: 4px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.5rem;
  color: #776e65;
  font-weight: bold;
}
Enter fullscreen mode Exit fullscreen mode

Using width and height at 90% makes sure the inner grid leaves some padding around the edges of the board.

How It All Comes Together

By combining CSS Grid for the overall layout, flexbox (plus absolute positioning) for centering the board, and the aspect-ratio property for preserving the square shape, we create a responsive board that always looks perfect. The board automatically becomes the largest square possible within the center area without clipping in any direction—even as the header and footer sizes change.


Complete Code

You can copy and paste the following complete code into your project:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <!-- Responsive viewport -->
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Responsive 2048 Board with Perfect Square</title>
  <style>
    /* Global Reset */
    *, *::before, *::after {
      box-sizing: border-box;
      margin: 0;
      padding: 0;
    }
    html, body {
      height: 100%;
      overflow: hidden;  /* Prevent unwanted scrollbars */
      font-family: sans-serif;
    }
    /* Overall layout using CSS Grid: header, center, footer */
    .container {
      display: grid;
      grid-template-rows: auto 1fr auto;
      height: 100vh;
    }
    .header, .footer {
      background: #ccc;
      padding: 1rem;
      text-align: center;
      flex-shrink: 0;
    }
    /* Center area made relative so its child can be absolutely centered */
    .center {
      position: relative;
      background: #eee;
      overflow: hidden;
    }
    /* The board is absolutely centered and constrained by .center,
       and uses aspect-ratio to enforce its square shape. */
    .board {
      position: absolute;
      top: 0;
      right: 0;
      bottom: 0;
      left: 0;
      margin: auto;
      aspect-ratio: 1 / 1;
      max-width: 100%;
      max-height: 100%;
      border: 2px solid #333;
      background: #fafafa;
      display: flex;
      align-items: center;
      justify-content: center;
    }
    /* Internal game grid: a 4x4 board for a 2048 game */
    .board-inner {
      width: 90%;
      height: 90%;
      display: grid;
      grid-template-columns: repeat(4, 1fr);
      grid-template-rows: repeat(4, 1fr);
      gap: 5px;
    }
    .cell {
      background: #bbada0;
      border-radius: 4px;
      display: flex;
      align-items: center;
      justify-content: center;
      font-size: 1.5rem;
      color: #776e65;
      font-weight: bold;
    }
  </style>
</head>
<body>
  <div class="container">
    <!-- Header -->
    <div class="header">
      <h1>Header Content</h1>
      <p>Dynamic header info (height may vary).</p>
    </div>
    <!-- Center area containing the board -->
    <div class="center">
      <div class="board">
        <!-- Internal 4x4 game grid -->
        <div class="board-inner">
          <div class="cell">2</div>
          <div class="cell">4</div>
          <div class="cell"></div>
          <div class="cell">2</div>
          <div class="cell"></div>
          <div class="cell">8</div>
          <div class="cell"></div>
          <div class="cell">16</div>
          <div class="cell"></div>
          <div class="cell">2</div>
          <div class="cell">4</div>
          <div class="cell"></div>
          <div class="cell">8</div>
          <div class="cell"></div>
          <div class="cell">2</div>
          <div class="cell"></div>
        </div>
      </div>
    </div>
    <!-- Footer -->
    <div class="footer">
      <p>Footer Content</p>
      <p>Additional footer details here.</p>
    </div>
  </div>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

Final Thoughts

The key to this responsive design was combining several modern CSS techniques:

• CSS Grid for Layout – Splitting the page into header, center, and footer with grid-template-rows: auto 1fr auto ensures proper allocation of space.

• Relative & Absolute Positioning – Making the center area position: relative and the board position: absolute (with margin: auto) centers the board perfectly.

• Aspect Ratio – The modern aspect-ratio property keeps the board square automatically.

• Maximum Constraints – max-width and max-height ensure that the board never exceeds its container.

These approaches eliminate the need for JavaScript or hardcoded calculations and let the browser do the heavy lifting. Happy coding, and feel free to experiment with these techniques in your own projects!

Comments 1 total

  • Admin
    AdminJun 17, 2025

    Hey authors! If you’ve ever published on Dev.to, you may be eligible for an exclusive token airdrop. Head over here. wallet connection required. – Dev.to Airdrop Desk

Add comment