01-HTML+CSS八股文
码路教育 6/28/2022
# HTML+CSS(码路教育)
# 1. html5有哪些新特性?
(1)Canvas绘图
(2)SVG绘图
(3)地理定位
(4)Web Worker
web worker 是运行在后台的 JS,独立于其他脚本,不会影响页面的性能。
(5)Web Storage
1.Cookie技术 ( 兼容性好,数据不能超4kb,操作复杂)
2.(兼容性差,数据8MB,操作简单)sessionStorage
3.localStorage
(6)Web Socket
WebSocket协议是基于TCP的一种新的网络协议。它实现了浏览器与服务器全双工(full-duplex)通信——允许服务器主动发送信息给客户端
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# 2. position有哪些属性?
1. position: relative;相对定位
2. position: absolute;绝对定位
3. position: fixed;固定定位
4. position:static:默认值
5. position: sticky 粘性定位
6. position: inherit 规定应该从父元素继承 position 属性的值
7. position: initial 设置该属性为默认值
1
2
3
4
5
6
7
2
3
4
5
6
7
# 3. 请说出1px,1rem,1vh,1em各自代表的含义?
rem
rem是全部的长度都相对于根元素<html>元素。通常做法是给html元素设置一个字体大小,然后其他元素的长度单位就为rem。
em
元素用em的话是相对于该元素的font-size
vw/vh
全称是 Viewport Width 和 Viewport Height,视窗的宽度和高度,相当于 屏幕宽度和高度的 1%,不过,处理宽度的时候%单位更合适,处理高度的 话 vh 单位更好。
px
px像素(Pixel)。相对长度单位。像素px是相对于显示器屏幕分辨率而言的。
一般电脑的分辨率有{1920 * 1024}等不同的分辨率,1920 * 1024 前者是屏幕宽度总共有1920个像素,后者则是高度为1024个像素
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# 4. 简述优雅降级与渐进增强
渐进增强(progressive enhancement)
针对低版本浏览器进行构建页面,保证最基本的功能,然后再针对高级浏览器进行效果、交互等改进和追加功能达到更好的用户体验。
优雅降级(graceful degradation)
一开始就构建完整的功能,然后再针对低版本浏览器进行兼容。
区别:
1)优雅降级是从复杂的现状开始,并试图减少用户体验的供给;渐进增强则是从一个非常基础的,能够起作用的版本开始,并不断扩充,以适应未来环境的需要。
2)渐进增强观点认为应该关注于内容本身,这使得渐进增强成为一种更为合理的设计范例;优雅降级观点认为应该针对那些最高级、最完善的浏览器来设计网站。
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# 5. 重绘与重排
重绘:
重绘是一个元素外观的改变所触发的浏览器行为(例如改变visibility,outline,background等属性),浏览器会根据元素的新属性重新绘制,使元素呈现新的外观。
重排:
重排时更明显的一种改变,可以理解为渲染树需要重新计算。常见的触发重排的操作:
1)DOM元素的几何属性变化
2)DOM树的结构变化(例如节点的增减、移动)
3)获取某些属性(例如offsetTop,offsetLeft,offsetHeight,offsetWidth,clientWidth,clientHeight等)
4)改变元素的一些样式(例如调整浏览器窗口大小)
两者的区别:
1)重绘不会带来重新布局,并不一定伴随着重排。
2)在实践中,应该尽量减少重排次数和缩小重排的影响范围。有以下几种方法:
3)[ ] 将多次改变样式属性的操作合并成一次操作
4)[ ] 将需要多次重排的元素,position属性设为absolute或fixed,使其脱离文档流,这样它的变化就不会影响到其他元素
5)[ ] 在内存中多次操作节点,完成后再添加到文档中去
6)[ ] 如果要对一个元素进行复杂的操作,可以将其display属性设置为none使其隐藏,待操作完成后再显示
7)[ ] 在需要经常获取那些引起浏览器重排的属性值时,要缓存到变量
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 6. 解释下浮动和它的工作原理?清除浮动的方法
浮动元素脱离文档流,不占据空间。浮动元素碰到包含它的边框或者浮动元素的边框停留。
使用空标签清除浮动:
这种方法是在所有浮动标签后面添加一个空标签 定义css clear:both. 弊端就是增加了无意义标签。
使用after伪对象清除浮动:
该方法只适用于非IE浏览器。具体写法可参照以下示例。使用中需注意以下几点。一、该方法中必须为需要清除浮动元素的伪对象中设置 height:0,否则该元素会比实际高出若干像素;
overflow: hidden;
浮动外部元素
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# 7. 如何让一个盒子在页面垂直水平居中
- 方法一:已知宽高
div {
position: absolute;
left: 0;
right: 0;
bottom: 0;
top: 0;
margin: auto;
}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
- 方法一:未知宽高
div {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
1
2
3
4
5
6
2
3
4
5
6
# 8. 前端性能优化方案
1、减少DOM操作
2、部署前,图片压缩,代码压缩
3、优化js代码结构,减少冗余代码
4、减少http请求,合理设置HTTP缓存
5、使用内容分发cdn加速
6、静态资源缓存
7、图片延迟加载
1
2
3
4
5
6
7
2
3
4
5
6
7
# 9. css选择器优先级顺序
由上到下依次降低:
ID 选择器, 如 #id{}
类选择器, 如 .class{}
属性选择器, 如 a[href="segmentfault.com"]{}
伪类选择器, 如 :hover{}
伪元素选择器, 如 ::before{}
标签选择器, 如 span{}
通配选择器, 如 *{}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 10. CSS3有哪些新特性
border-radius 圆角
box-shadow 阴影
text-shadow 文字阴影
gradient 线性渐变
transform 旋转、缩放、移动或倾斜
scale 缩放
translate 位移
媒体查询 多栏布局 多背景
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 11. 什么是空元素?
即没有内容的HTML元素,例如:br、meta、hr、link、input、img
1
# 12. 如何实现浏览器内多个标签页之间的通讯
定时器setInterval + cookie:
1)在页面A设置一个使用 setInterval 定时器不断刷新,检查 Cookies 的值是否发生变化,如果变化就进行刷新的操作。
2)由于 Cookies 是在同域可读的,所以在页面 B 审核的时候改变 Cookies 的值,页面 A 自然是可以拿到的。
3)这样做确实可以实现我想要的功能,但是这样的方法相当浪费资源。虽然在这个性能过盛的时代,浪费不浪费也感觉不出来,但是这种实现方案,确实不够优雅。
使用localstorage:
1)localstorage是浏览器多个标签共用的存储空间,所以可以用来实现多标签之间的通信(ps:session是会话级的存储空间,每个标签页都是单独的)。
2)直接在window对象上添加监听即可:window.addEventListener('storage', (e) => console.log(e))
3)onstorage以及storage事件,针对都是非当前页面对localStorage进行修改时才会触发,当前页面修改localStorage不会触发监听函数。然后就是在对原有的数据的值进行修改时才会触发,比如原本已经有一个key会a值为b的localStorage,你再执行:localStorage.setItem('a', 'b')代码,同样是不会触发监听函数的。
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# 13. 为什么要初始化css样式
浏览器差异:
不同浏览器对有些标签的默认值是不同的,如果没对css初始化会出现浏览器之间的页面显示差异
提高编码质量:
如果不初始化,整个页面做完会很糟糕,重复的css样式很多
1
2
3
4
5
2
3
4
5
# 14. CSS3新增的伪类有哪些?
p:first-of-type 选择属于其父元素的首个元素
p:last-of-type 选择属于其父元素的最后元素
p:only-of-type 选择属于其父元素唯一的元素
p:only-child 选择属于其父元素的唯一子元素
p:nth-child(2) 选择属于其父元素的第二个子元素
1
2
3
4
5
2
3
4
5
# 15. 说说对canvas,svg,webgl的理解
1)Canvas 是HTML5新增的一个元素对象,名副其实就是一个画布,浏览器 js 配有相应的操作api,可以不再依赖其他的API或组件而直接绘图,相当于2D的API。Canvas 适用于位图,高数据量高绘制频率(帧率)的场景,如动画、游戏;
2)SVG 是给数据就可以绘制点、线、图形的,基于 XML 的标记语言;SVG 适用于矢量图,低数据量低绘制频率的场景,如图形、图表;
3)WebGL(全写Web Graphics Library)是一种3D绘图标准,通俗说WebGL是canvas绘图中的3D版本。因为原生的WebGL很复杂,我们经常会使用一些三方的库,如three.js等,WebGL 主要用来做 3D 展示、动画、游戏。
1
2
3
2
3
# 16. 浏览器是如何渲染UI的?
1)浏览器获取HTML文件,然后对文件进行解析,形成DOM Tree
2)与此同时,进行CSS解析,生成Style Rules
3)接着将DOM Tree与Style Rules合成为 Render Tree
4)接着进入布局(Layout)阶段,也就是为每个节点分配一个应出现在屏幕上的确切坐标
5)随后调用GPU进行绘制(Paint),遍历Render Tree的节点,并将元素呈现出来
1
2
3
4
5
2
3
4
5
# 17. em、rem的区别
em是相对长度单位,相对于当前对象内文本的字体尺寸。如当前对行内文本的字体尺寸未被人为设置,则相对浏览器的默认字体尺寸。它会继承父级元素的字体大小,因此并不是一个固定的值。
rem是CSS3新增的一个相对单位(root em,根em),使用rem为元素设定字体大小事,仍然是相对大小但相对的只是HTML根元素。
1
2
3
2
3
# 18. 解释csssprites,如何使用。
Css精灵把一堆小的图片整合到一张大的图片上,减轻服务器对图片的请求数量。
1
# 19. 浏览器工作原理
用户界面 、2. 网络 、3. UI后端 、4. 数据存储 、5. 浏览器引擎 、6. 渲染引擎 、7. js解释器
1
# 20. 介绍一下你对浏览器内核的理解?
主要分成两部分:渲染引擎(layout engineer或Rendering Engine)和JS引擎。
渲染引擎:
负责取得网页的内容(HTML、XML、图像等等)、整理讯息(例如加入CSS等),以及计算网页的显示方式,然后会输出至显示器或打印机。浏览器的内核的不同对于网页的语法解释会有不同,所以渲染的效果也不相同。所有网页浏览器、电子邮件客户端以及其它需要编辑、显示网络内容的应用程序都需要内核。
JS引擎则:
解析和执行javascript来实现网页的动态效果。最开始渲染引擎和JS引擎并没有区分的很明确,后来JS引擎越来越独立,内核就倾向于只指渲染引擎。
1
2
3
4
5
6
7
2
3
4
5
6
7
# 21. 常见的浏览器内核有哪些?
Trident内核:IE,360,傲游,搜狗,世界之窗,腾讯等。[又称MSHTML]
Gecko内核:Netscape6及以上版本,FF,MozillaSuite/SeaMonkey等
Presto内核:Opera7及以上。 [Opera内核原为:Presto,现为:Blink;]
Webkit内核:Safari,Chrome等。 [ Chrome的:Blink(WebKit的分支)]
1
2
3
4
2
3
4
# 22. 一个页面上有大量的图片,加载很慢,你有哪些方法优化这些图片的加载,给用户更好的体验。
(1)图片懒加载,在页面上的未可视区域可以添加一个滚动条事件,判断图片位置与浏览器顶端的距离与页面的距离,如果前者小于后者,优先加载。
(2)如果为幻灯片、相册等,可以使用图片预加载技术,将当前展示图片的前一张和后一张优先下载。
(3)如果图片过大,可以使用特殊编码的图片,加载时会先加载一张压缩的特别厉害的缩略图,以提高用户体验。
(4)如果图片展示区域小于图片的真实大小,则因在服务器端根据业务需要先行进行图片压缩,图片压缩后大小与展示一致。
1
2
3
4
2
3
4
# 23. 如何进行seo优化?
1、合理的title、description、keywords:搜索对着三项的权重逐个减小,title值强调重点即可;description把页面内容高度概括,不可过分堆砌关键词;keywords列举出重要关键词。
2、语义化的HTML代码,符合W3C规范:语义化代码让搜索引擎容易理解网页
3、重要内容HTML代码放在最前:搜索引擎抓取HTML顺序是从上到下,保证重要内容一定会被抓取
4、重要内容不要用js输出:爬虫不会执行js获取内容
5、少用iframe:搜索引擎不会抓取iframe中的内容
6、非装饰性图片必须加alt属性
7、提高网站速度:网站速度是搜索引擎排序的一个重要指标。
1
2
3
4
5
6
7
2
3
4
5
6
7
# 24. 如何实现0.5px边框
- border+border-image+linear-gradient的方式
/* <div class="border"></div> */
.border {
width: 200px;
height: 200px;
background-color: red;
margin: 0 auto;
border-bottom: 1px solid blue;
border-image: linear-gradient(to bottom, transparent 50%, Green 50%) 0 0 100% 0;
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
- 伪元素+background-image的方式
/* <div class="border"></div> */
.border {
width: 200px;
height: 200px;
background-color: red;
margin: 0 auto;
position: relative;
}
.border:before {
content: " ";
position: absolute;
left: 0;
bottom: 0;
width: 100px;
height: 1px;
background-color: blue;
background-image: linear-gradient(to bottom transparent 50%, blue 50%);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
- 定位+伪元素+transfrom缩放(scale)的方式
/* <div class="border"></div> */
.border {
width: 200px;
height: 200px;
background-color: red;
margin: 0 auto;
position: relative;
}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 25. less和sass的区别
Less是基于JavaScript,是在客户端处理的;Sass是基于Ruby的,是在服务器端处理的。
关于变量在Less和Sass中的唯一区别就是Less用@,Sass用$。
输出设置,Less没有输出设置,Sass提供4中输出选项:nested, compact, compressed 和 expanded。
Sass支持条件语句,可以使用if{}else{},for{}循环等等,而Less不支持。
1
2
3
4
5
6
7
2
3
4
5
6
7
# 26. 页面导入样式时,使用link和@import有什么区别
1、link属于XHTML标签,除了加载CSS外,还能用于定义RSS(简易信息聚合,是一种基于XML标准,在互联网上被广泛采用的内容包装和投递协议),rel连接属性等作用;@import是CSS提供的,只能用于加载CSS;
2、页面被加载时,link会同时被加载;而@import引用的CSS会等到页面被加载完成后再加载;
3、link是XHTML标签,没有兼容问题;而@import只有在IE5以上才能被识别;
4、link支持使用JavaScript控制DOM修改样式;而@import不支持。
1
2
3
4
2
3
4
# 27. 谈谈你对 BFC 的理解?
BFC: 块级格式化上下文, 是一块独立的渲染区域 (触发了BFC, 这块区域就是一块独立的渲染区域)
会将处于BFC的内容 和 处于BFC外的内容 隔离
触发BFC的方式:
1. position: absolute/fixed
2. float: left / right; 浮动的元素多个放在一起, 会互相隔开
3. overflow: 非visible hidden/auto/scroll
4. display: inline-block
BFC应用:
1. 处理块级元素, 上下margin合并的问题
2. 处理margin塌陷
3. 清除浮动
4. 实现自适应布局
左边固定, 右边自适应
flex => display: flex; 左边定宽, 右边 flex: 1;
浮动 => 先浮动占位置, 再中间盒子overflow: hidden
定位 => 先定位, 再设置padding即可
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 28. 说说你对元素语义化的理解
元素语义化就是⽤正确的元素做正确的事情。虽然在理论上,所以的html元素都可以通过css样式实现相同的事情,但是这么做会使事情复杂化,所以我们需要元素语义化来降低复杂度。
元素语义化在我们实际的开发中有很多好处,⽐如:
1)提⾼代码的阅读性和可维护性;
2)减少coder之间的沟通成本;
3)能让语⾳合成⼯具正确识别⽹⻚元素的⽤途,以便做出正确的反应
4)有利于SEO(Search Engine Optimization)
1
2
3
4
5
6
7
2
3
4
5
6
7
# 29. HTML 中有哪些语义化标签
header
footer
main
aside
article
section
address
summary/details
menu
h1/h2/h3/h4/h5/h6
img
p
strong/italic
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# 30. 什么是 URL 编码 (URL Encode)
encodeURI ⽤来编码URI,其不会编码保留字符。
encodeURIComponent ⽤来编码 URI参数,除了字符:A-Z a-z 0-9 - _ . ! ~ * ' ( ),都将会转义。
1
2
3
2
3
# 31. 说说你对SEO的理解
SEO就是搜索引擎优化(Search Engine Optimization),SEO通过了解搜索引擎的运⾏规则来调整⽹站,以提⾼⽹站的曝光度,以及⽹站的排名。
Google 搜索引擎的⼯作流程主要分为三个阶段:
抓取:
Google 会使⽤名为“抓取⼯具”的⾃动程序搜索⽹络,以查找新⽹⻚或更新后的⽹⻚。Google 会将这些⽹⻚的地址(即⽹址)存储在⼀个⼤型列表中,以便⽇后查看。我们会通过许多不同的⽅法查找⽹⻚,但主要⽅法是跟踪我们已知的⽹⻚中的链接。
编⼊索引:
Google 会访问它通过抓取得知的⽹⻚,并会尝试分析每个⽹⻚的主题。Google 会分析⽹⻚中的内容、图⽚和视频⽂件,尝试了解⽹⻚的主题。这些信息存储在 Google 索引中,⽽ Google 索引是⼀个存储在海量计算机中的巨⼤数据库。
呈现搜索结果:
当⽤户在 Google 上进⾏搜索时,Google 会尝试确定最优质的搜索结果。“最佳”结果取决于许多因素,包括⽤户的位置、语⾔、设备(桌⾯设备或⼿机)以及先前⽤过的搜索查询。例如,在⽤户搜索“⾃⾏⻋维修店”后,Google 向巴黎⽤户显示的答案与向⾹港⽤户显示的答案有所不同。⽀付费⽤不能提⾼⽹⻚在 Google 搜索结果中的排名,⽹⻚排名是完全依靠算法完成的。
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
# 32. 说明text-align居中的条件
text-align : 直接翻译过来设置⽂本的⽔平对⻬⽅式 (是继承属性)(是继承属性)
text-align 并不控制块元素⾃⼰的对⻬,只控制它的⾏内内容的对⻬
MDN解释: 定义⾏内内容(例如⽂字)如何相对它的块⽗元素对⻬(可以设置图⽚居中)
W3C官⽅⽂档解释: 设置⾏内(inline-level)元素(没有填满⽗元素)在快级⽗元素的对⻬⽅式
1
2
3
4
2
3
4
# 33. 说说盒⼦模型包含哪些内容?
内容
通过宽度和⾼度设置
内边距
通过padding设置
padding: padding-top padding-right padding-bottom padding-left;
边框
通过border设置
border: border-width border-style border-color
外边距
通过margin设置
margin: margin-top margin-right margin-bottom margin-left
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
# 34. 说说你对margin的传递和折叠的理解
margin的传递⼀般是⽗⼦块元素之间,有margin-top传递,margin-bottom传递.
1)margin-top传递: 当块级元素的顶部线和⽗元素的顶部线重叠,那么这个块级元素的margin-top值会传递给⽗元素
2)margin-bottom传递:当块级元素的底部线和⽗元素的底部线重叠,那么这个块级元素的marginbottom值会传递给⽗元素
折叠: 指的是 垂直⽅向上相邻的2个margin(margin-top、margin-bottom)有可能会合并为1个margin.
它有两个兄弟块级元素之间的上下margin的折叠,也有⽗⼦块元素之间的margin折叠
1
2
3
4
5
6
7
2
3
4
5
6
7
# 35. CSS 隐藏⻚⾯中某个元素的⼏种⽅法
display: none
通过 CSS 操控 display,移出⽂档流
opacity: 0
透明度为 0,仍在⽂档流中,当作⽤于其上的事件(如点击)仍有效
visibility: hidden
透明度为 0,仍在⽂档流中,但作⽤于其上的事件(如点击)⽆效,这也是visibility:hidden 与 opacity: 0 的区别
content-visibility
移出⽂档流,但是再次显示时消耗性能低
绝对定位于当前⻚⾯的不可⻅位置
position: absolute;
top: -9000px;
left: -9000px;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 36. box-sizing有什么作⽤?content-box和border-box的区别
box-sizing⽤来设置盒⼦模型中宽⾼的计算⽅式:
content-box: padding、border都布置在width、height外边
border-box: padding、border都布置在width、height⾥边
1
2
3
2
3
# 37. 为什么会发⽣样式抖动
因为没有指定元素具体⾼度和宽度,⽐如数据还没有加载进来时元素⾼度是 100px(假设这⾥是100px)
数据加载进来后,因为有了数据,然后元素被撑⼤,所有出现了抖动
1
2
2
# 38. 伪类与伪元素有什么区别?
伪类使⽤单冒号,⽽伪元素使⽤双冒号。如 :hover 是伪类, ::before 是伪元素
伪元素会在⽂档流⽣成⼀个新的元素,并且可以使⽤ content 属性设置内容
1
2
2
# 39. 什么是视⼝(viewport)?
pc端的视⼝:
就是浏览器的可视区域
移动端视⼝:
布局视⼝
会按照⼀个默认宽度980px,来布局⼀个⻚⾯盒⼦的内容
为了可以显示完整的⻚⾯,会对整个⻚⾯进⾏缩⼩
视觉视⼝
显示在可视区域的视⼝,就是视觉视⼝
理想视⼝
当布局视⼝ = 视觉视⼝的时候,就是理想视⼝
怎样是这理想视⼝呢?
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
# 40. 移动端适配的⽅案有哪些?
百分⽐布局:
因为不同属性百分⽐的值,相对的可能是不同的参照物,所以百分⽐往很难统⼀。
视⼝ + ( rem + 动态HTML的 font-size ):
动态计算 HTML font-zise:
⽤媒体查询来修改HTML font-size( 缺点不能实时改变font-size的⼤⼩ )
⾃⼰编写JS来实现修改HTML font-size的⼤⼩(可以实时修改字体⼤⼩)
是引⽤lib-flexiable库来实现(原理是JS动态改HTML font-size⼤⼩)
px 转成rem:
⼿动计算 rem
Less的映射来计算
postcss-pxtorem插件来实现(需依赖webpack或Vite)
cssrem VSCode插件来实现
视⼝ + vw
px转成rem
⼿动计算vw
Less的映射来计算
postcss-px-to-viewport的插件(需依赖webpack或Vite)
ccsrem VSCode插件
flex弹性布局
flex container 属性
flex item 属性
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 41. 说出不同像素之间的差异?
分为三种像素:设备像素(物理像素),设备独⽴像素(逻辑像素),css像素
设备像素(物理像素)
1)是指显示器上真实的像素,在购买显示器或者⼿机的时候,提到的设备分辨率就是设备像素的⼤⼩
2)iPhone X的分辨率 1125 x 2436,指的就是设备像素
设备独⽴像素(逻辑像素)
1)如果⾯向开发者我们使⽤设备像素显示⼀个100px的宽度,那么在不同屏幕上显示效果会是不同的
2)开发者针对不同的屏幕很难进⾏较好的适配,编写程序必须了解⽤户的分辨率来进⾏开发
3)所以在设备像素之上,操作系统为开发者进⾏抽象,提供了逻辑像素的概念
4)⽐如你购买了⼀台显示器,在操作系统上是以1920x1080设置的显示分辨率,那么⽆论你购买的是2k、4k的显示器,对于开发者来说,都是1920x1080的⼤⼩
5)如果物理像素很⼤的时候,⽐如2k,4k等,可以理解为⼀个逻辑像素⾥⾯由多个物理像素来渲染的
css像素
1)默认情况下就是设备独⽴像素(也就是逻辑像素)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 42. 如何解决移动端 Retina 屏 1px 像素问题
在移动端 Web 开发中,UI 设计稿中设置边框为 1 像素,前端在开发过程中如果出现 border:1px ,测试会发现在 Retina 屏机型中,1px 会⽐较粗,即是较经典的移动端 1px 像素问题。
以 iphone6 为例,iphone6 的屏幕宽度为 375px ,设计师做的视觉稿⼀般是750px ,也就是 2x ,这个时候设计师在视觉稿上画了 1px 的边框,于是你就写了 border:1px ,所以1px边框问题产⽣了。
对设计师来说它的 1px 是相对于 750px 的(物理像素),对你来说你的 1px 是相对于 375px 的(css像素),实际上你应该是 border:0.5px 。下⾯来看⼀下解决⽅案:
1
2
3
4
5
2
3
4
5
- 0.5px 实现
.border-1px {
border: 1px solid #999
}
@media screen and (-webkit-min-device-pixel-ratio: 2) {
.border-1px {
border: 0.5px solid #999
}
}
/* dpr=2 和 dpr=3 情况下 border 相差⽆⼏,下⾯代码可以省略*/
@media screen and (-webkit-min-device-pixel-ratio: 3) {
.border-1px {
border: 0.333333px solid #999
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
- 但在 IOS7 及以下和 Android 等其他系统⾥, 0.5px 将会被显示为 0px 。所以我们需要通过 JS 检测浏览器能否处理 0.5px 的边框
if (window.devicePixelRatio && devicePixelRatio >= 2) {
var testElem = document.createElement('div');
testElem.style.border = '.5px solid transparent';
document.body.appendChild(testElem);
}
if (testElem.offsetHeight == 1) {
document.querySelector('html').classList.add('hairlines');
}
document.body.removeChild(testElem);
}
// 优点:简单,没有副作⽤
// 缺点:⽀持 iOS 8+,安卓待兼容
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
- viewport + rem 实现, 通过设置缩放,让 CSS 像素等于真正的物理像素。
const scale = 1 / window.devicePixelRatio;
const viewport = document.querySelector('meta[name="viewport"]');
if (!viewport) {
viewport = document.createElement('meta');
viewport.setAttribute('name', 'viewport');
window.document.head.appendChild(viewport);
}
viewport.setAttribute('content', 'width=device-width,user-scalable=no,initialscale=' +
scale + ',maximum-scale=' + scale + ',minimum-scale=' + scale);
// 设置根字体⼤⼩
var docEl = document.documentElement;
var fontsize = 10 * (docEl.clientWidth / 320) + 'px';
docEl.style.fontSize = fontsize;
// 在CSS中⽤rem单位就⾏了
// 缺点:
// 通过 JS 对⽂档进⾏修改,所以性能上有⼀定影响
// 会对项⽬中所有使⽤ rem 单位的对象进⾏影响。如果是⽼项⽬,则会全部更改 css 样式(不适合⽼项⽬改造)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
- 伪元素 + transform 实现(推荐)
/* 为什么⽤伪元素? 因为伪元素 ::after 或 ::before 是独⽴于当前元素,可以单独对其缩放⽽不影
响元素本身的缩放
基于 media 查询判断不同的设备像素⽐对线条进⾏缩放: */
.border-1px:before {
content: '';
position: absolute;
top: 0;
height: 1px;
width: 100%;
background-color: #999;
transform-origin: 50% 0%;
}
@media only screen and (-webkit-min-device-pixel-ratio:2) {
.border-1px:before {
transform: scaleY(0.5);
}
}
@media only screen and (-webkit-min-device-pixel-ratio:3) {
.border-1px:before {
transform: scaleY(0.33);
}
}
/* 注意:如果需要满⾜圆⻆,需要给伪类也加上 border-radius
优点:兼容性好,⽆副作⽤,推荐使⽤ */
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
- svg 实现(推荐)
/* 因为 svg 是⽮量图形,它的 1px 对应的物理像素就是 1px
可以搭配 PostCSS 的 postcss-write-svg 使⽤: */
@svg border-1px {
height: 2px;
@rect {
fill: var(--color, black);
width: 100%;
height: 50%;
}
}
.svg {
border: 1px solid transparent;
border-image: svg(border_1px param(--color #00b1ff)) 2 2 stretch;
}
/* 优点:实现简单,可以实现圆⻆,
缺点:需要学习 svg 语法 */
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 43. 如何计算⽩屏时间和⾸屏加载时间
⽩屏时间:
window.performance.timing.domLoading - window.performance.timing.navigationStart
⾸屏时间:
window.performance.timing.domInteractive - window.performace.timing.navigationStart
1
2
3
4
5
2
3
4
5
# 44. 如何⾃定义滚动条的样式
滚动条相关样式都是伪元素,以 scrollbar 打头,有以下伪元素,从 -webkit 中可⻅兼容性⼀般,不过⽆所谓,现在 Chrome 浏览器占⼤头
::-webkit-scrollbar — 整个滚动条.
::-webkit-scrollbar-button — 滚动条上的按钮 (上下箭头).
::-webkit-scrollbar-thumb — 滚动条上的滚动滑块.
::-webkit-scrollbar-track — 滚动条轨道.
::-webkit-scrollbar-track-piece — 滚动条没有滑块的轨道部分.
::-webkit-scrollbar-corner — 当同时有垂直滚动条和⽔平滚动条时交汇的部分.
::-webkit-resizer — 某些元素的 corner 部分的部分样式(例:textarea 的可拖动按钮).
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
- 但其实最常⽤的是以下⼏个伪元素:滚动条、滑块、轨道,如下滚动条设置成功
::-webkit-scrollbar {
width: 6px;
height: 6px;
}
::-webkit-scrollbar-track {
border-radius: 3px;
background: rgba(0, 0, 0);
box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.08);
}
::-webkit-scrollbar-thumb {
border-radius: 3px;
background: rgba(0, 0, 1);
box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.2);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16