# CSS经典面试题

静态图片

# 已知宽高实现盒子水平垂直居中

<div class="box">
  <div class="son"></div>
</div>
1
2
3

方案一:手动设置 margin 或者 padding

借助盒子模型属性 - margin padding

  • 给子元素加间距 - margin-top(overflow: hidden) margin-left
  • 给父元素加间距 - padding-top padding-left (box-sizing: border-box)
.box {
  width: 400px;
  height: 400px;
  background-color: aqua;
  /* BFC */
  overflow: hidden;  /* 😸 😸 */ 
}
.son {
  width: 200px;
  height: 200px;
  background-color: rebeccapurple;
  /* 已知宽高的一半 */
  margin: 100px 0 0 100px;  /* 😸 😸 */
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
.box {
  width: 400px;
  height: 400px;
  background-color: aqua;
  padding: 100px 0 0 100px;   /* 😸 😸 */
  /* 开启怪异盒模型 */
  box-sizing: border-box;   /* 😸 😸 */
}
.son {
  width: 200px;
  height: 200px;
  background-color: rebeccapurple;
}
1
2
3
4
5
6
7
8
9
10
11
12
13

方案二:借助定位

父元素 - 相对定位 子元素 - 绝对定位

  • 给父元素 position: relative
  • 给子元素 position: absolute top:50%; left:50%
  • 反向移动 margin负值 => 宽高已知
  • transform: translate(-50%, -50%) => 宽高不定
  • 方位 top/bottom/left/right = 0 margin:auto
.box {
  width: 400px;
  height: 400px;
  background-color: aqua;
  position: relative;

}
.son {
  width: 200px;
  height: 200px;
  background-color: rebeccapurple;

  position: absolute;  /* 😸 😸 */
  top: 50%;   /* 😸 😸 */
  left: 50%;   /* 😸 😸 */
  margin: -100px 0 0 -100px;   /* 😸 😸 */
  /* 已知宽高和不已知宽高都可以用 transform */
  /* transform: translate(-50%,-50%); */
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
.son {
  width: 200px;
  height: 200px;
  background-color: rebeccapurple;
  position: absolute;  /* 😸 😸 */
  top:0;  /* 😸 😸 */
  bottom: 0;  /* 😸 😸 */
  left: 0;  /* 😸 😸 */
  right: 0;  /* 😸 😸 */
  margin: auto; /* 😸 😸 */
}
1
2
3
4
5
6
7
8
9
10
11

方案三:flex

  • display: flex;
  • justify-content: center; 水平排列 - 居中
  • align-items: center; 垂直排列 - 居中
.box{
  width: 400px;
  height: 400px;
  background-color: aqua;

  display: flex;  /* 😸 😸 */
  justify-content: center;  /* 😸 😸 */
  align-items: center;  /* 😸 😸 */

}
.son{
  width: 200px;
  height: 200px;
  background-color: rebeccapurple;
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

方案四:table

  • 给子元素 - 水平居中 => width + margin: 0 auto
  • 给父元素 - display:table-cell + vertical-align:middle
.box{
  width: 400px;
  height: 400px;
  background-color: aqua;

  display: table-cell; /* 😸 😸 */
  /* 垂直居中 */
  vertical-align: middle; /* 😸 😸 */
}
.son{
  width: 200px;
  height: 200px;
  background-color: rebeccapurple;
  /* 水平居中 */
  margin: 0 auto; /* 😸 😸 */
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# 宽高不定实现盒子水平垂直居中

方案一:flex

  • justify-content: center; 水平排列 - 居中
  • align-items: center; 垂直排列 - 居中

方案二:定位 + transform

transform: translate(-50%, -50%) => 宽高不定

# 关于CSS3中盒模型的几道面试题

红色的content元素块面积是多少?

设置 box-sizing: border-box; 时候 盒子宽度 = 500px; 此时会压缩内容宽度

设置 box-sizing: content-box 时候 :

盒子宽度 = 500 + 40 + 20 + 10 + 10 = 580px

盒子高度 = 500 + 50 + 30 + 10 = 590px

<div class="content"></div>
1
.content {
  background: red;
  width: 500px;
  height: 500px;
  border: 10px solid #000;
  /* 导致上边框线失效 */
  border-top: 50px;
  padding: 50px 40px 30px 20px;
  margin: 50px 40px 30px 20px;

  /* 
    坑:border-top 到底是多少  =  50 ? 10 ? 0 ?
      border-top: 复合属性 border-width border-style border-width
      只写一个宽度,是不生效的。
  */
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

静态图片

知识点: box-sizing 顺时针 上 右 下 左

box-sizing: content-box;(默认) 标准盒模型

计算公式:

盒子宽度 = width(内容宽度) + padding-left + padding-right + border-left + border-right

盒子高度 = height(内容高度) + padding-top + padding-bottom + border-top + border-bottom

box-sizing: border-box; 怪异盒模型(IE盒模型)

计算公式:

盒子宽度 = width(已经把padding + border已经算进去了)

盒子高度 = height

静态图片

静态图片

# 经典布局方案:圣杯、双飞翼实现

用css实现三栏布局;左定右定中间自适应

<div class="parent">
  <div class="left"></div>
  <div class="center"></div>
  <div class="right"></div>
</div>
1
2
3
4
5

方法1:float + margin (注意:HTML的结构)

<div class="parent">
  <div class="left"></div>
  <div class="right"></div>
  <div class="center"></div>
</div>
1
2
3
4
5
.parent {
  overflow: hidden;
}
.left {
  float: left; /* 😸 😸 */
  width: 200px;
  height: 500px;
  background-color: rebeccapurple;
}
.center {
  height: 500px;
  background-color: green;
  margin-left: 210px; /* 😸 😸 */
  margin-right: 210px; /* 😸 😸 */
}
.right {
  float: right; /* 😸 😸 */
  width: 200px;
  height: 500px;
  background-color: gold;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

方法2: float + overflow (和上面的没啥区别,注意HTML的顺序)

<div class="parent">
  <div class="left"></div>
  <div class="right"></div>
  <div class="center"></div>
</div>
1
2
3
4
5
.left {
  float: left;/* 😸 😸 */
  width: 200px;
  height: 500px;
  background-color: rebeccapurple;
}
.center {
  height:500px;
  background-color: green;
  overflow: hidden; /* 😸 😸 */
  margin-left: 210px;
  margin-right: 210px;
}
.right{
  float: right; /* 😸 😸 */
  width: 200px;
  height: 500px;
  background-color: gold;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

方法3:定位

子元素(左右): position:absolute / fixed

中间子元素 : margin-left + margin-right >= width(左右)

<div class="parent">
  <div class="left"></div>
  <div class="center"></div>
  <div class="right"></div>
</div>
1
2
3
4
5
.parent{
  position: relative; /* 😸 😸 */
}
.left {
  width: 200px;
  height: 500px;
  background-color: rebeccapurple;
  position: absolute; /* 😸 😸 */
  top: 0; /* 😸 😸 */
  left: 0; /* 😸 😸 */
}
.center {
  height: 500px;
  background-color: green;
  margin-left: 210px; /* 😸 😸 */
  margin-right: 210px; /* 😸 😸 */
}
.right {
  width: 200px;
  height: 500px;
  background-color: gold;
  position: absolute; /* 😸 😸 */
  top: 0; /* 😸 😸 */
  right: 0; /* 😸 😸 */
}

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

方法4:flex

父元素: flex - 子元素 水平排列

子元素: (左右定宽 中 flex:1)

<div class="parent">
  <div class="left"></div>
  <div class="center"></div>
  <div class="right"></div>
</div>
1
2
3
4
5
.parent{
  display: flex; /* 😸 😸 */
}
.left{
  width: 200px;
  height: 500px;
  background-color: rebeccapurple;
}
.center{
  height: 600px;
  background-color: green;
  flex: 1 /* 😸 😸 */
}
.right{
  width: 200px;
  height: 500px;
  background-color: gold;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

方案5:table

父元素 : display:table + width:100%

子元素 : display:table-cell (td)

<div class="parent">
  <div class="left"></div>
  <div class="center"></div>
  <div class="right"></div>
</div>
1
2
3
4
5
.parent {
  display: table; /* 😸 😸 */
  width: 100%; /* 😸 😸 */
}
.left,
.right {
  display: table-cell; /* 😸 😸 */
}
.left {
  width: 200px;
  height: 500px;
  background-color: rebeccapurple;
}
.center {
  height: 600px;
  margin-left: 20px;
  margin-right: 20px;
  background-color: green;
}
.right {
  width: 200px;
  height: 500px;
  background-color: gold;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

静态图片

圣杯、双⻜翼布局的区别

优先加载中间的结构

<div class="parent">
  <div class="center"></div>
  <div class="left"></div>
  <div class="right"></div>
</div>
1
2
3
4
5

圣杯布局

<div class="parent">
  <div class="center"></div>
  <div class="left"></div>
  <div class="right"></div>
</div>
1
2
3
4
5
.parent {
  padding-left: 210px;
  padding-right: 210px;
  overflow: hidden;
  margin-bottom: 100px;
}
.left {
  width: 200px;
  height: 400px;
  background-color: green;
}
.center {
  width: 100%;
  height: 400px;
  background-color: rebeccapurple;
}
.right {
  width: 200px;
  height: 400px;
  background-color: hotpink;
}

/* 三个列水平排列  - float */
.left,
.center,
.right {
  float: left;
}

/* 
  把left 和 right 移动它原本的位置  
  left在center前面 
  right在center后面 => margin负值技巧
*/
.left {
  margin-left: -100%;
}
.right {
  margin-left: -200px;
}

/* 
  移动到我们理想的位置 - 借助position进行移动
*/
.left {
  position: relative;
  left: -210px;
}
.right {
  position: relative;
  right: -210px;
}
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52

双飞翼:优化了 position , 但是结构多加了一个

<div class="parent1">
  <div class="center-wrap">
      <div class="center1"></div>
  </div>
  <div class="left1"></div>
  <div class="right1"></div>
</div>
1
2
3
4
5
6
7
/* 双飞翼  -  没有定位的代码  */
.parent1 {
  overflow: hidden;
}
.left1 {
  width: 200px;
  height: 400px;
  background-color: green;
}
.center-wrap {
  width: 100%;
}
.center1 {
  margin-left: 210px;
  margin-right: 210px;
  height: 400px;
  background-color: rebeccapurple;
}
.right1{
  width:200px;
  height:400px;
  background-color: hotpink;
}

/* 三个列水平排列  - float */
.left1,
.center-wrap,
.right1 {
  float: left;
}
    
/* 
  直接移动到理想的位置 -  把定位的代码给优化掉了
  方位 - left移动
*/
.left1 {
  margin-left: -100%;
} 
.right1 {
  margin-left: -200px;
}
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
29
30
31
32
33
34
35
36
37
38
39
40
41

静态图片

# 移动端响应式布局开发的三大方案

CSS响应式布局

=>  单位: vw +  vh

=> 单页面 后台系统 rem + %

=>  @media + viewport

=>  flex
1
2
3
4
5
6
7