I'm trying to create a part of a website, with 3 parts (let's call them A, B, C), where A and B are beside each other (aligned to touch opposite sides of a container), and below them is C, but when A, and B don't fit beside each other in the container, B wraps below C instead of between A and C.
A, B and C all have expanding-collapsing components, and the container can be resized by other elements, so all their sizes are unknown. This means that using @media is out of the question.
Expected result:
When A and B fit beside each other:
When they don't:
Is this possible to achieve with flexbox or grid?
This is as far as I got:
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>flexbox black magic</title>
</head>
<body>
<div style="width:50%; border:4px solid blue; margin:8px; display: flex; justify-content: space-between; flex-wrap: wrap;">
<div style="width: 100px; height: 60px; border: 4px solid red; margin:8px;">a</div>
<div style="width: 70px; height: 30px; border: 4px solid green; margin:8px;">b</div>
<div style="width: 100%">
<div style="width: 100%; max-width: 240px; height: 100px; border: 4px solid orange; margin:8px;">c</div>
</div>
</div>
</body>
</html>
1 Answer. Show activity on this post. Switch from flex-direction: row to column . In column mode the elements stack, just like in standard block layout, which is the reason why your layout is "fixed" when you disable the #about CSS rules.
The order property and accessibility Use of the order property has exactly the same implications for accessibility as changing the direction with flex-direction . Using order changes the order in which items are painted, and the order in which they appear visually.
The flex items break into multiple lines. The cross-start is either equivalent to start or before depending flex-direction value and the cross-end is the opposite of the specified cross-start. wrap-reverse. Behaves the same as wrap but cross-start and cross-end are permuted.
Here is an idea using float, yes float. Resize the blue container and see the result:
.box {
width: 50%;
border: 4px solid blue;
margin: 8px;
text-align: justify;
font-size:0; /* this will make sure the pseudo element won't have any size */
overflow: auto;
resize: horizontal;
}
.box > * {
font-size:initial; /* we reset the font for child element */
margin:8px;
box-sizing:border-box;
}
/* the below is used with text-align:justify to have the correct alignment on wrap */
.box::before {
content:"";
display:inline-block;
}
.box::after {
content:"";
display:inline-block;
width:100%;
}
/**/
.a {
max-width: 100px;
width: calc(100% - 16px);
height: 60px;
float:left; /* we float a */
}
.b {
width: 70px;
height: 30px;
display: inline-block;
}
.c {
height: 100px;
width: calc(100% - 16px);
max-width: 240px;
float:left; /* and we float c */
clear:left; /* don't forget this to make "c" always below "a" */
}
<div class="box">
<div class="a" style="border: 4px solid red;">a</div>
<div class="c" style="border: 4px solid orange;">c</div>
<div class="b" style="border: 4px solid green;">b</div>
</div>
One way (using mobile-first approach) would be set the .c
as your second element in the HTML
Then inside the media query you would set display:flex
to parent and the order: 1
to .c
* {
box-sizing: border-box;
margin: 0
}
.wrap {
width: 50%;
border: 4px solid blue;
}
.wrap>div {
border-width: 4px;
border-style: solid;
margin: 8px;
}
.a {
width: 100px;
height: 60px;
border-color: red
}
.b {
width: 70px;
height: 30px;
border-color: green
}
.c {
width: calc(100% - 16px);
height: 100px;
border-color: orange;
}
@media (min-width: 600px) {
.wrap {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
}
.c {
order: 1
}
}
<div class="wrap">
<div class="a">a</div>
<div class="c">c</div>
<div class="b">b</div>
</div>
One good rule of thumb is to always start from the mobile layout. Use grid-template-areas and make sure that the sizes of the surrounding areas are well defined, using grid-template-columns and grid-template-rows. Always use fr
values when specifying the columns and rows.
Please consider reading MDN Docs on CSS Grid and MDN Docs on Media queries for responsive design. CSS Grid will make your life easier but it takes time learning.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
box-sizing: border-box;
}
.container {
width: auto;
height: 300px;
border: 4px solid blue;
margin: 8px;
display: grid;
grid-template-columns: 1fr;
grid-template-rows: auto auto auto;
grid-template-areas:
"a"
"c"
"b";
}
.red-box {
grid-area: a;
width: 100px;
height: 60px;
border: 4px solid red;
margin: 8px;
}
.green-box {
grid-area: b;
width: 70px;
height: 30px;
border: 4px solid green;
margin: 8px;
}
.orange-box {
grid-area: c;
width: 100%;
max-width: 240px;
height: 100px;
border: 4px solid orange;
margin: 8px;
}
@media screen and (min-width: 768px) {
.container {
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr;
grid-template-areas:
"a . b"
"c c .";
margin: 0;
padding: 8px;
grid-gap: 21px;
}
.red-box {
width: 100%;
margin: 0;
}
.green-box {
width: 100%;
height: 100%;
margin: 0;
}
.orange-box {
padding-top: 21px;
max-width: 100%;
height: 100%;
margin: 0;
}
}
</style>
</head>
<body>
<div class="container">
<div class="red-box">a</div> <!-- red ends -->
<div class="green-box">b</div> <!-- green ends -->
<div class="orange-box">c</div> <!-- orange ends -->
</div> <!-- container ends -->
</body>
</html>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With