likes
comments
collection
share

页面布局不知道如何选择?来看看Flex和Grid吧

作者站长头像
站长
· 阅读数 23

一、前言

选择一个合适的技术,可以让你的代码更简洁、更易于维护和更具扩展性。

目前市面上比较流行的两个布局系统:CSS弹性盒子布局CSS网格布局

两者目前都可以实现比较复杂的响应式布局,但使用哪一个作为最优解,还是需要根据具体的使用情况来探讨的。

二、Flexbox

Flexbox提供了一种有效的方式来对齐和分配容器中项目之间的可用空间。它让父元素能够直接控制其直接子元素的顺序、宽度和高度,以更好地填充可用空间。

页面布局不知道如何选择?来看看Flex和Grid吧

.flex-1 {
  display: flex;  /* 让盒子变成flex布局 */
  justify-content: space-between;  /* 设置水平的主轴(X轴)的对齐方式 */
  align-items: center;  /* 设置垂直的交叉轴(Y轴)的对齐方式 */
  border: 1px solid #909399;
  width: 36rem;
  height: 6rem;
  border-radius: 4px;
  
  > div {
    width: 3rem;
    height: 3rem;
    line-height: 3rem;
    color: #fff;
    background-color: #007fff;
    border-radius: 4px;
  }
}

这样设置后,在display: flex;的容器内的所有直接子元素都会自动的变成弹性元素,然后我们就可以单独来设置每个子元素的顺序、宽度和高度。

页面布局不知道如何选择?来看看Flex和Grid吧

  .flex-1 > div {
    margin: 1rem;
  }

  .item-1 {
    align-self: flex-end;  /* 在Y轴的底部对齐 */
    order: 0;  /* 默认排序为0 */
  }

  .item-2 {
    align-self: stretch;  /* 默认值,未设置高度或设为auto,将占满整个容器 */
    flex-grow: 1;  /* 设置子元素放大比例,用于占据剩余的可用空间 */
    order: 2;  /* 设置该子元素的排序 */
  }

  .item-3 {
    order: 1;
  }

我们也可以按需求来设置按行排列按列排列

页面布局不知道如何选择?来看看Flex和Grid吧

  .flex-1 {
    display: flex;
    flex-direction: column;  /* 设置为纵向列排列布局 */
    align-items: stretch;
    
    > div {
      width: auto;
    }
  }

flex-direction: column;中,想让子元素自动占满父元素的宽度,则需要将子元素的宽度不设置或者设为auto,如果是正常的row(按行排列),则需设置的是高度。

Flexbox中提供了一种简单的方法来反正容器内的子元素。

页面布局不知道如何选择?来看看Flex和Grid吧

  .flex-1 {
    display: flex;
    flex-direction: row-reverse;
    
    > div {
      width: 3rem;
    }
  }

以上的示例主要是以单排或单列来展示,Flexbox也可以包含在多行或多列中,并且它可以根据内容和可用空间将每一行都视为一个单独的实体。

页面布局不知道如何选择?来看看Flex和Grid吧

  .flex-1 {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
  }

三、Grid

Grid允许我们在两个轴(水平和垂直)上布局,它将容器划分成,可以让我们把子元素精准的布局在某一个格内。

先上代码:

  .grid-1 {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;  /* 定义每列的宽度 */
    grid-template-rows: 6rem 9rem;  /* 定义每行的高度 */
    gap: 1.5rem;  /* 设置间距 */
  }

给容器添加display: grid;后,该容器变成了一个基础的网格布局,然后需要来设置网格的形状。

使用grid-template-columns: 1fr 1fr 1fr;我们定义了网格将拥有的列数。我们这里定义了三列,其中的每一个值都是网格布局中单独的一列。

使用grid-template-rows: 6rem 9rem;来定义网格的行。这里定义第一行高度为6rem,第二行高度为9rem

gap属性是用来定义行和列之间的间距,如果两个值相同,则可以简写成一个值。当然,也可以单独设置行间距和列间距grid-gap: <grid-row-gap> <grid-column-gap>;

页面布局不知道如何选择?来看看Flex和Grid吧

以上只是一个Grid的基础使用,接下来我们将把子元素放到你想要放入的单元格中。

这里先说明一下,默认情况下GridFlexbox一样,都是按子元素的顺序来排列的,因此,如果容器内有5个元素,那么上图就是我们网格布局的默认显示。

但是接下来的操作,我们将把第四个子元素放在第三列并占据两行

  .item-4 {
    grid-column: 3 / 4;
    grid-row: 1 / 3;
  }

这里有个重点,我们是定义的三列两行的网格布局,但是这个4是从哪里冒出来的?

页面布局不知道如何选择?来看看Flex和Grid吧

从图中可以看到,划分网格布局生成的网格线,三列布局形成了4条垂直的网格线,网格列是按其索引来进行控制,而不是按划分出的单元格。

如果我们想把item-4放在第三列,那我们必须使用垂直网格线3和4来定位到相应的单元格,也就是grid-column: 3 / 4;

接下来是grid-row: 1 / 3;它的工作方式和上面的相同,我们让该子元素占据水平网格线1到3的单元格空间。

保存代码后可以看到效果:

页面布局不知道如何选择?来看看Flex和Grid吧

这里我们可以看到,如果我们指定了某一个子元素占据单元格后,其余元素会自动的按默认排列方式自动重新排序。

在网格布局中,可能性是无穷的,完全可以按照你的需求来进行更多个性化的定制。

四、我们应该如何选择?

在此之前我们都有一个误解,认为Grid适合网页布局而Flexbox适合局部元素组件,因为Grid适合构建二维布局,Flexbox适合构建一维布局。

页面布局不知道如何选择?来看看Flex和Grid吧

但是我们可以使用Flexboxflex-wrap来创建二维布局,使用Grid的基础方式来实现一维布局。尽管Flexbox最开始不是用来构建网格布局的,但是我们在实际开发中经常按这种方式使用。

Grid布局允许在网格中精准的放置元素。

Flexbox更加关注与内容流,或者说更加关注元素如何在一维元素中排列。弹性盒子的子项,可以按需增长或减少自己在父容器中占据的可用空间。

在设计网页布局的时候,FlexboxGrid都是很强大的工具。就像开始说的,Flexbox主要面向的是一维布局,而Grid是面向二维布局的。

在实际使用中,我们几乎可以使用两者一起来搭建所有的布局,但还是要决定使用哪一个来提高我们的工作效率,或者是它们更加适合的场景。同样,我们也需要知道不同端的设计图和用户的屏幕尺寸来做决定。

如果单纯的使用到Flexbox的基础属性就能完成很好的布局而不用考虑太多的兼容性,或者只用关注内容流的布局,那么使用Flexbox就是最好的选择,但是在Flexbox布局的过程中,如果有子元素需要单独设计位置或者宽度/高度上出现不明确的定义,那么使用Grid会好一些。

最主要的可能还是需要我们使用比较简洁的代码,在实现需求和功能的同时,还要考虑到不同端和多设备之间的兼容性。

参考资料:

A Complete Guide to Grid | CSS-Tricks - CSS-Tricks

Flex 布局教程:语法篇 - 阮一峰的网络日志 (ruanyifeng.com)

CSS Grid 网格布局教程 - 阮一峰的网络日志 (ruanyifeng.com)