0 - CSS 布局发展历程

  1. 表格(table)布局
  2. 浮动、定位、内联块技术
  3. 弹性(Flex)布局、网格(Grid)布局
    • 弹性布局(一维布局,页面局部布局)
    • 网格布局(二维布局,页面整体布局)

1 - CSS Flex 弹性布局

1.1 基本概念

采用 flex 布局的元素,称为 Flex 容器(flex container),简称”容器”。它的所有子元素自动成为容器成员,称为 flex 项目(flex item),简称”项目”。 容器默认存在两根轴:水平的主轴(main axis)和垂直的交叉轴(cross axis)。主轴的开始位置(与边框的交叉点)叫做main start,结束位置叫做main end;交叉轴的开始位置叫做cross start,结束位置叫做cross end。 项目默认沿主轴排列。单个项目占据的主轴空间叫做main size,占据的交叉轴空间叫做cross size

1.2 容器属性

注意,设为flex布局以后,子元素的floatclearvertical-align属性将失效。

/* display */
display: flex | inline-flex;

flex-direction: 属性决定主轴的方向(即项目的排列方向)
    row(默认值): 主轴为水平方向,起点在左端。
    row-reverse: 主轴为水平方向,起点在右端。
    column: 主轴为垂直方向,起点在上沿。
    column-reverse: 主轴为垂直方向,起点在下沿。
    
flex-wrap: 默认情况下,项目都排在一条线(又称"轴线")上
    nowrap(默认): 不换行,缩放项目大小。
    wrap: 换行,第一行在上方。
    wrap-reverse: 换行,第一行在下方
    
flex-flow: 
    是flex-direction属性和flex-wrap属性的简写形式,默认值为row nowrap。
    
justify-content: 定义了项目在主轴上的对齐方式
    flex-start(默认值): 左对齐
    flex-end: 右对齐
    center: 居中
    space-between: 两端对齐,项目之间的间隔都相等。
    space-around: 每个项目两侧的间隔相等。
    
align-items: 定义项目在交叉轴上如何对齐
    flex-start: 交叉轴的起点对齐。
    flex-end: 交叉轴的终点对齐。
    center: 交叉轴的中点对齐。
    baseline: 项目的第一行文字的基线对齐。
    stretch(默认值): 如果项目未设置高度或设为auto,将占满整个容器的高度。

align-content: 定义了多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作用
    flex-start:与交叉轴的起点对齐。
    flex-end:与交叉轴的终点对齐。
    center:与交叉轴的中点对齐。
    space-between:与交叉轴两端对齐,轴线之间的间隔平均分布。
    space-around:每根轴线两侧的间隔都相等。
    stretch(默认值):轴线占满整个交叉轴。

1.3 项目属性

order: 定义项目的排列顺序。数值越小,排列越靠前,默认为0。

flex-grow: 定义项目的放大比例,默认为0,即如果存在剩余空间,也不放大。
    如果所有项目的flex-grow属性都为1,则它们将等分剩余空间(如果有的话)。
    如果一个项目的flex-grow属性为2,其他项目都为1,
    则前者占据的剩余空间将比其他项多一倍。
    
flex-shrink: 定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小。
    如果所有项目的flex-shrink属性都为1,当空间不足时,都将等比例缩小。
    如果一个项目的flex-shrink属性为0,其他项目都为1,则空间不足时,前者不缩小。
    负值对该属性无效。
    
flex-basis: 定义了在分配多余空间之前,项目占据的主轴空间(main size)。
    浏览器根据这个属性,计算主轴是否有多余空间。
    它的默认值为auto,即项目的本来大小。
    它可以设为跟width或height属性一样的值(比如350px),则项目将占据固定空间。
    
flex: 是flex-grow, flex-shrink 和 flex-basis的简写,默认值为0 1 auto。
    后两个属性可选。
    该属性有两个快捷值:auto (1 1 auto) 和 none (0 0 auto)。
    建议优先使用这个属性,而不是单独写三个分离的属性,因为浏览器会推算相关值。
    
align-self: 允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性。
    默认值为auto,表示继承父元素的align-items属性,
    如果没有父元素,则等同于stretch。
    该属性可能取6个值,除了auto,其他都与align-items属性完全一致。

2 - CSS Grid 网格布局

2.1 基本概念

grid 布局是 css 中的一种新的布局方式,对盒子和盒子内容的位置及尺寸有很强的控制能力。与 flex 不同,flex 着重于单轴,而 grid 适应于多轴。 flex 布局示意: grid 布局示意:

设置 display: grid; 的元素称为容器,它的直接子元素称为项目,但注意子孙元素不是项目。

grid line:网格线,构成 grid 布局的结构,分为水平和竖直两种。 grid track:两条相邻网格线之间的空间,可以认为是一行或者一列。 grid cell:两条相邻行和相邻列之间分割线组成的空间,是 grid 布局中的一个单元。 grid area:四条网格线包裹的全部空间,任意数量的 grid cell 组成一个 grid area

2.2 容器属性

/* display */
display: grid | inline-grid;

/* grid-template 系列 */
grid-template-columns:
grid-template-rows:
    200px 1fr 1fr;
    repeat(3, 1fr);
    minmax(200px, 1fr) 1fr 1fr;
    repeat(auto-fill, minmax(100px, 1fr));
    repeat(auto-fit, minmax(100px, 1fr));
grid-template-areas:
    "header header"
    "nav    nav"
    "footer footer";
    
/* grid-gap 系列 */
grid-gap: 3rem 1rem;
    grid-row-gap: 3rem;
    grid-column-gap: 1rem;
    
/* place 系列 */
justify-items: // 行轴(水平方向)各单元对齐
align-items: // 栏轴(垂直方向)各单元对齐
justify-content: // 行轴(水平方向)整体对齐
align-content: // 栏轴(垂直方向)整体对齐
    start;
    end;
    center;
    stretch;
    
/* grid 系列 */
grid-auto-columns: 2fr;
grid-auto-rows: 200px;
grid-auto-flow: row | column;

2.3 单元属性

/* 规定单元格位置和大小 */
grid-row: 2;
grid-column: 2;
    grid-row: 2 / 3;
    grid-column: 2 / 3;
        grid-column-start: 2;
        grid-column-end: 3;
        grid-row-start: 2;
        grid-row-end: 3;
grid-column: 2 / 4;
grid-row: 2 / 4;
    grid-column: 2 / span 2;
    grid-row: 2 / span 2;
grid-area: header; // 对应父级 grid-template-areas

/* 自身对齐特例 */
justify-self:
align-self:
    start;
    end;
    center;
    stretch;
    
/* z-index */
z-index: 1;

2.4 其他

2.4.1 显性网格和隐性网格

网格可以分为两种,一种是我们主动去定义的,称为显性网格(explicit grid);另一种是系统自动产生,称为隐性网格(implicit grid)。

2.4.2 auto-fill 与 auto-fit

auto-fill: 如果你确定了每一栏的最小宽度(如 100px),可以这样设定:

grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));

auto-fill 是自动填充的意思,minmax 的最小值设了 100px,最大值为 1fr。所以整句的意思是:每一栏最少为100px,屏幕宽度能放几个就放几个,多出来的自动移到下一行;若宽度太大,足以放多一栏时,则会填上空白栏;但不足以多放一栏时,则是平均地增加每一栏宽度。 下例网格容器中有 5 个 div,为了方便查看,每一个 div 都有以下 class

.part {
  background: blue;
  color: white;
  border: 1px solid red;
  padding: 10px;
  text-align: center;
}

当屏幕宽度能容下全部 5 个 div,但不足以容下多一个时,我们会看到以下画面: 当屏幕宽度能容下全部 5 个 div,且足以容下多一个 div100px)时,透过 Google Chrome 的开发者工具侦察(Inspect)的效果: 当屏幕宽度不足以容下全部 5 个 div 时: 这就可以在不使用媒体查询(Media Query)的情况下,实现响应式网页设计。当然,这也不是说,有了网格就不需要媒体查询,最好的做法是两者组合使用。

auto-fit: auto-fitauto-fill 非常类似,唯一的差别是上述的第二种情况:当屏幕宽度能容下更多的 div 时,auto-fit 会将多余的宽度平均分给每一栏,而不是像 auto-fill 那样增加一些空白栏。 第一行使用 auto-fill,自动产生了空白栏来填充多余的空间。 第二行使用 auto-fit,多余的空间被平均分配给了每一栏。