每天10个前端小知识 【Day 16】

在这里插入图片描述

👩 个人主页:不爱吃糖的程序媛
🙋‍♂️ 作者简介:前端领域新星创作者、CSDN内容合伙人,专注于前端各领域技术,成长的路上共同学习共同进步,一起加油呀!
✨系列专栏:前端面试宝典JavaScript进阶vue实战
📢 资料领取:前端进阶资料以及文中源码可以在🎈公众号【不爱吃糖的程序媛】领取

前端面试基础知识题

1.为什么有时候⽤translate来改变位置⽽不是使用position进行定位?

translate 是 transform 属性的⼀个值。

改变transform或opacity不会触发浏览器重新布局(reflow)或重绘(repaint),只会触发复合(compositions)。

⽽改变绝对定位会触发重新布局,进⽽触发重绘和复合。

transform使浏览器为元素创建⼀个 GPU 图层,但改变绝对定位会使⽤到 CPU。

因此translate()更⾼效,可以缩短平滑动画的绘制时间。

⽽translate改变位置时,元素依然会占据其原始空间,绝对定位就不会发⽣这种情况。

2.什么是硬件加速?

硬件加速就是将浏览器的渲染过程交给GPU处理,而不是使用自带的比较慢的渲染器。这样就可以使得 animation 与 transition 更加顺畅。

我们可以在浏览器中用css开启硬件加速,使GPU (Graphics Processing Unit) 发挥功能,从而提升性能。

现在大多数电脑的显卡都支持硬件加速。鉴于此,我们可以发挥GPU的力量,从而使我们的网站或应用表现的更为流畅。

3.怎么使用 CSS3 实现动画?

CSS动画(CSS Animations)是为层叠样式表建议的允许可扩展标记语言(XML)元素使用CSS的动画的模块,即指元素从一种样式逐渐过渡为另一种样式的过程。

常见的动画效果有很多,如平移、旋转、缩放等等,复杂动画则是多个简单动画的组合。

css实现动画的方式,有如下几种:

  • transition 实现渐变动画
  • transform 转变动画
  • animation 实现自定义动画

实现方式

transition 实现渐变动画

transition的属性如下:

  • property:填写需要变化的css属性
  • duration:完成过渡效果需要的时间单位(s或者ms)
  • timing-function:完成效果的速度曲线
  • delay: 动画效果的延迟触发时间

其中timing-function的值有如下:

在这里插入图片描述
注意:并不是所有的属性都能使用过渡的,如display:none<->display:block
举个例子,实现鼠标移动上去发生变化动画效果

<style>
       .base {
            width: 100px;
            height: 100px;
            display: inline-block;
            background-color: #0EA9FF;
            border-width: 5px;
            border-style: solid;
            border-color: #5daf34;
            transition-property: width, height, background-color, border-width;
            transition-duration: 2s;
            transition-timing-function: ease-in;
            transition-delay: 500ms;
        }

        /*简写*/
        /*transition: all 2s ease-in 500ms;*/
        .base:hover {
            width: 200px;
            height: 200px;
            background-color: #5daf34;
            border-width: 10px;
            border-color: #3a8ee6;
        }
</style>
<div class="base"></div>
transform 转变动画

包含四个常用的功能:

  • translate:位移
  • scale:缩放
  • rotate:旋转
  • skew:倾斜

一般配合transition过度使用。

注意的是,transform不支持inline元素,使用前把它变成block。

举个例子

<style>
    .base {
        width: 100px;
        height: 100px;
        display: inline-block;
        background-color: #0EA9FF;
        border-width: 5px;
        border-style: solid;
        border-color: #5daf34;
        transition-property: width, height, background-color, border-width;
        transition-duration: 2s;
        transition-timing-function: ease-in;
        transition-delay: 500ms;
    }
    .base2 {
        transform: none;
        transition-property: transform;
        transition-delay: 5ms;
    }

    .base2:hover {
        transform: scale(0.8, 1.5) rotate(35deg) skew(5deg) translate(15px, 25px);
    }
</style>
 <div class="base base2"></div>

可以看到盒子发生了旋转,倾斜,平移,放大。

animation 实现自定义动画

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;

总结

在这里插入图片描述

4.怎么让Chrome支持小于12px 的文字?

背景
Chrome 中文版浏览器会默认设定页面的最小字号是12px,英文版没有限制;原由 Chrome 团队认为汉字小于12px就会增加识别难度。

中文版浏览器

与网页语言无关,取决于用户在Chrome的设置里(chrome://settings/languages)把哪种语言设置为默认显示语言。

系统级最小字号

浏览器默认设定页面的最小字号,用户可以前往 chrome://settings/fonts 根据需求更改。

而我们在实际项目中,不能奢求用户更改浏览器设置。

对于文本需要以更小的字号来显示,就需要用到一些小技巧。

解决方案

常见的解决方案有:

  • zoom
  • -webkit-transform:scale()
  • -webkit-text-size-adjust:none
Zoom

zoom 的字面意思是“变焦”,可以改变页面上元素的尺寸,属于真实尺寸。

其支持的值类型有:

  • zoom:50%,表示缩小到原来的一半
  • zoom:0.5,表示缩小到原来的一半

使用 zoom 来”支持“ 12px 以下的字体
代码如下:

<style type="text/css">
    .span1{
        font-size: 12px;
        display: inline-block;
        zoom: 0.8;
    }
    .span2{
        display: inline-block;
        font-size: 12px;
    }
</style>
<body>
    <span class="span1">测试10px</span>
    <span class="span2">测试12px</span>
</body>

效果如下:
在这里插入图片描述

需要注意的是,Zoom 并不是标准属性,需要考虑其兼容性。

-webkit-transform:scale()

针对chrome浏览器,加webkit前缀,用transform:scale()这个属性进行放缩。

注意的是,使用scale属性只对可以定义宽高的元素生效,所以,下面代码中将span元素转为行内块元素
实现代码如下:

<style type="text/css">
    .span1{
        font-size: 12px;
        display: inline-block;
        -webkit-transform:scale(0.8);
    }
    .span2{
        display: inline-block;
        font-size: 12px;
    }
</style>
<body>
    <span class="span1">测试10px</span>
    <span class="span2">测试12px</span>
</body>

效果如下:
在这里插入图片描述

-webkit-text-size-adjust:none

该属性用来设定文字大小是否根据设备(浏览器)来自动调整显示大小。

属性值:

percentage:字体显示的大小;
auto:默认,字体大小会根据设备/浏览器来自动调整;
none:字体大小不会自动调整

html { -webkit-text-size-adjust: none; }

这样设置之后会有一个问题,就是当你放大网页时,一般情况下字体也会随着变大,而设置了以上代码后,字体只会显示你当前设置的字体大小,不会随着网页放大而变大了。

所以,我们不建议全局应用该属性,而是单独对某一属性使用。

需要注意的是,自从chrome 27之后,就取消了对这个属性的支持。同时,该属性只对英文、数字生效,对中文不生效。

总结

  • Zoom 非标属性,有兼容问题,缩放会改变了元素占据的空间大小,触发重排。
  • -webkit-transform:scale() 大部分现代浏览器支持,并且对英文、数字、中文也能够生效,缩放不会改变了元素占据的空间大小,页面布局不会发生变化。
  • -webkit-text-size-adjust对谷歌浏览器有版本要求,在27之后,就取消了该属性的支持,并且只对英文、数字生效。

5.css选择器有哪些?优先级分别是什么?哪些属性可以继承?

关于css属性选择器常用的有:

  • id选择器(#box),选择id为box的元素
  • 类选择器(.one),选择类名为one的所有元素
  • 标签选择器(div),选择标签为div的所有元素
  • 后代选择器(#box div),选择id为box元素内部所有的div元素
  • 子选择器(.one>one_1),选择父元素为.one的所有.one_1的元素
  • 相邻同胞选择器(.one+.two),选择紧接在.one之后的所有.two元素
  • 群组选择器(div,p),选择div、p的所有元素

还有一些使用频率相对没那么多的选择器:

  • 伪类选择器
: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开头的元素

在CSS3中新增的选择器有如下:

  • 层次选择器(p~ul),选择前面有p元素的每个ul元素
  • 伪类选择器
: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) 选择非 <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标签字体的大下也是不能被继承的

无继承的属性

  • display
  • 文本属性:vertical-align、text-decoration
  • 盒子模型的属性:宽度、高度、内外边距、边框等
  • 背景属性:背景图片、颜色、位置等
  • 定位属性:浮动、清除浮动、定位position等
  • 生成内容属性:content、counter-reset、counter-increment
  • 轮廓样式属性:outline-style、outline-width、outline-color、outline
  • 页面样式属性:size、page-break-before、page-break-after

6.怎么实现一个宽高自适应的正方形?

  • 利用vw来实现:
.square {
  width: 10%;
  height: 10vw;
  background: tomato;
}
  • 利用元素的margin/padding百分比是相对父元素width的性质来实现:
.square {
  width: 20%;
  height: 0;
  padding-top: 20%;
  background: orange;
}
  • 利用子元素的margin-top的值来实现:
.square {
  width: 30%;
  overflow: hidden;
  background: yellow;
}
.square::after {
  content: '';
  display: block;
  margin-top: 100%;
}

7.CSS预处理器/后处理器是什么?为什么要使用它们?

预处理器, 如: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。

使用原因:

  • 结构清晰, 便于扩展
  • 可以很方便的屏蔽浏览器私有语法的差异
  • 可以轻松实现多重继承
  • 完美的兼容了CSS代码,可以应用到老项目中

8.硬件加速的原理是什么?

面试中可能会经常会碰到怎么解决动画卡顿的问题,然后会引导到硬件加速。那么究竟什么是硬件加速,为什么它可以提高咱们的动画效率?我们今天就来一探究竟。
首先,我们先从 CPU 和 GPU 开始了解。

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 内完成,超出这个时间,页面的渲染就会出现卡顿现象,影响用户体验。
简单概括下,浏览器在每一帧里会依次执行以下这些动作:

  • JavaScript:JavaScript 实现动画效果,DOM 元素操作等。
  • Style(计算样式):确定每个 DOM 元素应该应用什么 CSS 规则。
  • Layout(布局):计算每个 DOM 元素在最终屏幕上显示的大小和位置。由于 web 页面的元素布局是相对的,所以其中任意一个元素的位置发生变化,都会联动的引起其他元素发生变化,这个过程叫 reflow。
  • Paint(绘制):在多个层上绘制 DOM 元素的的文字、颜色、图像、边框和阴影等。
    VComposite(渲染层合并):按照合理的顺序合并图层然后显示到屏幕上。

减少或者避免 layout,paint 可以让页面减少卡顿,动画效果更加流畅。

完整的渲染流程

更具体一些,一个完整的渲染步骤大致可总结为如下:

  • 渲染进程将HTML内容转换为能够读懂的DOM树结构。
  • 渲染引擎将CSS样式表转化为浏览器可以理解的 styleSheets ,计算出DOM节点的样式。
  • 创建布局树,并计算元素的布局信息。
  • 对布局树进行分层,并生成分层树。
  • 为每个图层生成绘制列表,并将其提交到合成线程。
  • 合成线程将图层分成图块,并在光栅化线程池中将图块转换成位图。
  • 合成线程发送绘制图块命令DrawQuad给浏览器进程。
  • 浏览器进程根据DrawQuad消息生成页面,并显示到显示器上

普通图层和复合图层

上面的介绍中,提到了 composite 概念。
可以简单的这样理解,浏览器渲染的图层一般包含两大类:渲染图层(普通图层)以及复合图层

  • 渲染图层:又称默认复合层,是页面普通的文档流。我们虽然可以通过绝对定位,相对定位,浮动定位脱离文档流,但它仍然属于默认复合层,共用同一个绘图上下文对象(GraphicsContext)。
  • 复合图层,它会单独分配资源(当然也会脱离普通文档流,这样一来,不管这个复合图层中怎么变化,也不会影响默认复合层里的回流重绘)

某些特殊的渲染层会被提升为复合成层(Compositing Layers),复合图层拥有单独的 GraphicsLayer,而其他不是复合图层的渲染层,则和其第一个拥有 GraphicsLayer 父层共用一个。

每个 GraphicsLayer 都有一个 GraphicsContext,GraphicsContext 会负责输出该层的位图,位图是存储在共享内存中,作为纹理上传到 GPU 中,最后由 GPU 将多个位图进行合成,然后 draw 到屏幕上,此时,我们的页面也就展现到了屏幕上。
可以 Chrome源码调试 -> More Tools -> Rendering -> Layer borders中看到,黄色的就是复合图层信息。

硬件加速

硬件加速,直观上说就是依赖 GPU 实现图形绘制加速,软硬件加速的区别主要是图形的绘制究竟是 GPU 来处理还是 CPU,如果是 GPU,就认为是硬件加速绘制,反之,则为软件绘制。
一般一个元素开启硬件加速后会变成复合图层,可以独立于普通文档流中,改动后可以避免整个页面重绘,提升性能。

常用的硬件加速方法有:

  • 最常用的方式:translate3d、translateZ
  • opacity 属性/过渡动画(需要动画执行的过程中才会创建合成层,动画没有开始或结束后元素还会回到之前的状态)
  • will-change属性(这个知识点比较冷僻),一般配合 opacity 与 translate 使用(而且经测试,除了上述可以引发硬件加速的属性外,其它属性并不会变成复合层),作用是提前告诉浏览器要变化,这样浏览器会开始做一些优化工作(这个最好用完后就释放)
  • <video>、<iframe>、<canvas>、<webgl> 等元素
  • 其它,譬如以前的 flash 插件

当然,有的时候我们想强制触发硬件渲染,就可以通过上面的属性,比如

will-change: transform; 

或者

transform:translate3d(0, 0, 0);

使用硬件加速的注意事项

使用硬件加速并不是十全十美的事情,比如:

  • 内存。如果GPU加载了大量的纹理,那么很容易就会发生内容问题,这一点在移动端浏览器上尤为明显,所以,一定要牢记不要让页面的每个元素都使用硬件加速。
  • 使用GPU渲染会影响字体的抗锯齿效果。这是因为GPU和CPU具有不同的渲染机制。即使最终硬件加速停止了,文本还是会在动画期间显示得很模糊。

所以不要大量使用复合图层,否则由于资源消耗过度,页面可能会变的更加卡顿。
同时,在使用硬件加速时,尽可能的使用z-index,防止浏览器默认给后续的元素创建复合层渲染。

具体的原理是这样的:

webkit
CSS3中,如果一个元素添加了硬件加速,并且z-index层级比较低,那么在这个元素的后面其它元素(层级比这个元素高的,或者相同的,并且releative或absolute属性相同的),会默认变为复合层渲染,如果处理不当会极大的影响性能。

简单点理解,其实可以认为是一个隐式合成的概念:如果a是一个复合图层,而且b在a上面,那么b也会被隐式转为一个复合图层,这点需要特别注意。

9.CSS动画和JS实现的动画分别有哪些优缺点?

CSS动画

优点
  • 浏览器可以对动画进行优化;
  • 代码相对简单,性能调优方向固定;
  • 对于帧速表现不好的低版本浏览器,CSS3可以做到自然降级,而JS则需要撰写额外代码;
缺点
  • 运行过程控制较弱,无法附加事件绑定回调函数;
  • 代码冗长,想用CSS实现稍微复杂一点动画,最后CSS代码都会变得非常笨重;

JS动画

优点
  • 控制能力很强, 可以在动画播放过程中对动画进行控制:开始、暂停、回放、终止、取消都是可以做到的;
  • 动画效果比css3动画丰富,有些动画效果,比如曲线运动,冲击闪烁,视差滚动效果,只有js动画才能完成
    CSS3有兼容性问题,而JS大多时候没有兼容性问题;
缺点
  • 代码的复杂度高于CSS动画
  • JavaScript在浏览器的主线程中运行,而主线程中还有其它需要运行的JavaScript脚本、样式计算、布局、绘制任务等,对其干扰导致线程可能出现阻塞,从而造成丢帧的情况

10.前端实现动画有哪些方式?

前端常用的动画实现方式有以下几种:

  • css3的transition 属性
  • css3的animation 属性
  • 原生JS动画
  • 使用canvas绘制动画
  • SVG动画
  • Jquery的animate函数
  • 使用gif图片
  • 9
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序媛夏天

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值