CSS Grid:插图介绍
我记得第一次学习CSS时,我很高兴能够了解浮动和内联显示以将元素放置在所需的布局中。我想知道如果当时有二维布局系统,我会如何反应。实际上,即使是现在我也对此感到兴奋,因为它改变了一切:我们编写CSS的方式以及编写标记的方式。使用CSS网格,构建响应式,动态和源顺序无关的布局比以往任何时候都更容易。
在这篇文章中,我们将了解所有CSS网格属性,以便构建简单的布局和一些不太简单的布局。我们将定义所有内容,然后我们将深入挖矿,看看我们可以用CSS网格实现什么。话虽这么说,如果你准备好学习一种新的思考布局的方法,那就拿红色药丸我会告诉你兔子洞的深度。
1.在我们开始之前
但在我们开始之前,我想解决您可能遇到的一些问题,并确保我们熟悉CSS网格及其术语的基础知识。
Q&A
CSS网格是否取代了flex-box?
好吧,CSS网格不能取代flex-box。它们是用于不同目的的两种不同工具。实际上,它们可以很好地协同工作,我们可以在网格显示内部进行柔性显示,反之亦然。
CSS网格和flex-box有什么区别?
存在很多差异,但主要的一点是flex-box是一维布局系统而CSS网格是二维布局系统。看看下面的图1.1:
图1.1:Flex-box与CSS网格为什么不使用bootstrap?
我认为这个问题的最佳答案是Jen Simmons的引用:
我越是使用CSS Grid,我越相信通过在其上添加一层抽象没有任何好处。 CSS Grid是直接嵌入浏览器的布局框架 – Jen Simmons
CSS网格生产准备好了吗?
这取决于。你需要支持:IE,Opera mini,Blackberry浏览器还是百度手机?如果答案是否定的,那么是生产就绪,如果答案是肯定的,那么无论如何你可以使用它来支持它的浏览器(没有前缀:91.61%)使用 @supports
CSS规则:
@supports (display: grid) { div { display: grid; } }
基本
基本上,网格可以分解为两个元素:网格容器和网格项。
图1.2:基本网格
正如我们在图1.2中看到的那样,网格容器是一组列和行。一种 row
是两个连续的行线(水平线)和a之间的空格 column
是两个连续列线(垂直线)之间的空格。一行可以称为轨道,而列也是如此。一个网格 track
是两条平行网格线之间的空间。
每个轨道可以有一个或多个网格单元。网格 cell
是最基本的网格单元,因为它是最小的网格单元。它是四条相交网格线之间的空间。如果我们将多个网格单元组合在一起,我们有一个网格 area
。重要的是要提到网格区域必须是矩形的,例如我们可以具有T形网格区域。
网格线从1开始到显式或隐式定义的行数。网格线的最后一个数字可以称为-1,它之前的元素为-2,依此类推。这将在以后派上用场。
在图1.2中,列线的数量从1到6(从-6到-1),行线的数量从1到5(或-5到-1)。
考虑网格线的数量 explicit
如果你在CSS中明确设置它。它被认为是 implicit
如果它是由浏览器设置的。
最后,网格单元可以通过空间或间隙分开。这些差距被称为 gutters
,但我们通常将它们称为 gaps
:)。
2. CSS网格基本属性
好的,我们应该准备好开始实现一些网格。我们首先要讨论我们可以使用网格容器的所有属性,然后我们将看看网格项的属性。
让我们考虑本节的以下模板:
class="grid-container"> class="grid-item">grid item 1 class="grid-item">grid item 2 class="grid-item">grid item 3 class="grid-item">grid item 4 class="grid-item">grid item 5 class="grid-item">grid item 6 class="grid-item">grid item 7 class="grid-item">grid item 8 class="grid-item">grid item 9
Grid容器
显示
使用CSS定义CSS网格 grid
的价值 display
属性。为了使用上面的模板来定义研磨,我们应该这样做:
.grid-container { display: grid; }
行和列
我们可以使用。在网格上定义列和行 grid-template-rows
和 grid-template-columns
特性:
.grid-container { grid-template-columns: 1fr 1fr 1fr 1fr; grid-template-rows: 1fr auto 2fr; }
或者我们可以使用 grid-template
我们首先定义的地方 grid-template-rows
那么 grid-template-columns
(用斜线分隔):
.grid-container { grid-template: 1fr 1fr 1fr 1fr / 1fr auto 2fr; }
顺便说一句 fr
是一个分数单位,所以 1fr
是1可用空间的一部分。
重复功能
该 repeat()
function表示轨道列表的重复片段。
所以我们可以像这样实现与上面相同的模板:
.grid-container { grid-template: repeat(4, 1fr) / 1fr auto 2fr; }
Minmax功能
该 minmax()
CSS函数定义大于或等于min且小于或等于max的大小范围。
我们可以用它 repeat()
像这样:
.grid-container { grid-columns: repeat(3, minmax(100px, 1fr)); }
差距
我们可以使用在行线之间添加间隙 row-gap
,我们可以在列线之间使用相同的方法 column-gap
:
.grid-container { row-gap: 5px; column-gap: 10px; }
或者我们可以使用 gap
我们首先定义的地方 row-gap
那么 column-gap
:
.grid-container { gap: 5px 10px; }
如果行间隙与列间隙相同,我们只能指定一个值。
网格项目
要指定网格项在网格中的起始位置,我们基本上使用四个属性。我们来看看他们的定义。
定义
属性 | 定义 |
---|---|
grid-row-start |
grid-row-start CSS属性通过贡献一行,一个跨度或什么都没有(自动)来指定网格行在网格行中的起始位置 |
grid-row-end |
grid-row-end CSS属性通过贡献一行,一个span或什么都没有(自动)来指定网格行在网格行中的结束位置 |
grid-column-start |
grid-column-start CSS属性通过贡献一行,一个跨度或什么都没有(自动)来指定网格列中网格项的起始位置 |
grid-column-end |
grid-column-end CSS属性通过提供一条线,一个跨度或什么都没有(自动)来指定网格列中网格项的结束位置 |
或者我们可以使用这些属性的缩短版本:
属性 | 定义 |
---|---|
grid-row |
网格行CSS属性是grid-row-start和grid-row-end的简写属性,用于指定网格项在网格行中的大小和位置 |
grid-column |
grid-column CSS属性是grid-column-start和grid-column-end的简写属性,用于指定网格列中网格项的大小和位置 |
基本模板间距
因此,考虑到我们在本节开头的标记,假设我们希望第三个网格项采用4个单元而不是一个(我们希望它跨越两个网格列和两个网格行),如图1.3所示。我们怎么能这样做?
图1.3:模板间距示例
我们可以像这样实现:
// Grid container .grid-container { display: grid; gap: 10px; grid-template-columns: repeat(4, 1fr); grid-template-rows: repeat(3, 1fr); } // Grid item (third) .grid-container .grid-item:nth-child(3) { grid-column-start: 1; grid-column-end: 3; grid-row-start: 1; grid-row-end: 3; // or grid-column: 1 / 3; grid-row: 1 / 3; // or grid-column: 1 / span 2; grid-row: 1 / span 2; // or grid-column: -5 / span 2; // because we have 4 columns grid-row: -4 / span 2; // because we have 3 rows }
请注意,第三个网格项实际上是图1.3中的第一个。这与使用CSS网格我们可以(第一次)源顺序独立的事实有关。稍后我们将讨论这个问题时,我们会谈到这一点
grid-flow
。
如果您想使用它并探索不同的解决方案,请单击此处。
3.高级模板
有更多高级属性可以帮助您根据需要调整模板。在本节中,我们将了解这些属性,并了解如何在CSS中使用它们。
对于本节,请考虑以下模板:
class="grid-container"> class="grid-item header">Header class="grid-item content">Content class="grid-item navbar">Navbar class="grid-item meta">Meta class="grid-item footer">Footer
使用我们之前学到的知识,我们可以实现以下CSS,使其看起来像一个基本的网站布局:
.grid-container { grid-template: repeat(6, 1fr) / repeat(12, 1fr);// rows then columns } .grid-container .header { grid-column: 1 / -1; grid-row: 1 / 2; } .grid-container .navbar { grid-column: 1 / 2; grid-row: 2 / -1; } .grid-container .content { grid-column: 2 / -1; grid-row: 2 / -2; } .grid-container .footer { grid-column: 2 / -1; grid-row: -2 / -1; } .grid-container .meta { grid-column: -3 / -1; grid-row: 2 / 4; }
图1.4:基本网站布局。代码在这里可用
现在让我们说我们希望我们的导航栏(右侧)有点宽,现在,它跨越一个列线,我们希望它跨越两个列线。要做到这一点,我们必须改变 .navbar
位置,但我们也必须改变 .content
和 .footer
位置,因为目前的 .navbar
从第1行到第2行,以及 .footer
& .content
从第2行到最后一行。
如果我们每次都必须这样做,那么改变元素的位置可能会很繁琐,如果有办法告诉CSS网格为我们自动执行此操作,那将会很棒。嗯,没有一种方法,但至少有两种方式。
命名行
第一个解决方案是命名特定行,然后我们使用别名而不是其编号来引用它。我们试着实现这一点。
.grid-container { grid-template-rows: repeat(6, 1fr); grid-template-columns: 1fr 1fr (content-start navbar-end) repeat(10, 1fr); }
在上面的代码中,我们使用带有别名的简单括号命名了tird行(sigle行可以有多个别名)。那么现在我们将改变前面提到的元素的CSS:
.grid-container .navbar { grid-column: 1 / navbar-end; grid-row: 2 / -1; } .grid-container .content { grid-column: content-start / -1; grid-row: 2 / -2; } .grid-container .footer { grid-column: content-start / -1; grid-row: -2 / -1; }
结果应如下所示:
图1.5:基本网站布局 – 扩展导航栏
元素模板区域
第二种解决方案包括使用模板区域。该 grid-template-areas
CSS属性指定命名的网格区域。这个属性有一个奇怪的CSS语法,但我们这样使用它们:
.grid-container { grid-template-areas: 'h h h h h h h h h h h h' 'n n c c c c c c c c c c' 'n n c c c c c c c c c c' 'n n c c c c c c c c c c' 'n n c c c c c c c c c c' 'n n f f f f f f f f f f'; } .grid-container .navbar { grid-area: n; } .grid-container .content { grid-area: c; } .grid-container .footer { grid-area: f; } .grid-container .header { grid-area: h; } .grid-container .meta { grid-column: -3 / -1; grid-row: 2 / 4; }
我们用 grid-template-areas
为了定义网格容器区域,我们将网格项目放在所需的区域中 grid-area
。
提醒一下,所有区域必须是矩形的。
请注意,我们没有使用
grid-area
对于.meta
元件。那是因为,目前还没有办法使用这种方法叠加元素。至少不是我知道的。
你可以玩它,代码可以在这里找到。
4.隐式行和网格流
我们考虑以下代码:
class="grid-container"> class="grid-item">1 class="grid-item">2 class="grid-item">3 class="grid-item">4 class="grid-item">5 class="grid-item">6 .grid-container { grid-template-columns: repeat(3, minmax(100px, 1fr)); grid-template-rows: 80px; } .grid-container .grid-item:nth-child(2) { grid-row: span 2; } .grid-container .grid-item:nth-child(3) { grid-column: span 3; }
我们有一个包含三列的网格,我们希望第二个网格项跨越两行,第三个跨越三列。这个重申:
图1.6看起来不好的网格
隐含的行
这看起来很糟糕,所以这里发生了什么?首先,第二个元素比第一个元素略高,因为我们告诉它要高一倍,但它看起来不高两倍。此外,从3到6的网格项目不如拳头高。
这与我们明确设置第一行的事实有关: grid-template-rows: 80px;
。但其他行是隐式创建的,因此第二行几乎不可见,因为它是空的,其他行与内容需要的一样大。我们可以通过使用设置隐式创建的行的高度来解决这个问题 grid-auto-rows
像这样:
.grid-container { grid-template-columns: repeat(4, minmax(100px, 1fr)); grid-template-rows: 80px; grid-auto-rows: 100px; }
这应该是这样的:
图1.7更好的网格,但仍然
这看起来更好但仍然可以做得更好。请注意blanc空格,为什么我们不使用它们来放置网格项目4,5和6?为此,我们可以使用 grid-auto-flow
。
网格流
该 grid-auto-flow
CSS属性控制自动放置算法的工作方式,准确指定自动放置的项目如何流入网格。它可能需要多个参数(你可以在这里阅读更多相关信息),但这里我们只对一个感兴趣: dense
。
这将告诉浏览器将项目放在任何足够大的空间上:
.grid-container { grid-auto-flow: dense; // default is row }
有了我们的网格终于看起来不错了:)
图1.8好看的网格结论
这是一个很长的介绍,但有了这个,我们覆盖了很多CSS网格属性,所以你应该能够在你的应用程序中开始使用CSS网格。我希望你能学到一些东西,一如既往,快乐的编码
嘿,让我们保持联系
我正在做很多很棒的帖子和教程。如果您喜欢这个,请在Twitter上关注我以了解下一个可能出现的时间。
接下来要读什么?
- 7作为Web开发人员提高工作效率的提示?
- 角度单元测试101(带示例)
- 您需要了解的有关Angular动画的所有信息