网格布局与其他布局方法的关系 | CSS Grid Layout: Relationship of Grid Layout
CSS网格布局:网格布局的关系
CSS网格布局被设计为与CSS的其他部分一起工作,作为完成布局的完整系统的一部分。在本指南中,我将解释网格是如何与您可能已经使用的其他技术结合在一起的。
网格和挠曲箱
CSS网格布局与CSS Flexbox布局柔性箱是为一维布局而设计的吗?或
一列。网格是为二维布局,行和列同时布局而设计的.。然而,这两种规范有一些共同的特性,如果您已经学习了如何使用Flexbox,那么希望您能够看到帮助您掌握Grid的相似之处。
一维与二维布局
一个简单的例子可以说明一维和二维布局的区别。
在第一个例子中,我使用Flexbox来布局一组盒子。我在我的容器中有五个子项目,我给出了FLEX属性值,这样它们就可以从200像素的弹性基础上生长和收缩。
我还设置了flex-wrap
财产wrap
这样,如果容器中的空间变得太窄,无法维护FLEX基础,则项目将被包装到新的行上。
<div class="wrapper">
<div>One</div>
<div>Two</div>
<div>Three</div>
<div>Four</div>
<div>Five</div>
</div>
.wrapper {
display: flex;
flex-wrap: wrap;
}
.wrapper > div {
flex: 1 1 200px;
}
在图像中,您可以看到两个项目已包装到一个新的行。这些项目共享可用空间,而不是在上面的项目下面排队。这是因为当您包装FLEX项时,每一行%28或每列在按列%29工作时都会成为一个新的FLEX容器。空间分布发生在行的两侧。
一个常见的问题是如何使这些项目排列起来。这就是您需要二维布局方法的地方:您希望通过行和列来控制对齐,这就是网格出现的地方。
CSS网格的相同布局
在下一个示例中,我使用Grid创建相同的布局。这次我们有三个1fr
柱轨。我们不需要在项目本身上设置任何东西;它们会将自己放置到创建的网格的每个单元中。正如您所看到的,它们保持在一个严格的网格中,排列成行和列。有五个项目,我们在第二行的末尾有一个缺口。
<div class="wrapper">
<div>One</div>
<div>Two</div>
<div>Three</div>
<div>Four</div>
<div>Five</div>
</div>
.wrapper {
display: grid;
grid-template-columns: repeat(3, 1fr
}
在决定网格还是柔性箱时,一个简单的问题是:
- 我只需要按行控制布局吗?
或
列-使用挠曲盒
- 我需要按行控制布局吗?
和
列-使用网格
内容还是布局?
除了一维和二维的区别之外,还有另一种方法来决定是否应该使用柔性盒或网格来进行布局。Flexbox从内容开始工作。柔性箱的一个理想的用例是,当您有一组项目,并希望将它们均匀地放置在容器中时。您可以让内容的大小决定每一项占用的单独空间。如果项目换到一个新行,它们将根据其大小和可用空间计算出它们的间距。在那条线上
...
网格从布局开始工作。当您使用css网格布局时,您创建一个布局,然后将项目放入其中,或者允许自动放置规则根据严格的网格将项目放置到网格单元格中。有能力创建的轨道,以响应的大小的内容,但他们也将改变整个轨道。
如果您正在使用Flexbox,并且发现自己禁用了一些灵活性,那么您可能需要使用CSSGrid布局。一个例子是,如果您正在为一个FLEX项目设置一个百分比宽度,使其与上面一行中的其他项对齐。在这种情况下,网格可能是一个更好的选择。
盒对齐
最令我们兴奋的是,柔韧性盒的特点是它首次给了我们正确的对齐控制。这使得在页面上居中一个框变得容易了。FLEX项可以伸展到FLEX容器的高度,这意味着可以使用等高列。这些都是我们很长时间以来一直想做的事情,并且想出了各种方法来创造视觉效果。
柔性盒规范中的对齐属性已添加到一个名为盒对齐级别3这意味着它们可以用于其他规范,包括网格布局。将来,它们也可以应用于其他布局方法。
在本系列的后续指南中,我将适当地了解Box对齐以及它在网格布局中的工作方式。然而,这里有一个比较柔性箱和网格的简单例子。
在第一个例子中,它使用了Flexbox,我有一个容器,里面有三个条目。包装器min-height
设置,因此它定义了FLEX容器的高度。我已经准备好了align-items
在Flex容器上flex-end
因此,这些项目将在FLEX容器的末尾排队。我还设置了align-self
财产上box1
因此,它将覆盖缺省值,并伸展到容器的高度和box2
因此它对齐了Flex容器的开始。
<div class="wrapper">
<div class="box1">One</div>
<div class="box2">Two</div>
<div class="box3">Three</div>
</div>
.wrapper {
display: flex;
align-items: flex-end;
min-height: 200px;
}
.box1 {
align-self: stretch;
}
.box2 {
align-self: flex-start;
}
CSS网格对齐
第二个例子使用网格创建相同的布局。这一次,我们使用框对齐属性,因为它们适用于网格布局。所以我们要start
和end
而不是flex-start
和flex-end
在网格布局的情况下,我们对齐它们的网格区域内的项目。在这种情况下,这是一个单一的网格单元,但它可以是一个区域由几个网格单元。
<div class="wrapper">
<div class="box1">One</div>
<div class="box2">Two</div>
<div class="box3">Three</div>
</div>
.wrapper {
display: grid;
grid-template-columns: repeat(3,1fr
align-items: end;
grid-auto-rows: 200px;
}
.box1 {
align-self: stretch;
}
.box2 {
align-self: start;
}
fr单位和flex-basis
我们已经看到fr
单元的工作是将网格容器中可用空间的一部分分配给我们的网格轨道。大fr
单位,当与minmax()
函数可以给出非常类似于flex
属性在柔性盒-同时仍然能够创建一个二维布局。
如果我们回顾一下我演示了三维布局之间的差异的例子,您会发现这两种布局的工作方式是不同的。使用FLEX布局,如果我们将窗口拖得越来越宽,那么FLEX框就很好地处理了根据可用空间调整每一行中的项目数的问题。如果我们有很大的空间,所有的五个项目都可以容纳在一行,如果我们有一个非常狭窄的容器,我们可能只有一个空间。
相比之下,网格版本总是有三条列轨。轨道本身将增长和缩小,但总有三个,正如我们要求的三个在定义我们的网格。
自动填网轨道
通过使用重复表示法和auto-fill
和auto-fit
财产。
在下一个示例中,我使用了auto-fill
关键字替换重复表示法中的整数,并将轨道列表设置为200像素。这意味着网格将创建多达200像素的列轨迹,以适应容器。
<div class="wrapper">
<div>One</div>
<div>Two</div>
<div>Three</div>
</div>
.wrapper {
display: grid;
grid-template-columns: repeat(auto-fill, 200px
}
灵活的轨道数目
这和柔性箱不太一样。在柔性盒示例中,项目在包装前大于200像素基础。我们可以在网格中通过合并来实现相同的目标。auto-fill
而minmax()
功能。在下一个示例中,我使用minmax
.我希望我的音轨至少是200像素,然后我把最大的1fr
一旦浏览器计算出了200像素放入容器中的次数--同时考虑到网格间隙--它将处理1fr
最大限度地作为在项目之间分配剩余空间的指示。
<div class="wrapper">
<div>One</div>
<div>Two</div>
<div>Three</div>
</div>
.wrapper {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)
}
我们现在可以创建一个具有灵活数量的灵活轨道的网格,但是可以看到网格上的项目同时按行和列排列。
网格和绝对定位元素
网格与绝对定位的元素进行交互,如果要将项放置在网格或网格区域中,这将非常有用。该规范定义了网格容器是包含块时的行为,以及网格容器是绝对定位项的父项的行为。
作为包含块的网格容器
要使网格容器成为包含块,您需要向容器中添加一个相对值的位置属性,就像为任何其他绝对定位的项创建包含块一样。一旦您完成了此操作,如果您给出了一个网格项position:
absolute
它将把网格容器作为其包含的块,或者,如果项目也有网格位置,则将其放置到的网格中。
在下面的示例中,我有一个包含四个子项的包装器。第三项是绝对定位的,并且也使用基于线的布局放置在网格上。网格容器position:
relative
因此成为这个项目的定位上下文。
<div class="wrapper">
<div class="box1">One</div>
<div class="box2">Two</div>
<div class="box3">
This block is absolutely positioned. In this example the grid container is the containing block and so the absolute positioning offset values are calculated in from the outer edges of the area it has been placed into.
</div>
<div class="box4">Four</div>
</div>
.wrapper {
display: grid;
grid-template-columns: repeat(4,1fr
grid-auto-rows: 200px;
grid-gap: 20px;
position: relative;
}
.box3 {
grid-column-start: 2;
grid-column-end: 4;
grid-row-start: 1;
grid-row-end: 3;
position: absolute;
top: 40px;
left: 40px;
}
您可以看到,该项将从网格行第2行到第4行,并从第1行之后开始。然后,使用顶部和左侧属性在该区域进行偏移。然而,它已经被从流程中拿出来了,因为通常是绝对定位的物品,所以自动放置规则现在把物品放置在相同的空间里。该项也不会导致创建额外的行以跨越第3行。
如果我们把position:
absolute
从规则.box3
您可以看到它在没有定位的情况下将如何显示。
作为父级的网格容器
如果绝对定位的子节点有一个网格容器作为父容器,但是该容器没有创建新的定位上下文,那么它就会像前面的示例一样从流中取出。定位上下文将是任何元素创建的定位上下文,这与其他布局方法相同。在我们的情况下,如果我们删除position:
relative
从上面的包装器中,定位上下文来自viewport,如下图所示。
再一次,该项目不再参与网格布局的大小调整或其他项目是自动放置。
以网格区域作为父区域。
如果绝对定位项嵌套在网格区域内,则可以在该区域上创建定位上下文。在下面的例子中,我们像以前一样有网格,但是这次我在里面嵌套了一个条目.box3
在电网里。
我给了.box3
定位相对项,然后使用偏移量属性定位子项。在这种情况下,定位上下文是网格区域。
<div class="wrapper">
<div class="box1">One</div>
<div class="box2">Two</div>
<div class="box3">Three
<div class="abspos">
This block is absolutely positioned. In this example the grid area is the containing block and so the absolute positioning offset values are calculated in from the outer edges of the grid area.
</div>
</div>
<div class="box4">Four</div>
</div>
.wrapper {
display: grid;
grid-template-columns: repeat(4,1fr
grid-auto-rows: 200px;
grid-gap: 20px;
}
.box3 {
grid-column-start: 2;
grid-column-end: 4;
grid-row-start: 1;
grid-row-end: 3;
position: relative;
}
.abspos {
position: absolute;
top: 40px;
left: 40px;
background-color: rgba(255,255,255,.5
border: 1px solid rgba(0,0,0,0.5
color: #000;
padding: 10px;
}
网格和display:contents
与另一个值得注意的布局规范的最后交互是CSS网格布局和display:
contents
...contents
属性中描述的新值。显示规格详情如下:
“元素本身不生成任何框,但是它的子元素和伪元素仍然生成正常的框。为了生成框和布局,必须将元素视为文档树中的子元素和伪元素。“
如果您将项目设置为display:
contents
它通常会创建的框消失了,子元素的框看起来就好像它们已经上升了一个级别。这意味着网格项的子元素可以成为网格项。听起来很奇怪?下面是一个简单的例子。在下面的标记中,我有一个网格,网格上的第一个项被设置为跨越所有三个列轨道。它包含三个嵌套项。由于这些项不是直接子元素,因此它们不会成为网格布局的一部分,因此使用常规块布局来显示。
<div class="wrapper">
<div class="box box1">
<div class="nested">a</div>
<div class="nested">b</div>
<div class="nested">c</div>
</div>
<div class="box box2">Two</div>
<div class="box box3">Three</div>
<div class="box box4">Four</div>
<div class="box box5">Five</div>
</div>
.wrapper {
display: grid;
grid-template-columns: repeat(3, 1fr
grid-auto-rows: minmax(100px, auto
}
.box1 {
grid-column-start: 1;
grid-column-end: 4;
}
如果我现在加上display:
contents
对……的规则box1
,该项目的框消失了,子项现在成为网格项,并使用自动放置规则自行布局。
<div class="wrapper">
<div class="box box1">
<div class="nested">a</div>
<div class="nested">b</div>
<div class="nested">c</div>
</div>
<div class="box box2">Two</div>
<div class="box box3">Three</div>
<div class="box box4">Four</div>
<div class="box box5">Five</div>
</div>
.wrapper {
display: grid;
grid-template-columns: repeat(3, 1fr
grid-auto-rows: minmax(100px, auto
}
.box1 {
grid-column-start: 1;
grid-column-end: 4;
display: contents;
}
这可以使嵌套在网格中的项充当网格的一部分,并且是解决子网格实现后将解决的一些问题的一种方法。您也可以使用display:
contents
以类似的方式使用Flexbox,使嵌套的项成为FLEX项。
从本指南中可以看到,CSS网格布局只是工具包的一部分。不要害怕把它和其他的布局方法混合起来,以获得你需要的不同效果。