今天看啥  ›  专栏  ›  CHICAGO

重整旗鼓,2019自结前端面试小册【CSS篇】

CHICAGO  · 掘金  ·  · 2019-12-26 06:04
阅读 256

重整旗鼓,2019自结前端面试小册【CSS篇】

前言

临近2019年的尾声,是不是该为了更好的2020年再战一回呢? ‘胜败兵家事不期,包羞忍耻是男儿。江东子弟多才俊,卷土重来未可知’,那些在秋招失利的人,难道就心甘情愿放弃吗!

此文总结2019年以来本人经历以及浏览文章中,较热门的一些面试题,涵盖从CSS到JS再到Vue再到网络等前端基础到进阶的一些知识。

总结面试题涉及的知识点是对自己的一个提升,也希望可以帮助到同学们,在2020年会有一个更好的竞争能力。

Module One - Css

'流'概念

'流'是css的一种基本定位布局机制,HTML默认的布局机制就是'流布局',是一种自上而下(例如块级元素div),从左到右(例如内联元素span)排列的布局方式

盒模型

元素按照盒模型的规则在页面中进行布局,它是由content+ margin + border + padding组成

盒模型可以分为两种:

  • IE盒模型(怪异盒模型)
    • width = border + padding + content
    • 一个块的宽度 = width + margin
  • W3C盒模型(标准盒模型)
    • width = content
    • 一个块的宽度 = width + padding + border + margin

Css中默认的盒模型是W3C盒模型,两者间的转换可以通过设置属性box-sizing来转换

box-sizing: content-size; // W3C盒模型标准
box-sizing: border-box; // IE盒模型标准
复制代码

content

content这个属性经常被忽略,它顾名思义就是内容了,对于div等非替换元素来看,其content就是div内部的元素。而对于替换元素,其content就是可替换的部分

content 常在伪元素中出现,作用是在css中直接生成可在网页中显示的内容

<!-- 假设我们要在这段内容后面再加一点内容 -->
<h1>I am Title!</h1> 

h1:after {
    content:'I am content!';
}

<!-- 将会渲染出 I am Title!I am content! -->
复制代码

margin | padding 分别适用于什么场合?

  • 何时使用margin:在border外侧需要留空
  • 何时使用padding:在border内侧需要留空

❗ 浏览器兼容性问题:在IE5.X,IE6中,为float的盒子指定margin时,左侧margin可能会变成两倍的宽度,通过改用padding或者指定盒子为display:inline就可以解决

对WEB标准以及W3C的理解与认识

  • 标签闭合,标签小写,不乱嵌套,提高搜索机器人搜索几率
  • 使用外链css和js脚本,结构行为表现的分离、文件下载与页面速度更快、内容能被更多的用户所访问、内容能被更广泛的设备所访问、更少的代码和组件 容易维护,改版容易,不需要变动页面的内容,提供打印版本而不需要复制内容,提高网站易用性

如何理解BFC规范?

BFC(block formatting context)是一个独立的容器,决定了该容器中的内容应该如何进行定位,以及与其他容器之间的相互作用。

一个页面是有多个box(盒子)组成,每一个box类型display属性决定了这个box的内部布局方式

不同类型的 box,会参与不同的 Formatting Context(决定如何渲染文档的容器),因此box内的元素会以不同的方式渲染,所以在一个BFC中,内部的元素不会影响到外部的元素

如何触发BFC?

1 - 根元素 → 根元素(html)就是最大的BFC
2 - position设置为 fixed 或者 absolute
3 - display设置为 inline-block 、table-block 、 table-caption
4 - overflow的值不为visible(默认)
5 - float的值不为none(默认)
复制代码

BFC的定位方案

1 - 内部的box会在垂直方向上一个接一个的摆放
2 - box垂直方向的距离由margin决定,属于同一个BFC中的两个相邻box的margin会重叠(注意是垂直方向上)
3 - BFC中每个元素的左边margin会与包含块的左边border相接触
4 - 计算BFC的高度时,浮动元素也会参与计算
复制代码

Css选择器有哪些? 哪些属性可以继承?

css选择器有:
    - id选择器
    - 类选择器
    - 标签
    - 相邻选择器(h1+p)
    - 子选择器(ul>li)
    - 后代选择器(li a)
    - 通配符选择器(*)
    - 属性选择器(a[rel = "XXX"])
    - 伪类选择器( :hover :first-child ···)
    - 伪元素选择器( :before :after ···)
    - 分组选择器
    
可继承的样式:font-size, font-family, color,ul,li,dl,dt,dd;

不可继承的样式:border, padding, margin, width, height
复制代码

Css选择器优先级

!important > 内联style > id > class > tag

优先级算法:
1 - 同权重情况下样式定义最近者为准(优先级相同,选择最后出现的样式)
2 - 元素选择符的权值:元素标签(派生选择器):1,class选择符:10,id选择符:100,内联样式权值最大,为1000
3 - 继承得到的样式的优先级最低
复制代码

Css权重是如何计算?

一般情况下 - !important > 内联style > ID选择器 > 类选择器 > 标签选择器 > 通配符选择器

但遇到这几种选择器同时作用于一个元素时,元素又是如何选择样式呢?

关于权重计算,有两种方式

  • 二进制规则计算
  • 以1,10,100,1000等数值计算

各选择器全值总览

  • 内联style,权值:1000
  • ID选择器,权值:0100
  • 类选择器,权值:0010
  • 标签选择器 & 伪元素选择器,权值:0001
  • 通配符、子选择器、相邻选择器等,权值:0000
  • 继承样式没有权值

如果层级相同,则向后比较,层级不同时,层级高的权重大

Css3新增伪类伪元素

x:first-of-type → 选择属于其父元素的首个 <x> 元素的每个 <x> 元素
x:last-of-type → 选择属于其父元素的最后一个 <x> 元素的每个 <x> 元素
x:only-of-type 选择属于其父元素唯一的 <x> 元素的每个 <x> 元素
x:only-child 选择属于其父元素的唯一子元素的每个 <x> 元素
x:nth-child(1) 选择属于其父元素的第一个子元素的每个 <x> 元素

:enabled 每个已启用的元素(多用于表单元素 例如input)
:disabled 控制表单控件的禁用状态
:checked,单选框或复选框被选中
:before在元素之前添加内容(可用来做清除浮动)
:after在元素之后添加内容
复制代码

Css伪类与伪元素有什么区别?

伪类选择元素基于的是当前元素处于的状态,或者说元素当前所具有的特性
而不是元素的di、class、属性等静态的标签
由于状态是动态变化的,所以一个元素达到一个特定状态时,他可能得到伪类的样式;当状态改变时,他又失去这个样式。

由此可以看出,他的功能和class有些类似,但它是基于文档之外的抽象,所以叫伪类
(:first-child   :link   :visitive   :hover   :focus   :lang)


伪元素:
与伪类针对特殊状态的元素不同的是,伪元素对元素中的特定内容进行操作,
它所操作的层次比伪类更深一层,
也因此它的动态性比伪类要低得多。它控制的内容实际上和元素是相同的,
但是它本身只是基于元素的抽象,并不存在于文档中,所以叫伪元素
(:first-line  :first-letter   :befoe   :after)
复制代码

display 各值解析

value describe
none 元素会被隐藏,不显示
inline 元素会被设置为内联元素,内部按行从左向右排列(元素前后没有换行符)
block 元素会被设置为块级元素,内部按列从上向下排列(元素前后带有换行符)
inline-block 元素会被设置为行内块级元素,不会独占一行的块级元素
list-item 元素会作为列表显示
table 元素会作为块级表格来显示(类似table),表格前后带有换行符
flex 元素会进入flex布局模式

inline、block、inline-block三者区别

block

块级元素特点:

1 - 每个块级元素都从新的一行开始,并且其后的元素也另起一行。(一个块级元素独占一行)

2 - 元素的高度、宽度、行高以及顶和底边距都可设置。

3 - 元素宽度在不设置的情况下,是它本身父容器的100%(和父元素的宽度一致),除非设定一个宽度。

 

 

inline
内联元素特点:

1 - 和其他元素都在一行上;

2 - 元素的高度、宽度及顶部和底部边距不可设置;

3 - 元素的宽度就是它包含的文字或图片的宽度,不可改变。

 

 

inline-block
内联块状元素(inline-block)就是同时具备内联元素、块状元素的特点。

inline-block 元素特点:

1 - 和其他元素都在一行上;

2 - 元素的高度、宽度、行高以及顶和底边距都可设置。
复制代码

使用 display:inline-block 会产生什么问题?又如何解决?

问题 两个display:inline-block元素放到一起时会产生一段空白。

原因 元素被当成了行内元素排版的时候,元素之间的空白符(空格、回车换行等)都会被浏览器处理,根据CSS中white-space属性默认是normal(合并多余空白),原来HTML代码中的回车换行符被转换成一个空白符,在字体不为0的情况下,空白符占据一定宽度,所以inline-block的元素之间就会出现空白间隙

解决方式

1 - 将子元素标签的结束符和下一个标签的开始符写在同一行

<div>
    <div></div><div></div>
</div>

2 - 父元素中设置font-size:0, 在子元素上设置正确font-size

3 - 为子元素设置float:left
复制代码

逢面必问的居中方案

水平居中
  • 行内元素:text-align:center
  • 块级元素(宽度确定)
1. width确定,使用margin实现:margin:0 auto
2. 绝对定位 + margin-left:负宽度/2 (前提父元素设置相对定位)
{
    width:100px;
    position:absolute;
    left:50%;
    margin-left:-50px
}
复制代码
  • 块级元素(宽度未知)
1. display:table + margin左右auto
2. display:inline-block + text-align:center
3. 绝对定位 + transform
{
    position: absolute;
    left: 50%;
    transform: translateX(-50%);
}
4. 万能flex布局(个人推荐)
{
    display:flex;
    justify-content:center;
}
复制代码
垂直居中
  • line-height 适合纯文字类内容居中
  • 父元素设置相对定位,子元素设置绝对定位,标签通过margin实现自适应居中
  • 万能flex
{
    display:flex;
    align-items:center;
}
复制代码
  • 父元素设置相对定位,子元素设置绝对定位,通过transform实现居中
  • 父元素设置display:table + 子元素设置vertical-align:middle
垂直水平居中
  • 万能flex(个人推荐) { display:flex; justify-content:center; align-items:center; }
  • position + transform (宽高未知)
父元素
{
    position:relative;
}
子元素
{
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%,-50%);
}
复制代码
  • position + margin (宽高确定)
父元素
{
    position: relative;
}
子元素
{
    width: 100px;
    height: 100px;
    position: absolute;
    left: 50%;
    top: 50%;
    margin-left: -50px;
    margin-top: -50px;
}
复制代码
  • 绝对定位设置各个方向为0,通过margin:auto实现垂直水平居中(宽高已知)
父元素
{
    position: relative;
}
子元素
{
    width: 100px;
    height: 100px;
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    margin: auto;
}
复制代码

吃透定位 position

position属性共有5和属性值,分别如下

  • relative 相对定位,相对于自身位置进行定位
很多人不明白相对于自身位置是什么意思,其实可以这样理解:

    将本身当前位置固定住,以此位置进行定位
复制代码
  • absolute 绝对定位,相对于position不为static的第一个父级元素进行定位
  • fixed 固定定位。相对于浏览器窗口进行定位
  • inherit 继承父级元素position属性值
  • static 默认值,即没有定位,仍为文档流

对于position,需要注意的是absolute到底是相对于哪一个父级进行定位

css3新增了一个新的定位属性 - sticky,作用类似于relativefixed. 元素在跨越特定阈值前为相对定位,跨越之后为固定定位。

浮动布局是什么?优劣势在哪?

浮动布局 - 当元素设置了浮动后,可以向左向右移动,直到它的外边缘碰到包含它的框或者另外一个浮动元素的边框为止。

浮动元素脱离了正常文档流,可以想象成浮动元素浮在了正常文档流上方,文档流不再有这个元素存在

优点

在图文混排的场景下十分适用,可以实现文字环绕图片的效果,当元素浮动后,它有着块级元素的特点(可设置宽高),但它与inline-block存在差别

  • float可以在横向排序上设置方向,而inline-block不可
  • inline-block会出现存在空白间隙情况
缺点

float致使元素脱离文档流,若父元素高度自适应,则会引起父元素高度塌陷

清除浮动(常见面试题)
  • 通过伪类选择器清除浮动(关键方式)
<div class="Parent">
    <div class="Float"></div>
</div>

设置 .Parent:after伪元素
.Parent:after{
      /* 设置添加子元素的内容是空 */
      content: '';  
      /* 设置添加子元素为块级元素 */
      display: block;
      /* 设置添加的子元素的高度0 */
      height: 0;
      /* 设置添加子元素看不见 */
      visibility: hidden;
      /* 设置clear:both */
      clear: both;
}
复制代码
  • 父级元素添加overflow属性,或者设置高度(原理是触发父元素BFC)
<div class="Parent" style="overflow:hidden">//auto 也可以
    <div class="Float"></div>
</div>
复制代码
  • 添加额外标签
<div class="Parent">
    //添加额外标签并且添加clear属性
    <div style="clear:both"></div>
    <div class='Float'></div>
</div>
复制代码

▲ 注意:设置元素浮动后,该元素的display值会变为block

当position跟display、overflow、float这些特性相互叠加后会出现什么情况?

- display:规定元素应该生成的框的类型(子元素的排序方式)
- position:规定元素的定位类型
- float:定义元素在哪个方向浮动

其中,position:absolute / fixed 优先级最高
当position设置为absolute或者fixed时,float失效,display需要调整
float / absolute定位的元素,只能是块元素或表单(block / table)
复制代码

布局精英 - flex 布局

该布局提供了一种更高效的方法对容器中的项目进行布局、对齐和分配空间,他没有方向上的限制,可以由开发人员自由操作

使用场景: 移动端开发,安卓,iOS

容器属性(6)

  • flex-direction 决定主轴方向(容器排列方向)
flex-direction: row | row-reverse | column | column-reverse;
复制代码
  • flex-wrap 如果一条轴线排不下,定义换行规则
flex-wrap: nowrap | wrap | wrap-reverse;
复制代码
  • flex-flow flex-direction和flex-wrap的简写形式
flex-flow: <flex-direction> || <flex-wrap>;
复制代码
  • justify-content 定义容器在主轴上的对齐方式
justify-content: flex-start | flex-end | center | space-between | space-around;
复制代码
  • align-items 定义容器在交叉轴上的对齐方式
align-items: flex-start | flex-end | center | baseline | stretch;
复制代码
  • align-content 定义多根轴线的对齐方式,如果容器只有一根轴线,该属性不起作用
align-content: flex-start | flex-end | center | space-between | space-around | stretch;
复制代码

项目属性(6)

  • order 定义项目的排列顺序,数值越小,排列越靠前,默认为0
  • flex-grow 定义项目的放大比例,默认为0(即如果存在剩余空间,也不放大)
  • flex-shrink 定义项目的缩小比例,默认为1(即如果空间不足,该项目将缩小)
  • flex-basis 定义了在分配多余空间之前,项目占据的主轴空间。默认值为auto(项目本来大小)
  • flex 是flex-grow、flex-shrink和flex-basis的简写,默认值为 0 1 auto
flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]

该属性有两个快捷值: auto(1 1 auto) 和 none(0 0 auto)

建议优先使用这个属性,而不是单独写三个分离的属性

因为浏览器会推算相关值
复制代码
  • align-self 允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性,默认值为auto(表示继承父元素align-items属性,如果没有父元素,等同于stretch
align-self: auto | flex-start | flex-end | center | baseline | stretch;
复制代码

经典布局案例 - 三栏布局

三栏布局 - 左右容器自适应,中间容器自适应

三栏布局在实际中十分常用,也是css面试常题,实现方法有如下三种:

<div class="container">
    <div class="left">left</div>
    <div class="main">main</div>
    <div class="right">right</div>
</div>

第一种方式:flex
.container{
    display: flex;
}
.left{
    flex-basis:200px;
    background: green;
}
.main{
    flex: 1;
    background: red;
}
.right{
    flex-basis:200px;
    background: green;
}

第二种方式:position + margin
.left,.right{
    position: absolute;
    top: 0;
    background: red;
}
.left{
    left: 0;
    width: 200px;
}
.right{
    right: 0;
    width: 200px;
}
.main{
    margin: 0 200px ;
    background: green;
}

第三种方式 float + margin
.left{
    float:left;
    width:200px;
    background:red;
}
.main{
    margin:0 200px;
    background: green;
}
.right{
    float:right;
    width:200px;
    background:red;
}
复制代码

Css3有哪些新特性?

  • 各种css选择器
  • 圆角border-radius
  • 多列布局
  • 文本效果
  • 线性渐变
  • 2D转换
  • 过渡transition
  • 动画animation
  • flex布局
  • 旋转transform
  • 媒体查询

浏览器如何解析Css选择器?

css选择器的解析是从右向左解析,为了避免对所有元素进行解析

overflow属性解剖

- scroll:必定出现滚动条
- auto:子元素内容大于父元素时出现滚动条
- visible:溢出的内容出现在父元素之外
- hidden:溢出时隐藏
复制代码

全屏滚动的原理?需要哪些css属性?

原理 类似于轮播图,整体元素一直排列下去,假设有5个需要展示的全屏页面,那么高度将会是500%,但我们只能展示100%,剩下的内容可以通过transform进行Y轴定位,也可以通过margin-top实现

涉及css属性 overflow:hidden | transition:all 1000ms ease

响应式设计是什么?响应式设计的原理是什么?如何兼容低版本IE?

响应式设计 是指网站能够兼容多个终端,而不是为每一个终端特地去开发新的一个版本

原理 通过媒体查询测试不同的设备屏幕尺寸做处理

兼容低版本IE,页面头部必须有meta声明的viewport

<meta name=“viewport” content=“width=device-width,initial-scale=1.maximum-scale=1,user-scalable=no”>
复制代码

布局题:自适应填补

有一个高度固定的div,里面有两个div,一个高度100px,另一个填补剩下的高度

方案一 外层div使用position:relative;,要求高度自适用的div使用position:absolute; top:100px; bottom:0; left:0

方案二 使用flex布局方式,高度自适应的div使用flex:1

RGBA() 与 opacity 在透明效果上有什么区别?

  • opacity 作用于元素,以及元素内的所有内容的透明度
  • rgba() 只作用于元素的颜色或者背景色(设置rgba透明的元素的子元素不会继承透明效果)

px | em 有什么区别?

px 和 em 都是长度单位
区别在于px的值是固定的,指定多少就是多少,而em的值是不固定的,并且em会继承父级元素的字体大小


▲ 浏览器的默认字体高都是16px。
所以未经调整的浏览器都符合:1em=16px。那么12px = 0.75em  10px = 0.625em
复制代码

如何实现元素在z轴上移动?

  • translate3d(x,y,z)
  • translateZ(z)

Css有哪些引入方式? 通过link和@import引入有什么区别?

Css引入方式有4种 内联、内嵌、外链、导入

外链link 除了可以加载css之外,还可以定义rss、rel等属性,没有兼容性问题,支持使用javascript改变样式

@import 是css提供的,只能用于加载css,不支持通过javascript修改样式

▲ 页面被加载的时候,link会被同时加载,而@import则需等到页面加载完后再加载,可能出现无样式网页

图形题:纯Css创建一个三角形

原理 创建一个没有高度和宽度的div,设置其中一条边框的作为三角形,其他边框的颜色应为透明

{
    width:0px;
    height:0px;
    border-top:10px solid transparent;
    border-left:10px solid transparent;
    border-right:10px solid transparent;
    border-bottom:10px solid #000;
}
复制代码

display:none 与 visibility:hidden 的区别是什么?

  • display:none 隐藏对应的元素,在文档布局中不再分配空间(导致重排)
  • visibility:hidden 隐藏对应的元素,在文档布局中保留原来的空间(导致重绘)

浏览器是如何解析Css选择器?

Css选择的解析是从右向左解析,能够避免对所有元素进行解析

如何水平并垂直居中一张背景图?

设置属性 background-position:center;
复制代码

style 标签写在 body 后和 body 前有什么区别?

页面加载自上而下,当然是需要先加载样式

写在body标签后,由于浏览器以逐行方式对HTML文档进行解析,当解析写在尾部的样式表会导致浏览器停止之前的渲染,等待加载且解析样式表后才重新进行渲染,这样可能导致留白现象(所以最好将style标签写在body前)

常见的Css兼容性问题有哪些?

- 不同浏览器的标签默认的padding/margin不同,通过初始化css样式可以解决
    *{
        margin:0;
        padding:0px;
    }
- IE6双边距BUG
- 设置较小高度标签(一般小于10px),在IE6,IE7中高度超出自己设置的高度
    通过设置overflow:hidden;或者设置行高line-height小于你设置的高度
- IE下,可以使用获取常规属性的方法来获取自定义属性,也可以使用getAttribute()获取自定义属性
- Chrome中文界面下默认会将小于12px的文本强制为12px
    通过加入css属性 -webkit-text-size-adjust:none;可以解决,或者使用transform中的缩放属性
- 超链接访问过后hover样式就不出现,因为被点击访问过的超链接样式不再具有hover和active了
    解决方法是改变css属性的排列属性:L-V-H-A
    a:link{} → a:visited{} → a:hover{} → a:active{}
- IE下,event对象有x,y属性,但是没有pageX,pageY属性,但没有x,y属性
    解决方式:通过条件
- png24位的图片在IE6浏览器上出现背景,解决方案是做出PNG8
复制代码

Css优化,如何提高性能

  • 避免过渡约束
  • 避免后代选择符
  • 避免链式选择符
  • 使用紧凑的语法
  • 避免不必要的命名空间
  • 避免不必要的重复样式
  • 使用具有语义的名字
  • 避免使用 !important
  • 尽可能地精简规则
  • 修复解析错误
  • 避免使用多种类型选择符
  • 移除空的css规则
  • 正确使用display属性
inline后不应该使用width、height、margin、padding以及float;
inline-block后不应该使用float;
block后不应该使用vertical-align
复制代码
  • 不滥用浮动
  • 不滥用web字体
  • 不声明过多font-size
  • 少使用id选择器
  • 不给h1-h6定义过多样式
  • 不重复定义h1-h6
  • 值为0时不需要任何单位
  • 标准化各种浏览器前缀
  • 遵守盒模型规则



原文地址:访问原文地址
快照地址: 访问文章快照