如何使Flexbox跨越多条线?

时间:2014-07-31 04:45:27

标签: css css3 flexbox

我想使用CSS Flexbox 属性来制作某种网格,其中元素可能跨越多行。

以下是基本的HTML源代码:

<section class="group">
    <h1>...</h1>
    <section class="item">...</section>
    <section class="item">...</section>
    <section class="item">...</section>
    <section class="item">...</section>
    <section class="item">...</section>
    <section class="item">...</section>
</section>

这就是我想要实现的目标:

enter image description here

section.group内,我希望h1为100%宽,每个section.item为50%宽,排列在 n ×2网格中,其中 n 取决于内部sections的数量,这可能会发生变化。

我无法更改HTML,这意味着我无法使用非语义section.item来包装div。我只能使用CSS。这是我到目前为止所做的:

.group {
   display: flex;
}
.group h1 {}
.group .item {}

(开始时间不多)

如何使用 Flexbox模块来实现此目标?

2 个答案:

答案 0 :(得分:5)

首先,请确保flex-direction设置为rowrow-reverse,因为我们希望水平布局项目(从左到右或从右到左)。但实际上,flex-direction: row;是默认的,因此我们并不明确需要它。它只适合初学者。

然后,为了确保框中断多个轨道,请添加flex-wrap: wrap;

.group {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
}

现在我们必须调整项目的大小。 TLDR:

.group h1    { flex: 100%; } /* flex: 1 1 100%; */
.group .item { flex:  50%; } /* flex: 1 1  50%; */

如果您想知道原因,请继续阅读。否则就是这样!


默认情况下,每个Flex项的主要大小(在本例中为水平大小或宽度)都会延迟其width属性的指定值。乍一看,我们可能只想声明宽度:

/* NOPE!
.group h1    { width: 100%; }
.group .item { width:  50%; }
*/

然而,这不是非常适合未来的,因为我们可能希望稍后改变弹性方向,例如我们以垂直书写模式书写,或者即使我们只想交换布局。如果flex-directioncolumncolumn-reverse,那么设置宽度将无法获得我们想要的效果。我们真的希望确定主尺寸的尺寸,这是flex的用途。

(这是flex的一个非常基本的用法,但它实际上更多......嗯... 灵活 ....阅读有关MDN上flex shorthand property的更多信息。 )

以及CSS3 specsMDN guide中有关flexbox的更多信息。

答案 1 :(得分:2)

我的第一个答案是关于使用Flexbox来实现布局。

在这个答案中我谈到了网格。

要直接跳到这一点,应该在这种情况下使用CSS Grid。 Flexbox适用于一维布局,或者在包装行(或列)时,包装可以在我们无法控制的任何位置任意发生。

当我们想要完全控制行的行时。 CSS Grid是我们的解决方案。 CSS Grid也更容易,因为我们只需要设置网格容器的样式,而不是它的任何子容器。当然也有例外,比如我们的标题。

.group {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
}
.group h1 {
  grid-column: 1 / -1;
}

让我们分解它。

display: grid;

这是不言自明的。它设置了网格容器。

grid-template-columns: repeat(2, 1fr);

我们需要2列,每列1fr,其中fr单位是“剩余空间”。换句话说,两列共享相等数量的剩余空间。有很多方法可以写这个。

  • grid-template-columns: repeat(2, 1fr);是我们使用的,但我们可以编写
  • grid-template-columns: repeat(2, 50%);
  • grid-template-columns: 1fr 1fr;,甚至
  • grid-template-columns: 50% 50%;

这取决于您希望更改代码的频率。如果我们想要一个3列布局,那么后来可能是

  • grid-template-columns: repeat(3, 1fr);
  • grid-template-columns: repeat(3, 33.33%);
  • grid-template-columns: 1fr 1fr 1fr
  • grid-template-columns: 33.33% 33.33% 33.33%

或者说我们仍然想要2列,但我们希望左边是右边的一半 - 一对二的比例:

  • grid-template-columns: 1fr 2fr
  • grid-template-columns: 33.33% 66.67%

grid-template-columnsgrid-template-rows是非常复杂的属性,我仍然无法完全理解。甚至不要让我开始自动调整尺寸,灵活的宽度和尺寸范围。

我们要说明虽然grid-template-columns: repeat(2, auto);也是一种有效的风格,但这不是我们想要的,因为auto会根据内容对列进行调整,但我们无法确保每个列的内容都是50%宽。

grid-column: 1 / -1;

这个看起来很奇怪,但它很容易学习。 grid-columngrid-column-start / grid-column-end的简写,其中整数对定义列的行进行编号。你也可以使用名字,但这对于像我们这样简单的布局来说是过度的。

  1. 网格开头的第一行是1(非零)。
  2. 在我们的网格中,2是列之间的行,
  3. 3即将结束。
  4. 一般而言,负数从末尾倒数。因此,在我们的2列网格中,-13相同,但在3列布局中,-1将等同于4

    无论我们拥有多少列,我们都希望标题为全宽,因此它从1开始,到-1结束。

    (注意:请注意,您的预处理器可能会将斜杠解释为分割符号,编译为grid-column: -1;。不酷。所以至少在Less中,我会逃避字符串文字。我可以'为萨斯说话。)

    grid-column: ~'1 / -1'; // compiles to `grid-column: 1 / -1;`