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:
- Include padding and borders in
width
/height
calculations. - Wrap uneven keys in a separate flex container (with defaults
flex-direction: row
andflex-wrap: nowrap
) - Wrap long key in a separate flex container with wrapping enabled (and take enough siblings to create equal height with tall key).
- Force three keys per row max.
- Make long key twice the width of siblings. (Didn’t use simpler
long
class selector due to weaker specificity.) - Wrap tall key in a separate flex container with vertical orientation.
- Make tall key consume all available width and height of container.
UPDATE
From the comments:
Hi, 1. Can you explain me how flex basis works? and why did you use it instead of giving width to long button. 2. Why is it necessary to give flex: 1; to tall button, as i have read it is the default value.
Question #1:
The keys in the first sub-section container (containing .long
) are sized with flex: 1 0 33.33%
.
This is shorthand for flex-grow: 1
, flex-shrink: 0
, and flex-basis: 33.33%
.
For the .long
key we are simply overriding the flex-basis
component with 66.67%
. (there’s no need to re-declare the other two components).
Also, there’s really no difference in this case between width
and flex-basis
, but since we’re overriding flex-basis
, I used flex-basis
.
Using width
would leave the original flex-basis: 33.33%
intact, creating two width
rules which may, therefore, fail to expand the .long
key, depending on which rule prevails in the cascade.
For a complete explanation of flex-basis
vs. width
, see What are the differences between flex-basis and width?
Question #2:
Because the initial value of the flex-grow
component is 0
(source).