Home > Enterprise >  CSS Flexbox columns are overflowing
CSS Flexbox columns are overflowing

Time:10-07

I want to build a layout with CSS flexbox and I got into a problem while building a calculator.

I have a #controller that contains all my buttons on the calculator. The "=" button's size is twice the other buttons (vertically).

The bottom of the layout is like this (I cant upload pictures) ...

| 4 | 5 | 6 | / |
| 1 | 2 | 3 | = |
| . | 0 | % | = |

So I created div "rows" for the normal buttons in which they are set to flex-grow: 1; so it stays responsive to the width.

I made a div container called ".bottom" for the left and right "columns". The left contains the rows and the normal sized buttons, and the right contains the "=" button.

Problem:
Both columns inside the .bottom part are overflowing from the #controller with their content.

I don't necessarily want to wrap my layout. I figured out maybe I should create only columns, not rows, but before that I wanted to ask for advice. Thank you in advance!

HTML bottom part:

<div id="calculator">
  <!-- screen of calculator -->
  <div id="controller">
    <!-- upper part of button rows -->
    <div >
      <div >
        <div >
          <div >1</div>
          <div >2</div>
          <div >3</div>
        </div>
        <div >
          <div >.</div>
          <div >0</div>
          <div >%</div>
        </div>
      </div>
      <div >
        <div >=</div>
      </div>
    </div>
  </div>
</div>

CSS

#calculator, #controller {
  display: flex;
  flex-direction: column;
}

#calculator {
  margin: auto;
  width: 50%;
}

#controller .row {
  display: flex;
}

#controller .bottom {
  display: flex;
  flex-direction: row;
}

#controller .bottom .columnLeft, #controller .bottom .columnRight {
  display: flex;
}

#controller .bottom .columnLeft {
  flex-grow: 3;
  flex-direction: column;
}

#controller .bottom .columnRight {
  flex-grow: 1;
}

.button, .longButton{
  flex-grow: 1;
}

CodePudding user response:

Just place all the buttons in a CSS-Grid. To let an element occupy 2 rows you can use grid-row: span 2 on that element.

.calculator-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0.5em;
  max-width: 200px;
}

.row-2 {
  grid-row: span 2;
}
<div >
  <button>4</button>
  <button>5</button>
  <button>6</button>
  <button>/</button>
  
  <button>1</button>
  <button>2</button>
  <button>3</button>
  <button >=</button>
  
  <button>.</button>
  <button>0</button>
  <button>%</button>
  <!-- empty for equal button -->
</div>

CodePudding user response:

CSS grid is the way to go here. You can use grid-template areas to span cells like the calculator example I've done below. There's a great primer here and a good video by Kevin Powell here

I've knocked up an example to get you started.

.bottom {
      display: grid;
      width: 50%;
      grid-template-columns: repeat(4, 1fr);
      grid-template-areas: "b4 b5 b6 bdiv""b1 b2 b3 bequals""bdot b0 bpercent bequals";
      gap: 0.5rem;
    }

    .bottom>div {
      /* aspect-ratio: 1; */
      background-color: lightgray;
      display: grid;
      place-items: center;
      padding-block:1rem;
      transition: background-color 0.2s;
      cursor: pointer;
    }
    .bottom>div:hover {
      background-color:darkgray;
    }

    .button-1 {
      grid-area: b1;
    }

    .button-2 {
      grid-area: b2;
    }

    .button-3 {
      grid-area: b3;
    }

    .button-4 {
      grid-area: b4;
    }

    .button-5 {
      grid-area: b5;
    }

    .button-6 {
      grid-area: b6;
    }

    .button-div {
      grid-area: bdiv;
    }

    .button-percent {
      grid-area: bpercent;
    }

    .button-dot {
      grid-area: bdot;
    }

    .button-long {
      grid-area: bequals;
    }
<div id="calculator">
    <!-- screen of calculator -->
    <div id="controller">
      <!-- upper part of button rows -->
      <div >
        <div >4</div>
        <div >5</div>
        <div >6</div>
        <div >/</div>
        <div >1</div>
        <div >2</div>
        <div >3</div>
        <div >.</div>
        <div >0</div>
        <div >%</div>
        <div >=</div>
      </div>
    </div>
  </div>

  • Related