GitHub链接:前端主流布局与实战

传统布局

特点

  • 兼容性好;
  • 布局繁琐;
  • 局限性,不能在移动端很好的布局。

CSS盒子模型

CSS盒子模型
CSS盒子模型

css盒模型的注意点:

  1. padding不能为负值,而margin可以为负值;
  2. 背景色会平铺到非margin的区域;
  3. margin-top传递的现象及解决方案;
  4. margin上下叠加的现象及解决方案。

3、什么是margin-top的传递现象?当父元素嵌套 子元素,给子元素添加margin-top属性的时候,会出现子元素没有效果,但是父元素却出现了margin-top。举例:

margin-top的传递现象
margin-top的传递现象

解决方案:

  1. 给父元素添加一个边框即可解决——border-top: 1px solid rgba(0, 0, 0, 0)
  2. “障眼法”——子元素使用border-top: 20px solid blue
  3. 使用弹性布局(flex)或者网格布局(gird)。

4、margin上下叠加问题是指,当两个兄弟div,上一个设置了margin-bottom,下一个设置了margin-top,那么两个元素之间的举例并不是margin-bottom+margin-top,而是取最大值最为两者之间的距离,举个栗子:

解决方案:

  1. margin尽量设置到一个元素上;
  2. 使用弹性布局(flex)或者网格布局(gird)。

块级盒子与内联盒子

在CSS中我们广泛地使用两种“盒子”,块级盒子(block box)和内联盒子(inline box)。这两种盒子会在页面中表现出
不同的行为方式。

  • 块级盒子:divph1
  • 内联盒子:spanastrong

块状盒子特性

  1. 独占一行;
  2. 支持所有css样式;
  3. 不写宽度的时候,跟父元素的宽度相同;
  4. 所占区域是矩形。

内联盒子特性

  1. 盒子默认不会换行(一行显示);
  2. 有些样式不支持,例如:widthheight等;
  3. 不写宽度的时候,宽度由内容决定;
  4. 所占区域不一定是矩形;
  5. 内联标签与标签之间是有缝隙的。

内联盒子很多样式不支持,在做布局的时候应尽量避免去使用。

自适应盒模型的特性

自适应盒模型指的是:当盒子不设置宽度时,盒模型相关组成部分的处理方式是如何的。

当父元素嵌套子元素,子元素设置了固定宽度(具体的px值或者%),子元素的marginpaddingborder都会将元素“向外扩张”;但是如果子元素不设置width,或者width: initial,这个时候子元素会自动考虑marginpaddingborder。举个栗子:

标准盒模型与怪异盒模型

在标准模型中,如果你给盒设置widthheight,实际设置的是content box。paddingborder再加上设置的宽高一起决定整个盒子的大小。

在怪异模型中,所有宽度都是可见宽度,所以内容宽度是该宽度减去边框和填充部分。

如何将标准盒模型转化为怪异盒模型?通过设置属性:box-sizing: border-box来实现。

box-sizing属性:

  • content- box: width、height → content
  • border-box: width、height → content + padding + border

应用:

  1. 量取尺寸时不用再去计算一些值;
  2. 解决一些需要设置百分比和盒模型值。

淘宝移动端应用实例
淘宝移动端应用实例

浮动

样式讲解

当元素被浮动时,会脱离文档流,根据float的值向左或向右移动,直到它的外边界碰到父元素的内边界或另一个浮动元素的外边界为止,是CSS布局中实现左右布局的一种方式。

文档流:文档流是元素在Web页面上的一种呈现方式,按照出现的先后顺序进行排列。

float属性
float属性

清除浮动的方案

  • clear属性:leftrightboth三个属性值,用于清除兄弟节点的浮动,如果是父元素嵌套了子元素,子元素有浮动,那么可以通过给子元素添加一个空的同级兄弟空元素,然后清除浮动即可达到清除子元素浮动的效果;
  • BFC
  • 空标签
  • .clearfix::after{}:为浮动的元素设置一个伪类来清除浮动,不需要新增DOM元素,其本质还是方法一。
.clearFix::after{
    content: '';
    clear: both;
    display: block
}

特性注意点

1、浮动只会影响后面的元素。

2、文字永远不会被浮动元素覆盖。

借助此特性,可以实现某些图文混排的效果。

3、块状盒子具备内联盒子特性:宽度由内容决定。

div在默认情况下是块状元素,即display: block,对于块状元素,当不设置width时,其默认值为100%,也就是等于父元素的宽度。

但是如果div设置了浮动,那么其宽度就是由内部元素的宽度所决定,这个特性和内敛盒子一样。

4、内联盒子具备块状盒子的特性:支持所有样式。

内联盒子是不支持块状盒子特性的,比如width属性,但是当设置了float属性后,就会支持了。

5、浮动放不下,会自动换行。

这个不用解释,其实还就是当块状盒子设置了浮动,就具备了内联盒子的特性,会自动换行。

定位样式讲解

CSS position属性用于指定一个元素在文档中的定位方式,其中top、rightbottomleft属性则决定了该元素的最终位置。

相对定位

  • 相对定位的元素是在文档中的正常位置偏移给定的值(相对自身进行偏移);
  • 不影响其他元素的布局。

绝对定位

  • 绝对定位的元素脱离了正常的文档流,绝对定位元素不占据文档流空间;
  • 与使用了float属性的div相似,具备了内联盒子的特性——在不设置width属性的时候,宽度由内容决定;
  • 同样,当内联盒子使用了绝对定位,可以让其具备块级盒子的特性——支持所有的样式。

绝对定位元素相对于最近的非static祖元素定位,当这样的祖元素不存在时,则相对于可视区域定位。

固定定位

  • 固定定位与绝对定位相似,但是会固定在可视区域中;
  • 不受祖元素定位方式的影响;
  • 块级盒子使用了固定定位,就会具有内联盒子的特性;
  • 内联盒子使用了固定定位,就会具有块级盒子的特性。

粘性定位

粘性定位可以被认为是相对定位和固定定位的混合,元素在跨越特定阈值前为相对定位,之后为固定定位。

层级的改变

使用属性z-index可以对元素的层级进行调整,默认元素的z-index值为0。

flex弹性布局

  • flex 是 flexible Box 的缩写,意为"弹性布局",用来为盒状模型提供最大的灵活性,任何一个容器都可以指定为 flex 布局。
  • 当我们为父盒子设为 flex 布局以后,子元素的 float、clear 和 vertical-align 属性将失效。
  • flex布局又叫伸缩布局 、弹性布局 、伸缩盒布局 、弹性盒布局。
  • 采用 Flex 布局的元素,称为 Flex 容器(flex container),简称"容器"。它的所有子元素自动成为容器成员,称为 Flex 项目(flex item),简称"项目"。

弹性盒子是一种用于按行或按列布局元素的一维布局方法。元素可以膨胀以填充额外的空间,收缩以适应更小的空间。

通过给父盒子添加 flex 属性,来控制子盒子的位置和排列方式。

特点:

  • 操作方便,布局极其简单,移动端使用比较广泛
  • pc端浏览器支持情况比较差
  • IE11或更低版本不支持flex或仅支持部分
Header
Nav1
Nav2
Nav3
Nav4
Nav5
Nav6
Container Left
Container Main
Container Right
Footer

Flex容器基本概念

  • flex container:flex容器;
  • flex item:flex子项,默认沿水平横向排列;
  • main axis:主轴,水平横向,开始于main start,终止于main end;
  • cross axis:交叉轴,垂直竖向,开始于cross start,终止于cross end。

Flex容器设置项

flex-direction——设置主轴的方向

属性值含义
row默认值,从左到右
row-reverse从右到左
column从上到下
column-reverse从下到上

在 flex 布局中,是分为主轴和侧轴两个方向,同样的叫法有 : 行和列、x 轴和y轴。默认主轴方向就是 x 轴方向,水平向右;默认侧轴方向就是 y 轴方向,水平向下。

主轴和侧轴是会变化的,就看 flex-direction 设置谁为主轴,剩下的就是侧轴,而我们的子元素是跟着主轴来排列的。

flex-warp——设置是否换行

属性值含义
nowarp默认值,所有子项会在挤一行
warp从右到左
warp-reverse从上到下

使用flex-warp: warp,如果flex容器设置了高度,会进行等分,然后每一行元素顶着最上面;如果没有设置高度,则行与行之间会紧挨着。

flex-flow—— flex-direction 和 flex-wrap 属性的复合属性

flex-flow:row wrap

justify-content——设置主轴上的子元素排列方式

属性值含义
flex-start默认值,从头部开始,如果主轴是x轴,则从左到右
flex-end从尾部开始排列
center在主轴居中对齐(如果主轴是x轴则水平居中)
space-around平分剩余空间
space-between先两边贴边再平分剩余空间(重要)
space-evenly平分剩余空间

flex布局:justify-content示意图果
flex布局:justify-content示意图果

注意点:space-evenlyspace-around的区别,space-evenly是父容器宽度减去所有子元素宽度,然后平均分配;space-around是每个元素分配有两个边。

space-around
space-evenly

align-items(主轴对齐)——设置侧轴上的子元素排列方式(单行 ):

属性值含义
flex-start从头部开始
flex-end从尾部开始
center居中显示
stretch拉伸(使用该属性时,子盒子width属性不要出现,出现时该属性无效)
baseitems文字基线对齐,常用于一行显示图文,图片与文字的基线对齐

align-content(交叉轴对齐)——设置侧轴上的子元素的排列方式(多行)

该属性针对多行进行设置,只有当设置了flex-warp: warp属性值的时候才会生效!!!

属性值含义
stretch默认值,设置子项元素高度平分父元素高度
flex-start默认值在侧轴的头部开始排列
flex-end在侧轴的尾部开始排列
center在侧轴中间显示
space-around子项在侧轴平分剩余空间
space-between子项在侧轴先分布在两头,再平分剩余空间
space-evenly平分剩余空间

align-content 和align-items区别:

  • align-items适用于单行情况下, 只有上对齐、下对齐、居中和拉伸;
  • align-content适应于换行(多行)的情况下(单行情况下无效), 可以设置 上对齐、下对齐、居中、拉伸以及平均分配剩余空间等属性值;
  • 总结就是单行找align-items多行找align-content

Flex容器常用布局方式

内联和块的上下左右居中布局

方法一,给父盒子设置属性:

display: flex;
align-items: center;
justify-content:center 
我是div里面的文字

方法二,对父元素和子元素分别设置,

父盒子设置属性:

display: flex

子元素设置属性:

margin: auto

均分列布局

子项分组布局

当父元素设置为flex布局后,子元素设置属性margin-right: auto;后就会根据所有的空间进行均分。

1
2.1
2.2
3.1
3.2

不定向居中布局

Flex子项设置项

flex-grow——扩展比例

属性值含义
0默认值,表示不占用剩余的空白间隙扩展自己的宽度
0.5宽度增加剩余所有空间的50%
1占满剩余的所有空间
大于1还是占满剩余所有空间,与1效果相同

注意点:如果两个同级子元素(child-01、child-02)都设置了flex-grow属性,那么会根据他们的设置值进行分配。举例说明,如果child-01设置了flex-grow: .4,child-02设置了flex-grow: .6,那么child-01扩展剩下宽度的40%,child-02扩展剩下宽度的60%;如果child-01设置了flex-grow: 4,child-02设置了`flex-grow: .6,那么child-01扩展剩下宽度的4/(4+6)=40%,child-02扩展剩下宽度的6/(4+6)=60%。

我的宽度:20%
我的宽度:20%+flex-grow:0.5
我的宽度:20%+flex-grow: .4
我的宽度:20%+flex-grow: .6
我的宽度:20%+flex-grow: 4
我的宽度:20%+flex-grow: 6

flex-shrink——收缩比例

flex-shrinkflex-grow是一对相对的属性,

属性值含义
1默认值,表示当子元素宽度超出flex容器时,将其宽度收缩至父元素的100%
0.5宽度减少父元素的50%
0不对flex容器中的子元素宽度进行收缩
大于1还是宽度收缩至父元素,与1效果相同

注意点:如果两个同级子元素(child-01、child-02)默认情况下flex-shrink: 1,如果父元素width: 500px,child-01的width: 400px,child-02的width: 600px。那么在flex容器内,child-01的实际宽度就是:

$$ 400-\frac{400}{400+600}×[(400+600)-500]=200 $$

child-02的实际宽度就是:

$$ 600-\frac{600}{400+600}×[(400+600)-500]=300 $$

如果两个同级子元素(child-01、child-02),如果父元素width: 500px,child-01的width: 400px; flex-shrink: 2,child-02的width: 600px; flex-shrink: 1。那么在flex容器内,child-01的实际宽度就是:

$$ 400-\frac{400×2}{400×2+600}×[(400+600)-500]≈114 $$

child-02的实际宽度就是:

$$ 600-\frac{600}{400×2+600}×[(400+600)-500]≈386 $$

我的宽度:200px
我的宽度:300px
我的宽度:114px
我的宽度:386px

flex-basis

没搞明白这个属性有啥实际用处

flex

flex-growflex-shrinkflex-basis的缩写。

order

改变某一个flex子项的排序位置,默认值为0,如果元素设置为1,则排至最后,如果设置为负数,则排至第一位。

align-self

——控制单独某一个flex子项的垂直对齐方式,默认值是auto,其他属性值参考Flex容器设置项中的align-items属性。

Flex子项常用布局方式

等高布局

flex子元素默认高度就会与父元素等高。

测试内容

测试内容

测试内容

测试内容

测试内容

测试内容

测试内容

测试内容

测试内容

测试内容

测试内容

测试内容

测试内容

测试内容

两列与三列布局

Sticky Footer布局

Header
Container
Footer

综合案例

swiper轮播图

<
>

grid网格布局

概念

CSS网格是一个用于web的二维布局系统。利用网格,你可以把内容按照行与列的格式进行排版。另外,网格还能非常轻松地实现一些复杂的布局。

flex布局更适用于一行或者一列的一维布局,grid布局则是针对行与列同时存在的二维布局。

grid容器设置项

grid-template-row/columns——定义网格及fr单位

基于网格行和列的维度,去定义网格线的名称和网格轨道的尺寸大小。

display: grid;
grid-template-rows: 100px 100px 100px;
grid-template-columns: 100px 100px 100px
1
2
3
4
5
6
7
8
9

写法还可以进行混编:

grid-template-rows: 100px 20% auto;
1
2
3
4
5
6
7
8
9

还可以使用grid的专属单位fr

grid-template-columns: 1fr 1fr 1fr;

使用fr的意思就是自动分配比例,例如上面的其实就等同于grid-template-columns: 100px 100px 100px

grid-template-areas——合并网格及网格命名

使用命名方式定义网格区域,需配合grid-area属性进行使用。

对父级盒子设置:

display: grid;
grid-template-rows: 1fr 1fr 1fr;
grid-template-columns: 1fr 1fr 1fr;
grid-template-areas: 
"a1 a1 a2"
"a1 a1 a2"
"a3 a3 a3";

然后再对子集元素进行命名:

.grid-demo-02>div:first-of-type {
    grid-area: a1;
}

.grid-demo-02>div:nth-of-type(2) {
    grid-area: a2;
}

.grid-demo-02>div:last-of-type {
    grid-area: a3;
}

划分子区域只能按照矩形来划分~

1
2
3

grid-template

grid-template-rowsgrid-template-columnsgrid-template-areas属性的缩写。

上述的父级设置就可以简写为:

grid-template: 
    "a1 a1 a2" 1fr
    "a1 a1 a2" 1fr
    "a3 a3 a3" 1fr
    / 1fr 1fr 1fr;

grid-row/column-gapgrid-gap——网格间隙

用来设置元素行列之间的间隙大小,grid-gapgrid-row-gapgrid-column-gap的复合简写,推荐使用row-gapcolumn-gapgap

为什么要去掉前缀grid-?因为发现这个间隙的问题不止在grid布局中会出现,因此去掉了前缀使其也可以应用在其他布局中。

在VSC中输入gap会发现提示带有grid-前缀的属性已经过时
在VSC中输入gap会发现提示带有grid-前缀的属性已经过时

1
2
3

gap属性在flex布局中也是可以使用的:

1
2
3
4
5

justify/align-itemsplace-items——网格对齐方式及简写

默认值stretch,指定了子项在网格中的拉伸对齐。place-itemsalign-itemsjustify-items的复合简写属性。

属性值含义
start上/左
center
end下/右

如果子元素不设置宽高,默认是铺满每一个单元格:

1
2
3
4
5
6
7
8
9

如果强制设置其宽高,会发现每一个div默认是在grid单元格的左上角对齐的:

1
2
3
4
5
6
7
8
9

align/justify-contentplace-content——grid容器对齐方式及简写

指定gird容器的对齐方式,只有当grid布局的宽高小于容器宽度的时候设置才有效果。

1
2
3
4

对齐方式的区别
对齐方式的区别

grid-auto-flow/rows/columns——显式网格与隐式网格

指定在显示网格之外的隐式网格,如何排列及尺寸大小。什么是隐式网格?默认情况下,grid容器内部的子元素不设置宽高会自动拉伸:

1
2
3

在上述栗子基础上,再增加两个子元素,并给父元素grid容器设置:

grid-template-rows: 100px;

会发现第一行子元素的高度得到了限制(100px),第二行两个新加入的元素高度依旧会自适应拉伸:

1
2
3
4
5

之所以会出现这种情况就是隐式网格在背后“作怪”,默认有个属性:

grid-auto-flow: row

的意思就是出现没有进行高度设置的隐式网格的时候,隐式网格按照行进行排布。如果换成垂直布局可能更容易看出来:

1
2
3
4
5

这个时候会发现,多出来的两个元素被挤出了第一列,这就是因为默认的隐式网格设置是row——按照行来进行自动布局,但是这个时候我们是按照列来进行布局的,所以说我们只要改变属性值为column即可:

1
2
3
4
5

上面的案例可以看出,当有隐式网格时,其默认宽度或者高度是直接进行拉伸,那么如何给默认的隐式网格设置一个固定的高度呢?

1
2
3
4
5

上面这个案例,并没有进行grid-template-columns: 100px 100px的设置,但是却每一个元素的高度都是100px,这是因为我们设置了grid-auto-columns: 100px——如果元素没有设置固定高宽或者高度,其默认情况下会进行自适应拉伸占满gird,但是如果我们设置了grid-auto-columns,就会根据其设置的值进行解析。

grid子项设置项

grid-column/row-start/end——基于线的元素放置

表示grid子项所占据的区域的起始和终止位置,包括水平方向和垂直方向。

浏览器调试窗口显示grid子元素名称和分割线的序号
浏览器调试窗口显示grid子元素名称和分割线的序号

grid-column/row-start/end的设置方式有两种,第一种:

grid-column-start: 2;

表示这个子元素从第二列开始布局,第二种:

grid-column-end: span 2;
/* 等同于grid-column-end: 4; */

表示这个子元素占有两个网格位置。

grid-column-start: 2; grid-column-end: span 2;
2
3
4

上面的栗子中,第一个元素从第二列开始布局,那么第一个位置就空了出来,这是因为这个元素的默认属性grid-row-end: auto;,如果我们将其改为1(也就是这个子元素的布局在第一行就结束),那么后面的元素就会自动向前补充它的位置。

好像属性值设为任何一个数字都可以达到这个效果~

grid-column-start: 2; grid-column-end: span 2;
2
3
4

grid-rowgrid-row-startgrid-row-end的复合简写,grid-columngrid-column-startgrid-column-end的复合简写。grid-column: 2 / span 2等于grid-column-start: 2; grid-column-end: span 2;

grid-areagrid-row-startgrid-column-startgrid-row-end以及grid-column-end属性的缩写,以及额外支持grid-template-areas设置的网格名称(使用/分隔)。

属性值除了直接使用行号或者列号进行设置,还可以借助于自定义行名、列名进行设置,grid容器设置:

grid-template-rows: [row1] 100px [row2] 100px [row3] 100px [row4];
grid-template-columns: [col1] 100px [col2] 100px [col3] 100px [col4];

子项设置:

grid-row-start: row2;
grid-column-start: col1;

justify/align/place-self——子项对齐方式

place-item用法相同,只不过是place-item是grid容器的属性,针对全部子元素都生效,place-self是子元素的属性,操作指定的子项。

1
2

repeat()

repeat()方法及auto-fill可选值,指定可重复的数值。

grid-template-rows: repeat(3, 100px)等价于grid-template-rows: 100px 100px 100px;

grid-template-rows: repeat(*auto-fill*, 100px);使用auto-fill则会根据grid容器的宽度进行自动分配,防止隐式网格的产生。

minmax()

minmax()方法,设置最小和最大值的范围。

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

设置grid容器三列,第一列、第三列宽度为100px,中间的一列最小为100px,最宽无上限(1fr)。

1
2
3
4
5
6
7
8
9

grid布局案例

自适应布局

给父元素添加属性:

grid-template-columns: repeat(auto-fill, minmax(200px, 1fr))
1
2
3
4
5
6
7
8
9
10
11
12

比定位更方便的叠加布局

Img Box
置顶 手机热卖中...

多种组合排列布局

1
2
3
4
5
6

栅格布局

容器自适应行列布局

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
1
2
3
4
5
6
7
8
9

百度热词风云榜

新闻热榜
1
2
3
4
5
6
7
8

小米商品导航菜单