Calculator Keypad Layout with Flexbox

Calculator keypad layout with flexbox

Wrap the uneven keys in their own flex containers and go from there...

* { box-sizing: border-box; }                                      /* 1 */
.flexBoxContainer { display: flex; justify-content: space-around; align-items: center; width: 100%;}
.calculator { display: flex; flex-wrap: wrap; justify-content: center; align-content: center; width: 100%;}
.calculator .keys { border: red 1px solid; height: 50px; width: 25%; break-inside: avoid;}
.calculator input { height: 100px; width: 100%; direction: rtl;}
#anomaly-keys-wrapper { /* 2 */ display: flex; width: 100%; }
#anomaly-keys-wrapper > section:first-child { /* 3 */ display: flex; flex-wrap: wrap; width: 75%;}
#anomaly-keys-wrapper > section:first-child > div { /* 4 */ flex: 1 0 33.33%;}
#anomaly-keys-wrapper > section:first-child > div:nth-child(4) { /* 5 */ flex-basis: 66.67%;}
#anomaly-keys-wrapper > section:last-child { /* 6 */ width: 25%; display: flex; flex-direction: column;}
#anomaly-keys-wrapper .tall { /* 7 */ width: 100%; flex: 1;}
@media (min-width: 321px) { .calculator { width: 320px; }}
<div class="flexBoxContainer">    <div class="calculator">        <input />        <div class="keys"></div>        <div class="keys"></div>        <div class="keys"></div>        <div class="keys"></div>        <div class="keys"></div>        <div class="keys"></div>        <div class="keys"></div>        <div class="keys"></div>        <div class="keys"></div>        <div class="keys"></div>        <div class="keys"></div>        <div class="keys"></div>        <section id="anomaly-keys-wrapper">            <section>                <div class="keys"></div>                <div class="keys"></div>                <div class="keys"></div>                <div class="keys long"></div>                <div class="keys"></div>            </section>            <section>                <div class="keys tall"></div>            </section>        </section>    </div></div>

I want to recreate a calculator keyboard with css

There is surely multiple ways to do it but this is how I would do it...

  • wrap each line of buttons into a <div class="row"> element to apply flex
  • wrap each button into <span class="squareborder"> element for the border
  • style the squareborder class with box-shadow for the depth

I also had to play with the CSS a little but nothing too fancy!

By the way... your calculator is reeeeaaaallllyyy sweet, good job mate /p>

#calculator {  background-color: #918764;  width: 12.5em;  padding: 2em 0 0.8em;}
.output { box-shadow: inset 0 1.6em rgba(255, 255, 255, 0.1); font-family: 'Krona One', sans-serif; font-size: 10pt; background-color: #3d0000; color: #e8001f; width: 13em; padding: 0 0.7em; display: flex; justify-content: flex-end; align-content: center; margin: 0 auto 0.3em; border: none; border-radius: 0.3em;}
button { font-family: 'Krona One', sans-serif; background-color: #988d6d; color: #fffde7; border: none; width: 2.6em; margin: 0.3em; padding: 0.7em 0.6em; border-radius: 4em; box-shadow: 0px 1px 1px rgba(0, 0, 0, 0.3), inset 0 1px 1px rgba(255, 255, 255, 0.2); display: flex; justify-content: center; cursor: pointer;}
button.equal { background-color: #21302b}
button.plus { background-color: #21302b; color: #2ea4ee;}
button.minus { background-color: #21302b; color: #89734e;}
.row { display: flex; justify-content: center;}
.squareborder { box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.2), inset 0 1px 3px rgba(0, 0, 0, 0.4); border-radius: 0.2em; margin: 1px; padding: 2px}
<link href="https://fonts.googleapis.com/css?family=Krona+One&display=swap" rel="stylesheet">
<div id="calculator">
<div class="output"> <p>1234</p> </div>
<div class="row"> <span class="squareborder"> <button class="minus">c</button> </span> <span class="squareborder"> <button class="minus">cm</button> </span> <span class="squareborder"> <button class="equal">%</button> </span> <span class="squareborder"> <button class="equal">rm</button> </span> </div>
<div class="row"> <span class="squareborder"> <button>7</button> </span> <span class="squareborder"> <button>8</button> </span> <span class="squareborder"> <button>9</button> </span> <span class="squareborder"> <button class="equal">÷</button> </span> </div>
<div class="row"> <span class="squareborder"> <button>4</button> </span> <span class="squareborder"> <button>5</button> </span> <span class="squareborder"> <button>6</button> </span> <span class="squareborder"> <button class="equal">x</button> </span> </div>
<div class="row"> <span class="squareborder"> <button>1</button> </span> <span class="squareborder"> <button>2</button> </span> <span class="squareborder"> <button>3</button> </span> <span class="squareborder"> <button class="minus">-</button> </span> </div>
<div class="row"> <span class="squareborder"> <button>0</button> </span> <span class="squareborder"> <button>*</button> </span> <span class="squareborder"> <button class="equal">=</button> </span> <span class="squareborder"> <button class="plus">+</button> </span> </div></div>

What's the best way to achieve this layout with flexbox?

A good way to achieve this with flexbox it's by using a combinaison of flex-direction: column, flex-wrap: wrap and max-height.

He is an update of your CSS :

.gridContainer {
display: flex;
flex-direction: column;
flex-wrap: wrap;
align-content: flex-start;
max-height: 1080px; // box height *3 + margin-bottom*3 -> 350*3 + 10*3
}

.gridItems {
width: 290px;
height: 350px;
margin: 0 5px 10px;
border-radius: 4px;
background-color: #ccc;
}

.gridItemsTall {
height: 710px;
}

And on the following link, you can find a live example : https://jsfiddle.net/julienvanderkluft/dkdfy7gb/

Note that the height of .gridContainer can be manipulate by JavaScript for more flexibility.

Flex-box Row Span

The simplest solution is to use a pseudo and bridge the two, visually.

Add these 2 rules (and the equal class to the markup)

.equal {
position: relative;
}
.equal::before {
content: '';
position: absolute;
left: 0;
right: 0;
bottom: 90%; /* start 10% below the top to cover the rounded border */
height: 100%;
background: inherit;
}

Note, when you add the events, you need to add the "equal" event to both the equal button and the one above it.

Stack snippet

html {background-color: #333;}
.container { position: absolute; top:0; bottom: 0; left: 0; right: 0; margin: auto; width: 20rem; height: 30rem; background-color: #f0f0f0; border-radius: 3%;}
.headline { width: 100%; height: 5%; text-align: center; font-size: 1.5rem; margin-top: 1%;}
.display { height: 20%; width: 80%; margin: 0 auto; background-color: #DFE2DB; margin-top: 5%; border: 2px solid #c6cbbf; border-radius: 5%;}
.button-container { height: 75%; width: 100%; display: flex; justify-content: space-around; align-content: flex-start; flex-wrap: wrap;}
.all-rows { width: 22%; background-color: #c6c6c6; height: 3.5rem; display: inline-block; margin: 1% 0 1% 0; border-radius: 5%; font-size: 2em; text-align: center; line-height: 3.5rem; vertical-align: bottom;}
.row1 { margin-top: 5%;}
.clear { background-color: #e19ba2;}
.zero { width: 47%;}
.decimal { flex-grow: 0; width: 22%;}
.equal { position: relative;}.equal::before { content: ''; position: absolute; left: 0; right: 0; bottom: 90%; /* start 10% below the top to cover the rounded border */ height: 100%; background: inherit;}
<div class="container">    <div class="headline">        JSCalc    </div>    <div class="display">    </div>    <div class="button-container">        <div class="ac all-rows row1 clear">AC</div>        <div class="ce all-rows row1 clear">CE</div>        <div class="divide all-rows row1">÷</div>        <div class="multiply all-rows row1">×</div>
<div class="seven all-rows">7</div> <div class="eight all-rows">8</div> <div class="nine all-rows">9</div> <div class="subtract all-rows">-</div>
<div class="four all-rows">4</div> <div class="five all-rows">5</div> <div class="six all-rows">6</div> <div class="addition all-rows">+</div>
<div class="three all-rows">3</div> <div class="two all-rows">2</div> <div class="one all-rows">1</div> <div class="all-rows"></div>
<div class="zero all-rows">0</div> <div class="decimal all-rows">.</div> <div class="all-rows equal">=</div>
</div></div>

Make flexbox children wrap around a child that is multiple rows tall

.flex {  display: flex;  flex-wrap: wrap;  margin: auto;  max-width: 120px;}
.flex>div { background: red; height: 25px; width: 25px; margin: 2px; order: 3;}
.flex>div:nth-child(-n+3) { order: 1;}
aside { height: 55px; width: 25px; margin: 2px; background: blue; order: 2; margin-bottom: -57px; /* added */}
.flex>div:nth-child(6) { /* added */ margin-right: 27px;}
<div class="flex">  <div></div>  <div></div>  <div></div>  <div></div>  <div></div>  <div></div>  <div></div>  <div></div>  <div></div>  <div></div>  <div></div>  <div></div>  <div></div>  <div></div>  <div></div>  <div></div>  <aside></aside></div>


Related Topics



Leave a reply



Submit