基础知识点快速回忆:

CSS选择器:

元素选择器、类选择器(.class)、ID选择器(#id)、后代选择器、子元素选择器(>)、兄弟选择器(+ 和 ~)、伪类选择器(如:hover、:first-child)等

display属性:

值包括none、block、inline、inline-block、flex、grid等

盒模型(Box Model):

内容(content)、内边距(padding)、边框(border)、外边距(margin)

响应式设计:

使用媒体查询(Media Queries)、相对单位(em/rem)、弹性盒子(Flexbox)和网格系统(Grid)实现。

Flexbox与Grid布局:

Flexbox适合单一轴线布局,Grid适合复杂的二维布局。

清除浮动(Clearfix):

方法包括使用overflow: auto;或::after伪元素。

BEM命名方法:

一种保持CSS选择器结构清晰和可维护性的命名约定。

position属性:

包括static、relative、absolute、fixed、sticky

水平垂直居中:

可以使用Flexbox的align-items和justify-content属性,或者绝对定位结合transform属性。

CSS3动画:

使用@keyframes定义动画的关键帧,然后通过animation属性应用到元素上。

box-sizing属性:

定义了如何计算元素的总宽度和高度
值有content-box和border-box

CSS预处理器:

如Sass、Less,允许使用变量、混合、函数等编程特性。
优化CSS性能:
减少选择器复杂度,避免过度层叠和继承,合理使用CSS3的GPU加速特性。

层叠和继承:

层叠是指样式根据权重叠加到元素上,继承是指子元素继承父元素的样式。

多列布局:

使用CSS3的多列布局相关属性如column-count、column-gap、column-rule。

事件冒泡和事件捕获:

分别是事件从子元素向父元素传递的过程,和从父元素向子元素传递的过程。

圆角(border-radius):

使用该属性并提供像素值或百分比来实现。

伪类和伪元素的区别:

伪类用于添加特殊状态下的样式,伪元素用于创建特殊效果。

题目

标准盒模型与怪异盒模型ie的区别及如何切换

标准盒模型中,设置 width: 100px,实际内容区域是 100px,而 padding 和 border 会额外增加宽度;
怪异盒模型则把 padding 和 border 算进 width 里,更适合现代布局。
通过 box-sizing 属性切换,默认是 content-box,但很多框架(比如 Bootstrap)会全局设置为 border-box 来简化计算

Less/Sass

都是css的预处理器,允许用更强大的语法编写css,然后编译成浏览器 能够识别的普通css
允许变量复用、函数计算、可以嵌套(比如多层选择器时)、代码组织。

  • less: @,客户端编译,轻量级,不可以嵌套属性,不可以@extend,能Mixin,社区生态小,已停止更新
  • sass:&,服务器编译,功能强大,可以嵌套属性,可以@extend集成,有很多第三方库,持续更新中

原生 CSS 的痛点:

写重复样式麻烦(比如多个按钮颜色统一修改)、嵌套层级难管理(比如  .container .header .nav  写起来长)、没有变量和函数概念。

  • scoped 属性:
     .vue  文件中  <style scoped>  会自动给样式加唯一属性选择器(如  data-v-xxx ),避免组件样式冲突。语法差异:Less 更简单,Sass 更灵活
  • 变量定义:
    Less:用  @  符号,比如  @width: 100px; 
    Sass:用  $  符号,比如  $width: 100px;
  • 核心价值
  • 提升开发效率:变量改一次全项目生效,混合类复用代码
  • 优化代码结构:嵌套写法让样式和 HTML 结构对应,更容易维护
  • 与 Vue3 无缝结合:scoped 保证样式隔离,预处理器让组件样式更模块化

Sass 中 @extend 和 @mixin 的区别?

@extend 复用选择器,生成组合样式。
@mixin 复用代码块,生成重复样式

如何优化 CSS 性能?

关键措施:
减少选择器复杂度:避免深层嵌套(如 body div ul li a)
避免行内样式:影响缓存和维护性
减少重排(reflow)和重绘(repaint):
批量修改样式(先修改再应用)
使用 transform 和 opacity 进行动画(触发合成层)
压缩和分割 CSS:减小文件体积,利用浏览器并行加载

flex:1什么意思

flex: 1是个缩写,展开来是flex-grow: 1、flex-shrink: 1、flex-basis: 0
用于控制弹性容器中的子元素如何分配空间。

  • flex-grow: 1
    表示元素会主动扩张,当容器中有剩余空间时,该元素会按比例放大,占据这些空间。
    如果所有子元素的flex-grow都为1,它们将平均分配剩余空间。
  • flex-shrink: 1
    表示空间不足时,元素会同等缩小。
    如果所有子元素的 flex-shrink都为1,它们在空间不足时会均匀地缩小。
  • flex-basis: 0%
    指定弹性项目在分配剩余空间前的初始大小。
    设置为0% 意味着元素的初始大小不计入空间分配,完全由 flex-grow 和 flex-shrink 决定。
  • 总结:
    flex: 1 使元素能够根据容器的可用空间自动调整大小。
    元素会尽可能地扩展以填充剩余空间,并在空间不足时均匀收缩。
    常用于创建等宽列布局或使某个元素占据容器的全部剩余空间。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    .container {
    display: flex;
    }
    .sidebar {
    width: 200px; /* 固定宽度 */
    }
    .main-content {
    flex: 1; /* 占满剩余空间 */
    }

fixed 定位失效的原因

祖先元素有 transform、filter 等属性会创建新的层叠上下文,导致 fixed 定位基准改变

盒模型的 margin 折叠问题

垂直方向上相邻元素的 margin 会合并(取较大值)

Flexbox 和 Grid 的区别

Flexbox 是一维布局(单行或单列),Grid 是二维布局(多行多列)。
Flexbox 适合组件级布局,Grid 适合页面级布局。

position

static(默认值)
relative:(相对定位)为子元素提供定位上下文。
absolute:(绝对定位)基于最近的定位祖先元素定位。
fixed:(固定定位)固定在视口,适合导航栏。
sticky:(粘性定位)滚动时“粘”在指定位置,适合表头。
z-index:控制层级,需注意堆叠上下文。

各属性值详解

  1. static(静态定位)
    特点:元素按默认文档流排列,top/bottom/left/right 和 z-index 无效
  2. relative(相对定位)
    元素相对于自身原始位置偏移。不脱离文档流(其他元素仍占据原始空间)。常作为 absolute 定位的参考点
    场景:需要微调元素位置,或为子元素提供绝对定位的上下文
  3. absolute(绝对定位)
    素脱离文档流,基于最近的已定位祖先元素(position 非 static)进行定位。
    如果没有已定位的祖先元素,则相对于 (即视口)定位。
    场景:需要精确定位子元素(如弹窗、提示框)
  4. fixed(固定定位)
    元素始终固定在视口的某个位置(不随页面滚动变化)。脱离文档流。
    场景:固定导航栏、悬浮按钮、侧边栏

object-fit属性

适用于图片或video的高度和宽度
类似background-size属性,但是这个属性只能作用于背景图片,而object-fit适用于所有图片

布局题

如何实现响应式布局?请列举至少 3 种方法

媒体查询(Media Query):基于屏幕宽度应用不同样式
弹性布局(Flex/Grid):自动适应容器尺寸
rem/em 单位:相对于根元素或父元素字体大小
viewport 单位(vw/vh):相对于视口尺寸

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/* 媒体查询实现断点布局 */
.container {
display: grid;
grid-template-columns: repeat(4, 1fr); /* 默认4列 */
}

@media (max-width: 768px) {
.container {
grid-template-columns: repeat(2, 1fr); /* 平板2列 */
}
}

@media (max-width: 480px) {
.container {
grid-template-columns: 1fr; /* 手机1列 */
}
}

/* vw单位实现自适应字体 */
.title {
font-size: 5vw; /* 相对于视口宽度的5% */
}

如何实现元素的垂直居中?

  1. 行内元素:
    line-height 等于容器高度(单行文本)
  2. 块级元素:
    • Flexbox:display: flex; align-items: center; justify-content: center
    • Grid:display: grid; place-items: center
    • 绝对定位 + transform:top: 50%; left: 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
      /* Flexbox 方案 */
      .flex-center {
      display: flex;
      align-items: center; /* 垂直居中 */
      justify-content: center; /* 水平居中 */
      }

      /* Grid 方案 */
      .grid-center {
      display: grid;
      place-items: center; /* 同时实现垂直和水平居中 */
      }

      /* 绝对定位 + transform 方案(适用于未知尺寸元素) */
      .absolute-center {
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      }

圣杯布局

header和footer各自占领屏幕所有宽度,高度固定。
中间的container是一个三栏布局。
三栏布局两侧宽度固定不变,中间部分自动填充整个区域。
中间部分的高度是三栏中最高的区域的高度。

浮动

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
<div class="container">
<main class="main">中间栏</main>
<div class="left">左侧栏</div>
<div class="right">右侧栏</div>
</div>

<style>
.container {
padding: 0 200px; /* 预留左右栏宽度 */
}
.main {
float: left;
width: 100%;
}
.left {
float: left;
width: 200px;
margin-left: -100%; /* 拉回左侧栏 */
position: relative;
left: -200px; /* 向左偏移 */
}
.right {
float: left;
width: 200px;
margin-right: -200px; /* 拉回右侧栏 */
}
</style>
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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
<!DOCTYPE html>
<html>

<head>
<meta charset="utf-8">
<script src="http://lib.sinaapp.com/js/jquery/2.0.2/jquery-2.0.2.min.js"></script>
</head>
<style>
body {
min-width: 550px; /* 2x leftContent width + rightContent width */
font-weight: bold;
font-size: 20px;
}

#header, #footer {
background: rgba(29, 27, 27, 0.726);
text-align: center;
height: 60px;
line-height: 60px;
}
#footer {
clear: both;
}

#container {
padding-left: 200px; /* leftContent width */
padding-right: 150px; /* rightContent width */
overflow: hidden;
}

#container .column {
position: relative;
float: left;
text-align: center;
height: 300px;
line-height: 300px;
}

#center {
width: 100%;
background: rgb(206, 201, 201);
}

#left {
width: 200px; /* leftContent width */
right: 200px; /* leftContent width */
margin-left: -100%;
background: rgba(95, 179, 235, 0.972);
}

#right {
width: 150px; /* rightContent width */
margin-left: -150px; /* rightContent width */
right: -150px;
background: rgb(231, 105, 2);
}

</style>

<body>
<div id="header">#header</div>
<div id="container">
<div id="center" class="column">#center</div>
<div id="left" class="column">#left</div>
<div id="right" class="column">#right</div>
</div>
<div id="footer">#footer</div>


</body>

</html>

flex弹性盒子

header和footer设置样式,横向撑满。
container中的left、center、right依次排布即可
给container设置弹性布局 display: flex;
left和right区域定宽,center设置 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
44
45
46
47
48
49
50
51
52
<!DOCTYPE html>
<html>

<head>
<meta charset="utf-8">
<script src="http://lib.sinaapp.com/js/jquery/2.0.2/jquery-2.0.2.min.js"></script>
</head>
<style>
body {
min-width: 550px;
font-weight: bold;
font-size: 20px;
}
#header, #footer {
background: rgba(29, 27, 27, 0.726);
text-align: center;
height: 60px;
line-height: 60px;
}
#container {
display: flex;
}
#container .column {
text-align: center;
height: 300px;
line-height: 300px;
}
#center {
flex: 1;
background: rgb(206, 201, 201);
}
#left {
width: 200px;
background: rgba(95, 179, 235, 0.972);
}
#right {
width: 150px;
background: rgb(231, 105, 2);
}
</style>

<body>
<div id="header">#header</div>
<div id="container">
<div id="left" class="column">#left</div>
<div id="center" class="column">#center</div>
<div id="right" class="column">#right</div>
</div>
<div id="footer">#footer</div>
</body>

</html>

grid布局

把body划分成三行四列的网格

给body元素添加display: grid;属性变成一个grid(网格)
给header元素设置grid-row: 1; 和 grid-column: 1/5; 意思是占据第一行网格的从第一条列网格线开始到第五条列网格线结束
给footer元素设置grid-row: 1; 和 grid-column: 1/5; 意思是占据第三行网格的从第一条列网格线开始到第五条列网格线结束
给left元素设置grid-row: 2; 和 grid-column: 1/2; 意思是占据第二行网格的从第一条列网格线开始到第二条列网格线结束
给center元素设置grid-row: 2; 和 grid-column: 2/4; 意思是占据第二行网格的从第二条列网格线开始到第四条列网格线结束
给right元素设置grid-row: 2; 和 grid-column: 4/5; 意思是占据第二行网格的从第四条列网格线开始到第五条列网格线结束

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
57
58
59
60
<!DOCTYPE html>
<html>

<head>
<meta charset="utf-8">
<script src="http://lib.sinaapp.com/js/jquery/2.0.2/jquery-2.0.2.min.js"></script>
</head>
<style>
body {
min-width: 550px;
font-weight: bold;
font-size: 20px;
display: grid;
}
#header,
#footer {
background: rgba(29, 27, 27, 0.726);
text-align: center;
height: 60px;
line-height: 60px;
}
#header {
grid-row: 1;
grid-column: 1/5;
}
#footer {
grid-row: 3;
grid-column: 1/5;
}
.column {
text-align: center;
height: 300px;
line-height: 300px;
}
#left {
grid-row: 2;
grid-column: 1/2;
background: rgba(95, 179, 235, 0.972);
}
#center {
grid-row: 2;
grid-column: 2/4;
background: rgb(206, 201, 201);
}
#right {
grid-row: 2;
grid-column: 4/5;
background: rgb(231, 105, 2);
}
</style>

<body>
<div id="header">#header</div>
<div id="left" class="column">#left</div>
<div id="center" class="column">#center</div>
<div id="right" class="column">#right</div>
<div id="footer">#footer</div>
</body>

</html>

如何让元素的总宽度固定为 200px,不受 padding 影响?

1
2
3
4
5
.box {
box-sizing: border-box;
width: 200px;
padding: 20px; /* 内边距不会撑大盒子 */
}

如何让一个元素覆盖在另一个元素上方

1
2
3
4
.overlay {
position: absolute;
z-index: 100;
}

移动端适配

如何实现移动端1px边框

.box {
border: 1px solid #000;
@media (-webkit-min-device-pixel-ratio: 2) {
border-width: 0.5px; /* 高清屏适配 */
}
}

移动端点击 300ms 延迟如何解决

使用 <meta name="viewport" content="width=device-width"> 或 FastClick 库

过度和动画

如何实现无限循环动画

1
2
3
4
5
6
7
.box {
animation: spin 2s linear infinite;
}
@keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}

transform 和 position 动画的性能差异?

transform 和 opacity 不会触发重排(使用 GPU 加速),性能更高