构建flexbox网格的问题

时间:2017-05-18 15:07:29

标签: html css css3 flexbox css-grid

我正在尝试使用以下设计构建自己的flexbox:

我的HTML看起来像这样(我不想改变这个):

<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>

这是joomla联系页面的标准布局。我想在不改变html / php代码的情况下改变设计。

使用flexbox可以吗?

我是否可以使用@media次查询使right_1 - right_4在移动视图下移至left下(&lt; 800px或示例)?

我自己无法让它工作,我总是以right_1 - right_4彼此相邻,而不是堆叠到左侧部分的总高度。

3 个答案:

答案 0 :(得分:3)

使用flexbox无法实现所需的布局。原因在这里解释:

但是,Is it possible for flex items to align tightly to the items above them?的布局相对简单。

实际上,有多种方法可以使用Grid构建布局。我将使用CSS Grid属性,它允许您使用ASCII艺术布局元素。

.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>

grid-template-areas

从本质上讲,这是它的工作原理:

  1. 我们使用display: grid建立块级网格。
  2. 使用grid-template-columns: 1fr 1fr,我们告诉网格创建两列。 fr单元告诉容器消耗可用空间。它类似于flexbox的flex-grow属性。因此,两列将共享容器的整个宽度。
  3. grid-template-areas属性允许您布置命名网格区域(已定义),以使用ASCII艺术创建布局的直观表示。
  4. 在较小屏幕的媒体查询中,我们删除一列并重新排序网格区域。
  5. CSS网格的浏览器支持

    • Chrome - 完全支持截至2017年3月8日(第57版)
    • Firefox - 完全支持截至2017年3月6日(第52版)
    • Safari - 完全支持截至2017年3月26日(版本10.1)
    • Edge - 截至2017年10月16日(第16版)的全面支持
    • IE11 - 不支持当前规范;支持过时版本

    以下是完整图片:jsFiddle demo

答案 1 :(得分:2)

基于现有的标记和CSS Flexbox,这是解决这个问题的一种方法。

left需要绝对定位于桌面视图,page-header需要固定的高度。

如果您不想设置固定高度,则需要一个负责高度计算的脚本

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>

答案 2 :(得分:0)

可能是更改div元素顺序的最简单方法,您可以使用Jquery来实现此目的。例如:

$("#element1").before($("#element2"));

最后:

<强> 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>

它应该有用。