1

My goal is to create nxn tic tac toe game in React. Now I have the board class wrapping squares. This is the css:

.board {
  display: grid;
  width: 25rem;
  height: 25rem;
  **grid-template: repeat(3, 1fr) / repeat(3, 1fr);**
     
}
.square {
  border: 1px solid black;
  display: grid;
  place-items: center;
  font-size: 40px;
}

In the .board css how can I make this dynamic and not 3 - for example if the grid is 4X4 then I will have to do repeat(4,1fr) etc...how it will be generic for all sizes?

1
  • you have to pass value to repeat, how will it know what n x n box it has to make ? depending on width and height ? Commented Aug 27, 2020 at 17:17

1 Answer 1

1

UPDATE

If you specifically want a React solution, I've put together a demo for you here.

import React, { useState, useEffect, useRef } from "react";
import "./styles.css";

export default function App() {
  const [gridSize, setGridSize] = useState(4);
  const boardRef = useRef(null);

  useEffect(() => {
    boardRef.current.style.setProperty("--grid-size", gridSize);
  }, [gridSize]);

  const createSquares = () => {
    let html = [];
    for (let i = 0; i < gridSize * gridSize; i++) {
      html.push(<div key={i} className="square"></div>);
    }
    return html;
  };

  function handleClick() {
    setGridSize(gridSize === 4 ? 3 : 4);
  }

  return (
    <div className="App">
      <button className="my-button" onClick={handleClick}>
        Toggle grid
      </button>

      <div ref={boardRef} className="board">
        {createSquares()}
      </div>
    </div>
  );
}
.board {
  --grid-size: 4;
  /* Start with 4x4 */
  display: grid;
  width: 25rem;
  height: 25rem;
  grid-template: repeat(var(--grid-size), 1fr) / repeat(var(--grid-size), 1fr);
}

.square {
  border: 1px solid black;
  display: grid;
  place-items: center;
  font-size: 40px;
}

.my-button {
  padding: 1rem;
  position: absolute;
  right: 0;
  top: 0;
}


I would use a CSS custom property, which you can set via JavaScript at any time.

const button = document.querySelector('.my-button');

const board = document.querySelector(".board");

button.addEventListener("click", handleClick);

function handleClick() {
  board.innerHTML = '';
  for (let i = 0; i < 9; i++) {
    board.innerHTML +='<div class="square"></div>';
  }
  board.style.setProperty("--grid-size", 3);
}
.board {
  --grid-size: 4; /* Start with 4x4 */
  display: grid;
  width: 25rem;
  height: 25rem;
  grid-template: repeat(var(--grid-size), 1fr) / repeat(var(--grid-size), 1fr);
}

.square {
  border: 1px solid black;
  display: grid;
  place-items: center;
  font-size: 40px;
}

.my-button {
  padding: 1rem;
  position: absolute;
  right: 0;
  top: 0;
}
<div class="board">
  <div class="square"></div>
  <div class="square"></div>
  <div class="square"></div>
  <div class="square"></div>
  <div class="square"></div>
  <div class="square"></div>
  <div class="square"></div>
  <div class="square"></div>
  <div class="square"></div>
  <div class="square"></div>
  <div class="square"></div>
  <div class="square"></div>  
</div>

<button class="my-button">
  Change to 3x3
</button>

jsFiddle

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for your reply, how can that be achieved without jquery? Pure css/react
@Kaki6876 I'm using native JavaScript—no jQuery.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.