问题
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>
But this not only wraps the elements in the wrong order, it also makes C stick out of the container.
回答1:
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>
回答2:
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>
回答3:
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>
来源:https://stackoverflow.com/questions/64948263/is-there-a-way-to-change-the-order-of-items-when-wrapping