Suyash Gulati Suyash Gulati - 3 months ago 15
CSS Question

For calculator layout, make one key twice the height and another key twice the width

I am building a calculator with flexbox. I want one of its keys twice the height and another key twice the width.

I googled much about it but couldn't find both cases together.

For twice height key, only answers I found was to make

flex-direction
as
column
. But in that case I will not be able to make double width key.

Here is my code (on codepen.io). Please help.

HTML Code :

<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>
<div class="keys"></div>
<div class="keys"></div>
<div class="keys"></div>
<div class="keys long"></div>
<div class="keys big"></div>
<div class="keys"></div>
</div>
</div>


SCSS Code:

$white: rgba(255, 255, 255, 1);
$aqua: rgba(132, 220, 198, 1);
$mint: rgba(165, 255, 214, 1);
$pink: rgba(255, 166, 158, 1);
$red: rgba(255, 104, 107, 1);
$gtphone: "(min-width : 321px)";
.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%;
@media #{$gtphone} {
width: 320px;
}
.keys {
border: red 1px solid;
height: 50px;
width: 24%;
break-inside: avoid;
}
.long {
height: 100px !important;
}
.big {
width: 49% !important;
}
input {
height: 100px;
width: 100%;
direction: rtl;
}
}

Answer

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>

Revised Codepen (with compiled CSS)

Notes:

  1. Include padding and borders in width / height calculations.
  2. Wrap uneven keys in a separate flex container (with defaults flex-direction: row and flex-wrap: nowrap)
  3. Wrap long key in a separate flex container with wrapping enabled (and take enough siblings to create equal height with tall key).
  4. Force three keys per row max.
  5. Make long key twice the width of siblings. (Didn't use simpler long class selector due to weaker specificity.)
  6. Wrap tall key in a separate flex container with vertical orientation.
  7. Make tall key consume all available width and height of container.