问题
I'm trying to build myself a flexbox with the following design:
My html looks like this (and I would like to NOT change this):
<div class="wrapper">
<div class="page-header">Heading</div>
<h3 class="right_1">right_1</h3>
<div class="right_2">right_2</div>
<div class="left">form element</div>
<h3 class="right_3">right_3</h3>
<div class="right_4">right_4</div>
</div>
This is the standard layout of the joomla contact page. I want to change the design though without altering html/php code.
Is that possible using flexbox?
And can I use @media
queries to make right_1
- right_4
to move under left
on mobile view (< 800px or example)?
I myself cannot get it to work, I always end up with right_1
- right_4
next to each other instead of them stacking to the total height of the left portion.
回答1:
The layout you want cannot be achieved with flexbox. The reasons are explained here:
- Is it possible for flex items to align tightly to the items above them?
However, the layout is relatively simple with CSS Grid.
There are, in fact, multiple methods for building the layout with Grid. I'll use the grid-template-areas property, which allows you to lay out your elements using ASCII art.
.wrapper {
display: grid;
height: 100vh;
grid-template-columns: 1fr 1fr;
grid-template-areas:
" heading heading "
" left_ right1 "
" left_ right2 "
" left_ right3 "
" left_ right4 "
}
.page-header { grid-area: heading; }
.right_1 { grid-area: right1; }
.right_2 { grid-area: right2; }
.right_3 { grid-area: right3; }
.right_4 { grid-area: right4; }
.left { grid-area: left_; } /* "left" is a pre-defined CSS keyword,
so it may not work */
@media ( max-width: 800px ) {
.wrapper {
grid-template-columns: 1fr;
grid-template-areas:
" heading "
" left_ "
" right1 "
" right2 "
" right3 "
" right4 "
}
}
/* non-essential decorative styles */
.page-header { background-color: red; }
.right_1 { background-color: chartreuse; }
.right_2 { background-color: aqua; }
.right_3 { background-color: skyblue; }
.right_4 { background-color: black; color: white; }
.left { background-color: cornsilk; }
body { margin: 0; }
.wrapper > * {
font-weight: bold;
font-size: 1.5em;
border: 1px solid black;
margin: 0;
display: flex;
justify-content: center;
align-items: center;
}
<div class="wrapper">
<div class="page-header">Heading</div>
<h3 class="right_1">right_1</h3>
<div class="right_2">right_2</div>
<div class="left">form element</div>
<h3 class="right_3">right_3</h3>
<div class="right_4">right_4</div>
</div>
jsFiddle demo
In essence, here's how it works:
- We establish a block-level grid with
display: grid
. - With
grid-template-columns: 1fr 1fr
we are telling the grid to create two columns. Thefr
unit tells the container to consume available space. It's similar to flexbox'sflex-grow
property. So both columns will share the full width of the container. - The
grid-template-areas
property allows you to lay out named grid areas (that you have defined) to create a visual representation of your layout using ASCII art. - In the media query for smaller screens, we remove one column and re-order the grid areas.
Browser Support for CSS Grid
- Chrome - full support as of March 8, 2017 (version 57)
- Firefox - full support as of March 6, 2017 (version 52)
- Safari - full support as of March 26, 2017 (version 10.1)
- Edge - full support as of October 16, 2017 (version 16)
- IE11 - no support for current spec; supports obsolete version
Here's the complete picture: http://caniuse.com/#search=grid
回答2:
Here is one way to solve that, based on the existing markup and CSS Flexbox.
The left
needs to be absolute positioned for desktop view and the page-header
need a fixed height.
If you don't want to set a fixed height, you'll need a script that takes care of the height calculation
html, body {
margin: 0;
}
.wrapper {
position: relative;
display: flex;
flex-direction: column;
min-height: 100vh;
}
.wrapper * {
padding: 0 10px;
margin: 0;
border: 1px solid black;
box-sizing: border-box;
}
.page-header {
height: 70px;
width: 100%;
background: red;
}
.right_1, .right_2, .right_3, .right_4 {
flex: 1;
width: 50%;
margin-left: 50%;
background: lightblue;
}
.left {
position: absolute;
left: 0;
top: 70px;
width: 50%;
min-height: calc(100vh - 70px);
background: yellow;
}
@media only screen and (orientation: portrait) {
.wrapper * {
width: 100%;
margin: 0;
}
.left {
position: static;
flex: 1;
min-height: auto;
order: -1
}
.page-header {
order: -2;
}
}
<div class="wrapper">
<div class="page-header">Heading</div>
<h3 class="right_1">right_1</h3>
<div class="right_2">right_2</div>
<div class="left">form element</div>
<h3 class="right_3">right_3</h3>
<div class="right_4">right_4</div>
</div>
回答3:
Probably the easiest way to change the order of div elements, you can use Jquery for this purpose. For example:
$("#element1").before($("#element2"));
Eventually:
CSS:
#blocks {
display: box;
box-orient: vertical;
}
#b1 {
box-ordinal-group: 2;
}
#b2 {
box-ordinal-group: 3;
}
HTML:
<div id="blocks">
<div id="b1">Block 1</div>
<div id="b2">Block 2</div>
<div id="b3">Block 3</div>
</div>
It should work.
来源:https://stackoverflow.com/questions/44051482/problems-building-a-flexbox-grid