# 知识点
# CSS 加载会阻塞 DOM 的解析渲染吗
- CSS 加载不会阻塞 DOM 的解析(因为 DOM 解析跟 CSS 加载解析是并行的,但不是同时开始)
- CSS 加载会阻塞 DOM 的渲染(因为 DOM Tree 结合 CSSOM Tree 形成 Render Tree)
- CSS 加载会阻塞后面 JS 语句的执行(因为后面的 JS 语句可能需要操作加载的 CSS)
- JS 会阻塞 DOM 的解析(因为 JS 可能会修改 DOM 结构)
注意:浏览器它的解析和渲染并不是一个串行的过程。它是一个并行的过程,会边解析边渲染。因此,你把 Link 标签写在 div 下面的话,当解析到 Link 标签的时候,基本上 div 标签已经渲染完毕了。但是 link 标签后面的内容的渲染,是会被阻塞的
# 从 CSS 方面减少白屏时间
为了避免让用户看到长时间的白屏时间,我们应该尽可能的提高 css 加载速度,比如可以使用以下几种方法:
- 使用 CDN(因为 CDN 会根据你的网络状况,替你挑选最近的一个具有缓存内容的节点为你提供资源,因此可以减少加载时间)
- 对 css 进行压缩(可以用很多打包工具,比如 webpack,gulp 等,也可以通过开启 gzip 压缩)
- 合理的使用缓存(设置 cache-control,expires,以及 E-tag 都是不错的,不过要注意一个问题,就是文件更新后,你要避免缓存而带来的影响。其中一个解决防范是在文件名字后面加一个版本号)
- 减少 http 请求数,将多个 css 文件合并,或者是干脆直接写成内联样式(内联样式的一个缺点就是不能缓存)
# 关于 DOMContentLoaded 事件
DOMContentLoaded 事件会在 DOM解析完成的时候触发
- 当页面只存在 css,或者 js 都在 css 前面,那么 DOMContentLoaded 不需要等到 css 加载完毕,因为 css 加载不会阻塞 DOM 解析
- 当页面里同时存在 css 和 js,并且 js 在 css 后面的时候,DOMContentLoaded 必须等到 css 和 js 都加载完毕才触发,因为 css 加载会阻塞后面 js 语句的执行,且 js 会阻塞 DOM 解析
# script 中 async 和 defer 属性
普通 script,加载时阻塞 dom 解析,执行顺序由 HTML 位置决定,加载并执行完 JS 继续 dom 解析,
带 async 的 script,加载时不阻塞 dom 解析,执行顺序由网络请求返回的顺序决定,执行时如果 dom 未解析完成,则阻塞 dom 解析,执行完继续 dom 解析,如果 dom 已经解析完成,则直接执行
带 defer 的 script,加载时不阻塞 dom 解析,执行顺序由 HTML 位置决定,dom 解析完成才执行
script 标签 | JS 执行顺序 | 是否阻塞 HTML 解析 |
---|---|---|
script | HTML 位置 | 加载,执行都阻塞 |
script async | 网络请求 | 加载不阻塞,执行可能阻塞 |
script defer | HTML 位置 | 加载,执行都不阻塞 |
# 空元素定义
标签内没有内容的 HTML 标签被称为空元素。空元素是在开始标签中关闭的。
常见的空元素有:br hr img input link meta
# 页面导入样式时,使用 link 和 @import 有什么区别?
从属关系区别
- @import 是 CSS 提供的语法规则,只有导入样式表的作用;
- link 是 HTML 提供的标签,不仅可以加载 CSS 文件,还可以定义 RSS、rel 连接属性、引入网站图标等。
加载顺序区别
- 加载页面时,link 标签引入的 CSS 被同时加载;
- @import 引入的 CSS 将在页面加载完毕后被加载。
兼容性区别
- @import 是 CSS2.1 才有的语法,故只可在 IE5+ 才能识别;
- link 标签作为 HTML 元素,不存在兼容性问题。
DOM 可控性区别
- 可以通过 JS 操作 DOM ,插入 link 标签来改变样式;
- 由于 DOM 方法是基于文档的,无法使用 @import 的方式插入样式。
# 什么是文档的预解析?
Webkit 和 Firefox 都做了这个优化,当执行 JavaScript 脚本时,另一个线程解析剩下的文档,并加载后面需要通过网络加载的资源。这种方式可以使资源并行加载从而使整体速度更快。需要注意的是,预解析并不改变 DOM 树,它将这个工作留给主解析过程,自己只解析外部资源的引用,比如外部脚本、样式表及图片。
# 渲染页面时常见哪些不良现象?
FOUC:主要指的是样式闪烁的问题,由于浏览器渲染机制(比如 firefox),在 CSS 加载之前,先呈现了 HTML,就会导致展示出无样式内容,然后样式突然呈现的现象。会出现这个问题的原因主要是 CSS 加载时间过长,或者 CSS 被放在了文档底部。
白屏:有些浏览器渲染机制(比如 chrome)要先构建 DOM 树和 CSSOM 树,构建完成后再进行渲染,如果 CSS 部分放在 HTML 尾部,由于 CSS 未加载完成,浏览器迟迟未渲染,从而导致白屏;也可能是把 JS 文件放在头部,脚本的加载会阻塞后面文档内容的解析,从而页面迟迟未渲染出来,出现白屏问题。
# 如何优化关键渲染路径?
为尽快完成首次渲染,我们需要最大限度减小以下三种可变因素:
(1)关键资源的数量。 (2)关键路径长度。 (3)关键字节的数量。
关键资源是可能阻止网页首次渲染的资源。这些资源越少,浏览器的工作量就越小,对 CPU 以及其他资源的占用也就越少。
同样,关键路径长度受所有关键资源与其字节大小之间依赖关系图的影响:某些资源只能在上一资源处理完毕之后才能开始下载, 并且资源越大,下载所需的往返次数就越多。
最后,浏览器需要下载的关键字节越少,处理内容并让其出现在屏幕上的速度就越快。要减少字节数,我们可以减少资源数(将它们删除或设为非关键资源),此外还要压缩和优化各项资源,确保最大限度减小传送大小。
优化关键渲染路径的常规步骤如下:
(1)对关键路径进行分析和特性描述:资源数、字节数、长度。 (2)最大限度减少关键资源的数量:删除它们,延迟它们的下载,将它们标记为异步等。 (3)优化关键字节数以缩短下载时间(往返次数)。 (4)优化其余关键资源的加载顺序:您需要尽早下载所有关键资产,以缩短关键路径长度。
# b 与 strong 的区别和 i 与 em 的区别?
从页面显示效果来看,被 <b>
和 <strong>
包围的文字将会被加粗,而被 <i>
和 <em>
包围的文字将以斜体的形式呈现。
但是 <b> <i>
是自然样式标签,分别表示无意义的加粗,无意义的斜体,表现样式为 { font-weight: bolder},仅仅表示「这 里应该用粗体显示」或者「这里应该用斜体显示」,此两个标签在 HTML4.01 中并不被推荐使用。
而 <em>
和 <strong>
是语义样式标签。 <em>
表示一般的强调文本,而 <strong>
表示比 <em>
语义更强的强调文本。
使用阅读设备阅读网页时:<strong>
会重读,而 <b>
是展示强调内容。
# 前端需要注意哪些 SEO ?
(1)合理的 title、description、keywords:搜索对着三项的权重逐个减小,title 值强调重点即可,重要关键词出现不要超 过 2 次,而且要靠前,不同页面 title 要有所不同;description 把页面内容高度概括,长度合适,不可过分堆砌关键词,不 同页面 description 有所不同;keywords 列举出重要关键词即可。
(2)语义化的 HTML 代码,符合 W3C 规范:语义化代码让搜索引擎容易理解网页。
(3)重要内容 HTML 代码放在最前:搜索引擎抓取 HTML 顺序是从上到下,有的搜索引擎对抓取长度有限制,保证重要内容肯定被 抓取。
(4)重要内容不要用 js 输出:爬虫不会执行 js 获取内容
(5)少用 iframe:搜索引擎不会抓取 iframe 中的内容
(6)非装饰性图片必须加 alt
(7)提高网站速度:网站速度是搜索引擎排序的一个重要指标
# HTML5 的离线储存怎么使用,工作原理能不能解释一下?
在用户没有与因特网连接时,可以正常访问站点或应用,在用户与因特网连接时,更新用户机器上的缓存文件。
原理:HTML5 的离线存储是基于一个新建的 .appcache 文件的缓存机制(不是存储技术),通过这个文件上的解析清单离线存储资源,这些资源就会像 cookie 一样被存储了下来。之后当网络在处于离线状态下时,浏览器会通过被离线存储的数据进行页面展示。
如何使用:
(1)创建一个和 html 同名的 manifest 文件,然后在页面头部像下面一样加入一个 manifest 的属性。
<html lang="en" manifest="index.manifest">
(2)在如下 cache.manifest 文件的编写离线存储的资源。
CACHE MANIFEST
#v0.11
CACHE:
js/app.js
css/style.css
NETWORK:
resourse/logo.png
FALLBACK:
// offline.html
2
3
4
5
6
7
8
9
- CACHE: 表示需要离线存储的资源列表,由于包含 manifest 文件的页面将被自动离线存储,所以不需要把页面自身也列出来。
- NETWORK: 表示在它下面列出来的资源只有在在线的情况下才能访问,他们不会被离线存储,所以在离线情况下无法使用这些资源。不过,如果在 CACHE 和 NETWORK 中有一个相同的资源,那么这个资源还是会被离线存储,也就是说 CACHE 的优先级更高。
- FALLBACK:表示如果访问第一个资源失败,那么就使用第二个资源来替换他,比如上面这个文件表示的就是如果访问根目录下任何一个资源失败了,那么就去访问 offline.html 。
(3)在离线状态时,操作 window.applicationCache 进行离线缓存的操作。
如何更新缓存:
(1)更新 manifest 文件 (2)通过 javascript 操作 (3)清除浏览器缓存
注意事项:
(1)浏览器对缓存数据的容量限制可能不太一样(某些浏览器设置的限制是每个站点 5MB)。 (2)如果 manifest 文件,或者内部列举的某一个文件不能正常下载,整个更新过程都将失败,浏览器继续全部使用老的缓存。 (3)引用 manifest 的 html 必须与 manifest 文件同源,在同一个域下。 (4)FALLBACK 中的资源必须和 manifest 文件同源。 (5)当一个资源被缓存后,该浏览器直接请求这个绝对路径也会访问缓存中的资源。 (6)站点中的其他页面即使没有设置 manifest 属性,请求的资源如果在缓存中也从缓存中访问。 (7)当 manifest 文件发生改变时,资源请求本身也会触发更新。
# 浏览器是怎么对 HTML5 的离线储存资源进行管理和加载的呢?
在线的情况下,浏览器发现 html 头部有 manifest 属性,它会请求 manifest 文件,如果是第一次访问 app ,那么浏览器就会根据 manifest 文件的内容下载相应的资源并且进行离线存储。如果已经访问过 app 并且资源已经离线存储了,那么浏览器就会使用离线的资源加载页面,然后浏览器会对比新的 manifest 文件与旧的 manifest 文件,如果文件没有发生改变,就不做任何操作,如果文件改变了,那么就会重新下载文件中的资源并进行离线存储。
离线的情况下,浏览器就直接使用离线存储的资源。
# iframe 有那些缺点?
iframe 元素会创建包含另外一个文档的内联框架(即行内框架)。
主要缺点有:
(1) iframe 会阻塞主页面的 onload 事件。window 的 onload 事件需要在所有 iframe 加载完毕后(包含里面的元素)才会触发。在 Safari 和 Chrome 里,通过 JavaScript 动态设置 iframe 的 src 可以避免这种阻塞情况。 (2) 搜索引擎的检索程序无法解读这种页面,不利于网页的 SEO 。 (3) iframe 和主页面共享连接池,而浏览器对相同域的连接有限制,所以会影响页面的并行加载。 (4) 浏览器的后退按钮失效。 (5) 小型的移动设备无法完全显示框架。
# HTML5 的 form 的自动完成功能是什么?
autocomplete 属性规定输入字段是否应该启用自动完成功能。默认为启用,设置为 autocomplete=off 可以关闭该功能。
自动完成允许浏览器预测对字段的输入。当用户在字段开始键入时,浏览器基于之前键入过的值,应该显示出在字段中填写的选项。
autocomplete 属性适用于 <form>
,以及下面的 <input>
类型:text, search, url, telephone, email, password, datepickers, range 以及 color。
# 如何实现浏览器内多个标签页之间的通信?
(1)使用 WebSocket,通信的标签页连接同一个服务器,发送消息到服务器后,服务器推送消息给所有连接的客户端。
(2)使用 SharedWorker (只在 chrome 浏览器实现了),两个页面共享同一个线程,通过向线程发送数据和接收数据来实现标签页之间的双向通行。
(3)可以调用 localStorage、cookies 等本地存储方式,localStorge 另一个浏览上下文里被添加、修改或删除时,它都会触 发一个 storage 事件,我们通过监听 storage 事件,控制它的值来进行页面信息通信;
(4)如果我们能够获得对应标签页的引用,通过 postMessage 方法也是可以实现多个标签页通信的。
# 页面可见性(Page Visibility API) 可以有哪些用途?
这个新的 API 的意义在于,通过监听网页的可见性,可以预判网页的卸载,还可以用来节省资源,减缓电能的消耗。比如,一旦用户不看网页,下面这些网页行为都是可以暂停的。
(1)对服务器的轮询 (2)网页动画 (3)正在播放的音频或视频
# <img>
的 title 和 alt 有什么区别?
title 通常当鼠标滑动到元素上的时候显示
alt 是 <img>
的特有属性,是图片内容的等价描述,用于图片无法加载时显示、读屏器阅读图片。可提图片高可访问性,除了纯装饰图片外都必须设置有意义的值,搜索引擎会重点分析。
# Canvas 和 SVG 有什么区别?
Canvas 是一种通过 JavaScript 来绘制 2D 图形的方法。Canvas 是逐像素来进行渲染的,因此当我们对 Canvas 进行缩放时,会出现锯齿或者失真的情况。
SVG 是一种使用 XML 描述 2D 图形的语言。SVG 基于 XML,这意味着 SVG DOM 中的每个元素都是可用的。我们可以为某个元素附加 JavaScript 事件监听函数。并且 SVG 保存的是图形的绘制方法,因此当 SVG 图形缩放时并不会失真。
# attribute 和 property 的区别是什么?
attribute 是 dom 元素在文档中作为 html 标签拥有的属性;
property 就是 dom 元素在 js 中作为对象拥有的属性。
对于 html 的标准属性来说,attribute 和 property 是同步的,是会自动更新的,但是对于自定义的属性来说,他们是不同步的。
# Flash、Ajax 各自的优缺点,在使用中如何取舍?
Flash: (1) Flash 适合处理多媒体、矢量图形、访问机器 (2) 对 CSS、处理文本上不足,不容易被搜索
Ajax: (1) Ajax 对 CSS、文本支持很好,支持搜索 (2) 多媒体、矢量图形、机器访问不足
共同点: (1) 与服务器的无刷新传递消息 (2) 可以检测用户离线和在线状态 (3) 操作 DOM
# 浏览器架构
- 用户界面
- 主进程
- 内核
- 渲染引擎
- JS 引擎
- 执行栈
- 事件触发线程
- 消息队列
- 微任务
- 宏任务
- 消息队列
- 网络异步线程
- 定时器线程
# 用于预格式化文本的标签是?
预格式化就是保留文字在源码中的格式 最后显示出来样式与源码中的样式一致 所见即所得。
<pre>
定义预格式文本,保持文本原有的格式
# 前端性能优化?
前端性能优化主要是为了提高页面的加载速度,优化用户的访问体验。我认为可以从这些方面来进行优化。
第一个方面是页面的内容方面
(1)通过文件合并、css 雪碧图、使用 base64 等方式来减少 HTTP 请求数,避免过多的请求造成等待的情况。
(2)通过 DNS 缓存等机制来减少 DNS 的查询次数。
(3)通过设置缓存策略,对常用不变的资源进行缓存。
(4)使用延迟加载的方式,来减少页面首屏加载时需要请求的资源。延迟加载的资源当用户需要访问时,再去请求加载。
(5)通过用户行为,对某些资源使用预加载的方式,来提高用户需要访问资源时的响应速度。
第二个方面是服务器方面
(1)使用 CDN 服务,来提高用户对于资源请求时的响应速度。
(2)服务器端启用 Gzip、Deflate 等方式对于传输的资源进行压缩,减小文件的体积。
(3)尽可能减小 cookie 的大小,并且通过将静态资源分配到其他域名下,来避免对静态资源请求时携带不必要的 cookie
第三个方面是 CSS 和 JavaScript 方面
(1)把样式表放在页面的 head 标签中,减少页面的首次渲染的时间。
(2)避免使用 @import 标签。
(3)尽量把 js 脚本放在页面底部或者使用 defer 或 async 属性,避免脚本的加载和执行阻塞页面的渲染。
(4)通过对 JavaScript 和 CSS 的文件进行压缩,来减小文件的体积。
# 扫描二维码登录网页是什么原理,前后两个事件是如何联系的?
核心过程应该是:浏览器获得一个临时 id,通过长连接等待客户端扫描带有此 id 的二维码后,从长连接中获得客户端上报给 server 的帐号信息进行展示。并在客户端点击确认后,获得服务器授信的令牌,进行随后的信息交互过程。在超时、网络断开、其他设备上登录后,此前获得的令牌或丢失、或失效,对授权过程形成有效的安全防护。
我的理解
二维码登录网页的基本原理是,用户进入登录网页后,服务器生成一个 uid 来标识一个用户。对应的二维码对应了一个对应 uid 的链接,任何能够识别二维码的应用都可以获得这个链接,但是它们没有办法和对应登录的服务器响应。比如微信的二维码登录,只有用微信识这个二维码才有效。当微信客户端打开这个链接时,对应的登录服务器就获得了用户的相关信息。这个时候登录网页根据先前的长连接获取到服务器传过来的用户信息进行显示。然后提前预加载一些登录后可能用到的信息。当客户端点击确认授权登陆后,服务器生成一个权限令牌给网页,网页之后使用这个令牌进行信息的交互过程。由于整个授权的过程都是在手机端进行的,因此能够很好的防止 PC 上泛滥的病毒。并且在超时、网络断开、其他设备上登录后,此前获得的令牌或丢失、或失效,对授权过程能够形成有效的安全防护。
# Html 规范中为什么要求引用资源不加协议头http
或者https
?
如果用户当前访问的页面是通过 HTTPS 协议来浏览的,那么网页中的资源也只能通过 HTTPS 协议来引用,否则浏览器会出现警告信息,不同浏览器警告信息展现形式不同。
为了解决这个问题,我们可以省略 URL 的协议声明,省略后浏览器照样可以正常引用相应的资源,这项解决方案称为 protocol-relative URL,暂且可译作协议相对 URL。
如果使用协议相对 URL,无论是使用 HTTPS,还是 HTTP 访问页面,浏览器都会以相同的协议请求页面中的资源,避免弹出类似的警告信息,同时还可以节省 5 字节的数据量。
示例:
// 在HTML中,如果想引用图片,通常会使用类似以下的代码:
<img src="https://www.ludou.org/logo.png" alt="" />
// 改成协议相对URL
<img src="//www.ludou.org/logo.png" alt="" />
2
3
4
5
# 关于伪类 LVHA 的解释?
a 标签有四种状态:链接访问前、链接访问后、鼠标滑过、激活,分别对应四种伪类:link、:visited、:hover、:active;
当链接未访问过时:
(1)当鼠标滑过 a 链接时,满足:link 和:hover 两种状态,要改变 a 标签的颜色,就必须将:hover 伪类在:link 伪类后面声明;(2)当鼠标点击激活 a 链接时,同时满足:link、:hover、:active 三种状态,要显示 a 标签激活时的样式(:active),必须将:active 声明放到:link 和:hover 之后。因此得出 LVHA 这个顺序。
当链接访问过时,情况基本同上,只不过需要将:link 换成:visited。
这个顺序能不能变?可以,但也只有:link 和:visited 可以交换位置,因为一个链接要么访问过要么没访问过,不可能同时满足,也就不存在覆盖的问题。
# 经常遇到的浏览器的兼容性有哪些?原因,解决方法是什么,常用 hack 的技巧?
(1)png24 位的图片在 iE6 浏览器上出现背景
解决方案:做成 PNG8,也可以引用一段脚本处理。
(2)浏览器默认的 margin 和 padding 不同
解决方案:加一个全局的*{margin:0;padding:0;}
来统一。
(3)IE6 双边距 bug:在 IE6 下,如果对元素设置了浮动,同时又设置了 margin-left 或 margin-right,margin 值会加倍。
#box {
float: left;
width: 10px;
margin: 0 0 0 10px;
}
2
3
4
5
这种情况之下 IE 会产生 20px 的距离
解决方案:在 float 的标签样式控制中加入*display:inline;将其转化为行内属性。(*这个符号只有 ie6 会识别)
(4)渐进识别的方式,从总体中逐渐排除局部。
首先,巧妙的使用"\9"
这一标记,将 IE 游览器从所有情况中分离出来。
接着,再次使用"+"
将 IE8 和 IE7、IE6 分离开来,这样 IE8 已经独立识别。
.bb {
background-color: #f1ee18; /*所有识别*/
.background-color: #00deff\9; /*IE6、7、8识别*/
+background-color: #a200ff; /*IE6、7识别*/
_background-color: #1e0bd1; /*IE6识别*/
}
2
3
4
5
6
(5)IE 下,可以使用获取常规属性的方法来获取自定义属性,也可以使用 getAttribute()获取自定义属性;Firefox 下,只能使用 getAttribute()获取自定义属性
解决方法:统一通过 getAttribute()获取自定义属性。
(6)IE 下,event 对象有 x、y 属性,但是没有 pageX、pageY 属性;Firefox 下,event 对象有 pageX、pageY 属性,但是没有 x、y 属性。
解决方法:(条件注释)缺点是在 IE 浏览器下可能会增加额外的 HTTP 请求数。
(7)Chrome 中文界面下默认会将小于 12px 的文本强制按照 12px 显示
解决方法:
1.可通过加入 CSS 属性-webkit-text-size-adjust:none;
解决。但是,在 chrome 更新到 27 版本之后就不可以用了。
2.还可以使用-webkit-transform:scale(0.5);
注意-webkit-transform:scale(0.75);
收缩的是整个 span 的大小,这时候,必须要将 span 转换成块元素,可以使用display:block/inline-block/...;
(8)超链接访问过后 hover 样式就不出现了,被点击访问过的超链接样式不再具有 hover 和 active 了
解决方法:改变 CSS 属性的排列顺序 L-V-H-A
(9)怪异模式问题:漏写 DTD 声明,Firefox 仍然会按照标准模式来解析网页,但在 IE 中会触发怪异模式。为避免怪异模式给我们带来不必要的麻烦,最好养成书写 DTD 声明的好习惯。
# li 与 li 之间有看不见的空白间隔是什么原因引起的?有什么解决办法?
浏览器会把 inline 元素间的空白字符(空格、换行、Tab 等)渲染成一个空格。而为了美观。我们通常是一个<li>
放在一行,这导致<li>
换行后产生换行字符,它变成一个空格,占用了一个字符的宽度。
解决办法:
(1)为<li>
设置 float:left。不足:有些容器是不能设置浮动,如左右切换的焦点图等。
(2)将所有<li>
写在同一行。不足:代码不美观。
(3)将<ul>
内的字符尺寸直接设为 0,即 font-size:0。不足:<ul>
中的其他字符尺寸也被设为 0,需要额外重新设定其他字符尺寸,且在 Safari 浏览器依然会出现空白间隔。
(4)消除<ul>
的字符间隔letter-spacing:-8px
,不足:这也设置了<li>
内的字符间隔,因此需要将<li>
内的字符间隔设为默认 letter-spacing:normal。
# CSS 里的 visibility 属性有个 collapse 属性值是干嘛用的?在不同浏览器下以后什么区别?
(1)对于一般的元素,它的表现跟 visibility:hidden;是一样的。元素是不可见的,但此时仍占用页面空间。
(2)但例外的是,如果这个元素是 table 相关的元素,例如 table 行,table group,table 列,table column group,它的表现却跟 display:none 一样,也就是说,它们占用的空间也会释放。
在不同浏览器下的区别:
在谷歌浏览器里,使用 collapse 值和使用 hidden 值没有什么区别。
在火狐浏览器、Opera 和 IE11 里,使用 collapse 值的效果就如它的字面意思:table 的行会消失,它的下面一行会补充它的位置。
# 简单介绍使用图片 base64 编码的优点和缺点。
base64 编码是一种图片处理格式,通过特定的算法将图片编码成一长串字符串,在页面上显示的时候,可以用该字符串来代替图片的 url 属性。
使用 base64 的优点是:
(1)减少一个图片的 HTTP 请求
使用 base64 的缺点是:
(1)根据 base64 的编码原理,编码后的大小会比原文件大小大 1/3,如果把大图片编码到 html/css 中,不仅会造成文件体积的增加,影响文件的加载速度,还会增加浏览器对 html 或 css 文件解析渲染的时间。
(2)使用 base64 无法直接缓存,要缓存只能缓存包含 base64 的文件,比如 HTML 或者 CSS,这相比域直接缓存图片的效果要差很多。
(3)兼容性的问题,ie8 以前的浏览器不支持。
一般一些网站的小图标可以使用 base64 图片来引入。
# 对 BFC 规范(块级格式化上下文:block formatting context)的理解?
块格式化上下文(Block Formatting Context,BFC)是 Web 页面的可视化 CSS 渲染的一部分,是布局过程中生成块级盒子的区域,也是浮动元素与其他元素的交互限定区域。
通俗来讲
- BFC 是一个独立的布局环境,可以理解为一个容器,在这个容器中按照一定规则进行物品摆放,并且不会影响其它环境中的物品。
- 如果一个元素符合触发 BFC 的条件,则 BFC 中的元素布局不受外部影响。
创建 BFC
(1)根元素或包含根元素的元素(2)浮动元素 float = left|right 或 inherit(≠none)(3)绝对定位元素 position = absolute 或 fixed (4)display = inline-block|flex|inline-flex|table-cell 或 table-caption (5)overflow = hidden|auto 或 scroll(≠visible)
回答:
BFC 指的是块级格式化上下文,一个元素形成了 BFC 之后,那么它内部元素产生的布局不会影响到外部元素,外部元素的布局也不会影响到 BFC 中的内部元素。一个 BFC 就像是一个隔离区域,和其他区域互不影响。
一般来说根元素是一个 BFC 区域,浮动和绝对定位的元素也会形成 BFC,display 属性的值为 inline-block、flex 这些属性时也会创建 BFC。还有就是元素的 overflow 的值不为 visible 时都会创建 BFC。
# CSS 优化、提高性能的方法有哪些?
加载性能:
(1)css 压缩:将写好的 css 进行打包压缩,可以减少很多的体积。(2)css 单一样式:当需要下边距和左边距的时候,很多时候选择:margin:top 0 bottom 0;
但margin-bottom:bottom;margin-left:left;
执行的效率更高。(3)减少使用@import,而建议使用 link,因为后者在页面加载时一起加载,前者是等待页面加载完成之后再进行加载。
选择器性能:
(1)关键选择器(key selector)。选择器的最后面的部分为关键选择器(即用来匹配目标元素的部分)。CSS 选择符是从右到左进行匹配的。当使用后代选择器的时候,浏览器会遍历所有子元素来确定是否是指定的元素等等;
(2)如果规则拥有 ID 选择器作为其关键选择器,则不要为规则增加标签。过滤掉无关的规则(这样样式系统就不会浪费时间去匹配它们了)。
(3)避免使用通配规则,如*{}计算次数惊人!只对需要用到的元素进行选择。
(4)尽量少的去对标签进行选择,而是用 class。
(5)尽量少的去使用后代选择器,降低选择器的权重值。后代选择器的开销是最高的,尽量将选择器的深度降到最低,最高不要超过三层,更多的使用类来关联每一个标签元素。
(6)了解哪些属性是可以通过继承而来的,然后避免对这些属性重复指定规则。
渲染性能:
(1)慎重使用高性能属性:浮动、定位。
(2)尽量减少页面重排、重绘。
(3)去除空规则:{}。空规则的产生原因一般来说是为了预留样式。去除这些空规则无疑能减少 css 文档体积。
(4)属性值为 0 时,不加单位。
(5)属性值为浮动小数 0.**,可以省略小数点之前的 0。
(6)标准化各种浏览器前缀:带浏览器前缀的在前。标准属性在后。
(7)不使用@import 前缀,它会影响 css 的加载速度。
(8)选择器优化嵌套,尽量避免层级过深。
(9)css 雪碧图,同一页面相近部分的小图标,方便使用,减少页面的请求次数,但是同时图片本身会变大,使用时,优劣考虑清楚,再使用。
(10)正确使用 display 的属性,由于 display 的作用,某些样式组合会无效,徒增样式体积的同时也影响解析性能。
(11)不滥用 web 字体。对于中文网站来说 WebFonts 可能很陌生,国外却很流行。web fonts 通常体积庞大,而且一些浏览器在下载 web fonts 时会阻塞页面渲染
损伤性能。
可维护性、健壮性:
(1)将具有相同属性的样式抽离出来,整合并通过 class 在页面中进行使用,提高 css 的可维护性。
(2)样式与内容分离:将 css 代码定义到外部 css 中。
# 在网页中应该使用奇数还是偶数的字体?为什么呢?
(1)偶数字号相对更容易和 web 设计的其他部分构成比例关系。比如:当我用了 14px 的正文字号,我可能会在一些地方用 14×0.5=7px 的 margin,在另一些地方用 14×1.5=21px 的标题字号。
(2)浏览器缘故,低版本的浏览器 ie6 会把奇数字体强制转化为偶数,即 13px 渲染为 14px。
(3)系统差别,早期的 Windows 里,中易宋体点阵只有 12 和 14、15、16px,唯独缺少 13px。
# 元素竖向的百分比设定是相对于容器的高度吗?
如果是 height 的话,是相对于包含块的高度。
如果是 padding 或者 margin 竖直方向的属性则是相对于包含块的宽度。
# 如何修改 chrome 记住密码后自动填充表单的黄色背景?
chrome 表单自动填充后,input 文本框的背景会变成黄色的,通过审查元素可以看到这是由于 chrome 会默认给自动填充的 input 表单加上 input:-webkit-autofill 私有属性,然后对其赋予以下样式:
{
background-color: rgb(250, 255, 189) !important;
background-image: none !important;
color: rgb(0, 0, 0) !important;
}
2
3
4
5
对 chrome 默认定义的 background-color,background-image,color 使用 important 是不能提高其优先级的,但是其他属性可使用。
使用足够大的纯色内阴影来覆盖 input 输入框的黄色背景,处理如下
input:-webkit-autofill,
textarea:-webkit-autofill,
select:-webkit-autofill {
-webkit-box-shadow: 000px 1000px white inset;
border: 1px solid #ccc !important;
}
2
3
4
5
6
# 怎么让 Chrome 支持小于 12px 的文字?
在谷歌下 css 设置字体大小为 12px 及以下时,显示都是一样大小,都是默认 12px。
解决办法:
(1)可以使用 Webkit 的内核的-webkit-text-size-adjust 的私有 CSS 属性来解决,只要加了-webkit-text-size-adjust:none;字体大小就不受限制了。但是 chrome 更
新到 27 版本之后就不可以用了。所以高版本 chrome 谷歌浏览器已经不再支持-webkit-text-size-adjust 样式,所以要使用时候慎用。
(2)还可以使用 css3 的 transform 缩放属性-webkit-transform:scale(0.5);
注意-webkit-transform:scale(0.75);
收缩的是整个元素的大小,这时候,如果是内联元素,必须要将内联元素转换成块元素,可以使用display:block/inline-block/...;
(3)使用图片:如果是内容固定不变情况下,使用将小于 12px 文字内容切出做图片,这样不影响兼容也不影响美观。
# 让页面里的字体变清晰,变细用 CSS 怎么做?
webkit 内核的私有属性:-webkit-font-smoothing
,用于字体抗锯齿,使用后字体看起来会更清晰舒服。
在 MacOS 测试环境下面设置-webkit-font-smoothing:antialiased
;但是这个属性仅仅是面向 MacOS,其他操作系统设置后无效。
# 设备像素、css 像素、设备独立像素、dpr、ppi 之间的区别?
设备像素指的是物理像素,一般手机的分辨率指的就是设备像素,一个设备的设备像素是不可变的。
css 像素和设备独立像素是等价的,不管在何种分辨率的设备上,css 像素的大小应该是一致的,css 像素是一个相对单位,它是相对于设备像素的,一个 css 像素的大小取决于页面缩放程度和 dpr 的大小。
dpr 指的是设备像素和设备独立像素的比值,一般的 pc 屏幕,dpr=1。在 iphone4 时,苹果推出了 retina 屏幕,它的 dpr 为 2。屏幕的缩放会改变 dpr 的值。
ppi 指的是每英寸的物理像素的密度,ppi 越大,屏幕的分辨率越大。
# layout viewport、visual viewport 和 ideal viewport 的区别?
如果把移动设备上浏览器的可视区域设为 viewport 的话,某些网站就会因为 viewport 太窄而显示错乱,所以这些浏览器就决定默认情况下把 viewport 设为一个较宽的值,比如 980px,这样的话即使是那些为桌面设计的网站也能在移动浏览器上正常显示了。ppk 把这个浏览器默认的 viewport 叫做 layout viewport。
layout viewport 的宽度是大于浏览器可视区域的宽度的,所以我们还需要一个 viewport 来代表浏览器可视区域的大小,ppk 把这个 viewport 叫做 visual viewport。
ideal viewport 是最适合移动设备的 viewport,ideal viewport 的宽度等于移动设备的屏幕宽度,只要在 css 中把某一元素的宽度设为 ideal viewport 的宽度(单位用 px),那么这个元素的宽度就是设备屏幕的宽度了,也就是宽度为 100%的效果。ideal viewport 的意义在于,无论在何种分辨率的屏幕下,那些针对 ideal viewport 而设计的网站,不需要用户手动缩放,也不需要出现横向滚动条,都可以完美的呈现给用户。
回答:
移动端一共需要理解三个 viewport 的概念的理解。
第一个视口是布局视口,在移动端显示网页时,由于移动端的屏幕尺寸比较小,如果网页使用移动端的屏幕尺寸进行布局的话,那么整个页面的布局都会显示错乱。所以移动端浏览器提供了一个 layout viewport 布局视口的概念,使用这个视口来对页面进行布局展示,一般 layout viewport 的大小为 980px,因此页面布局不会有太大的变化,我们可以通过拖动和缩放来查看到这个页面。
第二个视口指的是视觉视口,visual viewport 指的是移动设备上我们可见的区域的视口大小,一般为屏幕的分辨率的大小。visual viewport 和 layout viewport 的关系,就像是我们通过窗户看外面的风景,视觉视口就是窗户,而外面的风景就是布局视口中的网页内容。
第三个视口是理想视口,由于 layout viewport 一般比 visual viewport 要大,所以想要看到整个页面必须通过拖动和缩放才能实现。所以又提出了 ideal viewport 的概念,ideal viewport 下用户不用缩放和滚动条就能够查看到整个页面,并且页面在不同分辨率下显示的内容大小相同。ideal viewport 其实就是通过修改 layout viewport 的大小,让它等于设备的宽度,这个宽度可以理解为是设备独立像素,因此根据 ideal viewport 设计的页面,在不同分辨率的屏幕下,显示应该相同。
# position:fixed;在 android 下无效怎么处理?
因为移动端浏览器默认的 viewport 叫做 layout viewport。在移动端显示时,因为 layout viewport 的宽度大于移动端屏幕的宽度,所以页面会出现滚动条左右移动,fixed 的元素是相对 layout viewport 来固定位置的,而不是移动端屏幕来固定位置的,所以会出现感觉 fixed 无效的情况。
如果想实现 fixed 相对于屏幕的固定效果,我们需要改变的是 viewport 的大小为 ideal viewport,可以如下设置:
<metaname="viewport"content="width=device-width,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0,user-scalable=no"/>
# 如果需要手动写动画,你认为最小时间间隔是多久,为什么?(阿里)
多数显示器默认频率是 60Hz,即 1 秒刷新 60 次,所以理论上最小间隔为1/60*1000ms=16.7ms
# 有一个高度自适应的 div,里面有两个 div,一个高度 100px,希望另一个填满剩下的高度。
/*方案一*/
// 父元素padding-top撑开100px空间,子元素A设置margin负值100px,子元素B设置height为100%(父元素的content高度)
.outer {
height: 100%;
padding: 100px 0 0;
box-sizing: border-box;
}
.A {
height: 100px;
margin: -100px 0 0;
background: #bbe8f2;
}
.B {
height: 100%;
background: #d9c666;
}
/*方案二*/
// 父元素padding-top撑开100px空间,子元素A设置绝对定位到顶部,子元素B设置height为100%(父元素的content高度)
.outer {
height: 100%;
padding: 100px 0 0;
box-sizing: border-box;
position: relative;
}
.A {
height: 100px;
background: #bbe8f2;
position: absolute;
top: 0;
left: 0;
width: 100%;
}
.B {
height: 100%;
background: #d9c666;
}
/*方案三*/
// 父元素设置相对定位,子元素B设置绝对定位,top设置为100px,高度自动填充
.outer {
height: 100%;
position: relative;
}
.A {
height: 100px;
background: #bbe8f2;
}
.B {
background: #d9c666;
width: 100%;
position: absolute;
top: 100px;
left: 0;
bottom: 0;
}
/*方案四*/
// 子元素B设置height为calc即可
.outer {
height: 100%;
}
.A {
height: 100px;
background: #bbe8f2;
}
.B {
height: calc(100% - 100px);
background: #d9c666;
}
/*方案五*/
// 父元素设置flex定位,排列方向为竖直,子元素B设置flex-grow为1
.outer {
height: 100%;
display: flex;
flex-direction: column;
}
.A {
height: 100px;
background: #bbe8f2;
}
.B {
flex: 1;
background: #d9c666;
}
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# png、jpg、gif 这些图片格式解释一下,分别什么时候用。有没有了解过 webp?
(1)BMP,是无损的、既支持索引色也支持直接色的、点阵图。这种图片格式几乎没有对数据进行压缩,所以 BMP 格式的图片通常具有较大的文件大小。
(2)GIF 是无损的、采用索引色的、点阵图。采用 LZW 压缩算法进行编码。文件小,是 GIF 格式的优点,同时,GIF 格式还具有支持动画以及透明的优点。但,GIF 格式仅支持 8bit 的索引色,所以 GIF 格式适用于对色彩要求不高同时需要文件体积较小的场景。
(3)JPEG 是有损的、采用直接色的、点阵图。JPEG 的图片的优点,是采用了直接色,得益于更丰富的色彩,JPEG 非常适合用来存储照片,与 GIF 相比,JPEG 不适合用来存储企业 Logo、线框类的图。因为有损压缩会导致图片模糊,而直接色的选用,又会导致图片文件较 GIF 更大。
(4)PNG-8 是无损的、使用索引色的、点阵图。PNG 是一种比较新的图片格式,PNG-8 是非常好的 GIF 格式替代者,在可能的情况下,应该尽可能的使用 PNG-8 而不是 GIF,因为在相同的图片效果下,PNG-8 具有更小的文件体积。除此之外,PNG-8 还支持透明度的调节,而 GIF 并不支持。现在,除非需要动画的支持,否则我们没有理由使用 GIF 而不是 PNG-8。
(5)PNG-24 是无损的、使用直接色的、点阵图。PNG-24 的优点在于,它压缩了图片的数据,使得同样效果的图片,PNG-24 格式的文件大小要比 BMP 小得多。当然,PNG24 的图片还是要比 JPEG、GIF、PNG-8 大得多。
(6)SVG 是无损的、矢量图。SVG 是矢量图。这意味着 SVG 图片由直线和曲线以及绘制它们的方法组成。当你放大一个 SVG 图片的时候,你看到的还是线和曲线,而不会出现像素点。这意味着 SVG 图片在放大时,不会失真,所以它非常适合用来绘制企业 Logo、Icon 等。
(7)WebP 是谷歌开发的一种新图片格式,WebP 是同时支持有损和无损压缩的、使用直接色的、点阵图。从名字就可以看出来它是为 Web 而生的,什么叫为 Web 而生呢?就是说相同质量的图片,WebP 具有更小的文件体积。现在网站上充满了大量的图片,如果能够降低每一个图片的文件大小,那么将大大减少浏览器和服务器之间的数据传输量,进而降低访问延迟,提升访问体验。
- 在无损压缩的情况下,相同质量的 WebP 图片,文件大小要比 PNG 小 26%;
- 在有损压缩的情况下,具有相同图片精度的 WebP 图片,文件大小要比 JPEG 小 25%~34%;
- WebP 图片格式支持图片透明度,一个无损压缩的 WebP 图片,如果要支持透明度只需要 22%的格外文件大小。
但是目前只有 Chrome 浏览器和 Opera 浏览器支持 WebP 格式,兼容性不太好。
回答:
我了解到的一共有七种常见的图片的格式。
(1)第一种是 BMP 格式,它是无损压缩的,支持索引色和直接色的点阵图。由于它基本上没有进行压缩,因此它的文件体积一般比较大。
(2)第二种是 GIF 格式,它是无损压缩的使用索引色的点阵图。由于使用了 LZW 压缩方法,因此文件的体积很小。并且 GIF 还支持动画和透明度。但因为它使用的是索引色,所以它适用于一些对颜色要求不高且需要文件体积小的场景。
(3)第三种是 JPEG 格式,它是有损压缩的使用直接色的点阵图。由于使用了直接色,色彩较为丰富,一般适用于来存储照片。但由于使用的是直接色,可能文件的体积相对于 GIF 格式来说更大。
(4)第四种是 PNG-8 格式,它是无损压缩的使用索引色的点阵图。它是 GIF 的一种很好的替代格式,它也支持透明度的调整,并且文件的体积相对于 GIF 格式更小。一般来说如果不是需要动画的情况,我们都可以使用 PNG-8 格式代替 GIF 格式。
(5)第五种是 PNG-24 格式,它是无损压缩的使用直接色的点阵图。PNG-24 的优点是它使用了压缩算法,所以它的体积比 BMP 格式的文件要小得多,但是相对于其他的几种格式,还是要大一些。
(6)第六种格式是 svg 格式,它是矢量图,它记录的图片的绘制方式,因此对矢量图进行放大和缩小不会产生锯齿和失真。它一般适合于用来制作一些网站 logo 或者图标之类的图片。
(7)第七种格式是 webp 格式,它是支持有损和无损两种压缩方式的使用直接色的点阵图。使用 webp 格式的最大的优点是,在相同质量的文件下,它拥有更小的文件体积。因此它非常适合于网络图片的传输,因为图片体积的减少,意味着请求时间的减小,这样会提高用户的体验。这是谷歌开发的一种新的图片格式,目前在兼容性上还不是太好。
# 浏览器如何判断是否支持 webp 格式图片
(1)宽高判断法。通过创建 image 对象,将其 src 属性设置为 webp 格式的图片,然后在 onload 事件中获取图片的宽高,如果能够获取,则说明浏览器支持 webp 格式图片。如果不能获取或者触发了 onerror 函数,那么就说明浏览器不支持 webp 格式的图片。
(2)canvas 判断方法。我们可以动态的创建一个 canvas 对象,通过 canvas 的 toDataURL 将设置为 webp 格式,然后判断返回值中是否含有 image/webp 字段,如果包含则说明支持 WebP,反之则不支持。
# 什么是 Cookie 隔离?(或者说:请求资源的时候不要让它带 cookie 怎么做)
网站向服务器请求的时候,会自动带上 cookie 这样增加表头信息量,使请求变慢。
如果静态文件都放在主域名下,那静态文件请求的时候都带有的 cookie 的数据提交给 server 的,非常浪费流量,所以不如隔离开,静态资源放 CDN。
因为 cookie 有域的限制,因此不能跨域提交请求,故使用非主要域名的时候,请求头中就不会带有 cookie 数据,这样可以降低请求头的大小,降低请求时间,从而达到降低整体请求延时的目的。
同时这种方式不会将 cookie 传入 WebServer,也减少了 WebServer 对 cookie 的处理分析环节,提高了 webserver 的 http 请求的解析速度。
# 画一条 0.5px 的线
直接设置 0.5px,在不同的浏览器会有不同的表现
Chrome 把 0.5px 四舍五入变成了 1px,而 firefox/safari 能够画出半个像素的边,并且 Chrome 会把小于 0.5px 的当成 0,而 Firefox 会把不小于 0.55px 当成 1px,Safari 是把不小于 0.75px 当成 1px,进一步在手机上观察 IOS 的 Chrome 会画出 0.5px 的边,而安卓(5.0)原生浏览器是不行的
/*方法一*/
// 设置salce和transform-origin
.div {
height: 1px;
transform: scaleY(0.5);
transform-origin: 50% 100%;
}
/*方法二*/
// 使用background-image设置svg
.div {
background: none;
height: 1px;
// background: url("data:image/svg+xml;utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='100%' height='1px'><line x1='0' y1='0' x2='100%' y2='0' stroke='#000'></line></svg>")
// firefox的background-image如果是svg的话只支持命名的颜色,如"black"、"red"等,如果把上面代码的svg里面的#000改成black的话就可以显示出来,但是这样就很不灵活了。否则只能把svg转成base64的形式,我们把svg的内容转成base64
background: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHdpZHRoPScxMDAlJyBoZWlnaHQ9JzFweCc+PGxpbmUgeDE9JzAnIHkxPScwJyB4Mj0nMTAwJScgeTI9JzAnIHN0cm9rZT0nIzAwMCc+PC9saW5lPjwvc3ZnPg==");
}
/*方法三*/
// 控制viewport
// 在移端开发里面一般会把viewport的scale设置成1:
<meta name="viewport" content="width=device-width,initial-sacle=1">
// 其中width=device-width表示将viewport视窗的宽度调整为设备的宽度,这个宽度通常是指物理上宽度。默认的缩放比例为1,如iphone 6竖屏的宽度为750px,它的dpr=2,用2px表示1px,这样设置之后viewport的宽度就变成375px
// 可以把scale改成0.5:
<meta name="viewport" content="width=device-width,initial-sacle=0.5">
// 这样的话,viewport的宽度就是原本的750px,所以1个px还是1px,正常画就行,但这样也意味着UI需要按2倍图的出,整体页面的单位都会放大一倍
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
# 什么是首选最小宽度?
“首选最小宽度”,指的是元素最适合的最小宽度。
东亚文字(如中文)最小宽度为每个汉字的宽度。
西方文字最小宽度由特定的连续的英文字符单元决定。并不是所有的英文字符都会组成连续单元,一般会终止于空格(普通空格)、短横线、问号以及其他非英文字符等。
如果想让英文字符和中文一样,每一个字符都用最小宽度单元,可以试试使用 CSS 中的 word-break:break-all。
# 什么是替换元素?
通过修改某个属性值呈现的内容就可以被替换的元素就称为“替换元素”。因此,<img>
、<object>
、<video>
、<iframe>
或者表单元素<textarea>
和<input>
和<select>
都是典型的替换元素。
替换元素除了内容可替换这一特性以外,还有以下一些特性。
(1)内容的外观不受页面上的 CSS 的影响。用专业的话讲就是在样式表现在 CSS 作用域之外。如何更改替换元素本身的外观需要类似 appearance 属性,或者浏览器自身暴露的一些样式接口,
(2)有自己的尺寸。在 Web 中,很多替换元素在没有明确尺寸设定的情况下,其默认的尺寸(不包括边框)是 300 像素 ×150 像素,如<video>
、<iframe>
或者<canvas>
等,也有少部分替换元素为 0 像素,如<img>
图片,而表单元素的替换元素的尺寸则和浏览器有关,没有明显的规律。
(3)在很多 CSS 属性上有自己的一套表现规则。比较具有代表性的就是 vertical-align 属性,对于替换元素和非替换元素,vertical-align 属性值的解释是不一样的。比方说 vertical-align 的默认值的 baseline,很简单的属性值,基线之意,被定义为字符 x 的下边缘,而替换元素的基线却被硬生生定义成了元素的下边缘。
(4)所有的替换元素都是内联水平元素,也就是替换元素和替换元素、替换元素和文字都是可以在一行显示的。但是,替换元素默认的 display 值却是不一样的,有的是 inline,有的是 inline-block。
# 无依赖绝对定位是什么?
没有设置 left/top/right/bottom 属性值的绝对定位称为“无依赖绝对定位”。
无依赖绝对定位其定位的位置和没有设置 position:absolute 时候的位置相关。
# 什么是层叠上下文?
层叠上下文,英文称作 stacking context,是 HTML 中的一个三维的概念。如果一个元素含有层叠上下文,我们可以理解为这个元素在 z 轴上就“高人一等”。
层叠上下文元素有如下特性:
(1)层叠上下文的层叠水平要比普通元素高(原因后面会说明)。(2)层叠上下文可以阻断元素的混合模式。(3)层叠上下文可以嵌套,内部层叠上下文及其所有子元素均受制于外部的“层叠上下文”。(4)每个层叠上下文和兄弟元素独立,也就是说,当进行层叠变化或渲染的时候,只需要考虑后代元素。(5)每个层叠上下文是自成体系的,当元素发生层叠的时候,整个元素被认为是在父层叠上下文的层叠顺序中。
层叠上下文的创建:
(1)页面根元素天生具有层叠上下文,称为根层叠上下文。根层叠上下文指的是页面根元素,可以看成是<html>
元素。因此,页面中所有的元素一定处于至少一个“层叠结界”中。
(2)对于 position 值为 relative/absolute 以及 Firefox/IE 浏览器(不包括 Chrome 浏览器)下含有 position:fixed 声明的定位元素,当其 z-index 值不是 auto 的时候,会创建层叠上下文。Chrome 等 WebKit 内核浏览器下,position:fixed 元素天然层叠上下文元素,无须 z-index 为数值。根据我的测试,目前 IE 和 Firefox 仍是老套路。
(3)其他一些 CSS3 属性,比如元素的 opacity 值不是 1。
# 如何实现单行/多行文本溢出的省略(...)?
/*单行文本溢出*/
p {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
/*多行文本溢出*/
p {
position: relative;
line-height: 1.5em;
/*高度为需要显示的行数*行高,比如这里我们显示两行,则为3*/
height: 3em;
overflow: hidden;
}
p:after {
content: '...';
position: absolute;
bottom: 0;
right: 0;
background-color: #fff;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 常见的元素隐藏方式?
(1)使用 display:none;隐藏元素,渲染树不会包含该渲染对象,因此该元素不会在页面中占据位置,也不会响应绑定的监听事件。
(2)使用 visibility:hidden;隐藏元素。元素在页面中仍占据空间,但是不会响应绑定的监听事件。
(3)使用 opacity:0;将元素的透明度设置为 0,以此来实现元素的隐藏。元素在页面中仍然占据空间,并且能够响应元素绑定的监听事件。
(4)通过使用绝对定位将元素移除可视区域内,以此来实现元素的隐藏。
(5)通过 z-index 负值,来使其他元素遮盖住该元素,以此来实现隐藏。
(6)通过 clip/clip-path 元素裁剪的方法来实现元素的隐藏,这种方法下,元素仍在页面中占据位置,但是不会响应绑定的监听事件。
(7)通过 transform:scale(0,0)来将元素缩放为 0,以此来实现元素的隐藏。这种方法下,元素仍在页面中占据位置,但是不会响应绑定的监听事件。
# css 实现上下固定中间自适应布局?
/* 利用绝对定位实现 */
body {
padding: 0;
margin: 0;
}
.header {
position: absolute;
top: 0;
width: 100%;
height: 100px;
background: red;
}
.container {
position: absolute;
top: 100px;
bottom: 100px;
width: 100%;
background: green;
}
.footer {
position: absolute;
bottom: 0;
height: 100px;
width: 100%;
background: red;
}
/* 利用flex布局实现html,*/
body {
height: 100%;
}
body {
display: flex;
padding: 0;
margin: 0;
flex-direction: column;
}
.header {
height: 100px;
background: red;
}
.container {
flex-grow: 1;
background: green;
}
.footer {
height: 100px;
background: red;
}
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# css 两栏布局的实现?
/*两栏布局一般指的是页面中一共两栏,左边固定,右边自适应的布局,一共有四种实现的方式。*/
/*以左边宽度固定为200px为例*/
/*(1)利用浮动,将左边元素宽度设置为200px,并且设置向左浮动。将右边元素的margin-left设置为200px,宽度设置为auto(默认为auto,撑满整个父元素)。*/
.outer {
height: 100px;
}
.left {
float: left;
height: 100px;
width: 200px;
background: tomato;
}
.right {
margin-left: 200px;
width: auto;
height: 100px;
background: gold;
}
/*(2)第二种是利用flex布局,将左边元素的放大和缩小比例设置为0,基础大小设置为200px。将右边的元素的放大比例设置为1,缩小比例设置为1,基础大小设置为auto。*/
.outer {
display: flex;
height: 100px;
}
.left {
flex-shrink: 0;
flex-grow: 0;
flex-basis: 200px;
background: tomato;
}
.right {
flex: auto;
/*11auto*/
background: gold;
}
/*(3)第三种是利用绝对定位布局的方式,将父级元素设置相对定位。左边元素设置为absolute定位,并且宽度设置为200px。将右边元素的margin-left的值设置为200px。*/
.outer {
position: relative;
height: 100px;
}
.left {
position: absolute;
width: 200px;
height: 100px;
background: tomato;
}
.right {
margin-left: 200px;
height: 100px;
background: gold;
}
/*(4)第四种还是利用绝对定位的方式,将父级元素设置为相对定位。左边元素宽度设置为200px,右边元素设置为绝对定位,左边定位为200px,其余方向定位为0。*/
.outer {
position: relative;
height: 100px;
}
.left {
width: 200px;
height: 100px;
background: tomato;
}
.right {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 200px;
background: gold;
}
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# css 三栏布局的实现?
/*三栏布局一般指的是页面中一共有三栏,左右两栏宽度固定,中间自适应的布局,一共有五种实现方式。
这里以左边宽度固定为100px,右边宽度固定为200px为例。*/
/*(1)利用绝对定位的方式,左右两栏设置为绝对定位,中间设置对应方向大小的margin的值。*/
.outer {
position: relative;
height: 100px;
}
.left {
position: absolute;
width: 100px;
height: 100px;
background: tomato;
}
.right {
position: absolute;
top: 0;
right: 0;
width: 200px;
height: 100px;
background: gold;
}
.center {
margin-left: 100px;
margin-right: 200px;
height: 100px;
background: lightgreen;
}
/*(2)利用flex布局的方式,左右两栏的放大和缩小比例都设置为0,基础大小设置为固定的大小,中间一栏设置为auto*/
.outer {
display: flex;
height: 100px;
}
.left {
flex: 0 0 100px;
background: tomato;
}
.right {
flex: 0 0 200px;
background: gold;
}
.center {
flex: auto;
background: lightgreen;
}
/*(3)利用浮动的方式,左右两栏设置固定大小,并设置对应方向的浮动。中间一栏设置左右两个方向的margin值,注意这种方式,中间一栏必须放到最后。*/
.outer {
height: 100px;
}
.left {
float: left;
width: 100px;
height: 100px;
background: tomato;
}
.right {
float: right;
width: 200px;
height: 100px;
background: gold;
}
.center {
height: 100px;
margin-left: 100px;
margin-right: 200px;
background: lightgreen;
}
/*(4)圣杯布局,利用浮动和负边距来实现。父级元素设置左右的 padding,三列均设置向左浮动,中间一列放在最前面,宽度设置为父级元素的宽度,因此后面两列都被挤到了下一行,通过设置 margin 负值将其移动到上一行,再利用相对定位,定位到两边。*/
.outer {
height: 100px;
padding-left: 100px;
padding-right: 200px;
}
.left {
position: relative;
left: -100px;
float: left;
margin-left: -100%;
width: 100px;
height: 100px;
background: tomato;
}
.right {
position: relative;
left: 200px;
float: right;
margin-left: -200px;
width: 200px;
height: 100px;
background: gold;
}
.center {
float: left;
width: 100%;
height: 100px;
background: lightgreen;
}
/*(5)双飞翼布局,双飞翼布局相对于圣杯布局来说,左右位置的保留是通过中间列的 margin 值来实现的,而不是通过父元素的 padding 来实现的。本质上来说,也是通过浮动和外边距负值来实现的。*/
.outer {
height: 100px;
}
.left {
float: left;
margin-left: -100%;
width: 100px;
height: 100px;
background: tomato;
}
.right {
float: left;
margin-left: -200px;
width: 200px;
height: 100px;
background: gold;
}
.wrapper {
float: left;
width: 100%;
height: 100px;
background: lightgreen;
}
.center {
margin-left: 100px;
margin-right: 200px;
height: 100px;
}
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# 实现一个宽高自适应的正方形
/*1.第一种方式是利用vw来实现*/
.square {
width: 10%;
height: 10vw;
background: tomato;
}
/*2.第二种方式是利用元素的margin/padding百分比是相对父元素width的性质来实现*/
.square {
width: 20%;
height: 0;
padding-top: 20%;
background: orange;
}
/*3.第三种方式是利用子元素的margin-top的值来实现的*/
.square {
width: 30%;
overflow: hidden;
background: yellow;
}
.square::after {
content: '';
display: block;
margin-top: 100%;
}
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
# 实现一个三角形
/*三角形的实现原理是利用了元素边框连接处的等分原理。*/
.triangle {
width: 0;
height: 0;
border-width: 100px;
border-style: solid;
border-color: tomato transparent transparent transparent;
}
2
3
4
5
6
7
8
# 一个自适应矩形,水平垂直居中,且宽高比为 2:1
/*实现原理参考自适应正方形和水平居中方式*/
.box {
position: absolute;
top: 0;
right: 0;
left: 0;
bottom: 0;
margin: auto;
width: 10%;
height: 0;
padding-top: 20%;
background: tomato;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
# 已知如下代码,如何修改才能让图片宽度为 300px ?注意下面代码不可修改
<img src="1.jpg" style="width:480px!important;”>
设置max-width: 300px
即可
# 如何用 css 或 js 实现多行文本溢出省略效果,考虑兼容性
单行
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
2
3
多行
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3; //行数
overflow: hidden;
2
3
4
兼容
p {
position: relative;
line-height: 20px;
max-height: 40px;
overflow: hidden;
}
p::after {
content: '...';
position: absolute;
bottom: 0;
right: 0;
padding-left: 40px;
background: -webkit-linear-gradient(left, transparent, #fff 55%);
background: -o-linear-gradient(right, transparent, #fff 55%);
background: -moz-linear-gradient(right, transparent, #fff 55%);
background: linear-gradient(to right, transparent, #fff 55%);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
← 雷达图