CSS Flexbox 和 Grid:构建响应式布局的艺术

Flex 灵活布局

显示:弹性

开启 Flex 布局模式,将某个元素设置为 Flex 容器,其直接子元素将成为 Flex 项目。

.container {
    display: flex;
}

弹性方向

定义主轴方向(item排列的方向)。可选值:

  • 行(默认):水平,从左到右。
  • row-reverse:水平,从右到左。
  • 列:垂直,从上到下。
  • column-reverse:垂直,从下到上。
  • .container {
        flex-direction: row | row-reverse | column | column-reverse;
    }

    弹性包裹

    控制当一行中没有足够的空间时是否换行。可选值:

  • nowrap (默认):不换行,项目可能会溢出容器。
  • wrap:包装,项目排列成多行。
  • wrap-reverse:换行,第一行在最下面,后续行向上排列。
  • .container {
        flex-wrap: nowrap | wrap | wrap-reverse;
    }

    对齐内容

    定义主轴上的对齐方式。可选值:

  • flex-start(默认):项目与起点对齐。
  • flex-end:项目与终点对齐。
  • 中心:项目居中对齐。
  • space-between:均匀分布项目之间的间距,第一个和最后一个项目分别附加到容器的两端。
  • space-around:均匀分布项目之间的间距,项目两边的间距相等。
  • space-evenly:均匀分布项目之间的间距,项目之间以及项目与容器边缘之间的间距相等。
  • .container {
      justify-content: flex-start | flex-end | center | space-between | space-around | space-evenly;
    }

    对齐项目

    定义交叉轴上的对齐方式。可选值:

  • 拉伸(默认):项目拉伸以填充整个横轴。
  • flex-start:项目与横轴的起点对齐。
  • flex-end:项目与横轴的末端对齐。
  • 中心:项目位于横轴的中心。
  • 基线:项目按基线对齐。
  • .container {
        align-items: stretch | flex-start | flex-end | center | baseline;
    }

    对齐内容

    仅适用于多行 Flex 布局(flex-wrap: wrap),定义多行项目在横轴上的对齐方式。可选值:

  • 拉伸(默认):每一行都会拉伸以填充整个横轴。
  • flex-start:每行与横轴的起点对齐。
  • flex-end:每一行与横轴的末尾对齐。
  • 中心:每行与横轴的中心对齐。
  • space-between:均匀分布每行之间的空间,第一行和最后一行分别贴在容器的两端。
  • space-around:均匀分布各行之间的空间,且行两边的空间相等。
  • .container {
        align-content: stretch | flex-start | flex-end | center | space-between | space-around;
    }

    命令

    定义项目的排序,值越小排序越高,默认值为 0。

    .item {
        order: ;
    }

    弹性生长

    定义项目的放大比例,默认值为0,表示不放大,若所有项目均设置为非0值,则按比例分配剩余空间。

    .item {
        flex-grow: ; /* Default is 0 */
    }

    弹性收缩

    定义项目的收缩比例。默认为 1,表示可以收缩。如果所有项目都设置为非零值,则它们会按比例收缩以防止溢出容器。

    .item {
        flex-shrink: ; /* defaults to 1 */
    }

    弹性基础

    定义在分配剩余空间之前项目的初始大小。接受长度、百分比、自动(默认)或内容值。

    .item {
        flex-basis:  |  | auto | content;
    }

    弹性

    flex-grow、flex-shrink 和 flex-basis 的简写。默认为 0 1 auto。

    .item {
      flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ];
    }

    对齐自身

    覆盖容器的 align-items 属性,定义单个项目在横轴上的对齐方式。可选值与 align-items 相同。

    .item {
    align-self: auto | stretch | flex-start | flex-end | center | baseline;
    }

    网格 网格布局

    显示:网格;

    开启网格布局模式,将元素设置为网格容器,其直接子元素将成为网格项(单元格)。

    .container {
    display: grid;
    }

    grid-template-columns 和 grid-template-rows

    定义网格的列和行轨道的大小。接受长度、百分比、fr(分数单位,表示网格空间的分数)或自动值。您还可以使用 repeat() 函数创建重复轨道,以及使用 minmax() 函数定义轨道的最小和最大尺寸。

    .container {
        grid-template-columns:  ... | repeat(, ) | auto-fill | auto-fit;
        grid-template-rows:  ... | repeat(, ) | auto-fill | auto-fit;
    }
    
    /* Example */
    .container {
        grid-template-columns: 1fr 2fr 1fr; /* Three columns, width ratio is 1:2:1 */
        grid-template-rows: 50px auto 1fr; /* Three rows, the first row is 50px, the second row is adaptive height, and the third row is the remaining space */
    }

    网格模板区域

    通过命名项目和用字符串描述网格结构来定义网格布局的区域。项目名称使用 . 来表示空白单元格。

    .container {
      grid-template-areas:
        "header header header"
        "nav main sidebar"
        "footer footer footer";
    }
    
    /* The corresponding items need to set the grid-area attribute */
    .item1 {
      grid-area: header;
    }
    .item2 {
      grid-area: nav;
    }
    .item3 {
      grid-area: main;
    }
    .item4 {
      grid-area: sidebar;
    }
    .item5 {
      grid-area: footer;
    }

    grid-gap 或 grid-column-gap 和 grid-row-gap

    设置网格中项目之间的间隙。接受长度或百分比值。

    .container {
        grid-gap:  ; /* Shorthand form, set both row and column gaps */
        grid-row-gap:  | ; /* Set row gaps separately */
        grid-column-gap:  | ; /* Set column gaps separately */
    }
    
    /* Example */
    .container {
        grid-gap: 10px 20px; /* 10px row gap, 20px column gap */
    }

    grid-auto-columns 和 grid-auto-rows

    定义自动填充网格时新添加的行或列的轨道大小。当项目超出定义的网格范围时生效。

    .container {
    grid-auto-columns:  ... | repeat(, );
    grid-auto-rows:  ... | repeat(, );
    }
    
    /* Example */
    .container {
        grid-auto-rows: minmax(100px, auto); /* The minimum height of the newly added row is 100px, and the maximum height is adaptive to the content */
    }

    网格自动流

    控制网格项如何自动填充和排列。可选值:

  • row(默认):按行填充。
  • 列:按列填充。
  • 密集:当行或列与密集一起使用时,如果网格中有空隙,新项目将尝试填补这些空隙,而不是仅仅将它们添加到网格的末尾。
  • .container {
        grid-auto-flow: row | column | row dense | column dense;
    }

    grid-column-start、grid-column-end、grid-row-start 和 grid-row-end

    手动指定网格中项目的开始和结束位置。

    .item {
        grid-column-start:  |  | auto;
        grid-column-end:  |  | span  | auto;
        grid-row-start:  |  | auto;
        grid-row-end:  |  | span  | auto;
    }
    
    /* Example */
    .item {
        grid-column: 1 / 3; /* Equivalent to grid-column-start: 1; grid-column-end: 3;, occupying the first to third columns */
        grid-row: 2 / span 2; /* Equivalent to grid-row-start: 2; grid-row-end: span 2;, starting from the second row, spanning two rows */
    }

    网格区域

    用于同时设置 grid-row-start、grid-column-start、grid-row-end 和 grid-column-end 的简写属性,或引用 grid-template-areas 中定义的区域名称。

    .item {
        grid-area:  |  /  /  / ;
    }
    
    /* Example */
    .item {
        grid-area: header; /* Referencing the area name defined in grid-template-areas */
    }

    CSS Grid 与 Flexbox 结合

    在某些情况下,我们可以结合 CSS Grid 和 Flexbox 的优点来创建更复杂的响应式布局。

    /* Container style */
    .container {
        display: grid;
        grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); /* Adaptive column width */
        grid-gap: 10px;
        padding: 10px;
    }
    
    /* Sub-element style */
    .container > div {
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        background-color: #f0f0f0;
        padding: 20px;
        box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
        border-radius: 5px;
    }
    
    /* Responsive layout */
    @media screen and (max-width: 768px) {
        .container {
            grid-template-columns: 1fr; /* Single column layout */
        }
    
        .container > div {
            height: 100%; /* Keep child element height */
        }
    }

    首先使用 CSS Grid 创建自适应列宽的网格布局,每个网格项(子元素)内部使用 Flexbox 将内容垂直居中,当屏幕宽度小于 768px 时,媒体查询会切换为单列布局,以适配移动设备。

    弹性框与网格选择

    选择使用 Flexbox 还是 Grid 通常取决于具体的需求:

  • Flexbox 适合处理一维布局,例如元素按行或列排列,以及元素对齐和填充。
  • CSS Grid 更适合处理二维布局,例如表格或复杂的网格布局,以及精确的单元格控制。