- A+
一,面试基础 HTML和CSS
ps:这俩面试答不上来的,基本就可以回去了,以下是HTML题,一般来说这地方不会出太多题,面试官也不愿意花太多时间在这上面。
1,HTML语义化,如何理解语义化?
让人更容易懂(增加代码的可读性)
让搜索引擎更容易懂,有利于爬虫抓取
在没有css的情况下,页面也能更好的展现出其内容结构,代码·结构
2,script 标签中 defer 和 async 的区别?
script:会阻碍HTML解析,只有下载好并执行完脚本才会继续解析HTML
async:解析HTML的过程中会异步下载脚本,下载成功后立即执行,可能会阻断HTML的解析
defer:完全不会阻断HTML解析,解析完成之后在按顺序执行脚本
图解 script 标签中的 async 和 defer 属性
3,从浏览器地址栏输入 url 到请求返回发生了什么
3.1,输入url之后,会解析出主机,端口,路径,协议等信息,构造一个HTTP请求
3.2,DNS域名解析
3.3,TCP链接,http请求
3.4,服务器处理请求并返回HTTP报文
3.5,浏览器渲染(HTML解析,css解析,js解析,render树)
从上到下依次阅读
4,HTTP和HTTPS的区别
http:
-
-
- 不安全
- 协议对客户端没有状态存储【没有状态】
- 每次请求需要TCP三次握手四次挥手,和服务器重新建立连接【没有连接】
- 基本的特性,由客户端发起请求,服务端响应
- 简单快速、灵活
- 使用明文、请求和响应不进行确认
-
https:
-
-
- 安全
- HTTP安全版本,通过SSL或TLS提供加密处理数据、验证对方身份以及数据完整性保护
- 采用混合加密技术,传输过程无法直接查看明文内容【传输加密】
- 通过证书认证客户端访问的是自己的服务器【身份认证】
- 传输过程防止被篡改【数据完整】
-
ps:以下是css的面试题,打不出来的话可能会有非常不好的印象
5,css盒子模型的介绍
css3中盒子模型有两种,一种是W3C标准盒子模型,一种是IE盒子模型
两种盒子模型都是由content,margin,padding,border构成,其大小都是由content,padding,border决定的,但是盒子内容却有所不同:
-
-
- 标准盒模型:只包含
content
。 - IE(替代)盒模型:
content + padding + border
。
- 标准盒模型:只包含
-
可以通过 box-sizing
来改变元素的盒模型:
-
-
box-sizing: content-box
:标准盒模型(默认值)。box-sizing: border-box
:IE(替代)盒模型。
-
6,css选择器
选择器 | 权重 | 使用示例 |
---|---|---|
!important | 1111 | * {color: '#00f' !important} |
行内 | 1000 | <span style={color:'#00f'} /> |
id | 0100 | #id{color:'#00f} |
class | 0010 | .calssName{color:'#00f} |
标签 | 0001 | div{color:'#00f} |
子选择 | 0001 | div > span{color:'#00f} |
伪类 | 0001 | a:hover {color:'#00f}> |
优先级的计算规则:
相信每位写过CSS的朋友都知道,CSS选择器的优先级关系是: 内联 > ID选择器 > 类选择器 > 标签选择器
但是,浏览器具体的优先级算法是怎样的?可能还有些人不知道 。《CSS REFACTORING》 中提到了算法的过程
A specificity is determined by plugging numbers into (a, b, c, d): If the styles are applied via the style attribute, a=1; otherwise, a=0. b is equal to the number of ID selectors present. c is equal to the number of class selectors, attribute selectors, and pseudoclasses present. d is equal to the number of type selectors and pseudoelements present.
简单来说就是通过,A,B,C,D四个值来确定,具体的规则如下:
如果存在内联样式,那么 A = 1,否则 A = 0 ;
B 的值等于 ID选择器(#id) 出现的次数;
C 的值等于 类选择器(.class) 和 属性选择器(a[href="https://example.org"]) 和 伪类(:first-child) 出现的总次数;
D 的值等于 标签选择器(h1,a,div) 和 伪元素(::before,::after) 出现的总次数。
而比较规则是: 从左往右依次进行比较 ,较大者胜出,如果相等,则继续往右移动一位进行比较 。如果4位全部相等,则后面的会覆盖前面的
举个栗子:
<div class="nav-list" id="nav-list"> <div class="item">nav1</div> <div class="item">nav2</div> </div> #nav-list .item { color: #f00; } .nav-list .item { color: #0f0; }
上边代码,算出 #nav-list .item 的优先级是(0,1,1,0) 算出 .nav-list .item 的优先级是(0,0,2,0)
首先比较第一位都是0,相等,往右边找第二位,#nav-list .item的优先级第二位是1,.nav-list .item 优先级的第二位是0,所以#nav-list .item的优先级大于.nav-list .item
7,重排(reflow)和重绘(repaint)的区别
两种概念:
-
-
- 重排:无论通过什么方式影响了元素的几何信息(元素在视口内的位置和尺寸大小),浏览器需要重新计算元素在视口内的几何属性,这个过程叫做重排。
- 重绘::通过构造渲染树和重排(回流)阶段,我们知道了哪些节点是可见的,以及可见节点的样式和具体的几何信息(元素在视口内的位置和尺寸大小),接下来就可以将渲染树的每个节点都转换为屏幕上的实际像素,这个阶段就叫做重绘。
-
如何减少重排和重绘
最小化重绘和重排,比如样式集中改变,使用添加新样式类名 .class
或 cssText
批量操作 DOM,比如读取某元素 offsetWidth
属性存到一个临时变量,再去使用,而不是频繁使用这个计算属性;又比如利用 document.createDocumentFragment()
来添加要被添加的节点,处理完之后再插入到实际 DOM 中
使用 **absolute**
或 **fixed**
使元素脱离文档流,这在制作复杂的动画时对性能的影响比较明显
开启 GPU 加速,利用 css 属性 transform
、will-change
等,比如改变元素位置,我们使用 translate
会比使用绝对定位改变其 left
、top
等来的高效,因为它不会触发重排或重绘,transform
使浏览器为元素创建⼀个 GPU 图层,这使得动画元素在一个独立的层中进行渲染。当元素的内容没有发生改变,就没有必要进行重绘作者:vortesnail
浏览器渲染的过程
- 解析HTML生成DOM树,解析CSS生成CSSOM树
- 将DOM树和CSSOM树结合,生成渲染树(Render Tree)
- Layout(回流):根据生成的渲染树,进行回流(Layout),得到节点的几何信息(位置,大小)
- Painting(重绘):根据渲染树以及回流得到的几何信息,得到节点的绝对像素
- Display:将像素发送给GPU,展示在页面上。
为了构建渲染树,浏览器主要完成了以下工作:
- 从DOM树的根部开始遍历出每个可见的节点 (不可见的节点有:script、meta、link等。还有一些通过css进行隐藏的节点。比如display:none)
- 对每个可见的节点,找到CSSOM树上对应的规则,并应用他们
- 根据每个可见节点以及其对应的样式,组合生成渲染树
注意:渲染树只包含可见的节点
注意,利用visibility和opacity隐藏的节点,还是会显示在渲染树上的。只有display:none的节点才不会显示在渲染树上
从上边的例子我们可以看到span标签的样式有一个display:none,它最终并没有在渲染树上
回流(Layout)
我们通过构造渲染树,将可见DOM节点以及它对应的样式结合起来,可是我们还需要计算它们在设备视口(viewport)内的确切位置和大小,这个计算的阶段就是回流
为了弄清每个对象在网站上的确切大小和位置,浏览器从渲染树的根节点开始遍历,举个栗子:
<!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width,initial-scale=1"> <title>Critial Path: Hello world!</title> </head> <body> <div style="width: 50%"> <div style="width: 50%">Hello world!</div> </div> </body> </html>
我们可以看到,第一个div将节点的显示尺寸设置为视口宽度的50%,第二个div将其尺寸设置为父节点的50%
而在回流这个阶段,我们就需要根据视口具体的宽度,将其转为实际的像素值
重绘(Painting)
最终,我们通过构造渲染树和回流阶段,知道了那些元素是可见的,以及可见节点的样式和具体的几何图像信息(也就是在页面上的位置,大小)那么我们就可以将渲染树的每个节点都转换为屏幕上的实际像素,这个阶段就叫做重绘节点
何时会发生回流重绘?
既然前边我们都知道了,回流这一阶段主要是计算节点的位置和几何信息,那么当页面布局和几何信息发生变化的时候,就需要回流。举几个栗子:
-
-
-
- 添加或删除可见的DOM元素
- 元素的位置发生变化
- 元素的尺寸发生变化(包括外边距、内边框、边框大小、高度和宽度等)
- 内容发生变化,比如文本变化或图片被另一个不同尺寸的图片所替代。
- 页面一开始渲染的时候(这肯定避免不了)
- 浏览器的窗口尺寸变化(因为回流是根据视口的大小来计算元素的位置和大小的)
-
-
注意:回流一定会触发重绘,而重绘不一定会回流
根据改变的范围和程度,渲染树中或大或小的部分需要重新计算,有些改变会触发整个页面的重排,比如,滚动条出现的时候或者修改了根节点
推荐腾讯 IVWEB 团队的这篇文章:你真的了解回流和重绘吗
8,对BFC的理解
全程 block format contex 块级格式上下文,就是一块独立渲染区域,不影响文档流
创建 BFC 的方式:
-
-
- 绝对定位元素(
position
为absolute
或fixed
)。 - 行内块元素,即
display
为inline-block
。 overflow
的值不为visible
。
- 绝对定位元素(
-
推荐文章:可能是最好的 BFC 解析了...
9,实现两栏布局(左侧固定,右侧自适应)
DOM结构:
<div class="outer"> <div class="left">左侧</div> <div class="right">右侧</div> </div>
方法一:
利用浮动,左边元素宽度固定,右边元素的margin-left固定,注意:右边元素的width是auto,跟随父级自动撑满
.outer { height: 100px; } .left { float: left; width: 200px; height: 100%; background: lightcoral; } .right { margin-left: 200px; height: 100%; background: lightseagreen; }
方法二:
同样利用浮动,将左边元素宽度固定,然后給右边元素加上overflow:hidden,这样就触发了 BFC ,BFC的区域不会与浮动元素发生重叠,所以两侧就不会发生重叠
.outer { height: 100px; } .left { float: left; width: 200px; height: 100%; background: lightcoral; } .right { overflow: hidden; height: 100%; background: lightseagreen; }
方法三:
利用 flex布局,左边元素固定宽度,右边的元素设置 flex: 1
.outer { display: flex; height: 100px; } .left { width: 200px; height: 100%; background: lightcoral; } .right { flex: 1; height: 100%; background: lightseagreen; }
方法四:
利用定位,給父级元素相对定位,給左边元素绝对定位,固定左边元素的宽度,右边元素margin-left 留出位置
.outer { position: relative; height: 100px; } .left { position: absolute; width: 200px; height: 100%; background: lightcoral; } .right { margin-left: 200px; height: 100%; background: lightseagreen; }
方法五:
也是定位,給右边元素绝对定位,給父级相对定位,然后固定左边元素的宽度,給右边元素设置 left 留出位置,剩余的全为0
.outer { position: relative; height: 100px; } .left { width: 200px; height: 100%; background: lightcoral; } .right { position: absolute; left: 200px; top: 0; right: 0; bottom: 0; height: 100%; background: lightseagreen; }
10,实现圣杯布局和双飞翼布局(经典的三栏布局)
询问圣杯布局和双飞翼布局的目的:
- 三栏布局,中间的内容一定要优先渲染(内容最重要)
- 两边固定,中间的随着页面自适应
- 用于pc端页面
技术总结:
- 使用 float 布局
- 两侧使用
margin
负值,以便和中间内容横向重叠 - 防止中间内容被两侧覆盖,圣杯布局用
padding
,双飞翼布局用margin
圣杯布局:
<div id="container" class="clearfix"> <p class="center">我是中间</p> <p class="left">我是左边</p> <p class="right">我是右边</p> </div>
css样式:
#container { padding-left: 200px; padding-right: 150px; overflow: auto; } #container p { float: left; } .center { width: 100%; background-color: lightcoral; } .left { width: 200px; position: relative; left: -200px; margin-left: -100%; background-color: lightcyan; } .right { width: 150px; margin-right: -150px; background-color: lightgreen; } .clearfix:after { content: ""; display: table; clear: both; }
双飞翼布局:
<div id="main" class="float"> <div id="main-wrap">main</div> </div> <div id="left" class="float">left</div> <div id="right" class="float">right</div>
css样式:
.float { float: left; } #main { width: 100%; height: 200px; background-color: lightpink; } #main-wrap { margin: 0 190px 0 190px; } #left { width: 190px; height: 200px; background-color: lightsalmon; margin-left: -100%; } #right { width: 190px; height: 200px; background-color: lightskyblue; margin-left: -190px; }
11,水平垂直居中
方法一:flex 布局
.box{ display: flex; justify-content: center; align-items: center; }
方法二:利用绝对定位,left:50% top:50% 然后再通过 margin-left
和 margin-top 设置负值实现
.father { position: relative; } .son { position: absolute; left: 50%; top: 50%; width: 200px; height: 200px; margin-left: -100px; margin-top: -100px; }
方法三:和上边的方法差不多,但用了css3新增的属性 translate 来实现
.father { position: relative; } .son { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); }
方法四:利用绝对定位,子元素所有方向都为 0
,将 margin
设置为 auto
,由于宽高固定,对应方向实现平分,注意:该方法必须盒子有宽高
.father { position: relative; } .son { position: absolute; top: 0; left: 0; right: 0; bottom: 0px; margin: auto; height: 100px; width: 100px; }
关于div居中的方法还有很多这里推荐一篇:面试官:你能实现多少种水平垂直居中的布局(定宽高和不定宽高)
12,flex布局
Flex 是 Flexible Box 的缩写,意为"弹性布局",用来为盒状模型提供最大的灵活性,任何一个容器都可以指定为 Flex 布局
推荐阅读:Flex 布局教程
13,line-height 如何继承?
-
-
- 父元素的
line-height
写了具体数值,比如30px
,则子元素line-height
继承该值 - 父元素的
line-height
写了比例,比如1.5 或 2
,则子元素line-height
也是继承该比例 - 父元素的
line-height
写了百分比,比如200%
,则子元素line-height
继承的是父元素font-size * 200%
计算出来的值
- 父元素的
-