回归基础:我们应该使用 Flexbox 还是 Grid?
《回归基础》将解答我刚开始学习 CSS 时的一些疑问。我个人认为,开始学习 CSS 会非常困难,因为 CSS 大约有 520 个属性可以使用。当然,我们不会全部用到,还有很多属性我还不了解,但要精通 CSS,我们需要理解很多属性。这篇博客不会从最基础的 CSS 开始讲解,但我会尝试向你展示实现方法。
如果您以前从未使用过 flexbox 或 grid,您可以查看css-tricks 的flexbox 指南和grid 指南。
问题
我们什么时候应该使用 flex 或 grid?
刚开始学习 CSS 并了解 flexbox 和 grid 的时候,我有点困惑该何时使用 flexbox 和 grid。在这篇博客中,我将尝试解释如何根据具体情况在 flexbox 和 grid 之间进行选择。
使用 Flex 的用例
我总是使用 flex 来创建只有一个维度(水平或垂直)的布局。在这篇博客中,我将结合我做过的一些项目,提供一些 flexbox 的使用案例。
1. 所有元素水平和垂直方向均位于中心的容器
我们通常在登陆页面看到这个
例子:
为了实现这个布局,我们只需要3行CSS,我建议你记住这个组合,因为你将在很多情况下使用它。
.container {
/* make sure the parent element has height */
min-height: 100vh;
/* css to align vertically and horizontally */
display: flex;
align-items: center;
justify-content: center;
}
/* If you want to make a full-page,
make sure the container has a height of the viewport */
2. 将页面分成几个部分
这种布局也很常见,通常将容器分成2个宽度相同的部分,我们也可以将其分成3个,4个或任意多个。
这个布局可以通过使用 flex 轻松实现,我们先看看 HTML
<div class="container">
<div class="content">
<h1>Hello Bambang</h1>
<p>welcome to my page</p>
<button>click me</button>
</div>
<img class="content" src="https://unsplash.it/700/600" alt="unsplash" />
</div>
我们可以看到,它div.container
有 2 个项目,分别是div.content
和img.content
,所以我们可以制作相等部分的布局。
.container {
min-height: 100vh;
display: flex;
}
.content {
/* this will make it divides in equal parts */
width: 100%;
/* you should use flex-basis for this, but flex-basis didn't really works on images, so I use width */
/* flex-basis: 100%; */
/* other tag like div works well tho! */
}
div.content {
/* the first flexbox use case */
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
img.content {
object-fit: cover;
}
通过使用,width: 100%
我们让子元素占用尽可能多的空间。因为它们都希望达到 100%,所以它们妥协并跨越了 50% 的空间。
请注意,为了兼容 IE,你应该
width: 100%
用替换flex-basis: 100%
(感谢 Ihor Vorotnov),但我特意在这里使用了 width,因为 flex-basis 不适用于图像。在其他标签上,比如 div 或标题,它就可以正常工作。
我们还可以将宽度或 flex-basis 硬编码为 50%,但是这样做违背了将内容划分为相等部分的目的,因为我们需要在每次添加新子项时更改百分比。
如果我们想用这个布局制作一个响应式设计,我们可以利用
flex-direction
.container {
min-height: 100vh;
display: flex;
/* add this to make the flex stacked vertically */
flex-direction: column;
}
@media (min-width: 700px) {
.container {
flex-direction: row;
}
}
因此,当我们处于移动视图中时,flex 将垂直堆叠(就像 HTML 的正常工作方式一样),而当我们进入更大的视口时,flex 将使子元素水平堆叠(检查 codepen 中的演示)
3.创建导航栏(使用空格)
创建一个简单的导航栏是很常见的事,通常布局是分开的,左侧是徽标,右侧是导航。
<nav>
<h3>Home</h3>
<ul>
<li>Route</li>
<li>Route</li>
</ul>
</nav>
nav
有两个子元素,分别是h3
和ul
。接下来,我们只需要重置基础样式,并使用 space-between 分隔子元素
nav {
background-color: lightblue;
display: flex;
align-items: center;
/* this property will make the child spaced apart */
justify-content: space-between;
}
ul {
/* remove bullet style */
list-style: none;
display: flex;
}
ul > li + li {
/* add space between navigation links */
margin-left: 2em;
}
以上所有示例实际上都可以用网格来实现。但是,使用网格比使用弹性盒子需要编写更多的 CSS。
使用网格的用例
网格通常用于实现更复杂的布局。我的决定是:如果 flex 太难,那就用 grid。
使用flex布局其实也可以实现复杂的布局,但是使用grid会简单很多。
1.制作二维布局
我通常使用网格来创建这种布局,因为它有一个gap
功能可以将它们隔开。如果我们想要实现响应式设计,使用弹性元素来隔开元素会更加困难。
如果使用网格,这样的布局会非常简单,我们只需要将其分成两列即可。
<div class="container">
<div class="item">item1</div>
<div class="item">item2</div>
<div class="item">item3</div>
</div>
div.container
我们将使用和 3来简化布局div.item
.container {
/* container base layout */
max-width: 700px;
margin: 0 auto;
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 1em;
}
.item {
border: 0.2px solid white;
height: 15em;
}
通过使用,grid-template-columns: repeat(2, 1fr)
我们设置网格将列分为两列,并且item
将遵循我们设置的规则。最后,我们添加gap: 1em
来创建一些空白。
网格在响应式设计中非常有用,我们只需要将 grid-tem 上的规则更改为在较小屏幕尺寸下为 1 列,在较大屏幕尺寸下为 2 列
.container {
/* container base layout */
max-width: 700px;
margin: 0 auto;
display: grid;
/* no need to add grid template, because grid defaults to 1 column */
gap: 1em;
}
@media (min-width: 700px) {
.container {
grid-template-columns: repeat(2, 1fr);
}
}
2. 制作不同尺寸的布局
我建议您使用 Firefox Dev Tools 来查看指示网格编号的线条。
我们通过设置 4 列 2 行来实现这种布局,然后为每个元素指定行和列的位置。例如,第一张图片跨越 2 列 2 行。如果您还不了解网格编号系统,请查看此处。
<div class="container">
<div class="item item1">item1</div>
<div class="item item2">item2</div>
<div class="item item3">item3</div>
<div class="item item4">item4</div>
</div>
.container
我们将使用作为父级来简化布局。
.container {
max-width: 700px;
margin: 0 auto;
display: grid;
/* makes the grid into 4 columns and 2 rows */
grid-template-columns: repeat(4, 1fr);
grid-template-rows: repeat(2, 1fr);
}
.item {
border: 1px solid white;
min-height: 10rem;
}
.item1 {
grid-column: 1 / 3;
grid-row: 1 / 3;
}
.item2 {
grid-column: 3 / 5;
}
/* you can also give value to item 3 and 4,
but because it follows the natural flow of the grid I won't continue */
对于响应式设计,我们可以根据我们想要的行和列放置图像,我们也可以更改模板
概括
如果使用 flex 变得太复杂,请使用 Grid
文章来源:https://dev.to/theodorusclarence/back-to-basic-should-we-use-flexbox-or-grid-1h9i