面试题 - 前端 - CSS

display: none; 与 visibility: hidden; 的区别 ?

  • 联系:它们都能让元素不可见
  • 区别:
    • display:none;会让元素完全从渲染树中消失,渲染的时候不占据任何空间;visibility: hidden;不会让元素从渲染树消失,渲染师元素继续占据空间,只是内容不可见
    • 修改常规流中元素的display通常会造成文档重排。修改visibility属性只会造成本元素的重绘

如何避免外边折叠(collapsing margins) ?

外边折叠

毗邻的两个或多个 margin 会合并成一个margin,叫做外边距折叠。规则如下:

  • 两个或多个毗邻的普通流中的块元素垂直方向上的margin会折叠
  • 浮动元素或display: inline-block元素或绝对定位元素的margin不会和垂直方向上的其他元素的 margin 折叠
  • 创建了块级格式化上下文(BFC)的元素,不会和它的子元素发生 margin 折叠

z-index 是什么?在 position 的值什么时候可以触发?

z-index 属性设置元素的堆叠顺序。拥有更⾼堆叠顺序的元素总是会处于堆叠顺序较低的元素的前⾯,当 脱离⽂档流内容较多,并且相互重叠的时候,就有可能发⽣本想完全显示的内容被其他内容遮挡的结 果,这时我们就需要⼈为指定哪个层在上⾯,哪个在下⾯,z-index 属性就是⼲这个⽤的。

注意:Z-index 仅能在定位元素上奏效.

在 position 的值是 relative、absolute、fixed、sticky 时候可以触发。

简述 box-sizing 的有效值以及所对应的盒模型规则

box-sizing 属性允许您以特定的⽅式定义匹配某个区域的特定元素。

语法:box-sizing: content-box|border-box|inherit;

1)box-sizing:content-box;这是由 CSS2.1 规定的宽度⾼度⾏为。宽度和⾼度分别应⽤到元素的内容框。 在宽度和⾼度之外绘制元素的内边距和边框。是默认值。如果你设置⼀个元素的宽为 100px,那么这个元 素的内容区会有 100px 宽,并且任何边框和内边距的宽度都会被增加到最后绘制出来的元素宽度中

2)box-sizing:border-box;为元素指定的任何内边距和边框都将在已设定的宽度和⾼度内进⾏绘制。告诉 浏览器去理解你设置的边框和内边距的值是包含在 width 内的。也就是说,如果你将⼀个元素的 width 设 为 100px,那么这 100px 会包含其它的 border 和 padding,内容区的实际宽度会是 width 减去 border + padding 的计算值。⼤多数情况下这使得我们更容易的去设定⼀个元素的宽⾼

3)box-sizing:inherit;;规定应从⽗元素继承 box-sizing 属性的值

人话:box-sizing:content-box 的元素 width 和 height 不包含 padding 和 border;box-sizing:border-box 的元素包含。

移动端适配怎么做?

1) meta viewport(视⼝)

移动端初始视⼝的⼤⼩为什么默认是 980px?

因为世界上绝⼤多数 PC ⽹⻚的版⼼宽度为 980px ,如果⽹⻚没有专⻔做移动端适配,此时⽤⼿机访问⽹ ⻚旁边刚好没有留⽩,不过⻚⾯缩放后⽂字会变得⾮常⼩。

为了解决⻚⾯缩放的体验问题,在⽹⻚代码的头部,加⼊⼀⾏ viewport 元标签。

这⾥的 device-width 告诉浏览器,将视⼝的宽度设置为设备宽度(这个宽度是⼈为预设的,不设的话就是 980px)。 属性含义

1
2
3
4
initial-scale:第⼀次进⼊⻚⾯的初始⽐例
minimum-scale:允许缩⼩最⼩⽐例
maximum-scale:允许放⼤最⼤⽐例
user-scalable:允许使⽤者缩放,1 or 0 (yes or no)

人话:用 viewport 告诉浏览器“页面的宽度和设备的宽度一致“。

2) 图⽚适配

img { max-width: 100%; } 此时图⽚会⾃动缩放,同时图⽚最⼤显示为其⾃身的 100%(即最⼤只 可以显示为⾃身那么⼤) 为什么不⽤ img { width: 100%; } ? 当容器⼤于图⽚宽度时,图⽚会⽆ 情的拉伸变形

人话:图片设置最大宽度。

3) 媒体查询

为什么要媒体查询?

针对不⽤的设备提前为⽹⻚设定各种 CSS 样式 CSS3 中的 Media Query 模块,⾃动检测屏幕宽度,然后加载 相应的 CSS ⽂件

语法举例

1
2
3
4
5
@media screen and (min-width: 1200px) {
body {
background-color: red;
}
}

当屏幕宽度⼤于 1200px 时,背景⾊变为红⾊

4) 动态 rem ⽅案

为什么要⽤ rem?

和媒体查询配合,实现响应式布局

px、em、rem 有什么不同?

px 是 pixel(像素),是屏幕上显示数据的最基本的点,在 HTML 中,默认的单位就是 px;em 是⼀个相对 ⼤⼩,相对于⽗元素 font-size 的百分⽐⼤⼩ rem 是相对于根元素的 font-size

⽤法示例

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
/*
这里根据设计稿来。
比如设计稿基于的页面宽度是375px,用vm表示整个宽度为100vw,1vw = 3.75px。
为了方面和设计稿对应,即设例如计稿上显示字体大小16px,样式代码就写16rem。而设计稿的 1px = 0.2666667vw。(100 / 375)
所以根元素的font-size就设置为.2666667vw
*/
html {
font-size: .2666667vw;
}
body {
font-size: 16rem;
}
</style>
</head>
<body>
<div class="box">赵钱孙李</div>
</body>
</html>

人话:px 是绝对大小。rem, em是相对大小。em是相对父元素的大小,rem是相对根元素(HTML)的font-size大小。一般前端拿到页面设计稿,设计稿上有页面宽度大小,用百分比可计算出设计稿上的一个像素多少宽度百分比vw。即可定义根元素的font-size的大小是多少vw.

什么是CSS3 transform? transition? animation? 区别是什么?

CSS3属性中关于制作动画的三个属性:Transform,Transition,Animation。
1、transform:描述了元素的静态样式,本身不会呈现动画效果,可以对元素进⾏ 旋转rotate、扭曲skew、缩放scale和移动translate以及矩阵变形matrix。

1
2
3
div{
  transform:scale(2);
}

transition和animation两者都能实现动画效果
transform常常配合transition和animation使⽤

2、transition样式过渡,从⼀种效果逐渐改变为另⼀种效果
transition是⼀个合写属性
transition:transition-property transition-duration transition-timing-function transition-delay
从左到右分别是:css属性、过渡效果花费时间、速度曲线、过渡开始的延迟时间

1
2
3
4
5
6
7
8
div{
width100px;
height:100px;
transition:transform 2s;
}
div:hover{
transform:rotate(180deg);
}

transition通常和hover等事件配合使⽤,需要由事件来触发过渡
我们知道 transition 虽然简单好⽤,但是我们会发现它受到各种限制。
(1)transition需要⼀个事件来触发,⽐如hover,所以没法在⽹⻚加载时⾃动发⽣
(2) transition是⼀次性的,不能重复发⽣,除⾮⼀再触发。
(3) transition只能定义开始状态和结束状态,不能定义中间状态,也就是说只有两个状态。
(4)⼀条transition规则,只能定义⼀个属性的变化,不能涉及多个属性。

3、animation动画 由@keyframes来描述每⼀帧的样式

1
2
3
4
5
6
7
div{
  animation:myAnimation 5s infinite
}
@keyframes myAnimation {
  0%{left:0;transform:rotate(0);}
  100%{left:200px;transform:rotate(180deg);}
}

区别:
(1)transform仅描述元素的静态样式,常常配合transition和animation使⽤
(2)transition通常和hover等事件配合使⽤,animation是⾃发的,⽴即播放
(3)animation可设置循环次数
(4)animation可设置每⼀帧的样式和时间,transition只能设置头尾
(5)transition可与js配合使⽤,js设定要变化的样式,transition负责动画效果,如:

animation属性类似于transition,他们都是随着时间改变元素的属性值,
其主要区别在于:transition需要触发⼀个事件才会随着时间改变其CSS属性;
animation在不需要触发任何事件的情况下,也可以显式的随时间变化来改变元素CSS属性,达到⼀种动画的效果
1)动画不需要事件触发,过渡需要。
2)过渡只有⼀组(两个:开始-结束) 关键帧,动画可以设置多个。

人话:

  • transform和动画无关,它设置元素的旋转、缩放,位移等样式;
  • transition可以设置起点样式、终点样式、过渡时间、速度曲线和延迟时间。一条transition只可以设置一个样式属性。触发是通过元素的伪类(例如hover)或者JS(element.classList.add)。
  • animation可以设置起点样式、关键帧样式、过渡时间、速度曲线、延迟时间、播放次数等。一条animation可以设置多个样式属性。不需要事件触发。和transition最大的区别是animation可以设置多个关键帧的样式,而transition只能设置起点和终点的样式。

⽗元素和⼦元素宽⾼不固定,如何实现⽔平垂直居中

方法一:父元素用相对定位,子元素用绝对定位。子元素定位left:50%,top:50%,最后用transform做位移translate(-50%, -50%)。

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
53
54
55
56
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
padding: 0;
margin: 0;
}

html,
body {
width: 100%;
height: 100%;
}

body {
background-color: azure;
}

.parent {
width: 500px;
height: 500px;
background-color: yellowgreen;
position: relative;
}

.child {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
/* 使⽤css3的transform来实现 */
}

.child p {
width: 300px;
height: 300px;
background-color: blue;
}
</style>
</head>

<body>
<div class="parent">
<div class="child">
<p></p>
</div>
</div>
</body>

</html>

方法二:父元素使用flex布局,横轴居中(justify-content: center),纵轴居中(align-items: center)。

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
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
padding: 0;
margin: 0;
}

body,
html {
width: 100%;
height: 100%;
}

.parent {
display: flex;
justify-content: center;
align-items: center;
width: 600px;
height: 600px;
background: yellow;
}

.parent .child {
color: #fff;
width: 300px;
height: 300px;
text-align: center;
background-color: blue;
}
</style>
</head>

<body>
<div class="parent">
<div class="child">hello world</div>
</div>
</body>

</html>

假设高度默认100px ,请写出三栏布局,其中左栏、右栏各为300px,中间自适应

假设高度默认

方法一:父元素用flex布局,中间子元素设置flex:1

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>

<style>
*{
margin:0;
padding:0;
}

.box div{
height: 100px;
}
.box{
display: flex;
}

.left{
width: 300px;
background:gray;
}
.right{
width: 300px;
background:gray;
}
.center{
flex:1;
background-color: yellowgreen;
}
</style>
</head>
<body>
<div class="box">
<div class="left">left</div>
<div class="center">center</div>

<div class="right">right</div>
</div>
</body>
</html>

方法二:子元素用绝对定位,左侧元素left:0px,右侧元素right:0px,中间元素leftright 都为300px

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>

<style>
*{
margin:0;
padding:0;
}

.box div{
height: 100px;
}

.left{
width: 300px;
position: absolute;
left:0;
background:gray;
}
.right{
width: 300px;
position: absolute;
right:0;
background:gray;
}
.center{
position: absolute;
left:300px;
right:300px;
background-color: yellowgreen;
}
</style>
</head>
<body>
<div class="box">
<div class="left">left</div>
<div class="center">center</div>

<div class="right">right</div>
</div>
</body>
</html>

方法三:左侧子元素设置左浮动,右侧子元素设置右浮动。

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>

<style>
*{
margin:0;
padding:0;
}

.box div{
height: 100px;
}

.left{
width: 300px;
float:left;
background:gray;
}
.right{
width: 300px;
float: right;;
background:gray;
}
.center{
background-color: yellowgreen;
}
</style>
</head>
<body>
<div class="box">
<div class="left">left</div>
<div class="right">right</div>
<div class="center">center</div>
</div>
</body>
</html>