跳到主要内容

应用-常见问题

  • link 属于 XHTML 标签,而@import 是 CSS 提供的。
  • 页面被加载时,link 会同时被加载,而@import 引用的 CSS 会等到页面被加载完再加载。
  • import 只在 IE 5 以上才能识别,而 link 是 XHTML 标签,无兼容问题。
  • link 方式的样式权重高于@import 的权重。
  • 使用 dom 控制样式时的差别。当使用 javascript 控制 dom 去改变样式的时候,只能使用 link 标签,因为@import 不是 dom 可以控制的。

CSS 硬件加速

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

开启硬件加速只要使用特定的 css 语句就可以了:

/**使用3d效果来开启硬件加速**/
.speed-up {
-webkit-transform: translate3d(250px, 250px, 250px) rotate3d(250px, 250px, 250px, -120deg) scale3d(0.5, 0.5, 0.5);
}

如果不需要用到 transform 变换, 仅仅是开启硬件加速, 则可以这样写:

/**原理上还是使用3d效果来开启硬件加速**/
.speed-up {
-webkit-transform: translateZ(0);
-moz-transform: translateZ(0);
-ms-transform: translateZ(0);
-o-transform: translateZ(0);
transform: translateZ(0);
}

对于 safari 和 chrome, 可能在使用 animation 或者 transition 时出现闪烁的问题, 可以使用这个方法来解决:

.speed-up {
-webkit-backface-visibility: hidden;
-moz-backface-visibility: hidden;
-ms-backface-visibility: hidden;
backface-visibility: hidden;

-webkit-perspective: 1000;
-moz-perspective: 1000;
-ms-perspective: 1000;
perspective: 1000;

/**webkit上也可以用以下语句 **/
-webkit-transform: translate3d(0, 0, 0);
-moz-transform: translate3d(0, 0, 0);
-ms-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}

注意: 硬件加速最好只用在 animation 或者 transform 上。不要滥用硬件加速,因为这样会增加性能的消耗,如果滥用反而会使动画变得更加卡,这样就得不偿失了。

移动端的 1px 问题

移动端设备存在一个参数: DPR(devicePixelRatio), 设备像素比, 它是默认缩放为100%的情况下, 设备像素和CSS像素的比值.

window.devicePixelRatio = `物理像素 /CSS像素`

目前主流的屏幕DRP为2(Iphone 8), 或者3(iphone 8 plus).

解决方案

1. WWDC对IOS给出的方案: 缩小数值

border:0.5px solid #E5E5E5
  • 优点: 简单, 没有副作用
  • 缺点: 支持IOS8+

2. 使用边框图片

border: 1px solid transparent;
border-image: url('./../../image/96.jpg') 2 repeat;
  • 优点:没有副作用
  • 缺点: 不够灵活, 性能不好

3. 使用 box-shadow

box-shadow: 0  -1px 1px -1px #e5e5e5,   //上边线
1px 0 1px -1px #e5e5e5, //右边线
0 1px 1px -1px #e5e5e5, //下边线
-1px 0 1px -1px #e5e5e5; //左边线

4. 使用伪元素

  1. 一条border
.setOnePx{
position: relative;
&::after{
position: absolute;
content: '';
background-color: #e5e5e5;
display: block;
width: 100%;
height: 1px; /*no*/
transform: scale(1, 0.5);
top: 0;
left: 0;
}
}
  1. 四条border:
.setBorderAll{
position: relative;
&:after{
content:" ";
position:absolute;
top: 0;
left: 0;
width: 200%;
height: 200%;
transform: scale(0.5);
transform-origin: left top;
box-sizing: border-box;
border: 1px solid #E5E5E5;
border-radius: 4px;
}
}
  • 优点: 兼容性好
  • 缺点: 需要考虑样式的影响

5. 设置viewport的scale

<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<meta name="viewport" id="WebViewport" content="initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
<script>
var viewport = document.querySelector("meta[name=viewport]");
//下面是根据设备像素设置viewport
if (window.devicePixelRatio == 1) {
viewport.setAttribute('content', 'width=device-width,initial-scale=1,maximum-scale=1, minimum-scale=1, user-scalable=no');
}
if (window.devicePixelRatio == 2) {
viewport.setAttribute('content', 'width=device-width,initial-scale=0.5,maximum-scale=0.5, minimum-scale=0.5, user-scalable=no');
}
if (window.devicePixelRatio == 3) {
viewport.setAttribute('content', 'width=device-width,initial-scale=03333333333333333, maximum-scale=0.3333333333333333, minimum-scale=03333333333333333, user-scalable=no');
}
var docEl = document.documentElement;
var fontsize = 32* (docEl.clientWidth / 750) + 'px';
docEl.style.fontSize = fontsize;
</script>
  • 优点: 方便, 直接写1px即可
  • 缺点: 不适用老的项目, 影响的范围比较大

CSS 性能优化的方法有哪些?

  1. 合并css文件,如果页面加载10个css文件,每个文件1k,那么也要比只加载一个100k的css文件慢。
  2. 减少css嵌套,最好不要嵌套三层以上。
  3. 不要在ID选择器前面进行嵌套,ID本来就是唯一的而且权限值大,嵌套完全是浪费性能。
  4. 建立公共样式类,把相同样式提取出来作为公共类使用。
  5. 减少通配符*或者类似[hidden="true"]这类选择器的使用,挨个查找所有...这性能能好吗?
  6. 巧妙运用css的继承机制,如果父节点定义了,子节点就无需定义。
  7. 拆分出公共css文件,对于比较大的项目可以将大部分页面的公共结构样式提取出来放到单独css文件里,这样一次下载 后就放到缓存里,当然这种做法会增加请求,具体做法应以实际情况而定。
  8. 不用css表达式,表达式只是让你的代码显得更加酷炫,但是对性能的浪费可能是超乎你想象的。
  9. 少用css rest,可能会觉得重置样式是规范,但是其实其中有很多操作是不必要不友好的,有需求有兴趣,可以选择normolize.css。
  10. cssSprite,合成所有icon图片,用宽高加上background-position的背景图方式显现icon图,这样很实用,减少了http请求。
  11. 善后工作,css压缩(在线压缩工具 YUI Compressor), 是对文件大小的优化
  12. GZIP压缩,是一种流行的文件压缩算法, 进一步减少网络传输负载, 提高加载性能
  13. 避免使用@import, 外部的css文件中使用@import会使得页面在加载时增加额外的延迟.
  14. 避免过分重排(回流): 浏览器发生回流会消耗大量的计算资源, 要尽量避免

导致reflow发生的情况:

  1. 改变窗口的大小
  2. 改变文字的大小
  3. 添加 删除样式表
  4. 内容的改变 输入框输入内容也会
  5. 伪类的激活
  6. 操作class属性
  7. 脚本操作dom js改变css类
  8. 计算offsetWidth和offsetHeight
  9. 设置style属性
  10. 改变元素的内外边距

常见的回流元素

  1. 大小有关的 width,height,padding,margin,border-width,border,min-height
  2. 布局有关的 display,top,position,float,left,right,bottom
  3. 字体有关的 font-size,text-align,font-weight,font-family,line-height,white-space,vertical-align
  4. 隐藏有关的 overflow,overflow-x,overflow-y

优化回流的建议

  1. 不要一条条的修改dom的样式,预先定义好class,然后修改dom的classname
  2. 不要修改影响范围较大的dom
  3. 为动画元素使用绝对定位
  4. 不要table布局,因为一个很小的改动会造成整个table重新布局
  5. 避免设置大量的style属性,通过设置style属性改变节点样式的话,每一次设置都会触发一次reflow,所以最好使用class属性
  6. 如果css里面有计算表达式,每次都会重新计算一遍,触发一次reflow

transition 和 animation 的区别

  1. transition需要触发, 比如点击事件, 鼠标移入事件, 而animation可以配合@keyframe可以自动执行
  2. transition触发一次播放一次, 而animation则可以通过设置修改循环次数, 动画结束状态等.
  3. transition关注样式属性的变化, 属性值和时间的关系可以是一个三次贝塞尔曲线, animation作用域元素本身而不是样式属性, 使用关键帧的概念, 可以实现更自由的动画效果
  4. 在性能方面: 浏览器有一个主线程和排版线程, 主线程主要负责js运行, 页面布局, 生成位图等等, 然后把生成好的位图传递给排版线程, 排版线程会通过GPU将位图绘制到页面上, 也会向主线请求位图等. 在使用animation的过程中, 我们可能会改变的width,height等改变文档流的属性, 就会引起页面的回流和重绘, 对性能造成影响. 而transition会结合transform来进行旋转和缩放, 会新建layer, 而不会引起重绘和回流.

calc, support, media各自的含义及用法?

@supprot主要用于检测浏览器是否支持CSS的某个属性, 本质上是条件判断, 如果支持某个属性就应用一套的样式, 否则就提供另一套样式.

@supports (display: grid) {
div {
display: grid;
}
}

@supports not (display: grid) {
div {
float: right;
}
}

在js中可以通过css对象接口模型CSSSupportsRule来访问@supports.

calc()用于动态的计算长度值, 支持常规的四则运算/

@media, 用于进行媒体查询, 以应用不同的样式.

图片base64编码的优缺点

优点:

  1. 减少一个图片的HTTP请求

缺点:

  1. 根据base64编码的原理, 编码后的文件大小会比源文件大1/3, 如果把大图片编码到html/css中, 会造成文件体积的增加, 影响文件的加载速度, 也会增加浏览器解析html和css的时间
  2. 使用basr64无法直接缓存, 比直接缓存图片的效果差很多
  3. ie8之前的浏览器不支持

layout viewport、visual viewport 和 ideal viewport 的区别?

移动端一共需要理解三个viewport的概念:

  1. 布局视口(layout viewport), 在移动端显示网页的时候, 由于移动端的屏幕尺寸比较小, 如果网页使用移动端的屏幕尺寸进行布局, 那么整个页面会显示错乱. 因此移动端浏览器提供了一个layout viewport的布局视口的概念, 使用这个视口对页面进行显示, 一般layout viewport的大小为980px, 因此页面布局不会有太大的变化, 我们可以通过拖动和缩放来看这个页面
  2. 视觉视口(visual viewport), 视觉视口指的是移动设备商我们可见的区域的视口大小, 一般为屏幕的分辨率的大小, 视觉视口和布局视口的关系: 视觉视口就像是一扇窗户, 布局视口就是窗外的风景.
  3. 理想视口(ideal viewport), 理想视口, 由于layout viewport一般比visual viewport要大, 所以想要看到整个页面就必须拖动页面. 因此出现了理想视口的概念, ideal viewport下用户不同缩放和滚动条就能看到整个页面, 并且页面在不同分辨率下显示的内容大小都是相同的. ideal viewport其实就是通过修改layout viewport的大小, 让大等于设备的宽度, 这里设备的宽度可以理解为设备独立像素. 因此根据理想视口设计的页面, 在不同分辨率下显示应该相同.

设置如下:

<metaname="viewport"content="width=device-width,initial-scale=1.0,maximum-scale=1.0,minimum-sca
le=1.0,user-scalable=no"/>

overflow:scroll 时不能平滑滚动的问题怎么处理?

{
-webkit-overflow-scrolling:touch; // 开启硬件加速
}

浏览器如何判断是否支持 webp 格式图片

  1. 宽高判断法。通过创建image对象,将其src属性设置为webp格式的图片,然后在onload事件中获取图片的宽高,如 果能够获取,则说明浏览器支持webp格式图片。如果不能获取或者触发了onerror函数,那么就说明浏览器不支持webp格 式的图片。

  2. canvas判断方法。我们可以动态的创建一个canvas对象,通过canvas的toDataURL将设置为webp格式,然后判断 返回值中是否含有image/webp字段,如果包含则说明支持WebP,反之则不支持。

什么是替换元素

通过修改某个属性值呈现的内容就可以被替换的元素就称为“替换元素”。因此,<img><object><video><iframe>或者表 单元素<textarea><input><select>都是典型的替换元素。

替换元素除了内容可替换这一特性以外,还有以下一些特性。

  1. 内容的外观不受页面上的CSS的影响。用专业的话讲就是在样式表现在CSS作用域之外。如何更改替换元素本身的外观需要 类似appearance属性,或者浏览器自身暴露的一些样式接口,

  2. 有自己的尺寸。在Web中,很多替换元素在没有明确尺寸设定的情况下,其默认的尺寸(不包括边框)是300像素×150像 素,如<video><iframe>或者<canvas>等,也有少部分替换元素为0像素,如<img>图片,而表单元素的替换元素 的尺寸则和浏览器有关,没有明显的规律。

  3. 在很多CSS属性上有自己的一套表现规则。比较具有代表性的就是vertical-align属性,对于替换元素和非替换元素,ve rtical-align属性值的解释是不一样的。比方说vertical-align的默认值的baseline,很简单的属性值,基线之意, 被定义为字符x的下边缘,而替换元素的基线却被硬生生定义成了元素的下边缘。

  4. 所有的替换元素都是内联水平元素,也就是替换元素和替换元素、替换元素和文字都是可以在一行显示的。但是,替换元素默认 的display值却是不一样的,有的是inline,有的是inline-block。

隐藏元素的background-image会不会加载?

  1. 元素的背景图片:

    1. 元素本身设置 display:none,会请求图片,
    2. 父级元素设置 display:none,不会请求图片
    3. 样式没有元素使用,不会请求
    4. :hover样式下,触发时请求
  2. img标签图片: 任何情况下都会请求图片

img / background 的区别

  1. 从解析机制来看:
    1. 按照浏览器的解析机制, HTML标签是优先解析的.
    2. 如果仅仅是显示一张图片, 比如banner广告图, 则可以使用background, 不重要的自动往后面排, 避免占用带宽, 造成数据堵塞
    3. 当图片很多并且没有进行lazy-load, 使用background是更好的选择
    4. img标签的有点: 自闭合标签, 并且能避免空便签
  2. 从SEO来看:
    1. img是自闭合标签, 不能添加文本内容, 可以设置alt属性.
    2. 优点在于: 对屏幕阅读器友好; 缺点在于: 需要设置显示区间
  3. 从语义化的角度:
    1. img是语义化的标签

实现一个宽高自适应的正方形

/*1.第一种方式是利用vw来实现*/
.square {
width: 10%;
height: 10vw;
background: tomato;
}

/*2.第二种方式是利用元素的margin/padding百分比是相对父元素width的性质来实现 */
.square {
width: 20%; /* 父元素宽度的20% */
height: 0;
padding-top: 20%; /* 父元素宽度的20% */
background: orange;
}

/*3.第三种方式是利用子元素的margin-top的值来实现的*/
.square {
width: 30%;
overflow: hidden;
background: yellow;
}

.square::after {
content: '';
display: block;
margin-top: 100%;
}

CSS 中不同属性设置为百分比%时对应的计算基准?

公式:当前元素某CSS属性值 = 基准 * 对应的百分比

  • 元素的 position 为 relative 和 absolute 时,top和bottom、left和right基准分别为包含块的 height、width
  • 元素的 position 为 fixed 时,top和bottom、left和right基准分别为初始包含块(也就是视口)的 height、width,移动设备较为复杂,基准为 Layout viewport 的 height、width
  • 元素的 height 和 width 设置为百分比时,基准分别为包含块的 height 和 width
  • *元素的 margin 和 padding 设置为百分比时,基准为包含块的 width(易错)
  • 元素的 border-width,不支持百分比
  • 元素的 text-indent,基准为包含块的 width
  • 元素的 border-radius,基准为分别为自身的height、width
  • 元素的 background-size,基准为分别为自身的height、width
  • 元素的 translateX、translateY,基准为分别为自身的height、width
  • 元素的 line-height,基准为自身的 font-size
  • 元素的 font-size,基准为父元素字体

参考链接