Search code examples
htmlcssreactjscss-grid

How to apply css grid-template-areas to span multiple grid


I am trying to replicate the calculator here using grid-template-areas.

As you can see the "0" button should extend two grid horizontally, but I am not able to get it to work. My setup only put "0" in one grid, and shifts the other two grid towards the left.

enter image description here

I am following the example here.

Thanks,

App.js

import logo from "./logo.svg";
import "./App.css";
import Button from "./components/Button";
import NumberButton from "./components/NumberButton";

function App() {
  return (
    <div className="App">
      <Button text="AC" className="ac" />
      <Button text="+/-" className="polarity" />
      <Button text="%" className="percent" />
      <Button text="+" className="divide" />
      <NumberButton number="7" className="seven" />
      <NumberButton number="8" className="eight" />
      <NumberButton number="9" className="nine" />
      <Button text="x" className="multi" />
      <NumberButton number="4" className="four" />
      <NumberButton number="5" className="five" />
      <NumberButton number="6" className="six" />
      <Button text="-" className="minus" />
      <NumberButton number="1" className="one" />
      <NumberButton number="2" className="two" />
      <NumberButton number="3" className="three" />
      <Button text="+" className="plus" />
      <NumberButton number="0" className="zero2" />

      <Button text="." className="dot1" />
      <Button text="=" className="equal" />
    </div>
  );
}

export default App;

App.css

.App {
  display: grid;
  grid-template-areas:
    "ac polarity percent divide"
    "seven eight nine multi"
    "four five fix minus"
    "one two three plus"
    "zero2 zero2 dot1 equal";
  text-align: center;
}

.ac {
  grid-area: ac;
}
.polarity {
  grid-area: polarity;
}
.percent {
  grid-area: percent;
}
.divide {
  grid-area: divide;
}
.seven {
  grid-area: seven;
}
.eight {
  grid-area: eight;
}
.nine {
  grid-area: nine;
}
.multi {
  grid-area: multi;
}
.four {
  grid-area: four;
}
.five {
  grid-area: five;
}
.six {
  grid-area: six;
}
.minus {
  grid-area: minus;
}
.one {
  grid-area: one;
}
.two {
  grid-area: two;
}
.three {
  grid-area: three;
}
.plus {
  grid-area: plus;
}
.zero2 {
  grid-area: zero2;
}
.dot1 {
  grid-area: dot1;
}
.equal {
  grid-area: equal;
}

Solution

  • It turned out that I made a mistake with React, when I tried to apply the class directly to the React component. I really should pass it as a prop to the component, then apply it to the html within the component, as below.

    App.js

    import logo from "./logo.svg";
    import "./App.css";
    import Button from "./components/Button";
    import NumberButton from "./components/NumberButton";
    
    function App() {
      return (
        <div className="App">
          <Button text="AC" class_name="ac" />
          <Button text="+/-" class_name="polarity" />
          <Button text="%" class_name="percent" />
          <Button text="+" class_name="divide" />
          <NumberButton number="7" class_name="seven" />
          <NumberButton number="8" class_name="eight" />
          <NumberButton number="9" class_name="nine" />
          <Button text="x" class_name="multi" />
          <NumberButton number="4" class_name="four" />
          <NumberButton number="5" class_name="five" />
          <NumberButton number="6" class_name="six" />
          <Button text="-" class_name="minus" />
          <NumberButton number="1" class_name="one" />
          <NumberButton number="2" class_name="two" />
          <NumberButton number="3" class_name="three" />
          <Button text="+" class_name="plus" />
          <NumberButton number="0" class_name="zero2" />
    
          <Button text="." class_name="dot1" />
          <Button text="=" class_name="equal" />
        </div>
      );
    }
    
    export default App;
    

    Button.js

    import React, { Component } from "react";
    
    export default class Button extends Component {
      render() {
        return (
          <div className={this.props.class_name}>
            <p>{this.props.text}</p>
          </div>
        );
      }
    }