网格布置中的框对齐方式 | CSS Grid Layout: Box Alignment in CSS Grid Layout
CSS网格布局:CSS网格布局中的框对齐
如果您熟悉flexbox,那么您可能已经知道了让flex项目在Flex容器内正确对齐的方法。我们在flexbox规范中首次遇到的这些对齐属性已被移入一个称为Box Alignment Level 3的新规范中。本规范详细说明了对齐如何在所有不同的布局方法中起作用。
实现Box Alignment的每种布局方法都会有一些差异,因为每种方法都有不同的特性和约束(以及传统行为),因此无法以完全相同的方式进行对齐。Box Alignment规范详细介绍了每种方法,但如果您现在尝试使用多种方法进行对齐,您会感到失望,因为对此的浏览器支持尚不存在。我们在浏览器中支持框对齐规范中的对齐和空间分布属性是网格布局。在本指南中,我将演示这些工作如何。您将在Flexbox中看到这些属性和值如何工作的许多相似之处。由于网格是二维的,且flexbox是一维,因此您应该注意一些小的差异。
网格布局的两个轴。
在使用网格布局时,可以使用两个轴来对齐块,列或轴
以及内联或行,轴
。块轴是以块布局布置块的轴。如果你的页面上有两个段落,则它们显示为一个在另一个下面,所以这个方向我们称之为块轴。在CSS网格布局规范中,它被称为列轴,因为这是我们列轨道运行的轴向。
内联轴
跨过块轴线运行时,它是文本在常规内联流内运行的方向。在CSS网格布局规范中,有时将它称为行轴,即我们的行轨道沿其运行的轴。
我们可以对齐网格区域内的内容,网格可以在这两个轴上跟踪它们自己。
对齐块,或列Axis上的项目
align-self
和align-items
属性控制块轴的对齐方式。当我们使用这些属性时,我们正在更改放置它的网格区域内的项目的对齐方式。
在下面的例子中,我的网格中有四个网格区域。我可以使用网格容器上的align-items
属性,即使用以下值之一对齐项目:
auto
normal
start
end
center
stretch
baseline
first baseline
last baseline
.wrapper {
display: grid;
grid-template-columns: repeat(8, 1fr
grid-gap: 10px;
grid-auto-rows: 100px;
grid-template-areas:
"a a a a b b b b"
"a a a a b b b b"
"c c c c d d d d"
"c c c c d d d d";
align-items: start;
}
.item1 {
grid-area: a;
}
.item2 {
grid-area: b;
}
.item3 {
grid-area: c;
}
.item4 {
grid-area: d;
}
<div class="wrapper">
<div class="item1">Item 1</div>
<div class="item2">Item 2</div>
<div class="item3">Item 3</div>
<div class="item4">Item 4</div>
</div>
align-items
属性设置align-self
所有子网格项目的属性。这意味着您可以通过使用align-self
网格项目单独设置属性。
在下一个示例中,我使用align-self
属性来演示不同的对齐值。第一个区域显示的是默认行为align-self
,即拉伸。第二个项目的align-self
值是start
第三个end
和第四个center
。
.wrapper {
display: grid;
grid-template-columns: repeat(8, 1fr
grid-gap: 10px;
grid-auto-rows: 100px;
grid-template-areas:
"a a a a b b b b"
"a a a a b b b b"
"c c c c d d d d"
"c c c c d d d d";
}
.item1 {
grid-area: a;
}
.item2 {
grid-area: b;
align-self: start;
}
.item3 {
grid-area: c;
align-self: end;
}
.item4 {
grid-area: d;
align-self: center;
}
<div class="wrapper">
<div class="item1">Item 1</div>
<div class="item2">Item 2</div>
<div class="item3">Item 3</div>
<div class="item4">Item 4</div>
</div>
具有固有长宽比的项目
规范详细说明了默认行为align-self
是拉伸的,除了具有固有纵横比的项目,在这种情况下,它们的行为如同start
。原因是,如果具有纵横比的项目设置为伸展,则此缺省会扭曲它们。
这个行为现在已经在规范中得到澄清,但浏览器还没有实现正确的行为。在这种情况发生之前,您可以通过设置align-self
和justify-self
启动来确保项目不会拉伸,如图像,它们是网格的直接子节点。这将确保正确行为。
调整行内或行轴上的项目
当align-items
和align-self
处理块轴上项目的对齐方式时,justify-items
和justify-self
在内联轴或行轴上执行相同的工作。您可以选择的值与align-self
相同。
auto
normal
start
end
center
stretch
baseline
first baseline
last baseline
你可以在align-items
下面看到同样的例子。这一次,我们正在应用该justify-self
属性。
再次强调一次,除了具有固有宽高比的项目之外,stretch
为默认值。这意味着默认情况下,网格项目将覆盖它们的网格区域,除非您通过设置对齐来更改网格区域。示例中的第一项演示了此默认对齐方式:
.wrapper {
display: grid;
grid-template-columns: repeat(8, 1fr
grid-gap: 10px;
grid-auto-rows: 100px;
grid-template-areas:
"a a a a b b b b"
"a a a a b b b b"
"c c c c d d d d"
"c c c c d d d d";
}
.item1 {
grid-area: a;
}
.item2 {
grid-area: b;
justify-self: start;
}
.item3 {
grid-area: c;
justify-self: end;
}
.item4 {
grid-area: d;
justify-self: center;
}
<div class="wrapper">
<div class="item1">Item 1</div>
<div class="item2">Item 2</div>
<div class="item3">Item 3</div>
<div class="item4">Item 4</div>
</div>
同align-self
和align-items
一样,您可以应用justify-items
到网格容器,为所有项目设置justify-self
值。
justify-self
和justify-items
属性没有在Flexbox中实现。这是由于flexbox的一维性质,并且沿轴可能有多个项目,使得无法证明单个项目是合理的。要沿flexbox中的主轴,内联轴对齐项目,请使用该justify-content
属性。
居中区域中的项目
通过结合align和justify属性,我们可以轻松地将项目置于网格区域内。
.wrapper {
display: grid;
grid-template-columns: repeat(4, 1fr
grid-gap: 10px;
grid-auto-rows: 200px;
grid-template-areas:
". a a ."
". a a .";
}
.item1 {
grid-area: a;
align-self: center;
justify-self: center;
}
<div class="wrapper">
<div class="item1">Item 1</div>
</div>
对齐块或列轴上的网格轨道
如果您的网格轨道使用比网格容器小的区域,则可以在该容器内对齐网格轨道本身。这再次在块和内联轴上运行,使用align-content
对齐块轴上的轨迹,以及justify-content
在内联轴上执行对齐。的值align-content
和justify-content
是:
normal
start
end
center
stretch
space-around
space-between
space-evenly
baseline
first baseline
last baseline
在下面的例子中,我有一个500像素乘500像素的网格容器。我已经定义了3个行和列的轨道,每个100个像素和一个10像素的分割线。这意味着网格容器内部的空间都在块和内嵌方向上。
align-content
属性应用于网格容器,因为它在整个网格上工作。网格布局中的默认行为是start
,这就是为什么我们的网格轨道位于网格的左上角,与开始网格线对齐:
.wrapper {
display: grid;
grid-template-columns: repeat(3, 100px
grid-template-rows: repeat(3,100px
height: 500px;
width: 500px;
grid-gap: 10px;
grid-template-areas:
"a a b"
"a a b"
"c d d";
}
.item1 {
grid-area: a;
}
.item2 {
grid-area: b;
}
.item3 {
grid-area: c;
}
.item4 {
grid-area: d;
}
<div class="wrapper">
<div class="item1">Item 1</div>
<div class="item2">Item 2</div>
<div class="item3">Item 3</div>
<div class="item4">Item 4</div>
</div>
如果我添加align-content
到我的容器中,值为end
,轨道全部移动到块维度中的网格容器的末行:
.wrapper {
display: grid;
grid-template-columns: repeat(3, 100px
grid-template-rows: repeat(3,100px
height: 500px;
width: 500px;
grid-gap: 10px;
grid-template-areas:
"a a b"
"a a b"
"c d d";
align-content: end;
}
.item1 {
grid-area: a;
}
.item2 {
grid-area: b;
}
.item3 {
grid-area: c;
}
.item4 {
grid-area: d;
}
<div class="wrapper">
<div class="item1">Item 1</div>
<div class="item2">Item 2</div>
<div class="item3">Item 3</div>
<div class="item4">Item 4</div>
</div>
我们也可以使用flexbox中熟悉的属性值; 如空间分布的值space-between
,space-around
和space-evenly
。如果我们将align-content
变为space-between
,您可以看到我们网格上的元素如何是如何分隔的:
.wrapper {
display: grid;
grid-template-columns: repeat(3, 100px
grid-template-rows: repeat(3,100px
height: 500px;
width: 500px;
grid-gap: 10px;
grid-template-areas:
"a a b"
"a a b"
"c d d";
align-content: space-between;
}
.item1 {
grid-area: a;
}
.item2 {
grid-area: b;
}
.item3 {
grid-area: c;
}
.item4 {
grid-area: d;
}
<div class="wrapper">
<div class="item1">Item 1</div>
<div class="item2">Item 2</div>
<div class="item3">Item 3</div>
<div class="item4">Item 4</div>
</div>
值得注意的是,使用这些空间分布值可能会导致网格上的项目变大。如果一个项目跨越多个网格轨道,由于在轨道之间增加了更多空间,该项目需要变大才能吸收空间。我们一直在严格的网格中工作。因此,如果您决定使用这些值,请确保曲目的内容可以处理额外的空间,或者您已使用项目的对齐属性,使得它们移动到开始位置而不是延伸位置。
在下面的图片中,我已经放置了align-content
属性设为start
的网格且网格的align-content
属性的值为space-between
。您可以看到项目1和2(跨越两行轨道)是如何获得额外高度的,因为它们获得了添加到这两条轨道之间的间隙中的额外空间:
调整行轴上的网格轨道
在内联轴上,我们可以使用justify-content
来执行与align-content
在块轴中的相同类型的对齐。
使用相同的例子,我设置justify-content
为space-around
。这再次导致跨越多个列轨道的轨道获得额外的空间:
.wrapper {
display: grid;
grid-template-columns: repeat(3, 100px
grid-template-rows: repeat(3,100px
height: 500px;
width: 500px;
grid-gap: 10px;
grid-template-areas:
"a a b"
"a a b"
"c d d";
align-content: space-between;
justify-content: space-around;
}
.item1 {
grid-area: a;
}
.item2 {
grid-area: b;
}
.item3 {
grid-area: c;
}
.item4 {
grid-area: d;
}
<div class="wrapper">
<div class="item1">Item 1</div>
<div class="item2">Item 2</div>
<div class="item3">Item 3</div>
<div class="item4">Item 4</div>
</div>
对齐和自动边距
对齐区域内物品的另一种方法是使用自动边距。如果您曾将视图中的布局居中,则通过将容器块的左右边距设置为auto
,您知道自动边距会吸收所有可用空间。通过将边距设置在auto
两侧,将边框推到中间,因为两边都尝试占据所有空间。
在下一个例子中,我给项目1一个左边界auto
。您可以看到如何将内容推送到该区域的右侧,因为在为该项目的内容指定了空间之后,自动边距会占用剩余空间:
.wrapper {
display: grid;
grid-template-columns: repeat(3, 100px
grid-template-rows: repeat(3,100px
height: 500px;
width: 500px;
grid-gap: 10px;
grid-template-areas:
"a a b"
"a a b"
"c d d";
}
.item1 {
grid-area: a;
margin-left: auto;
}
.item2 {
grid-area: b;
}
.item3 {
grid-area: c;
}
.item4 {
grid-area: d;
}
<div class="wrapper">
<div class="item1">Item 1</div>
<div class="item2">Item 2</div>
<div class="item3">Item 3</div>
<div class="item4">Item 4</div>
</div>
您可以通过使用Firefox Grid Highlighter查看项目是如何对齐的:
对齐与书写模式
在所有这些例子中,我一直在用英语工作,这是一种从左到右的语言。这意味着我们的起点线在我们的网格的顶部和左侧当在物理方向上思考时。
CSS网格布局和“框对齐”规范旨在与CSS中的书写模式一起使用。这意味着如果您正在从右向左语言(如阿拉伯语)工作,则网格的开始位置将是最上方的右侧。这意味着默认的justify-content: start
网格轨道将从网格的右侧开始。但是设置自动边距,使用margin-right
或margin-left
,或使用绝对定位的项目top
,right
,bottom
和left
偏移量不会兑现写作模式。在下一个指南中,我们将进一步探讨CSS网格布局,框对齐和书写模式之间的交互。如果您开发以多种语言显示的网站,或者希望在设计中混合使用语言或书写模式,这一点很重要。