前端主流布局方法
GitHub链接
传统布局
特点
- 兼容性好;
- 布局繁琐;
- 局限性,不能在移动端很好的布局。
CSS盒子模型
css盒模型的注意点:
padding
不能为负值,而margin
可以为负值;- 背景色会平铺到非
margin
的区域; margin-top
传递的现象及解决方案;margin
上下叠加的现象及解决方案。
3、什么是margin-top
的传递现象?当父元素嵌套 子元素,给子元素添加margin-top
属性的时候,会出现子元素没有效果,但是父元素却出现了margin-top
。举例:
解决方案:
- 给父元素添加一个边框即可解决——
border-top: 1px solid rgba(0, 0, 0, 0)
; - “障眼法”——子元素使用
border-top: 20px solid blue
; - 使用弹性布局(flex)或者网格布局(gird)。
4、margin
上下叠加问题是指,当两个兄弟div
,上一个设置了margin-bottom
,下一个设置了margin-top
,那么两个元素之间的举例并不是margin-bottom
+margin-top
,而是取最大值最为两者之间的距离,举个栗子:
解决方案:
margin
尽量设置到一个元素上;- 使用弹性布局(flex)或者网格布局(gird)。
块级盒子与内联盒子
在CSS中我们广泛地使用两种“盒子”,块级盒子(block box)和内联盒子(inline box)。这两种盒子会在页面中表现出
不同的行为方式。
- 块级盒子:
div
、p
、h1
; - 内联盒子:
span
、a
、strong
。
块状盒子特性
- 独占一行;
- 支持所有css样式;
- 不写宽度的时候,跟父元素的宽度相同;
- 所占区域是矩形。
内联盒子特性
- 盒子默认不会换行(一行显示);
- 有些样式不支持,例如:
width
、height
等; - 不写宽度的时候,宽度由内容决定;
- 所占区域不一定是矩形;
- 内联标签与标签之间是有缝隙的。
Tips / 提示
内联盒子很多样式不支持,在做布局的时候应尽量避免去使用。
自适应盒模型的特性
自适应盒模型指的是:当盒子不设置宽度时,盒模型相关组成部分的处理方式是如何的。
当父元素嵌套子元素,子元素设置了固定宽度(具体的px
值或者%
),子元素的margin
、padding
、border
都会将元素“向外扩张”;但是如果子元素不设置width
,或者width: initial
,这个时候子元素会自动考虑margin
、padding
、border
。举个栗子:
标准盒模型与怪异盒模型
在标准模型中,如果你给盒设置width
和height
,实际设置的是content box。padding
和border
再加上设置的宽高一起决定整个盒子的大小。
在怪异模型中,所有宽度都是可见宽度,所以内容宽度是该宽度减去边框和填充部分。
如何将标准盒模型转化为怪异盒模型?通过设置属性:box-sizing: border-box
来实现。
box-sizing
属性:
- content- box: width、height → content
- border-box: width、height → content + padding + border
应用:
- 量取尺寸时不用再去计算一些值;
- 解决一些需要设置百分比和盒模型值。
浮动
样式讲解
当元素被浮动时,会脱离文档流,根据float
的值向左或向右移动,直到它的外边界碰到父元素的内边界或另一个浮动元素的外边界为止,是CSS布局中实现左右布局的一种方式。
文档流:文档流是元素在Web页面上的一种呈现方式,按照出现的先后顺序进行排列。
清除浮动的方案
clear
属性:left
、right
、both
三个属性值,用于清除兄弟节点的浮动,如果是父元素嵌套了子元素,子元素有浮动,那么可以通过给子元素添加一个空的同级兄弟空元素,然后清除浮动即可达到清除子元素浮动的效果;- 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、right
、bottom
和left
属性则决定了该元素的最终位置。
相对定位
- 相对定位的元素是在文档中的正常位置偏移给定的值(相对自身进行偏移);
- 不影响其他元素的布局。
绝对定位
- 绝对定位的元素脱离了正常的文档流,绝对定位元素不占据文档流空间;
- 与使用了
float
属性的div
相似,具备了内联盒子的特性——在不设置width
属性的时候,宽度由内容决定; - 同样,当内联盒子使用了绝对定位,可以让其具备块级盒子的特性——支持所有的样式。
Expand / 拓展
绝对定位元素相对于最近的非
static
祖元素定位,当这样的祖元素不存在时,则相对于可视区域定位。
固定定位
- 固定定位与绝对定位相似,但是会固定在可视区域中;
- 不受祖元素定位方式的影响;
- 块级盒子使用了固定定位,就会具有内联盒子的特性;
- 内联盒子使用了固定定位,就会具有块级盒子的特性。
粘性定位
粘性定位可以被认为是相对定位和固定定位的混合,元素在跨越特定阈值前为相对定位,之后为固定定位。
层级的改变
使用属性z-index
可以对元素的层级进行调整,默认元素的z-index
值为0。
flex弹性布局
Tips / 提示
- flex 是 flexible Box 的缩写,意为"弹性布局",用来为盒状模型提供最大的灵活性,任何一个容器都可以指定为 flex 布局。
- 当我们为父盒子设为 flex 布局以后,子元素的 float、clear 和 vertical-align 属性将失效。
- flex布局又叫伸缩布局 、弹性布局 、伸缩盒布局 、弹性盒布局。
- 采用 Flex 布局的元素,称为 Flex 容器(flex container),简称"容器"。它的所有子元素自动成为容器成员,称为 Flex 项目(flex item),简称"项目"。
弹性盒子是一种用于按行或按列布局元素的一维布局方法。元素可以膨胀以填充额外的空间,收缩以适应更小的空间。
Tips / 提示
通过给父盒子添加 flex 属性,来控制子盒子的位置和排列方式。
特点:
- 操作方便,布局极其简单,移动端使用比较广泛
- pc端浏览器支持情况比较差
- IE11或更低版本不支持flex或仅支持部分
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 | 从上到下 |
[photos]
[/photos]
Warning / 注意
使用
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 | 平分剩余空间 |
Expand / 拓展
space-evenly
与space-around
的区别,space-evenly
是父容器宽度减去所有子元素宽度,然后平均分配;space-around
是每个元素分配有两个边。
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-items
适用于单行情况下, 只有上对齐、下对齐、居中和拉伸;align-content
适应于换行(多行)的情况下(单行情况下无效), 可以设置 上对齐、下对齐、居中、拉伸以及平均分配剩余空间等属性值;- 总结就是单行找
align-items
多行找align-content
。
align-content 和align-items区别
- `align-items`适用于单行情况下, 只有上对齐、下对齐、居中和拉伸; - `align-content`适应于换行(多行)的情况下(单行情况下无效), 可以设置 上对齐、下对齐、居中、拉伸以及平均分配剩余空间等属性值; - 总结就是单行找`align-items`多行找`align-content`。Flex容器常用布局方式
内联和块的上下左右居中布局
方法一,给父盒子设置属性:
display: flex;
align-items: center;
justify-content:center
方法二,对父元素和子元素分别设置,
父盒子设置属性:
display: flex
子元素设置属性:
margin: auto
均分列布局
子项分组布局
当父元素设置为flex布局后,子元素设置属性margin-right: auto;
后就会根据所有的空间进行均分。
不定向居中布局
Flex子项设置项
flex-grow——扩展比例
属性值 | 含义 |
---|---|
0 | 默认值,表示不占用剩余的空白间隙扩展自己的宽度 |
0.5 | 宽度增加剩余所有空间的50% |
1 | 占满剩余的所有空间 |
大于1 | 还是占满剩余所有空间,与1效果相同 |
Warning / 注意
如果两个同级子元素(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%。
flex-shrink——收缩比例
flex-shrink
与flex-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 $$
flex-basis
没搞明白这个属性有啥实际用处
flex
是flex-grow
、flex-shrink
和flex-basis
的缩写。
order
改变某一个flex子项的排序位置,默认值为0,如果元素设置为1,则排至最后,如果设置为负数,则排至第一位。
align-self
——控制单独某一个flex子项的垂直对齐方式,默认值是auto,其他属性值参考Flex容器设置项中的align-items
属性。
Flex子项常用布局方式
等高布局
flex子元素默认高度就会与父元素等高。
测试内容
测试内容
测试内容
测试内容
测试内容
测试内容
测试内容
测试内容
测试内容
测试内容
测试内容
测试内容
测试内容
测试内容
两列与三列布局
Sticky Footer布局
综合案例
swiper轮播图
grid网格布局
概念
CSS网格是一个用于web的二维布局系统。利用网格,你可以把内容按照行与列的格式进行排版。另外,网格还能非常轻松地实现一些复杂的布局。
Expand / 拓展
flex布局更适用于一行或者一列的一维布局,grid布局则是针对行与列同时存在的二维布局。
grid容器设置项
[photos]
[/photos]
grid-template-row/columns——定义网格及fr单位
基于网格行和列的维度,去定义网格线的名称和网格轨道的尺寸大小。
display: grid;
grid-template-rows: 100px 100px 100px;
grid-template-columns: 100px 100px 100px
写法还可以进行混编:
grid-template-rows: 100px 20% auto;
还可以使用grid的专属单位fr
:
grid-template-columns: 1fr 1fr 1fr;
Tips / 提示
使用
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;
}
划分子区域只能按照矩形来划分~
grid-template
grid-template-rows
、grid-template-columns
和grid-template-areas
属性的缩写。
上述的父级设置就可以简写为:
grid-template:
"a1 a1 a2" 1fr
"a1 a1 a2" 1fr
"a3 a3 a3" 1fr
/ 1fr 1fr 1fr;
grid-row/column-gap、grid-gap——网格间隙
用来设置元素行列之间的间隙大小,grid-gap
是grid-row-gap
与grid-column-gap
的复合简写,推荐使用row-gap
、column-gap
、gap
。
Tips / 提示
为什么要去掉前缀
grid-
?因为发现这个间隙的问题不止在grid布局中会出现,因此去掉了前缀使其也可以应用在其他布局中。
gap
属性在flex布局中也是可以使用的:
justify/align-items与place-items——网格对齐方式及简写
默认值stretch
,指定了子项在网格中的拉伸对齐。place-items
是align-items
与justify-items
的复合简写属性。
属性值 | 含义 |
---|---|
start | 上/左 |
center | 中 |
end | 下/右 |
如果子元素不设置宽高,默认是铺满每一个单元格:
如果强制设置其宽高,会发现每一个div默认是在grid单元格的左上角对齐的:
align/justify-content与place-content——grid容器对齐方式及简写
指定gird容器的对齐方式,只有当grid布局的宽高小于容器宽度的时候设置才有效果。
grid-auto-flow/rows/columns——显式网格与隐式网格
指定在显示网格之外的隐式网格,如何排列及尺寸大小。什么是隐式网格?默认情况下,grid容器内部的子元素不设置宽高会自动拉伸:
在上述栗子基础上,再增加两个子元素,并给父元素grid容器设置:
grid-template-rows: 100px;
会发现第一行子元素的高度得到了限制(100px),第二行两个新加入的元素高度依旧会自适应拉伸:
之所以会出现这种情况就是隐式网格在背后“作怪”,默认有个属性:
grid-auto-flow: row
的意思就是出现没有进行高度设置的隐式网格的时候,隐式网格按照行进行排布。如果换成垂直布局可能更容易看出来:
这个时候会发现,多出来的两个元素被挤出了第一列,这就是因为默认的隐式网格设置是row
——按照行来进行自动布局,但是这个时候我们是按照列来进行布局的,所以说我们只要改变属性值为column
即可:
上面的案例可以看出,当有隐式网格时,其默认宽度或者高度是直接进行拉伸,那么如何给默认的隐式网格设置一个固定的高度呢?
上面这个案例,并没有进行grid-template-columns: 100px 100px
的设置,但是却每一个元素的高度都是100px,这是因为我们设置了grid-auto-columns: 100px
——如果元素没有设置固定高宽或者高度,其默认情况下会进行自适应拉伸占满gird,但是如果我们设置了grid-auto-columns
,就会根据其设置的值进行解析。
grid子项设置项
grid-column/row-start/end——基于线的元素放置
表示grid子项所占据的区域的起始和终止位置,包括水平方向和垂直方向。
grid-column/row-start/end
的设置方式有两种,第一种:
grid-column-start: 2;
表示这个子元素从第二列开始布局,第二种:
grid-column-end: span 2;
/* 等同于grid-column-end: 4; */
表示这个子元素占有两个网格位置。
上面的栗子中,第一个元素从第二列开始布局,那么第一个位置就空了出来,这是因为这个元素的默认属性grid-row-end: auto;
,如果我们将其改为1(也就是这个子元素的布局在第一行就结束),那么后面的元素就会自动向前补充它的位置。
Quote / 参考
好像属性值设为任何一个数字都可以达到这个效果~
grid-row
是grid-row-start
与grid-row-end
的复合简写,grid-column
是grid-column-start
与grid-column-end
的复合简写。grid-column: 2 / span 2
等于grid-column-start: 2; grid-column-end: span 2;
。
grid-area
是grid-row-start
、grid-column-start
、grid-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
是子元素的属性,操作指定的子项。
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)。
grid布局案例
自适应布局
给父元素添加属性:
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr))