Course: Section

Get Started with Modern React: Learn by Doing

Episode: Title

S03・V06: CSS Layout

Date Created: July 17th, 2019
Last Updated: 27 days ago

Objective
  • We will be adding Flexbox CSS layouts to display a tic-tac-toe board.
Watch Video
Duration: 4m 56s

CSS Styles

Currently, our Game component looks like this:

src/index.js
const Game = () => {
  return (
    <div style={{
      backgroundColor: 'salmon',
      margin: 40,
      padding: 20,
    }}>
      Game
      <Board />
    </div>
  );
};

First, we will remove the inline styles in the Game component.

src/index.js
const Game = () => {
  return (
    <div>      Game
      <Board />
    </div>
  );
};

We will be using CSS styles instead. Add a prop called className. The className prop is the JavaScript equivalent of the CSS class attribute. The JavaScript keyword class is used for another purpose, so className was selected to avoid a naming clash. Usually, we follow the prop and equals sign with a JSX container. However, if the value is just a string, we can add it within quotes. We will add the string value "game".

src/index.js
const Game = () => {
  return (
    <div className="game">      Game
      <Board />
    </div>
  );
};

Move to index.css. Let’s add the game class styling. We will use Flexbox styling, and arrange the layout in a column. And we will align-items to the center.

src/index.css
body {
  background-color: #444;
  color: white;
  margin: 20px;
  font: 32px "Century Gothic", Futura, sans-serif;
}

.game {  display: flex;  flex-direction: column;  align-items: center;}

View the effect in the browser.

Move back to index.js. We want to render 9 tic-tac-toe squares inside our Board component. First, let's add two Squares to our Board.

src/index.js
const Board = () => {
  return (
    <div style={{
      backgroundColor: 'skyblue',
      margin: 40,
      padding: 20,
    }}>
      Board
      <Square />
      <Square />      <Square />    </div>
  );
};

View the effect in the browser. We want to put these 3 Squares in a row. We will use a Flexbox CSS layout to do this. First, wrap the 3 Squares in a div tag, with a className of board-row.

src/index.js
const Board = () => {
  return (
    <div style={{
      backgroundColor: 'skyblue',
      margin: 40,
      padding: 20,
    }}>
      Board
      <div className="board-row">        <Square />        <Square />        <Square />      </div>    </div>
  );
};

Let’s now add the CSS for the board-row class in the index.css file. We will make the board-row class a Flexbox container, arranging its items in a non-wrapping row.

src/index.css
body {
  background-color: #444;
  color: white;
  margin: 20px;
  font: 32px "Century Gothic", Futura, sans-serif;
}

.game {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.board-row {  display: flex;  flex-flow: row nowrap;}

View the effect in the browser. The 3 squares are now in a row.

Now, move back to index.js. Add 2 more rows of 3 squares in the Board component, by duplicating the first row twice.

src/index.js
const Board = () => {
  return (
    <div style={{
      backgroundColor: 'skyblue',
      margin: 40,
      padding: 20,
    }}>
      Board
      <div className="board-row">
        <Square />
        <Square />
        <Square />
      </div>
      <div className="board-row">        <Square />        <Square />        <Square />      </div>      <div className="board-row">        <Square />        <Square />        <Square />      </div>    </div>
  );
};

View the effect in the browser.

Now let’s add some additional styling to the Square component. First, let’s just put an X instead of displaying the word Square. Then, remove the inline styles and add the prop className and give it the value square.

src/index.js
const Square = () => {
  return (
    <div className="square">      X    </div>
  );
};

Now, we will add the square class CSS styles in the index.css file. Make the background-color dark grey, and the text color white. Add a lighter grey border and make the padding zero. Make the font-size 84 pixels large, and align the text to the center. Finally, make the width and height 100 pixels large.

src/index.css
body {
  background-color: #444;
  color: white;
  margin: 20px;
  font: 32px "Century Gothic", Futura, sans-serif;
}

.game {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.board-row {
  display: flex;
  flex-flow: row nowrap;
}

.square {  background-color: #444;  color: white;  border: 1px solid #999;  padding: 0;  font-size: 84px;  text-align: center;  width: 100px;  height: 100px;}

View the effect in the browser. It is starting to look like a proper tic-tac-toe board.

Code Snapshot

src/index.js
import React from 'react';
import ReactDOM from 'react-dom';

import './index.css';

const Square = () => {
  return (
    <div className="square">
      X
    </div>
  );
};

const Board = () => {
  return (
    <div style={{
      backgroundColor: 'skyblue',
      margin: 40,
      padding: 20,
    }}>
      Board
      <div className="board-row">
        <Square />
        <Square />
        <Square />
      </div>
      <div className="board-row">
        <Square />
        <Square />
        <Square />
      </div>
      <div className="board-row">
        <Square />
        <Square />
        <Square />
      </div>
    </div>
  );
};

const Game = () => {
  return (
    <div className="game">
      Game
      <Board />
    </div>
  );
};

ReactDOM.render(
  <Game />, // component to be rendered
  document.getElementById('root') // target DOM node
);

Summary

We added some Flexbox CSS layouts to display the tic-tac-toe board.

Next Up…

In the next video, we will show how to pass data from one component to another.