标题参考前端技能路线系列 (opens new window)
副标题参考 MDN (opens new window)
文章内容来源 表现 (opens new window)
# 规范
-  
CSS Working Group Editor Drafts 承担主要的 CSS 规范开发工作
 FX Task Force (opens new window)
FX Task Force Editor Drafts 主要是一些图形图像方面的规范,比如遮罩、滤镜
-  
CSS 新方向,浏览器暴露出更多 API,使 CSS 可以控制更多底层的东西,目前主要是 Chrome 团队在主导。
 -  
css 新特性阶段
 
# 伪类
伪类用于在页面中的元素处于某个状态时,为其添加指定的样式。
最常规的区分伪类和伪元素的方法是:实现伪类的效果可以通过添加类来实现,但是想要实现伪元素的等价效果只能创建实际的 DOM 节点。
# :hover
hover 元素要是想控制其他元素样式,除非是该元素的子元素,或者是兄弟元素,子元素直接在 :hover 后加空格加选择器,兄弟元素:hover 后加空格在加+
# 伪元素
伪元素会创建一个抽象的伪元素,这个元素不是 DOM 中的真实元素,但是会存在于最终的渲染树中,我们可以为其添加样式。
伪元素可以分为排版伪元素、突出显示伪元素、树中伪元素三类
# 排版伪元素
::first-line伪元素::first-letter伪元素
# 突出显示伪元素
突出显示伪元素表示文档中特定状态的部分,通常采用不同的样式展示该状态。如页面内容的选中。
突出显示伪元素不需要在元素树中有体现,并且可以任意跨越元素边界而不考虑其嵌套结构。
::selection与::inactive-selection
# 树中伪元素
这类伪元素会一直存在于元素树中,它们汇集成源元素的任何属性。
内容生成伪元素:
::before/::after列表项标记伪元素(只有 safari 支持):
::marker输入框占位伪元素:
::placeholder# aspect-ratio
aspect-ratio CSS (opens new window) 属性为box容器规定了一个期待的纵横比,这个纵横比可以用来计算自动尺寸以及为其他布局函数服务。还可以用作媒体查询
# content
CSS的 content CSS 属性用于在元素的 ::before 和 ::after 伪元素中插入内容。使用content 属性插入的内容都是匿名的可替换元素。
值可以为attr,取元素上的属性值,例如:content:attr(data-placeholder)
# clamp()
设置最小值和首选值、最大值,font-size: clamp(1rem, 2.5vw, 2rem);
# display
# inline-flex
元素宽度由子元素撑起
# block
# 块级元素的宽度
- 块级元素宽度未设置时,宽度始终等于父元素宽度。
 - 如果设置了左右margin,则宽度等于父元素减去两边边距。
 - 如果有设置宽度,并且有一个边距有值,另一个边距值为auto时,则auto自动填充剩余宽度。
 - 如果设置了宽度,并且也设置了左右边距,那么在从左往右阅读的语言中,会把右外边距的值重置为
auto。 - 当设置了宽度,两边边距为auto时,块级元素居中
 
# line-height
line-height 取值的区别(100%、1em、1):
- 百分比和 em 根据父元素 font-size 进行计算
 - 值为数字时,根据子元素的 font-size 进行计算
 
# var()
使用css变量,**var()函数可以代替元素中任何属性中的值的任何部分。var()**函数不能作为属性名、选择器或者其他除了属性值之外的值。
# vertical-align
vertical-align 使用条件:父元素必须含有 line-height(inline 元素有无皆可),子元素中的 vertical-align 才能起作用。 
# border-collapse
border-collapse CSS 属性是用来决定表格的边框是分开的还是合并的。在分隔模式下,相邻的单元格都拥有独立的边框。在合并模式下,相邻单元格共享边框。
# Grid
注意,设为网格布局以后,容器子元素(项目)的 flot、display:inline-block、display:table-cell、vertical-align 和 column-*等设置都将失效。
# position
# absolute
相对于最近的非static定位祖先元素的偏移
# sticky
# flex
flex不为人知的细节 (opens new window)
# font-size
原生端对于字体大小限制不一样,ios并没有限制字体大小,而android在小于8px之后不再变小(只测试了一台android)
可以在这个链接 (opens new window)进行测试。
# font-weight
默认为normal,当值为normal时与400等值
# @font-face
# font-display
font-display 属性决定了一个@font-face 在不同的下载时间和可用时间下是如何展示的。
 font-display 用法 (opens new window)
# unicode-range
指定字体使用的范围,比如该字体只应用在数字、英语、汉字中。
# 注意
- 不能在css选择器中定义font-face,这是无效的:
 
.className {
  @font-face {
    font-family: MyHelvetica;
    src: local("Helvetica Neue Bold"), local("HelveticaNeue-Bold"),
        url(MgOpenModernaBold.ttf);
    font-weight: bold;
  }
}
- 隐藏的元素不会加载字体。
 - 同名字体不会重复加载,即使字体本身内容不一样。
 
# font-variant-numeric
font-variant-numeric: tabular-nums;像是倒计时这种数字经常变化的情景,推荐使用。整齐的对齐数字。
# @media
媒体查询语法。max-width是小于指定值,而min-width是大于等于指定值
# calc()
calc 函数是基本的表达式计算,它支持加减乘除四则运算。在针对维度进行计算时,calc() 函数允许不同单位混合运算,这非常的有用。例如:
section {
  float: left;
  margin: 1em;
  border: solid 1px;
  width: calc(100% / 3 - 2 * 1em - 2 * 1px);
}
# overscroll-behavior-x
这个CSS属性用来控制当滚动到区域的水平边界时的浏览器行为。设置为contain效果为:
默认的滚动溢出行为将被内部的元素观察到,(例如: “bounce”效果或者刷新),但是相邻的区域不会产生连续滚动效果,例如: 在下面的元素不会被滚动。
# svg
svg是内联元素,也会像span那样存在间距问题。 svg的宽高比不会被background-size拉伸,需要修改svg的preserveAspectRatio属性
.page-home-wrap {
  height: 100vh;
  background: no-repeat
    url('~/assets/svg/202104_bg.svg#svgView(preserveAspectRatio(none))');
  background-size: 100% 100%;
}
多个svg有可能会互相影响,具体请看svg之间还能互相影响 (opens new window)
# scroll-snap-type
滚动容器中的一个临界点如何被严格的执行,配合scroll-snap-align使用
# scroll-snap-align
控制元素滚动结束时,是浏览器会滚动到元素的哪个位置,有三个选项start\end\center
# img
# srcset
指定img备用图片资源
# sizes
只有在srcset值存在时才有效,指定在不同屏幕尺寸使用的图片资源。
# z-index
基本概念:
- z-index是深度属性,设置元素在z轴上面的堆叠顺序。
 - z-index为负值时会隐藏到正常文档流下边,所以也无法触发点击事件。
 - 只有dom的position
属性值不是static时才生效 - 堆叠上下文:当前dom往上级找,如果该级设置了z-index属性值(非auto),那么该级别dom就是堆叠上下文;如果往上级一直找不到,那么根级别dom就是堆叠上下文。
 
z-index优先级别比较:
- 有postion属性的dom(脱离文档流的dom)会在没有position属性的dom(文档流内的dom)的上面。
 - 文档流内容的堆叠遵循后来居上的原则。(后面的如果和前面的dom重叠了,后面盖在前面)
 - 同级的dom,它们的堆叠上下文一定相同。所以直接z-index比较,大的在上面,小的在下面,相同的遵循后来居上的原则。
 - 非同级的dom,就比较他们堆叠上下文的z-index。(dom的z-index受父级的约束,父级如果小的话,子级再大也没用!)
 
参考:https://blog.csdn.net/qq_36333750/article/details/89893652
# zoom
傲娇怪firefox不支持zoom,和transform:scale的区别是:
- zoom的缩放是相对于左上角的;而scale默认是居中缩放;
 - zoom的缩放改变了元素占据的空间大小;而scale的缩放占据的原始尺寸不变,页面布局不会发生变化;
 - 性能问题,zoom是实际改变元素大小,所以性能没有scale好
 - zoom只是实验性支持,不同浏览器表现不一致
 - 设置了
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no"/>之后,android端zoom无效 
# BFC(块级格式化上下文)
比如说 BFC, BFC 是 block formatting context,也就是块级格式化上下文,是用于布局块级盒子的一块渲染区域。
# 如何触发 BFC?
即如何让某元素内形成 BFC 环境。
下列方式会创建块格式化上下文:
- 根元素(
<html>) - 浮动元素(元素的 
float不是none) - 绝对定位元素(元素的 
position为absolute或fixed) - 行内块元素(元素的 
display为inline-block) - 表格单元格(元素的 
display为table-cell,HTML 表格单元格默认为该值) - 表格标题(元素的 
display为table-caption,HTML 表格标题默认为该值) - 匿名表格单元格元素(元素的 
display为 table、table-row、 table-row-group、table-header-group、table-footer-group(分别是 HTML table、row、tbody、thead、tfoot 的默认属性)或 inline-table) overflow值不为visible的块元素display值为flow-root的元素contain值为layout、content或 paint的元素- 弹性元素(
display为 flex 或 inline-flex 元素的直接子元素) - 网格元素(
display为 grid 或 inline-grid 元素的直接子元素) - 多列容器(元素的 
column-count或column-width不为auto,包括column-count为 1)column-span为all的元素始终会创建一个新的 BFC,即使该元素没有包裹在一个多列容器中(标准变更,Chrome bug)。 
# BFC 布局规则
- 内部的 Box 会在垂直方向,一个接一个地放置。
 - Box 垂直方向的距离由 margin 决定。属于同一个 BFC 的两个相邻 Box 的 margin 会发生重叠
 - 每个元素的 margin box 的左边, 与包含块 border box 的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。
 - BFC 的区域不会与 float box 重叠。
 - BFC 就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。
 - 计算 BFC 的高度时,浮动元素也参与计算
 
# BFC 有哪些作用?
- 自适应两栏布局
 
<style>
  .wrapper div {
    height: 200px;
  }
  .left {
    float: left;
    width: 200px;
    background: gray;
  }
  .right {
    float: right;
    width: 200px;
    background: gray;
  }
  .main {
    /* 中间栏创建 BFC */
    /* 由于 盒子的 margin box 的左边和包含块 border box 的左边相接触 */
    /* 同时 BFC 区域不会和浮动盒重叠,所以宽度会自适应 */
    overflow: auto;
    background: cyan;
  }
</style>
<div class="wrapper">
  <div class="left"></div>
  <div class="right"></div>
  <div class="main"></div>
</div>
- 可以阻止元素被浮动元素覆盖
 
<!-- 文字浮动效果 -->
<div class="p">
  <div class="c1"></div>
  <div class="c2">对双方来说肯定附件是快乐的附件是领导看速度</div>
</div>
<style>
  .p {
    overflow: hidden;
    width: 5em;
    height: 200px;
  }
  .c1 {
    background: red;
    width: 100px;
    float: left;
    height: 100px;
  }
  .c2 {
    background: green;
  }
</style>
- 可以包含浮动元素——清除内部浮动
 
<!-- 父元素高度被flot子元素撑起 -->
<style>
.p {
  overflow: hidden;
  background: deepskyblue;
}
.c1 {
  background: red;
  float: left;
  width: 10%;
  height: 100px;
}
<style>
<div class="p">
  <div class="c1"></div>
</div>
分属于不同的 BFC 时可以阻止 margin 重叠
# 动画
几种动画的解决方案:
- gif,缺点是透明背景有毛边,显示不清楚,体积大
 - css关键帧动画,只能做简单的,比如随机函数做不了。
 - 使用AE的制作的动画,然后用Lottie转换成svg或者canvas,缺点:目前不支持wiggle path函数。也可以去物料库 lottiefiles.com/ (opens new window)找一个
json动画 - 一些css动画库:https://juejin.cn/post/7026867467783766047?utm_source=gold_browser_extension
 
# CSS NEXT
# CSS Nesting Module
css原生嵌套语法,有两种写法:直接嵌套和@nest规则。嵌套必须由选择符开始
.foo {
  color: blue;
  & { padding: 2ch; }
}
.foo {
  color: red;
  @nest & > .bar {
    color: blue;
  }
}
# env()
环境变量,目前支持的user-agent变量有:1. safe area inset 2. viewport-segment。除了UA变量还支持用户自定义变量,用户定义变量目前只能通过引用插件时定义,不能定义在css文件中
# 问题
# 如何禁止移动端长按选中?
-webkit-touch-callout: none; // 禁用长按菜单,只有ios支持
  user-select: none; // 禁止选中文字
  pointer-events: none; // 禁止点击
# 文字超出省略?
overflow:hidden;//隐藏文字
text-overflow:ellipsis;//显示 ...
white-space:nowrap; // 不换行
# 多行文字超出省略
display: -webkit-box; /*重点,不能用block等其他,将对象作为弹性伸缩盒子模型显示*/
      -webkit-box-orient: vertical; /*从上到下垂直排列子元素(设置伸缩盒子的子元素排列方式)*/
      -webkit-line-clamp: 3; /*行数,超出三行隐藏且多余的用省略号表示...*/
      line-clamp: 3;
      word-break: break-all;
      overflow: hidden;
      max-width: 100%;
# 如何处理小于12px的文字?
在有些PC浏览器中font-size无法小于12px,现有的几种解决办法:
- 使用zoom,但是兼容性和性能都不行,移动端会出问题。
 - 使用transform:scale()来缩小,但是还是会占用实际空间
 
display:inline-block; // transform:scale只对有宽高的元素生效
font-size: 16px;
transform: scale(0.5);
transform-origin: bottom left; 
line-height:8px; // line-height为font-size一半
margin-right: -宽度一半px;
- 使用svg替代文本,例子:https://www.zhangxinxu.com/wordpress/2018/03/svg-text-font-size-auto-scale/ 使用图片替代文本
 
# A 标签中包含嵌套 img 后,高度为什么多了几个像素?
a 元素下有一个匿名文本,这个文本外有一个匿名行级盒子,它有的默认 vertical-align 是 baseline 的,而且往往因为上文 line-height 的影响,使它有个 line-height,从而使其有了高度。而 img 是行内元素,即默认 display: inline; 所以,由于行级盒的对齐问题(baseline 对齐)的原因,a 标签下匿名盒子就会下沉,往下撑开一些距离,所以把 a 撑高了。解决办法一:
消除掉匿名盒子的高度,也就是将 a 标签的 display 设置为 block 或者 inline-block,并且 a 设置 line-height:0 或 font-size:0;
这个方法,作者测试发现 display:inline-block;line-heihgt:0px;的情况下,多出的 7 像素会跑到 a 标签的父标签里去,不知道为啥。而使用 display:block 则不会出现这种情况
解决办法二:
a 标签和 img 标签都设置 vertical-align:top,让其 top 对齐,而不是 baseline 对齐
解决办法三(推荐):
给 img 设置 display:block,让它和 a 标签下的匿名行级盒子不在一个布局上下文中,也就不存在行级盒的对齐问题。
# 如何选择第一个指定的class元素?
没有类似:first-of-class这种选择器,但是可以使用其他办法:
.home > .red {
    border: 1px solid red;
}
.home > .red ~ .red {
    border: none;
}
# 块级元素宽度不会被撑开?
块级元素被子元素撑开时,如果没设置宽度,宽度就是这个块级元素的父元素的100%
块级元素的宽度等于其父元素内容区的宽度, 所以跟儿子撑不撑没关系。
浮动元素和行内块级元素这种失去了天生宽度的元素,才有被儿子撑开一说
# box-shadow显示不全?
有可能是被相邻的overflow:hidden裁剪,添加边距可以解决。
# sticky定位失效?
- 祖先元素设置了
overflow:hidden; 
# rgba 和 opacity 的不同?
rgba 只是背景颜色有透明效果,内容不会透明,opacity 是所有后代都变透明
# 文字超出隐藏?
.hideText{
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
# flex 布局中文本超出隐藏无效?
- 在 flex 布局中使用文本超出隐藏时会遇见 bug,给该文本的父元素增加 min-width:0 可以解决。 1. 设置文本元素宽度100%
 
# 元素全屏后,弹窗元素不能显示?
- 原因:
使用 elementUI 时notify组件无法在全屏中显示出来,因为 notify 渲染在 body 下,全屏元素不与 notify 在同一层级下,如果 notify 组件为全屏元素的子元素,那么就会正常显示了。 - 解决思路:
- 把弹窗元素移到全屏元素下。
 - 把 body 全屏,把之前的全屏元素设置为:
 
 
.fullscreen {
  position: fixed;
  top: 0px;
  right: 0px;
  bottom: 0px;
  left: 0px;
  background: black;
}
# 防止滚动穿透?
- css方法:
- 设置滚动的元素pointer-events:none
 - 设置overflow:hidden
 
 - js方法:
 
// //阻止防止滚动、缩放。
// $(".sliders,.modals").on("touchmove",function(event){
// event.preventDefault();
// });
# 区分伪类和伪元素?
- 最常规的区分伪类和伪元素的方法是:实现伪类的效果可以通过添加类来实现,但是想要实现伪元素的等价效果只能创建实际的 DOM 节点。
 - 可以通过
:和::来区分,,:表示伪类,::表示伪元素 - 伪元素与伪类的根本区别在于:操作的对象元素是否存在于原来的 dom 结构里。
 
::before 伪类搭配 vertical-align:middle 实现垂直居中的原理?
- https://segmentfault.com/a/1190000020646920
 
# before和after伪类无法作用于img?
对于 img 这种自闭和标签,似乎不存在 content (内容或后代元素)在标签中,所以选择器没有生效
https://www.cnblogs.com/goodbeypeterpan/p/9620114.html
# 如何单独为after和before设置点击事件?
首先屏蔽父元素的点击事件pointer-events: none;,因为继承的原因,所以还有为伪类添加点击事件pointer-events: auto;
# 垂直水平居中?
<div class="parent">
  <div class="child"></div>
</div>
div.parent {
  display: flex;
  justify-content: center;
  align-items: center;
}
div.parent {
  position: relative;
}
div.child {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
/* 或者 */
div.child {
  width: 50px;
  height: 10px;
  position: absolute;
  top: 50%;
  left: 50%;
  margin-left: -25px;
  margin-top: -5px;
}
/* 或 */
div.child {
  width: 50px;
  height: 10px;
  position: absolute;
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
  margin: auto;
}
div.parent {
  display: grid;
}
div.child {
  justify-self: center;
  align-self: center;
}
div.parent {
  font-size: 0;
  text-align: center;
  &::before {
    content: "";
    display: inline-block;
    width: 0;
    height: 100%;
    vertical-align: middle;
  }
}
div.child {
  display: inline-block;
  vertical-align: middle;
}
div.parent {
  /* display:grid; 也可以*/
  display: flex;
}
div.child {
  margin: auto;
}
- 用于 ifc
 
/* line-height + text-algin */
.parent {
  height: 100px;
  line-height: 100px;
  text-align: center;
}
.child {
}
最简单方式,使用flex布局和
margin:auto.parent{ height:100px; display:flex; } .child{ margin:auto; }# 杯布局和双飞翼布局的好处?
杯布局和双飞翼布局可以让重要的文档流提前渲染 
# 清除浮动?
对于子元素设置 float:right 后脱离文档流的问题,可以对父元素设置 overflow:hidden 来解决 
# less如何在每个样式文件中都引入共通样式?
这时候我们经常会使用类似于 less-loader 的 additionalData 在每个样式文件头部引入相应的全局文件,从而避免在每个文件中都写 @import "@/styles/mixins.less" 语句
export default defineConfig({
  css: {
    preprocessorOptions: {
      less: {
        additionalData:
          '@import "@/styles/variables";\n@import "@/styles/mixins";\n',
      },
    },
  },
});
# 自适应布局?
- 自适应方案场景选择 (opens new window)
 - 自适应rem计算公式。
font-size:calc(100vw/设计图总宽度),这样可以用rem替代设计图中的px 
# border圆角渐变如何实现?
参考:https://www.cnblogs.com/imgss/p/11237170.html
# 如何实现虚线渐变?
参考:https://www.zhangxinxu.com/wordpress/2018/08/css-gradient-dashed-border/
.collapse__line {
  border-top: 1px dashed #e2e2e2;
  transform: scaleY(0.5);
  box-sizing: border-box;
}
@supports (-webkit-mask: none) or (mask: none) {
  .collapse__line {
    height: 1px;
    border: none;
    background: linear-gradient(
        90deg,
        rgb(226 226 226 / 0%) 0%,
        #e2e2e2 50%,
        rgb(226 226 226 / 0%) 100%
      )
      no-repeat;
    mask: linear-gradient(to right, #000 6px, transparent 6px) repeat-x,
      linear-gradient(to bottom, #000 6px, transparent 6px) repeat-y,
      linear-gradient(to right, #000 6px, transparent 6px) repeat-x 0 100%,
      linear-gradient(to bottom, #000 6px, transparent 6px) repeat-y 100% 0;
    mask-size: 8px 2px, 2px 8px, 8px 2px, 2px 8px;
  }
}
# margin:0 auto失效?
居中block元素没有设置宽度
# 如何在元素滚动结束时规定元素item的位置和对齐方式?
scroll-snap-type: x mandatory;
# 最佳实践
# content-visibility
值为auto时,网页只渲染可见区域内容,跳过不可见区域的元素。
# border
- 当动态 border(比如 hover 时显示 border)破坏布局,可以提前设置一个透明的 border,或者使用 outline,outline 不会影响布局,但是 outline 不能拆分成 top、bottom、left、right。
 
# color
- css 颜色值要使用小写 
 
# url
书写 css 时去除 url 引用资源的引号,这是没有必要的,影响阅读. 
# transform
- 在移动端开发中,直接使用 transition 动画会让页面变慢,甚至变卡顿,所以我们通常添加 transform:translate3D(0,0,0)或 transform:translateZ(0)来开启移动端动画的 gpu 加速,让动画过程更流畅。 
 - 在拖拽这种高性能需求场景,应该用 transform 替换
left top来实现元素的移动 
# /deep/
不要使用/deep/选择器,将要不被支持
# 字体
字体文件使用woff2格式的,体积小。为了进一步压缩字体大小,还可以使用fontmin来提取需要的文字。
-webkit-font-smoothing:抗锯齿渲染
# 间距
本人认为只有在元素存在时,间距才应生效,视情况优先使用margin-top、margin-left等遵循文档流方向的方案,能使用padding则优先使用padding,因为margin有可能在垂直方向上产生bfc
# img
设置最大宽度max-width:100%;
# 滚动元素
设置滚动结束时,元素的位置:
.carousel {
  scroll-snap-type: x mandatory;
}
.carousel .item {
   scroll-snap-align: start;
}
# 兼容 IE
# css hack
CSS hack 是通过在 CSS 样式中加入一些特殊的符号,让不同的浏览器识别不同的符号(什么样的浏览器识别什么样的符号是有标准的,CSS hack 就是让你记住这个标准),以达到应用不同的 CSS 样式的目的。
# IE8
由于 ie8 不支持 transform,所以有人特意写了个网站来自动转换成 IE 语法. CSS3 2D transforms (opens new window)
对于 IE8 及以下浏览器可以使用 PIE.htc 来使用一些 CSS3 的特性,PIE 下载地址 (opens new window)
border-radius
box-shadow
border-image
multiple background images
linear-gradient as background image
- 支持背景图片自适应:
 
  filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='./dist/image/background.png', sizingMethod='scale')