Flex
是 CSS 中常用的一维布局,使得父元素能控制子元素的布局。
缩写
flex: flex-grow flex-shrink flex-basis
省略时默认值:1 1 0% 初始值 initial:0 1 auto
flex-basis 百分比相对于父弹性容器主轴,固有值有 auto(会根据自身定,但也会伸缩)、content(与 auto 区别在于它会无视 width、height)、fit-content(宽度优先取本身,如果超过容器大小就会压缩到单词不换行)、max-content(内容能撑多大撑多大)、min-content(压缩到单词不断行)、fill(废弃)
单值
- 数字:flex-grow
- 带单位的长度、百分比、固有值:flex-basis
- none:0 0 auto
余下的值为默认值
双值
- 数字 数字:flex-grow flex-shrink
- 数字 带单位的长度、百分比、固有值:flex-grow flex-basis
余下的值为默认值
三值
flex: flex-grow flex-shrink flex-basis
轴
-
主轴 (main axis) :flex 容器的
flex-direction决定的方向- 默认是
row→ 水平从左到右 row-reverse→ 水平从右到左column→ 垂直从上到下column-reverse→ 垂直从下到上
- 默认是
-
交叉轴 (cross axis) :垂直于主轴
- 主轴水平 → 交叉轴垂直
- 主轴垂直 → 交叉轴水平
flex-warp 默认 nowrap,元素不换行。设置为 wrap 新行跟在后面,wrap-reverse 跟在前面。
justify-content(主轴对齐)
-
作用:沿主轴分配 整个容器的多余空间
-
常用值:
flex-start:起点对齐(默认)flex-end:末端对齐center:居中对齐space-between:两端对齐,间距平均分配space-around:每个项目两侧间距平均space-evenly:每个项目之间间距完全相等
align-items(交叉轴对齐,单行容器)
-
作用:控制子元素在交叉轴上的对齐方式
-
常用值:
flex-start:交叉轴起点对齐flex-end:交叉轴末端对齐center:交叉轴居中对齐baseline:按文本基线对齐stretch:拉伸填满(默认,如果没有固定高度)
align-content 的作用
-
作用对象:多行 flex 容器(
flex-wrap: wrap后才有多行) -
作用:沿 交叉轴 分配 多行之间的空间
-
区别于 align-items:
align-items→ 控制 每行内的单个元素 在交叉轴上的对齐align-content→ 控制 多行整体 在交叉轴上的对齐
常用值
| 值 | 说明 |
|---|---|
flex-start | 行靠交叉轴起点对齐 |
flex-end | 行靠交叉轴末端对齐 |
center | 行居中对齐 |
space-between | 第一行靠起点,最后一行靠末端,其余行平均间隔 |
space-around | 每行之间平均间隔,两端也留一半间距 |
space-evenly | 所有行间隔完全相等 |
stretch | 行沿交叉轴拉伸,占满整个容器(默认) |
如果只有一行,align-content 不起作用
align-self(单个子元素覆盖 align-items)
- 每个子元素可以单独设置
align-self,覆盖父容器的align-items
盒模型
区块盒子 = 内容 + 内边距 + 边框 + 外边距,但外边距不计入盒子大小,所以:
盒子大小 = 内容 + 内边距 + 边框
IE 盒模型(也叫可替代盒模型)
关键字:border-box
特点:width 和 height 是盒子大小,即边框外侧就是实际盒子大小,添加内边距会向内挤压
标准盒模型(默认)
关键字:content-box
特点:width 和 height 是内容大小,盒子大小需要加上内边距和边框,添加内边距会向外生长,不挤压内容
外边距折叠
根据外边距相接触的两个元素是正边距还是负边距,结果会有所不同:
- 两个正外边距将合并为一个外边距。其大小等于最大的单个外边距。
- 如果其中一个外边距为负值,其值将从总值中减去。
- 如果所有的外边距都为负值,折叠后的外边距的值为最小(绝对值最大)的负边距的值。
- 这一规则适用于相邻元素和嵌套元素。
- 外边距折叠仅与垂直方向有关。
- display 设置为 flex 或 grid 的容器中不会发生外边距折叠。
有三种情况会形成外边距折叠:
-
相邻的兄弟元素 相邻的同级元素之间的外边距会被折叠(除非后面的元素需要清除之前的浮动)。
-
没有内容将父元素和后代元素分开 如果没有设定边框(border)、内边距(padding)、行级(inline)内容,也没有创建区块格式化上下文或间隙来分隔块级元素的上边距(margin-top)与其内一个或多个子代块级元素的上边距(margin-top);或者没有设定边框、内边距、行级内容、高度(height)或最小高度(min-height)来分隔块级元素的下边距(margin-bottom)与其内部的一个或多个后代后代块元素的下边距(margin-bottom),则会出现这些外边距的折叠,重叠部分最终会溢出到父代元素的外面。
-
空的区块 如果块级元素没有设定边框、内边距、行级内容、高度(height)、最小高度(min-height)来分隔块级元素的上边距(margin-top)及其下边距(margin-bottom),则会出现其上下外边距的折叠。
包含块
元素的尺寸及位置,常常会受它的包含块所影响。对于一些属性,例如 width, height, padding, margin,绝对定位元素的偏移值(比如 position 被设置为 absolute 或 fixed),当我们对其赋予百分比值时,这些值的计算值,就是通过元素的包含块计算得来。
确定一个元素的包含块的过程完全依赖于这个元素的 position 属性:
-
如果 position 属性为
static、relative或sticky,一般情况下,包含块可能由它的最近的祖先 块元素 的 内容区 的边缘组成,特殊情况下则由触发了格式化上下文的祖先组成。 -
如果 position 属性为
absolute,包含块就是由它的最近的 position 的值不是static的祖先元素的 内边距区 的边缘组成。 -
如果 position 属性是
fixed,在连续媒体的情况下 (手机、电脑、平板之类) 包含块是 viewport, 在分页媒体 (比如打印机) 下的情况下包含块是分页区域。 -
如果 position 属性是
absolute或fixed,包含块也可能是由满足以下条件的最近父级元素的内边距区的边缘组成的:transform或perspective的值不是nonewill-change的值是transform或perspectivefilter的值不是nonecontain的值是layout、paint、strict或contentbackdrop-filter的值不是none
根元素<html>所在的包含块是一个被称为初始包含块的矩形。它具有视口(对于连续媒体)或页面区域(对于分页媒体)的尺寸。
当某些属性被赋予一个百分比值时,它的计算值取决于这个元素的包含块。以这种方式工作的属性包括盒模型属性和偏移属性:
height、top及bottom属性根据包含块的height计算百分比值。width、left、right、padding和margin属性根据包含块的width计算百分比值。
Position
有 5 个固定值,static(默认)、relative、absolute、sticky、fixed。
static
默认值,top、right、left、bottom、z-index无效。
relative
元素根据文档的正常流程定位,然后根据 top、right、bottom 和 left 的值相对于自身偏移(注意是偏移值,它在文档流的初始位置还是依据包含块算的),留下的空间和 static 时一样。
absolute
该元素将从正常文档流中移除,页面布局中不会为该元素创建任何空间。元素的位置是相对于其位置最近的祖先(如果有)或初始包含块。其最终位置由 top、right、bottom 和 left 的值决定。
fixed
元素会被移出正常文档流,并不为元素预留空间。元素的位置是相对于其初始包含块,也就是视觉媒体的视口。其最终位置由 top、right、bottom 和 left 的值决定。
该值总会创建一个新的层叠上下文
sticky
像是 relative + fixed 的混合体。
元素根据正常文档流进行定位,然后相对它的最近滚动祖先和包含块,基于 top、right、bottom 和 left 的值进行偏移。偏移值不会影响任何其他元素的位置。
偏移量(top / bottom / left / right)的计算基准:相对于最近的滚动祖先
活动范围的限制:最近包含块祖先的范围内吸附,一旦到达包含块的边界,它就不再“固定”,而是会被一起滚走。
该值总是创建一个新的层叠上下文。sticky 元素会“固定”在离它最近的一个拥有“滚动机制”的祖先上(当该祖先的 overflow 不是 visible),即便这个祖先不是最近的真实可滚动祖先。
至少有一个 inset属性(一个缩写属性,包含 top、inset-block-start、right、inset-inline-end等)需要设置为非 auto 值,不然就没用。如果某个轴的两个 inset 属性都设置为 auto,则该轴上的 sticky 值将表现为 relative,都设置为非 auto,那么可能被拉伸以达到黏附效果。
em 与 rem
em:相对于自身的 font-size 计算,如果自身没有,那么相对于继承的算,需要累积计算。
rem:相对于根元素 <html> 的 font-size 计算,全局统一,不受嵌套影响。
BFC
BFC 是一个独立的渲染区域,内部的布局不会影响到外部。
特点:
- margin 坍塌只发生在同一块格式化上下文中,
float和clear也只在同一 BFC 中生效 - 内部的块盒子从上到下排列(对于行内元素,会被浏览器包一个行框),这些盒子垂直方向的距离由 margin 决定
- BFC 区域不会与浮动元素重叠
- 计算 BFC 高度时,浮动元素也参与
以下方法会触发块格式化上下文,只列举常见的:
overflow不为visable的块元素float不为nonedisplay为inline-block、flex、inline-flex、grid、inline-grid等- 弹性项目(flex 或 inline-flex 的一级子元素)
- 网格布局元素
position为绝对定位,即absolute和fixed
它可以用来清除浮动、防止 margin 坍塌
margin 坍塌一般发生在没有阻隔的父子元素之间(之前写顶部导航栏遇到了,现在知道了),或者垂直排列的兄弟元素之间。
清除浮动
如果父元素未设置高度,浮动元素由于脱离了文档流,就会从父元素里漏出来,父元素高度塌陷,推荐方法有两种:
- 父元素设置
overflow非visable或display: flow-root(这种更好,没overflow那么大副作用,创建 BFC,定义自己为格式化上下文的根元素) - 添加
<div style="clear: both;"></div>
伪类与伪元素
伪类:是添加到选择器的关键字,用于指定所选元素的特殊状态,更像“CSS类”,以冒号开头 常见:
- 动态状态:
:hover、:active、:focus、:visited, - 结构性:
:first-child、:last-child、:nth-child(n)、:nth-of-type(n)、:not()、:is()、:where() - 其他:
:checked、:disabled、:required、:empty
题外话:<a> 上伪类的顺序性
:link(未访问的链接):visited(已访问的链接):hover(鼠标悬停时):active(正在点击时)
伪元素:是附加至选择器末的关键词,允许你对被选择元素的特定部分修改样式。更像“HTML元素”,双冒号开头 常见:
::before、::after(生成额外的行内元素)::first-line、::first-letter::selection(被选中区域)::placeholder(表单占位符文本)
first-child、 first-of-type 与 nth-of-type
first-child: 一组兄弟元素中的第一个元素 fisrt-of-type: 一组兄弟元素中其类型的第一个元素 nth-of-type: 相同类型(标签名称)的兄弟元素中的位置来匹配元素
选择器权重
行内 > id > class、伪类选择器、属性选择器 > 元素、伪元素
!important 优先级最高,通配符*/兄弟+/后代选择器权重为0,:where选择器使得选择器整体优先级为0,:is优先级取决于最高的那一项,:not自身不计入权重,里面的选择器才计入
比较规则是:
- 按区分大类
- 高位大者胜(1,2,3,0) > (1,99,3,0)
- 相同,后出现的胜