个人主页:不爱吃糖的程序媛
♂️ 作者简介:前端领域新星创作者、CSDN内容合伙人,专注于前端各领域技术,成长的路上共同学习共同进步,一起加油呀!
✨系列专栏:前端面试宝典、JavaScript进阶、vue实战
资料领取:前端进阶资料以及文中源码可以在公众号【不爱吃糖的程序媛】领取
translate 是 transform 属性的⼀个值。
改变transform或opacity不会触发浏览器重新布局(reflow)或重绘(repaint),只会触发复合(compositions)。
⽽改变绝对定位会触发重新布局,进⽽触发重绘和复合。
transform使浏览器为元素创建⼀个 GPU 图层,但改变绝对定位会使⽤到 CPU。
因此translate()更⾼效,可以缩短平滑动画的绘制时间。
⽽translate改变位置时,元素依然会占据其原始空间,绝对定位就不会发⽣这种情况。
硬件加速就是将浏览器的渲染过程交给GPU处理,而不是使用自带的比较慢的渲染器。这样就可以使得 animation 与 transition 更加顺畅。
我们可以在浏览器中用css开启硬件加速,使GPU (Graphics Processing Unit) 发挥功能,从而提升性能。
现在大多数电脑的显卡都支持硬件加速。鉴于此,我们可以发挥GPU的力量,从而使我们的网站或应用表现的更为流畅。
CSS动画(CSS Animations)是为层叠样式表建议的允许可扩展标记语言(XML)元素使用CSS的动画的模块,即指元素从一种样式逐渐过渡为另一种样式的过程。
常见的动画效果有很多,如平移、旋转、缩放等等,复杂动画则是多个简单动画的组合。
css实现动画的方式,有如下几种:
transition的属性如下:
其中timing-function的值有如下:
注意:并不是所有的属性都能使用过渡的,如display:none<->display:block
举个例子,实现鼠标移动上去发生变化动画效果
"base">
包含四个常用的功能:
一般配合transition过度使用。
注意的是,transform不支持inline元素,使用前把它变成block。
举个例子
"base base2">
可以看到盒子发生了旋转,倾斜,平移,放大。
animation是由 8 个属性的简写,分别如下:
CSS 动画只需要定义一些关键的帧,而其余的帧,浏览器会根据计时函数插值计算出来,
通过 @keyframes 来定义关键帧
因此,如果我们想要让元素旋转一圈,只需要定义开始和结束两帧即可:
@keyframes rotate{
from{
transform: rotate(0deg);
}
to{
transform: rotate(360deg);
}
}
from 表示最开始的那一帧,to 表示结束时的那一帧。
也可以使用百分比刻画生命周期
@keyframes rotate{
0%{
transform: rotate(0deg);
}
50%{
transform: rotate(180deg);
}
100%{
transform: rotate(360deg);
}
}
定义好了关键帧后,下来就可以直接用它了:
animation: rotate 2s;
背景
Chrome 中文版浏览器会默认设定页面的最小字号是12px,英文版没有限制;原由 Chrome 团队认为汉字小于12px就会增加识别难度。
中文版浏览器
与网页语言无关,取决于用户在Chrome的设置里(chrome://settings/languages)把哪种语言设置为默认显示语言。
系统级最小字号
浏览器默认设定页面的最小字号,用户可以前往 chrome://settings/fonts 根据需求更改。
而我们在实际项目中,不能奢求用户更改浏览器设置。
对于文本需要以更小的字号来显示,就需要用到一些小技巧。
常见的解决方案有:
zoom 的字面意思是“变焦”,可以改变页面上元素的尺寸,属于真实尺寸。
其支持的值类型有:
使用 zoom 来”支持“ 12px 以下的字体
代码如下:
"span1">测试10px
"span2">测试12px
需要注意的是,Zoom 并不是标准属性,需要考虑其兼容性。
针对chrome浏览器,加webkit前缀,用transform:scale()这个属性进行放缩。
注意的是,使用scale属性只对可以定义宽高的元素生效,所以,下面代码中将span元素转为行内块元素
实现代码如下:
"span1">测试10px
"span2">测试12px
该属性用来设定文字大小是否根据设备(浏览器)来自动调整显示大小。
percentage:字体显示的大小;
auto:默认,字体大小会根据设备/浏览器来自动调整;
none:字体大小不会自动调整
html { -webkit-text-size-adjust: none; }
这样设置之后会有一个问题,就是当你放大网页时,一般情况下字体也会随着变大,而设置了以上代码后,字体只会显示你当前设置的字体大小,不会随着网页放大而变大了。
所以,我们不建议全局应用该属性,而是单独对某一属性使用。
需要注意的是,自从chrome 27之后,就取消了对这个属性的支持。同时,该属性只对英文、数字生效,对中文不生效。
还有一些使用频率相对没那么多的选择器:
:link :选择未被访问的链接
:visited:选取已被访问的链接
:active:选择活动链接
:hover :鼠标指针浮动在上面的元素
:focus :选择具有焦点的
:first-child:父元素的首个子元素
:first-letter :用于选取指定选择器的首字母
:first-line :选取指定选择器的首行
:before : 选择器在被选元素的内容前面插入内容
:after : 选择器在被选元素的内容后面插入内容
[attribute] 选择带有attribute属性的元素
[attribute=value] 选择所有使用attribute=value的元素
[attribute~=value] 选择attribute属性包含value的元素
[attribute|=value]:选择attribute属性以value开头的元素
:first-of-type 父元素的首个元素
:last-of-type 父元素的最后一个元素
:only-of-type 父元素的特定类型的唯一子元素
:only-child 父元素中唯一子元素
:nth-child(n) 选择父元素中第N个子元素
:nth-last-of-type(n) 选择父元素中第N个子元素,从后往前
:last-child 父元素的最后一个元素
:root 设置HTML文档
:empty 指定空的元素
:enabled 选择被禁用元素
:disabled 选择被禁用元素
:checked 选择选中的元素
:not(selector) 选择非 元素的所有元素
[attribute*=value]:选择attribute属性值包含value的所有元素
[attribute^=value]:选择attribute属性开头为value的所有元素
[attribute$=value]:选择attribute属性结尾为value的所有元素
内联 > ID选择器 > 类选择器 > 标签选择器
内联样式的优先级最高,如果外部样式需要覆盖内联样式,就需要使用!important。
在css中,继承是指的是给父元素设置一些属性,后代元素会自动拥有这些属性 关于继承属性,可以分成:
字体系列属性
font:组合字体
font-family:规定元素的字体系列
font-weight:设置字体的粗细
font-size:设置字体的尺寸
font-style:定义字体的风格
font-variant:偏大或偏小的字体
文本系列属性
text-indent:文本缩进
text-align:文本水平对齐
line-height:行高
word-spacing:增加或减少单词间的空白
letter-spacing:增加或减少字符间的空白
text-transform:控制文本大小写
direction:规定文本的书写方向
color:文本颜色
元素可见性
visibility
表格布局属性
caption-side:定位表格标题位置
border-collapse:合并表格边框
border-spacing:设置相邻单元格的边框间的距离
empty-cells:单元格的边框的出现与消失
table-layout:表格的宽度由什么决定
列表属性
list-style-type:文字前面的小点点样式
list-style-position:小点点位置
list-style:以上的属性可通过这属性集合
引用
quotes:设置嵌套引用的引号类型
光标属性
cursor:箭头可以变成需要的形状
继承中比较特殊的几点:
a 标签的字体颜色不能被继承
h1-h6标签字体的大下也是不能被继承的
.square {
width: 10%;
height: 10vw;
background: tomato;
}
.square {
width: 20%;
height: 0;
padding-top: 20%;
background: orange;
}
.square {
width: 30%;
overflow: hidden;
background: yellow;
}
.square::after {
content: '';
display: block;
margin-top: 100%;
}
预处理器, 如:less,sass,stylus,用来预编译sass或者less,增加了css代码的复用性。层级,mixin, 变量,循环, 函数等对编写以及开发UI组件都极为方便。
后处理器, 如: postCss,通常是在完成的样式表中根据css规范处理css,让其更加有效。目前最常做的是给css属性添加浏览器私有前缀,实现跨浏览器兼容性的问题。
css预处理器为css增加一些编程特性,无需考虑浏览器的兼容问题,可以在CSS中使用变量,简单的逻辑程序,函数等在编程语言中的一些基本的性能,可以让css更加的简洁,增加适应性以及可读性,可维护性等。
其它css预处理器语言:Sass(Scss), Less, Stylus, Turbine, Swithch css, CSS Cacheer, DT Css。
面试中可能会经常会碰到怎么解决动画卡顿的问题,然后会引导到硬件加速。那么究竟什么是硬件加速,为什么它可以提高咱们的动画效率?我们今天就来一探究竟。
首先,我们先从 CPU 和 GPU 开始了解。
CPU 即中央处理器,GPU 即图形处理器。
CPU是计算机的大脑,它提供了一套指令集,我们写的程序最终会通过 CPU 指令来控制的计算机的运行。它会对指令进行译码,然后通过逻辑电路执行该指令。整个执行的流程分为了多个阶段,叫做流水线。指令流水线包括取指令、译码、执行、取数、写回五步,这是一个指令周期。CPU会不断的执行指令周期来完成各种任务。
GPU,是Graphics ProcessingUnit的简写,是现代显卡中非常重要的一个部分,其地位与CPU在主板上的地位一致,主要负责的任务是加速图形处理速度。GPU是显卡的“大脑”,它决定了该显卡的档次和大部分性能,同时也是2D显示卡和3D显示卡的区别依据。2D显示芯片在处理3D图像和特效时主要依赖CPU的处理能力,称为“软加速”。3D显示芯片是将三维图像和特效处理功能集中在显示芯片内,也即所谓的“硬件加速”功能。
要解释两者的区别,要先明白两者的相同之处:两者都有总线和外界联系,有自己的缓存体系,以及数字和逻辑运算单元。
一句话,两者都为了完成计算任务而设计。
两者的区别在于存在于片内的缓存体系和数字逻辑运算单元的结构差异:
CPU虽然有多核,但总数没有超过两位数,每个核都有足够大的缓存和足够多的数字和逻辑运算单元,并辅助有很多加速分支判断甚至更复杂的逻辑判断的硬件;
GPU 的核数远超CPU,被称为众核(NVIDIA Fermi有512个核)。每个核拥有的缓存大小相对小,数字逻辑运算单元也少而简单(GPU初始时在浮点计算上一直弱于CPU)。
从结果上导致CPU擅长处理具有复杂计算步骤和复杂数据依赖的计算任务,如分布式计算,数据压缩,人工智能,物理模拟,以及其他很多很多计算任务等。
GPU由于历史原因,是为了视频游戏而产生的(至今其主要驱动力还是不断增长的视频游戏市场),在三维游戏中常常出现的一类操作是对海量数据进行相同的操作,如:对每一个顶点进行同样的坐标变换,对每一个顶点按照同样的光照模型计算颜色值。
GPU的众核架构非常适合把同样的指令流并行发送到众核上,采用不同的输入数据执行。在通用计算领域有广泛应用,包括:数值分析,海量数据处理(排序,Map-Reduce等),金融分析等等。
简而言之,当程序员为CPU编写程序时,他们倾向于利用复杂的逻辑结构优化算法从而减少计算任务的运行时间,即 Latency。当程序员为GPU编写程序时,则利用其处理海量数据的优势,通过提高总的数据吞吐量(Throughput)来掩盖 Lantency。
目前,CPU 和 GPU 的区别正在逐渐缩小,因为GPU也在处理不规则任务和线程间通信方面有了长足的进步。
一般浏览器的刷新率为60HZ,即1秒钟刷新60次。
1000ms / 60hz = 16.6 ,也就是大概每过 16.6ms 浏览器就会渲染一帧画面。
浏览器对每一帧画面的渲染工作都要在 16ms 内完成,超出这个时间,页面的渲染就会出现卡顿现象,影响用户体验。
简单概括下,浏览器在每一帧里会依次执行以下这些动作:
减少或者避免 layout,paint 可以让页面减少卡顿,动画效果更加流畅。
更具体一些,一个完整的渲染步骤大致可总结为如下:
上面的介绍中,提到了 composite 概念。
可以简单的这样理解,浏览器渲染的图层一般包含两大类:渲染图层(普通图层)以及复合图层
某些特殊的渲染层会被提升为复合成层(Compositing Layers),复合图层拥有单独的 GraphicsLayer,而其他不是复合图层的渲染层,则和其第一个拥有 GraphicsLayer 父层共用一个。
每个 GraphicsLayer 都有一个 GraphicsContext,GraphicsContext 会负责输出该层的位图,位图是存储在共享内存中,作为纹理上传到 GPU 中,最后由 GPU 将多个位图进行合成,然后 draw 到屏幕上,此时,我们的页面也就展现到了屏幕上。
可以 Chrome源码调试 -> More Tools -> Rendering -> Layer borders中看到,黄色的就是复合图层信息。
硬件加速,直观上说就是依赖 GPU 实现图形绘制加速,软硬件加速的区别主要是图形的绘制究竟是 GPU 来处理还是 CPU,如果是 GPU,就认为是硬件加速绘制,反之,则为软件绘制。
一般一个元素开启硬件加速后会变成复合图层,可以独立于普通文档流中,改动后可以避免整个页面重绘,提升性能。
等元素当然,有的时候我们想强制触发硬件渲染,就可以通过上面的属性,比如
will-change: transform;
或者
transform:translate3d(0, 0, 0);
使用硬件加速并不是十全十美的事情,比如:
所以不要大量使用复合图层,否则由于资源消耗过度,页面可能会变的更加卡顿。
同时,在使用硬件加速时,尽可能的使用z-index,防止浏览器默认给后续的元素创建复合层渲染。
具体的原理是这样的:
webkit
CSS3中,如果一个元素添加了硬件加速,并且z-index层级比较低,那么在这个元素的后面其它元素(层级比这个元素高的,或者相同的,并且releative或absolute属性相同的),会默认变为复合层渲染,如果处理不当会极大的影响性能。
简单点理解,其实可以认为是一个隐式合成的概念:如果a是一个复合图层,而且b在a上面,那么b也会被隐式转为一个复合图层,这点需要特别注意。
前端常用的动画实现方式有以下几种: