深入理解 CSS | 青训营笔记

93 阅读10分钟

1 基础知识

1.1 层叠、优先级

层叠三大规则

样式表来源>选择器优先级>源码位置

1.1.1样式表来源重要排序

用户代理样式(浏览器默认样式)<用户样式表<作者样式表<作者样式表中的!important<用户样式表中的!important<用户代理样式表中的!important

1.1.2选择器

选择器分类

  • 基础选择器(ID、类)
  • 组合器(child>、Next-sibling+、……)
  • 属性选择器
  • 伪类选择器
  • 伪元素选择器
  • 逻辑选择器

选择器优先级

内联>id>class=attribute=pseudo-class>type=pseudo-element
注意:内联样式不属于选择器,仅用作对比

1.1.3源码顺序

后面出现的生效优先级高

Tips

  • 选择器尽量少用id:优先级太高,不利于复用,不利于后期覆盖。
  • 尽量不要用!important:压缩了扩展和灵活性
  • 自己的样式加载在引用库样式的后面:保证自己的样式优先级更高,能生效

1.2 继承

大部分具有继承特性的属性跟文本相关;可以使用inherit关键字显式指定一个属性值从其父元素继承

1.3 CSS的值和单位

  • 值:文字类、数值类、函数生成
  • 单位:长度、角度、时间、分辨率

1.4 盒模型

浏览器根据视觉格式化模型,将所有元素表示为盒子模型,css通过盒模型做layout,可以实现三角形、固定比例矩形、水平居中、渐变边框……

负外边距

只有margin可以设置负值,margin负值最终减少的是外界可感知的宽高

  • 设置margin-topmargin-left值为负,元素会相应的向左或向上移动,导致元素与它前面的元素重叠
  • 设置margin-bottommargin-right值为负,不会移动元素,而是将它后面的元素拉过来

2 布局和定位

CSS3之前常用布局
  • Normal Flow常规流
  • Float浮动流
  • Positioning定位流
CSS3之后新增布局
  • Flex弹性盒子布局(一维)
  • Gird网格布局(二维)
  • Multicol多列布局(文本、内容的多列展示)

2.1 常规流布局

任意盒子的display(外部/内部显示类型)→常规流中的盒子→

  1. 块级盒子→参与→块级格式化上下文BFC
  2. 内联级盒子→参与→内联级格式化上下文IFC 内联不参与BFC。若没有一个块级元素包裹它,CSS会强制一块内容生成无法看见的匿名块盒子将其包裹起来,这块盒子会参与BFC布局,但内部形成了一个IFC。

2.1.1 块级格式化上下文BFC

格式化上下文布局规范

在一个块格式区域中,盒子会从包含块的顶部开始,按序垂直排序。同级盒子间的垂直距离会由margin属性决定。相邻两个块级盒子之间的垂直间距会遵循外边距折叠原则被折叠。在一个块格式区域中,每个盒子的左外边缘会与包含块左边缘重合(如果是从右到左的排版顺序,则右)

BFC

不管外部显示类型,内部显示类型是flow-root,其实就是这个盒子内部形成了一个新的块级格式化上下文

满足方式
display: flow-root | inline-block;
position: absolute | fixed;
float: 不为none;
overflow: 不为visible
外边距塌陷

产生情况:

  • 两个Sibling元素之间相邻的上下外边距
  • parent元素和child元素之间相邻的上下外边距
  • 内容为空元素自己上下外边距相邻 消除方法:
  • 在两个相邻的上下边距之间增加border、padding或者内联元素,使之不相邻
  • 在parent和child元素重叠时,除了上述方法,还可以设置parent元素为BFC,使得parent和child不在同级BFC中

2.1.2 内联级格式化上下文IFC

在内联格式区域中,盒子会从包含块的顶部开始,按序水平排列。只有水平外边距、边框和内边距会被保留。这些盒子可以以不同的方式在垂直方向上对齐:可以底部对齐或者顶部对齐,或者按文字底部进行对齐。我们把包含一串盒子的矩形区域称为一个线条框(line box)
line box的高度为所包含的位置最高的元素的顶部位置最低的元素的底部的距离

case
// html
<div clss="title">我是标题</div>
// css
.title{
  background:antiquewhite;
  font-size:18px;
  line-height:36px;
  heigh:36px;
}
// html
<div class="wrap">
  <img src="dy.png" class="image">
  <span class="text">抖音同款能力</span>
</div>
// css
  .image{
    width: 24px;
    height: 24px;
    vertical-align: middle;
  }
  .text{
    font-size: 16px;
    line-height: 32px;
    margin-left: 4px;
    vertical-align: middle;
  }

2.2 弹性盒子布局

作用于parent元素:

  • display
  • flex-direction
  • flex-wrap
  • justify-content
  • align-items
  • align-content
  • gap
    作用于child元素:
  • flex-basis
  • flex-grow
  • flex-shrink
  • flex
  • order
  • align-self
case

三点骰子图案(竖分成三块):

<style>
    .dot-three{
        display: flex;
        justify-content: space-between;
    }
    .dot-center{
        align-self: center;
    }
    .dot-end{
        align-self: flex-end;
    }
</style>
<html>
    <div class="dot-three">
        <span class="dot"></span>
        <span class="dot dot-center"></span>
        <span class="dot dot-end"></span>
    </div>
</html>

五点骰子图案水平分成三块,其余同理

2.3 网格布局

可以定义由行和列组成的二维布局,然后将元素放置到网格中。元素可以占一或者多个单元格。
格式举例

display:grid;
grid-template-columns:100px 1fr;

这样,再用grid写骰子图案,只需要将面设置成均分的3*3grid布局,规定好所需要的点占用的area即可。

grid-template-areas:
  "lt . rt"
  "lc cc rc"
  "lb . rb";
Grid和Flex布局的使用策略
  • Grid:大面积或整体布局
  • Flex:小面积或组件中,或Grid Item中

2.4 定位Position

  • relative
  • absolute
  • fixed
  • sticky

3 层叠上下文(The Stacking Context)

对HTML元素的三维构想,将元素沿着垂直屏幕的虚构的Z轴排开

stacking order

层叠顺序不仅指不同的层叠上下文的顺序,同一个层叠上下文内,元素间也有顺序。

  • z-index只在同一个层叠上下文内比较
  • 子元素的z-index无法超越父元素的z-index显示顺序
  • positionabsolute或者relative时,z-index0或者auto有区别。0:创建了一个新的上下文,子元素无法超越父元素层叠水平。
编写z-index的建议
  1. 使用css变量或者预处理语言的变量,管理z-index的值
  2. 将预设间隔设为10或100,方便后续的插入

4 变形、过渡、动画

布局→绘制→合成

transform 变形

可以2D变形,也可以3D变形

transition 过渡

通过指定某些元素属性从一种起始状态,在一段时间内以某种变化节奏,过渡到终止状态

animation 动画

  • @keyframes 关键帧 用来定义动画过程中出现的关键样式
  • animation-*(-*)用来为元素添加动画

如何写动画性能最好?

  1. 尽量不用触发reflow的属性
  2. 在遇到性能问题时可以触发硬件加速,比如设置will-change属性,设置transform3d等
  3. 尽量使用transform和opacity去写动画

5 响应式设计

5.1 响应式设计原则

  • 优先选用流式布局,如百分比、flex、grid等
  • 使用响应式图片,匹配尺寸,节省带宽
  • 使用媒体查询为不同的设备类型做适配
  • 给移动端设备设置简单,统一的视口
  • 使用相对长度,em、rem、vw作为长度度量

5.2 媒体查询

5.2.1 媒体查询的使用

Tips

  1. 同样遵循cascading层叠覆盖原则,mix-和max-选择一个
  2. 由于设备的多样化逐渐不可枚举,断点的选择尽量根据内容选择
  3. 由于断点的增加会增加样式处理的复杂度,所以尽量减少断点

5.2.2 设备像素、参考像素和移动设备视口

设备像素(物理像素)

显示器上绘制的最小单位,显示屏通过控制每个像素点的颜色,使屏幕显示出不同的图像,和设备相关。

DPI && PPI

每英寸多少物理像素及显示器设备的点距

CSS像素

目的:保证阅读体验一致。CSS使得浏览器中1css像素的大小在不同物理设备上看上去大小差不多

DPR设备像素比

DPR = 设备像素/CSS像素

移动端的布局视口(viewport)

在移动设备中,默认的布局视口由于历史兼容PC屏幕的原因不符合需求,经常需要用<meta>标签对viewport进行设定。
常见的移动端viewport设置:

  1. 保持scale为1
  2. 保持scale放缩参数是1/dpr

5.3 相对长度

em

在非font-size属性中使用时相对于自身的字体大小
font-size上使用时相对于parent元素的字体大小(一般不在这个属性上使用)
应用场景:可以让展示区域根据展示字号的不同,做出放缩调整

rem

根元素的字体大小。通过伪类:root或者html选择器选定。不会像em那样出现多重嵌套的问题,可以用来做响应式布局

vw 和 vh

  • vw:视窗宽度的1%
  • vh: 视图高度的1%
例子
  1. 设置
    设置scale=1,保持视口和屏幕宽度一致
  2. 应用
    • 对于750px的设计稿,给一个卡片宽度60px:
    .card {
        width : 60px;
    }
    
    • 利用px2viewport之类的转换工具,将px替换为vw。因为设计稿是750px,设定转换基准:1vw=750 * 1%=7.5px
    .card {
        width : 8vw;
    }
    
  3. 表现
    • 375dpr=2的设备上:1vw = 375 * 1% = 3.75px,width = 8 * 3.75 = 30px
    • 320dpr=2的设备上:rem = 320 * 1% = 3.2px,width = 8 * 3.2 = 25.6px

6 CSS生态相关

6.1 语言增强

6.1.1 CSS预处理器

  • scss
  • less
  • stylus

三者对比

scsslessstylus
css语法兼容兼容兼容常规兼容
可编程能力较强(逻辑处理能力丰富)较弱(不支持自定义函数)较强
社区活跃、使用人数最多start3.3k;burbon库支持较多star16.9k;twitter bootstrap框架相对较少star11k

提高研发效率

  • 自定义变量 : 提高可复用
  • 嵌套、作用域 : 避免全局污染、结构层次清晰、减少复杂组合选择器
  • mixins、继承 : 提高可复用、可维护性
  • 操作符、条件/循环语句、自定义函数 : 提高可编程能力、增加灵活性

6.1.2 工程架构

CSS模块化

CSS Module是为了解决全局污染问题出现的方案。本质上是保证样式集和对应的选择器是唯一的,方案大概有:

  • BEM命名规范
  • vue-loader的scoped方案
  • CSS Modules

CSS-in-JS

将应用的CSS样式写在JS文件里,利用js动态生成css

styled-component

  1. 生成第一个classname作为componentId
  2. 生成第二个classname作为唯一类名(hash值),使用stylis生成和唯一类名关联的css字符串
  3. 唯一类名对应的css样式insert到的中
  4. 将两个类名写到目标节点的class中

原子化CSS

倾向于小巧且用途单一的class,并以视觉效果进行命名


7 个人感想和总结

  • 本次课并不是一个个讲解CSS的各种属性(太多了,且没有必要,毕竟可以使用的时候随时查阅,时间也不够),而是倾向于原理和CSS相关生态,给我构造了一个大体的知识脉络,给我提供了能继续深入钻研CSS的方向,授人以渔。举的几个例子也是简明直白,比如骰子图案的例子。
  • 掌握IFC、BFC原理,合理使用弹性布局才能画出好看合理的样式。网格布局我接触的比较少,用这种布局可以解决很多之前很麻烦的问题。