一,面试基础 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树)

推文:从输入 URL 开始建立前端知识体系

推文:从 URL 输入到页面展现到底发生什么

推文:字节面试被虐后,是时候搞懂 DNS 了

从上到下依次阅读

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选择器

选择器权重使用示例
!important1111* {color: ‘#00f’ !important}
行内1000
id0100#id{color:’#00f}
class0010.calssName{color:’#00f}
标签0001div{color:’#00f}
子选择0001div > span{color:’#00f}
伪类0001a: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 class="item">nav2#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

推荐:深入理解 CSS 选择器优先级

7,重排(reflow)和重绘(repaint)的区别

两种概念:

      • 重排:无论通过什么方式影响了元素的几何信息(元素在视口内的位置和尺寸大小),浏览器需要重新计算元素在视口内的几何属性,这个过程叫做重排。
      • 重绘::通过构造渲染树和重排(回流)阶段,我们知道了哪些节点是可见的,以及可见节点的样式和具体的几何信息(元素在视口内的位置和尺寸大小),接下来就可以将渲染树的每个节点都转换为屏幕上的实际像素,这个阶段就叫做重绘。

如何减少重排和重绘

最小化重绘和重排,比如样式集中改变,使用添加新样式类名.classcssText

批量操作 DOM,比如读取某元素offsetWidth属性存到一个临时变量,再去使用,而不是频繁使用这个计算属性;又比如利用document.createDocumentFragment()来添加要被添加的节点,处理完之后再插入到实际 DOM 中

使用**absolute****fixed**使元素脱离文档流,这在制作复杂的动画时对性能的影响比较明显

开启 GPU 加速,利用 css 属性 transformwill-change 等,比如改变元素位置,我们使用 translate 会比使用绝对定位改变其 lefttop 等来的高效,因为它不会触发重排或重绘,transform 使浏览器为元素创建⼀个 GPU 图层,这使得动画元素在一个独立的层中进行渲染。当元素的内容没有发生改变,就没有必要进行重绘作者:vortesnail

浏览器渲染的过程

  1. 解析HTML生成DOM树,解析CSS生成CSSOM树
  2. 将DOM树和CSSOM树结合,生成渲染树(Render Tree)
  3. Layout(回流):根据生成的渲染树,进行回流(Layout),得到节点的几何信息(位置,大小)
  4. Painting(重绘):根据渲染树以及回流得到的几何信息,得到节点的绝对像素
  5. Display:将像素发送给GPU,展示在页面上。

为了构建渲染树,浏览器主要完成了以下工作:

  1. 从DOM树的根部开始遍历出每个可见的节点 (不可见的节点有:script、meta、link等。还有一些通过css进行隐藏的节点。比如display:none)
  2. 对每个可见的节点,找到CSSOM树上对应的规则,并应用他们
  3. 根据每个可见节点以及其对应的样式,组合生成渲染树

注意:渲染树只包含可见的节点

注意,利用visibility和opacity隐藏的节点,还是会显示在渲染树上的。只有display:none的节点才不会显示在渲染树上

从上边的例子我们可以看到span标签的样式有一个display:none,它最终并没有在渲染树上

回流(Layout)

我们通过构造渲染树,将可见DOM节点以及它对应的样式结合起来,可是我们还需要计算它们在设备视口(viewport)内的确切位置和大小,这个计算的阶段就是回流

为了弄清每个对象在网站上的确切大小和位置,浏览器从渲染树的根节点开始遍历,举个栗子:

      <meta name="viewport" content="width=device-width,initial-scale=1">    Critial Path: Hello world!        <div style="width: 50%">      <div style="width: 50%">Hello world!      

我们可以看到,第一个div将节点的显示尺寸设置为视口宽度的50%,第二个div将其尺寸设置为父节点的50%

而在回流这个阶段,我们就需要根据视口具体的宽度,将其转为实际的像素值

重绘(Painting)

最终,我们通过构造渲染树和回流阶段,知道了那些元素是可见的,以及可见节点的样式和具体的几何图像信息(也就是在页面上的位置,大小)那么我们就可以将渲染树的每个节点都转换为屏幕上的实际像素,这个阶段就叫做重绘节点

何时会发生回流重绘?

既然前边我们都知道了,回流这一阶段主要是计算节点的位置和几何信息,那么当页面布局和几何信息发生变化的时候,就需要回流。举几个栗子:

        • 添加或删除可见的DOM元素
        • 元素的位置发生变化
        • 元素的尺寸发生变化(包括外边距、内边框、边框大小、高度和宽度等)
        • 内容发生变化,比如文本变化或图片被另一个不同尺寸的图片所替代。
        • 页面一开始渲染的时候(这肯定避免不了)
        • 浏览器的窗口尺寸变化(因为回流是根据视口的大小来计算元素的位置和大小的)

注意:回流一定会触发重绘,而重绘不一定会回流

根据改变的范围和程度,渲染树中或大或小的部分需要重新计算,有些改变会触发整个页面的重排,比如,滚动条出现的时候或者修改了根节点

推荐腾讯 IVWEB 团队的这篇文章:你真的了解回流和重绘吗

8,对BFC的理解

全程 block format contex 块级格式上下文,就是一块独立渲染区域,不影响文档流

创建 BFC 的方式:

      • 绝对定位元素(positionabsolutefixed)。
      • 行内块元素,即displayinline-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-leftmargin-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% 计算出来的值