Skip to content

CSS面试题库

1. CSS中的animation、transition、transform有什么区别?

参考答案:

在CSS中,animation、transition和transform是用来创建动画效果的关键属性,它们各自具有不同的作用和特点。

animation:

  • 用于创建复杂的动画序列,可以控制多个关键帧
  • 可以设置动画的持续时间、延迟、重复次数、播放方向等
  • 需要配合@keyframes规则定义动画的各个阶段

transition:

  • 用于指定在元素状态改变时,要以何种方式过渡到新状态
  • 通过指定过渡的属性、持续时间、动画方式、延迟时间等来控制过渡效果
  • 适用于元素从一种状态平滑过渡到另一种状态

transform:

  • 用于对元素进行变形,例如平移、旋转、缩放、倾斜等
  • 通常与transition或animation结合使用,使得变形动画更加平滑
  • 不会影响文档流,只是视觉上的变化

2. 怎么做移动端的样式适配?

参考答案:

移动端样式适配的常见方法:

1. 响应式设计(Responsive Design)

  • 使用媒体查询(@media)针对不同屏幕尺寸设置不同样式
  • 采用流式布局,使用百分比、vw/vh等相对单位
  • 设置合适的viewport meta标签

2. 弹性布局

  • 使用Flexbox和Grid布局
  • 相对单位:rem、em、vw、vh等
  • 避免使用固定像素值

3. 移动端优先

  • 先设计移动端样式,再适配桌面端
  • 渐进增强的设计理念

4. 图片和多媒体适配

  • 使用响应式图片(srcset、picture标签)
  • 压缩优化图片大小
  • 使用矢量图标(SVG、字体图标)

3. 相邻的两个inline-block节点为什么会出现间距,该怎么解决?

参考答案:

出现间距的原因: inline-block元素之间的空白符(空格、换行、制表符)会被浏览器解析为一个空格字符,从而产生间距。

解决方法:

  1. 移除空格
html
<div>item1</div>
<div>item2</div>
  1. 使用font-size: 0
css
.parent {
  font-size: 0;
}
.child {
  font-size: 14px;
}
  1. 使用margin负值
css
.inline-block {
  margin-right: -4px;
}
  1. 使用flexbox
css
.parent {
  display: flex;
}
  1. 使用float
css
.inline-block {
  float: left;
}

4. CSS Grid网格布局的基本概念和使用方法?

参考答案:

基本概念:

  • Grid是二维布局系统,可以同时处理行和列
  • 由网格容器(Grid Container)和网格项目(Grid Items)组成
  • 通过网格线(Grid Lines)划分网格轨道(Grid Tracks)

容器属性:

css
.grid-container {
  display: grid;
  grid-template-columns: 1fr 2fr 1fr; /* 列的定义 */
  grid-template-rows: 100px 200px; /* 行的定义 */
  grid-gap: 10px; /* 网格间距 */
  grid-template-areas: /* 区域命名 */
    'header header header'
    'sidebar content content';
}

项目属性:

css
.grid-item {
  grid-column: 1 / 3; /* 占据列1到列3 */
  grid-row: 1 / 2; /* 占据行1到行2 */
  grid-area: header; /* 指定区域 */
}

兼容性:

  • 现代浏览器支持良好
  • IE 10+部分支持,需要使用-ms-前缀

5. CSS3新增了哪些特性?

参考答案:

1. 新增选择器

  • 属性选择器:[attr^="value"][attr$="value"][attr*="value"]
  • 伪类选择器::nth-child():nth-of-type():not()
  • 伪元素选择器:::before::after

2. 边框和背景

  • border-radius:圆角边框
  • box-shadow:盒子阴影
  • border-image:边框图片
  • 多重背景:background-image支持多个值

3. 文字效果

  • text-shadow:文字阴影
  • word-wrap:文字换行
  • @font-face:自定义字体

4. 颜色

  • RGBA颜色:rgba(255, 0, 0, 0.5)
  • HSLA颜色:hsla(120, 100%, 50%, 0.3)
  • 渐变:linear-gradient()radial-gradient()

5. 动画和变换

  • transition:过渡效果
  • transform:2D/3D变换
  • animation:关键帧动画

6. 布局

  • Flexbox弹性布局
  • Grid网格布局
  • Multi-column多列布局

6. CSS实现动画的方式有哪些?

参考答案:

1. Transition过渡动画

css
.box {
  transition: all 0.3s ease;
}
.box:hover {
  transform: scale(1.2);
}

2. Transform变换动画

css
.box {
  transform: translateX(100px) rotate(45deg) scale(1.5);
}

3. Animation关键帧动画

css
@keyframes slideIn {
  from {
    transform: translateX(-100%);
  }
  to {
    transform: translateX(0);
  }
}
.box {
  animation: slideIn 1s ease-in-out;
}

4. JavaScript动画

  • 使用requestAnimationFrame
  • 修改元素的style属性
  • 使用动画库如GSAP、Anime.js

5. SVG动画

  • SMIL动画
  • CSS动画应用于SVG元素
  • JavaScript控制SVG动画

6. Canvas动画

  • 使用Canvas API绘制动画帧
  • WebGL 3D动画

7. 什么是回流和重绘?如何减少回流和重绘?

参考答案:

回流(Reflow):

  • 当元素的几何信息发生变化时,浏览器需要重新计算元素的位置和大小
  • 触发条件:添加/删除元素、改变尺寸、改变位置、改变字体大小等

重绘(Repaint):

  • 当元素的外观发生变化但几何信息不变时,浏览器重新绘制元素
  • 触发条件:改变颜色、背景、阴影等样式属性

减少回流和重绘的方法:

1. 批量修改DOM

javascript
// 不好的做法
element.style.width = '100px'
element.style.height = '100px'
element.style.background = 'red'

// 好的做法
element.className = 'new-style'

2. 使用文档片段

javascript
const fragment = document.createDocumentFragment()
// 在fragment中操作
document.body.appendChild(fragment)

3. 使用transform和opacity

css
/* 使用transform代替改变位置 */
.move {
  transform: translateX(100px);
}

4. 避免频繁读取会引起回流的属性

  • offsetTopoffsetLeftoffsetWidthoffsetHeight
  • clientTopclientLeftclientWidthclientHeight
  • scrollTopscrollLeftscrollWidthscrollHeight

8. CSS选择器的优先级是怎样的?

参考答案:

优先级计算规则:

  1. 内联样式:1000
  2. ID选择器:100
  3. 类选择器、属性选择器、伪类选择器:10
  4. 标签选择器、伪元素选择器:1
  5. 通配符选择器:0

特殊规则:

  • !important具有最高优先级
  • 相同优先级时,后定义的样式覆盖先定义的
  • 继承的样式优先级最低

示例:

css
/* 优先级:1 + 10 + 1 = 12 */
div.container p {
  color: red;
}

/* 优先级:100 */
#header {
  color: blue;
}

/* 优先级:1000 */
<div style="color: green;">

/* 最高优先级 */
.text {
  color: yellow !important;
}

最佳实践:

  • 避免使用!important
  • 尽量使用类选择器
  • 保持选择器简洁
  • 使用CSS预处理器管理复杂样式

9. 什么是BFC(块级格式化上下文)?

参考答案:

BFC定义: Block Formatting Context,块级格式化上下文,是Web页面中盒模型布局的CSS渲染模式,指一个独立的渲染区域。

BFC的特性:

  1. 内部的Box会在垂直方向一个接一个地放置
  2. Box垂直方向的距离由margin决定,同一个BFC的相邻Box的margin会发生重叠
  3. BFC的区域不会与float box重叠
  4. BFC是页面上的一个隔离的独立容器
  5. 计算BFC的高度时,浮动元素也参与计算

触发BFC的条件:

  • 根元素(html)
  • float属性不为none
  • position为absolute或fixed
  • display为inline-block、table-cell、table-caption、flex、inline-flex
  • overflow不为visible

BFC的应用:

1. 解决margin重叠

css
.bfc {
  overflow: hidden; /* 创建BFC */
}

2. 清除浮动

css
.clearfix {
  overflow: hidden; /* 包含浮动子元素 */
}

3. 防止文字环绕

css
.sidebar {
  float: left;
  width: 200px;
}
.content {
  overflow: hidden; /* 创建BFC,不与浮动元素重叠 */
}

10. Flexbox布局的主要特性和使用方法?

参考答案:

基本概念:

  • 主轴(main axis)和交叉轴(cross axis)
  • 容器(flex container)和项目(flex items)
  • 一维布局系统,主要处理一个方向上的布局

容器属性:

css
.flex-container {
  display: flex;
  flex-direction: row | column; /* 主轴方向 */
  flex-wrap: nowrap | wrap; /* 是否换行 */
  justify-content: flex-start | center | space-between; /* 主轴对齐 */
  align-items: stretch | center | flex-start; /* 交叉轴对齐 */
  align-content: stretch | center; /* 多行对齐 */
}

项目属性:

css
.flex-item {
  flex-grow: 1; /* 放大比例 */
  flex-shrink: 1; /* 缩小比例 */
  flex-basis: auto; /* 基础大小 */
  flex: 1; /* flex-grow, flex-shrink, flex-basis的简写 */
  align-self: auto | center; /* 单独的对齐方式 */
  order: 0; /* 排列顺序 */
}

常用布局模式:

1. 水平垂直居中

css
.center {
  display: flex;
  justify-content: center;
  align-items: center;
}

2. 等分布局

css
.equal {
  display: flex;
}
.equal > div {
  flex: 1;
}

3. 固定侧边栏

css
.layout {
  display: flex;
}
.sidebar {
  flex: 0 0 200px;
}
.content {
  flex: 1;
}

11. CSS中的position属性有哪些值?

参考答案:

1. static(默认值)

  • 正常文档流定位
  • top、right、bottom、left属性无效
  • 不会创建新的层叠上下文

2. relative(相对定位)

  • 相对于元素在正常文档流中的位置定位
  • 不脱离文档流,原位置保留
  • 可以使用z-index
css
.relative {
  position: relative;
  top: 10px;
  left: 20px;
}

3. absolute(绝对定位)

  • 相对于最近的已定位祖先元素定位
  • 脱离文档流
  • 如果没有已定位祖先,则相对于初始包含块定位
css
.absolute {
  position: absolute;
  top: 0;
  right: 0;
}

4. fixed(固定定位)

  • 相对于视口定位
  • 脱离文档流
  • 滚动时位置不变
css
.fixed {
  position: fixed;
  bottom: 20px;
  right: 20px;
}

5. sticky(粘性定位)

  • 根据滚动位置在relative和fixed之间切换
  • 需要指定top、right、bottom、left中的一个
css
.sticky {
  position: sticky;
  top: 0;
}

12. 如何实现元素的水平垂直居中?

参考答案:

1. Flexbox方法

css
.center {
  display: flex;
  justify-content: center;
  align-items: center;
}

2. Grid方法

css
.center {
  display: grid;
  place-items: center;
}

3. 绝对定位 + transform

css
.center {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

4. 绝对定位 + margin

css
.center {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  margin: auto;
  width: 200px;
  height: 100px;
}

5. table-cell方法

css
.center {
  display: table-cell;
  text-align: center;
  vertical-align: middle;
}

6. line-height方法(单行文本)

css
.center {
  height: 100px;
  line-height: 100px;
  text-align: center;
}

13. CSS盒模型是什么?

参考答案:

盒模型组成: CSS盒模型由内容(content)、内边距(padding)、边框(border)、外边距(margin)四部分组成。

两种盒模型:

1. 标准盒模型(content-box)

  • 宽度 = 内容宽度
  • 总宽度 = width + padding + border + margin

2. IE盒模型(border-box)

  • 宽度 = 内容宽度 + padding + border
  • 总宽度 = width + margin

box-sizing属性:

css
/* 标准盒模型 */
.standard {
  box-sizing: content-box;
}

/* IE盒模型 */
.border-box {
  box-sizing: border-box;
}

示例:

css
.box {
  width: 200px;
  padding: 20px;
  border: 5px solid #000;
  margin: 10px;
}

/* content-box: 总宽度 = 200 + 40 + 10 + 20 = 270px */
/* border-box: 总宽度 = 200 + 20 = 220px */

最佳实践:

css
* {
  box-sizing: border-box;
}

14. CSS中的float属性及其清除浮动的方法?

参考答案:

float属性:

  • left:元素向左浮动
  • right:元素向右浮动
  • none:默认值,不浮动

浮动的特性:

  1. 脱离文档流
  2. 向左或向右移动,直到碰到容器边缘或另一个浮动元素
  3. 浮动元素会尽可能向上移动
  4. 浮动元素不会超出包含块

清除浮动的方法:

1. 使用clear属性

css
.clear {
  clear: both; /* left | right | both */
}

2. 父元素添加overflow

css
.clearfix {
  overflow: hidden; /* 或 auto */
}

3. 使用伪元素清除

css
.clearfix::after {
  content: '';
  display: table;
  clear: both;
}

4. 父元素也浮动

css
.parent {
  float: left;
  width: 100%;
}

5. 使用display: flow-root

css
.clearfix {
  display: flow-root;
}

现代替代方案:

  • 使用Flexbox布局
  • 使用Grid布局
  • 避免使用float进行布局

15. CSS中的z-index属性如何工作?

参考答案:

z-index基本概念:

  • 控制元素在z轴(垂直于屏幕)上的堆叠顺序
  • 只对定位元素(position不为static)有效
  • 数值越大,元素越靠前

层叠上下文(Stacking Context):

创建层叠上下文的条件:

  • 根元素(html)
  • position为absolute或relative且z-index不为auto
  • position为fixed或sticky
  • flex项目且z-index不为auto
  • opacity小于1
  • transform不为none
  • filter不为none

层叠顺序(从底到顶):

  1. 层叠上下文的根
  2. z-index为负值的定位元素
  3. 非定位的块级元素
  4. 非定位的浮动元素
  5. 非定位的行内元素
  6. z-index为auto的定位元素
  7. z-index为正值的定位元素

示例:

css
.context {
  position: relative;
  z-index: 1;
}

.child1 {
  position: absolute;
  z-index: 100;
}

.child2 {
  position: absolute;
  z-index: 200;
}

注意事项:

  • 子元素的z-index只在父级层叠上下文内有效
  • 不要滥用过大的z-index值
  • 建议使用合理的z-index分层策略

16. CSS预处理器(Sass/Less)的优势是什么?

参考答案:

主要优势:

1. 变量(Variables)

scss
// Sass
$primary-color: #3498db;
$font-size: 16px;

.button {
  background-color: $primary-color;
  font-size: $font-size;
}

2. 嵌套(Nesting)

scss
.navbar {
  background: #333;

  ul {
    margin: 0;
    padding: 0;
  }

  li {
    list-style: none;

    a {
      text-decoration: none;
      color: white;

      &:hover {
        color: #ccc;
      }
    }
  }
}

3. 混合(Mixins)

scss
@mixin border-radius($radius) {
  -webkit-border-radius: $radius;
  -moz-border-radius: $radius;
  border-radius: $radius;
}

.button {
  @include border-radius(5px);
}

4. 继承(Inheritance)

scss
.message {
  border: 1px solid #ccc;
  padding: 10px;
  color: #333;
}

.success {
  @extend .message;
  border-color: green;
}

5. 函数和运算

scss
$base-font-size: 16px;

.title {
  font-size: $base-font-size * 1.5;
  margin-bottom: $base-font-size / 2;
}

6. 模块化

scss
// _variables.scss
$primary-color: #3498db;

// _mixins.scss
@mixin flex-center {
  display: flex;
  justify-content: center;
  align-items: center;
}

// main.scss
@import 'variables';
@import 'mixins';

其他优势:

  • 更好的代码组织和维护
  • 减少代码重复
  • 支持条件语句和循环
  • 丰富的内置函数
  • 更好的团队协作

17. 如何实现响应式设计?

参考答案:

1. 媒体查询(Media Queries)

css
/* 移动端优先 */
.container {
  width: 100%;
  padding: 10px;
}

/* 平板 */
@media (min-width: 768px) {
  .container {
    width: 750px;
    margin: 0 auto;
  }
}

/* 桌面端 */
@media (min-width: 1200px) {
  .container {
    width: 1170px;
  }
}

2. 流式布局

css
.container {
  max-width: 1200px;
  width: 100%;
  margin: 0 auto;
}

.column {
  width: 48%;
  float: left;
  margin: 1%;
}

3. 弹性图片

css
img {
  max-width: 100%;
  height: auto;
}

/* 响应式背景图 */
.hero {
  background-image: url('mobile.jpg');
}

@media (min-width: 768px) {
  .hero {
    background-image: url('desktop.jpg');
  }
}

4. 相对单位

css
.text {
  font-size: 1rem; /* 相对于根元素 */
  padding: 2em; /* 相对于当前元素 */
  width: 50vw; /* 相对于视口宽度 */
  height: 100vh; /* 相对于视口高度 */
}

5. Flexbox和Grid

css
.flex-container {
  display: flex;
  flex-wrap: wrap;
}

.flex-item {
  flex: 1 1 300px; /* 最小宽度300px */
}

.grid-container {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 20px;
}

6. 视口设置

html
<meta name="viewport" content="width=device-width, initial-scale=1.0" />

断点策略:

  • 移动端:320px - 767px
  • 平板:768px - 1023px
  • 桌面:1024px+

18. CSS中的伪类和伪元素有什么区别?

参考答案:

伪类(Pseudo-classes): 用于选择处于特定状态的元素,以单冒号:表示。

常用伪类:

css
/* 链接状态 */
a:link {
  color: blue;
}
a:visited {
  color: purple;
}
a:hover {
  color: red;
}
a:active {
  color: orange;
}

/* 结构伪类 */
li:first-child {
  font-weight: bold;
}
li:last-child {
  margin-bottom: 0;
}
li:nth-child(2n) {
  background: #f0f0f0;
}
li:nth-child(odd) {
  background: white;
}

/* 状态伪类 */
input:focus {
  border-color: blue;
}
input:disabled {
  opacity: 0.5;
}
input:checked + label {
  color: green;
}

/* 否定伪类 */
p:not(.special) {
  color: gray;
}

伪元素(Pseudo-elements): 用于创建和样式化不存在于HTML中的元素,以双冒号::表示(CSS3规范,但单冒号也兼容)。

常用伪元素:

css
/* 首字母和首行 */
p::first-letter {
  font-size: 2em;
  float: left;
}

p::first-line {
  font-weight: bold;
}

/* 前后插入内容 */
.quote::before {
  content: '' ';
  font-size: 2em;
}

.quote::after {
  content: ' '';
  font-size: 2em;
}

/* 选中文本 */
::selection {
  background: yellow;
  color: black;
}

/* 占位符 */
input::placeholder {
  color: #999;
  font-style: italic;
}

主要区别:

  1. 概念:伪类选择存在的元素的特定状态,伪元素创建虚拟元素
  2. 语法:伪类用单冒号,伪元素用双冒号(CSS3)
  3. 数量:一个元素可以有多个伪类,但只能有一个::before和一个::after
  4. DOM:伪类不创建新元素,伪元素创建虚拟元素

19. 什么是CSS Sprites?有什么优缺点?

参考答案:

CSS Sprites定义: CSS Sprites是一种网页图片应用处理方式,它将多个小图片合并成一张大图片,然后通过CSS的background-position属性来显示所需的图片部分。

实现方法:

css
.sprite {
  background-image: url('sprites.png');
  background-repeat: no-repeat;
  display: inline-block;
}

.icon-home {
  width: 32px;
  height: 32px;
  background-position: 0 0;
}

.icon-user {
  width: 32px;
  height: 32px;
  background-position: -32px 0;
}

.icon-settings {
  width: 32px;
  height: 32px;
  background-position: -64px 0;
}

优点:

  1. 减少HTTP请求:多个图片合并为一个,减少服务器请求次数
  2. 提高加载速度:减少网络延迟,提升页面性能
  3. 减少服务器压力:降低并发请求数量
  4. 缓存友好:一次加载,多次使用

缺点:

  1. 维护困难:添加或修改图标需要重新生成整个Sprite图
  2. 内存占用:加载整张大图,即使只使用部分图标
  3. 不够灵活:图标大小固定,难以适应响应式设计
  4. 开发复杂:需要精确计算坐标位置

现代替代方案:

1. 字体图标

css
@font-face {
  font-family: 'iconfont';
  src: url('iconfont.woff2') format('woff2');
}

.icon {
  font-family: 'iconfont';
}

.icon-home::before {
  content: '\e001';
}

2. SVG图标

html
<svg class="icon">
  <use xlink:href="#icon-home"></use>
</svg>

3. Base64内联

css
.icon {
  background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8/5+hHgAHggJ/PchI7wAAAABJRU5ErkJggg==');
}

20. CSS中的单位有哪些?

参考答案:

绝对单位:

1. px(像素)

css
.box {
  width: 300px;
  height: 200px;
}

2. pt(点)

  • 1pt = 1/72英寸
  • 主要用于打印样式

3. pc(派卡)

  • 1pc = 12pt

4. in(英寸)、cm(厘米)、mm(毫米)

css
@media print {
  .page {
    width: 8.5in;
    height: 11in;
  }
}

相对单位:

1. em

  • 相对于当前元素的字体大小
css
.parent {
  font-size: 16px;
}
.child {
  font-size: 1.5em; /* 24px */
  padding: 1em; /* 24px */
}

2. rem

  • 相对于根元素的字体大小
css
html {
  font-size: 16px;
}
.text {
  font-size: 1.2rem; /* 19.2px */
  margin: 2rem; /* 32px */
}

3. %(百分比)

css
.container {
  width: 80%; /* 相对于父元素宽度 */
  font-size: 120%; /* 相对于父元素字体大小 */
}

视口单位:

1. vw(视口宽度)

  • 1vw = 视口宽度的1%
css
.full-width {
  width: 100vw;
}

2. vh(视口高度)

  • 1vh = 视口高度的1%
css
.full-height {
  height: 100vh;
}

3. vmin和vmax

css
.square {
  width: 50vmin; /* 视口较小尺寸的50% */
  height: 50vmin;
}

新单位(CSS3+):

1. ch

  • 相对于字符"0"的宽度
css
.monospace {
  width: 40ch; /* 大约40个字符宽度 */
}

2. ex

  • 相对于字母"x"的高度

使用建议:

  • 字体大小:rem
  • 间距:rem或em
  • 边框:px
  • 布局宽度:%或vw
  • 响应式设计:相对单位优先

21. 如何实现CSS三角形?

参考答案:

基本原理: 利用border属性,将元素的宽高设为0,通过设置不同方向的border来形成三角形。

1. 向上的三角形

css
.triangle-up {
  width: 0;
  height: 0;
  border-left: 25px solid transparent;
  border-right: 25px solid transparent;
  border-bottom: 40px solid #333;
}

2. 向下的三角形

css
.triangle-down {
  width: 0;
  height: 0;
  border-left: 25px solid transparent;
  border-right: 25px solid transparent;
  border-top: 40px solid #333;
}

3. 向左的三角形

css
.triangle-left {
  width: 0;
  height: 0;
  border-top: 25px solid transparent;
  border-bottom: 25px solid transparent;
  border-right: 40px solid #333;
}

4. 向右的三角形

css
.triangle-right {
  width: 0;
  height: 0;
  border-top: 25px solid transparent;
  border-bottom: 25px solid transparent;
  border-left: 40px solid #333;
}

其他形状:

5. 等腰直角三角形

css
.triangle-right-angle {
  width: 0;
  height: 0;
  border-top: 50px solid #333;
  border-right: 50px solid transparent;
}

6. 聊天气泡

css
.chat-bubble {
  position: relative;
  background: #333;
  padding: 10px 15px;
  border-radius: 10px;
  color: white;
}

.chat-bubble::after {
  content: '';
  position: absolute;
  top: 100%;
  left: 20px;
  width: 0;
  height: 0;
  border-left: 10px solid transparent;
  border-right: 10px solid transparent;
  border-top: 10px solid #333;
}

现代替代方案:

1. 使用clip-path

css
.triangle-clip {
  width: 100px;
  height: 100px;
  background: #333;
  clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
}

2. 使用transform

css
.triangle-transform {
  width: 50px;
  height: 50px;
  background: #333;
  transform: rotate(45deg);
}

3. 使用SVG

html
<svg width="100" height="100">
  <polygon points="50,0 0,100 100,100" fill="#333" />
</svg>

22. CSS中的层叠规则是什么?

参考答案:

层叠(Cascade)的含义: CSS的"层叠"指的是当多个规则应用到同一个元素时,如何确定最终应用哪个规则的机制。

层叠顺序(按优先级从低到高):

1. 浏览器默认样式

css
/* 浏览器默认样式 */
p {
  margin: 1em 0;
}

2. 用户样式表

  • 用户在浏览器中设置的样式

3. 作者样式表(网站开发者编写的样式)

css
/* 外部样式表 */
@import url('style.css');

/* 内部样式表 */
<style>
  p { color: blue; }
</style>

/* 内联样式 */
<p style="color: red;">

4. 作者!important声明

css
p {
  color: green !important;
}

5. 用户!important声明

  • 用户设置的!important样式

6. 浏览器!important声明

  • 浏览器默认的!important样式

特殊性(Specificity)计算:

计算规则:

  • 内联样式:1000
  • ID选择器:100
  • 类、属性、伪类选择器:10
  • 元素、伪元素选择器:1

示例:

css
/* 特殊性:0001 */
p {
  color: black;
}

/* 特殊性:0010 */
.text {
  color: blue;
}

/* 特殊性:0100 */
#title {
  color: red;
}

/* 特殊性:0111 */
#title.text p {
  color: green;
}

/* 特殊性:1000 */
<p style="color: yellow;">

/* 最高优先级 */
p {
  color: purple !important;
}

层叠解决冲突的步骤:

  1. 找出所有相关规则
  2. 按来源和重要性排序
  3. 按特殊性排序
  4. 按源码顺序排序(后来居上)

最佳实践:

  • 避免使用!important
  • 保持选择器简洁
  • 使用有意义的类名
  • 遵循CSS架构方法(BEM、OOCSS等)

23. 什么是CSS-in-JS?有什么优缺点?

参考答案:

CSS-in-JS定义: CSS-in-JS是一种将CSS样式直接写在JavaScript代码中的技术,通常与React等组件化框架一起使用。

常见的CSS-in-JS库:

1. Styled-components

jsx
import styled from 'styled-components'

const Button = styled.button`
  background: ${props => (props.primary ? 'blue' : 'white')};
  color: ${props => (props.primary ? 'white' : 'blue')};
  font-size: 1em;
  margin: 1em;
  padding: 0.25em 1em;
  border: 2px solid blue;
  border-radius: 3px;
  cursor: pointer;

  &:hover {
    background: ${props => (props.primary ? 'darkblue' : 'lightblue')};
  }
`

// 使用
;<Button primary>Primary Button</Button>

2. Emotion

jsx
import { css } from '@emotion/react'

const buttonStyle = css`
  background: hotpink;
  &:hover {
    background: pink;
  }
`

;<button css={buttonStyle}>Click me</button>

3. JSS

jsx
import { createUseStyles } from 'react-jss'

const useStyles = createUseStyles({
  button: {
    background: 'blue',
    color: 'white',
    '&:hover': {
      background: 'darkblue'
    }
  }
})

function Button() {
  const classes = useStyles()
  return <button className={classes.button}>Click me</button>
}

优点:

1. 组件化

  • 样式与组件紧密绑定
  • 更好的封装性和可维护性

2. 动态样式

jsx
const Button = styled.button`
  background: ${props => props.theme.primary};
  opacity: ${props => (props.disabled ? 0.5 : 1)};
`

3. 自动前缀

  • 自动添加浏览器前缀
  • 处理兼容性问题

4. 死代码消除

  • 未使用的样式会被自动移除
  • 减少最终打包大小

5. 主题支持

jsx
const theme = {
  primary: 'blue',
  secondary: 'green'
}

;<ThemeProvider theme={theme}>
  <App />
</ThemeProvider>

缺点:

1. 学习成本

  • 需要学习新的API和语法
  • 与传统CSS开发方式不同

2. 运行时开销

  • 样式在运行时生成
  • 可能影响性能

3. 调试困难

  • 生成的类名不直观
  • 调试工具支持有限

4. 服务端渲染复杂

  • SSR配置相对复杂
  • 需要额外的设置

5. 工具链依赖

  • 依赖JavaScript构建工具
  • 增加了项目复杂度

适用场景:

  • React/Vue等组件化项目
  • 需要动态样式的应用
  • 大型团队协作项目
  • 需要严格样式隔离的场景

24. 如何实现CSS动画的性能优化?

参考答案:

1. 使用transform和opacity

这两个属性不会触发重排(reflow),只会触发重绘(repaint)或合成(composite)。

css
/* 好的做法 */
.animate {
  transform: translateX(100px);
  opacity: 0.5;
  transition:
    transform 0.3s,
    opacity 0.3s;
}

/* 避免的做法 */
.animate {
  left: 100px; /* 会触发重排 */
  width: 200px; /* 会触发重排 */
}

2. 启用硬件加速

css
.accelerated {
  transform: translateZ(0); /* 或 translate3d(0,0,0) */
  /* 或者 */
  will-change: transform;
}

3. 使用will-change属性

css
.element {
  will-change: transform, opacity;
}

/* 动画结束后移除 */
.element.animation-finished {
  will-change: auto;
}

4. 避免动画期间的重排属性

css
/* 会触发重排的属性(避免动画) */
.bad {
  animation: badAnimation 1s;
}

@keyframes badAnimation {
  from {
    width: 100px;
    height: 100px;
  }
  to {
    width: 200px;
    height: 200px;
  }
}

/* 好的替代方案 */
.good {
  animation: goodAnimation 1s;
}

@keyframes goodAnimation {
  from {
    transform: scale(1);
  }
  to {
    transform: scale(2);
  }
}

5. 使用CSS动画而非JavaScript

css
/* CSS动画 - 更好的性能 */
.css-animation {
  animation: slideIn 0.3s ease-out;
}

@keyframes slideIn {
  from {
    transform: translateX(-100%);
  }
  to {
    transform: translateX(0);
  }
}

6. 合理使用动画时长和缓动函数

css
.smooth {
  transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

/* 避免过长的动画时间 */
.too-slow {
  transition: transform 2s; /* 用户可能感到不耐烦 */
}

7. 减少同时运行的动画数量

javascript
// 使用requestAnimationFrame控制动画
function animate() {
  // 批量更新DOM
  elements.forEach(el => {
    el.style.transform = `translateX(${getNewPosition()}px)`
  })

  requestAnimationFrame(animate)
}

8. 使用transform3d强制开启GPU加速

css
.gpu-accelerated {
  transform: translate3d(0, 0, 0);
  /* 或者 */
  transform: translateZ(0);
  /* 或者 */
  backface-visibility: hidden;
}

9. 避免在动画中使用box-shadow

css
/* 性能较差 */
.shadow-animation {
  transition: box-shadow 0.3s;
}
.shadow-animation:hover {
  box-shadow: 0 10px 20px rgba(0, 0, 0, 0.3);
}

/* 更好的替代方案 */
.pseudo-shadow {
  position: relative;
}
.pseudo-shadow::after {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  box-shadow: 0 10px 20px rgba(0, 0, 0, 0.3);
  opacity: 0;
  transition: opacity 0.3s;
}
.pseudo-shadow:hover::after {
  opacity: 1;
}

10. 性能监控和调试

javascript
// 使用Performance API监控
performance.mark('animation-start')
// 动画代码
performance.mark('animation-end')
performance.measure('animation-duration', 'animation-start', 'animation-end')

最佳实践总结:

  • 优先使用transform和opacity
  • 合理使用will-change
  • 避免在动画中修改布局属性
  • 使用CSS动画替代JavaScript动画
  • 监控和测试动画性能

25. CSS中的@media查询有哪些常用的特性?

参考答案:

基本语法:

css
@media media-type and (media-feature) {
  /* CSS规则 */
}

媒体类型(Media Types):

css
@media screen {
  /* 屏幕设备 */
}
@media print {
  /* 打印设备 */
}
@media speech {
  /* 语音合成器 */
}
@media all {
  /* 所有设备(默认) */
}

常用媒体特性:

1. 宽度和高度

css
/* 视口宽度 */
@media (max-width: 768px) {
  .container {
    width: 100%;
  }
}

@media (min-width: 1200px) {
  .container {
    width: 1170px;
  }
}

/* 设备宽度 */
@media (max-device-width: 480px) {
  body {
    font-size: 14px;
  }
}

/* 高度 */
@media (max-height: 600px) {
  .header {
    height: 40px;
  }
}

2. 方向

css
/* 横屏 */
@media (orientation: landscape) {
  .sidebar {
    width: 300px;
  }
}

/* 竖屏 */
@media (orientation: portrait) {
  .sidebar {
    width: 100%;
  }
}

3. 分辨率

css
/* 高分辨率屏幕 */
@media (min-resolution: 2dppx) {
  .logo {
    background-image: url('logo@2x.png');
  }
}

/* Retina屏幕 */
@media (-webkit-min-device-pixel-ratio: 2) {
  .icon {
    background-size: 50% 50%;
  }
}

4. 颜色

css
/* 彩色屏幕 */
@media (color) {
  .colorful {
    color: red;
  }
}

/* 黑白屏幕 */
@media (monochrome) {
  .image {
    filter: grayscale(100%);
  }
}

5. 指针设备

css
/* 触摸设备 */
@media (pointer: coarse) {
  .button {
    min-height: 44px;
  }
}

/* 鼠标等精确指针 */
@media (pointer: fine) {
  .button {
    min-height: 32px;
  }
}

/* 悬停支持 */
@media (hover: hover) {
  .button:hover {
    background: #ccc;
  }
}

6. 暗色模式

css
/* 暗色主题 */
@media (prefers-color-scheme: dark) {
  body {
    background: #333;
    color: white;
  }
}

/* 亮色主题 */
@media (prefers-color-scheme: light) {
  body {
    background: white;
    color: black;
  }
}

7. 动画偏好

css
/* 用户偏好减少动画 */
@media (prefers-reduced-motion: reduce) {
  * {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

逻辑操作符:

1. and操作符

css
@media screen and (min-width: 768px) and (max-width: 1023px) {
  .tablet-only {
    display: block;
  }
}

2. or操作符(逗号)

css
@media (max-width: 768px), (orientation: portrait) {
  .mobile-or-portrait {
    width: 100%;
  }
}

3. not操作符

css
@media not screen {
  .no-screen {
    display: none;
  }
}

4. only操作符

css
@media only screen and (max-width: 768px) {
  .mobile-only {
    display: block;
  }
}

常用断点:

css
/* 移动端 */
@media (max-width: 767px) {
}

/* 平板 */
@media (min-width: 768px) and (max-width: 1023px) {
}

/* 桌面端 */
@media (min-width: 1024px) {
}

/* 大屏幕 */
@media (min-width: 1200px) {
}

最佳实践:

  • 移动端优先设计
  • 使用相对单位
  • 测试各种设备和屏幕尺寸
  • 考虑用户偏好设置
  • 合理组织媒体查询代码

26. 如何实现CSS的垂直居中?

参考答案:

1. Flexbox方法(推荐)

css
.container {
  display: flex;
  align-items: center; /* 垂直居中 */
  justify-content: center; /* 水平居中 */
  height: 100vh;
}

2. Grid方法

css
.container {
  display: grid;
  place-items: center;
  height: 100vh;
}

/* 或者 */
.container {
  display: grid;
  align-items: center;
  justify-items: center;
  height: 100vh;
}

3. 绝对定位 + transform

css
.container {
  position: relative;
  height: 100vh;
}

.centered {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

4. 绝对定位 + margin auto

css
.container {
  position: relative;
  height: 100vh;
}

.centered {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  margin: auto;
  width: 200px; /* 需要固定宽度 */
  height: 100px; /* 需要固定高度 */
}

5. table-cell方法

css
.container {
  display: table-cell;
  vertical-align: middle;
  text-align: center;
  width: 100vw;
  height: 100vh;
}

6. line-height方法(单行文本)

css
.container {
  height: 100px;
  line-height: 100px;
  text-align: center;
}

.centered {
  display: inline-block;
  vertical-align: middle;
  line-height: normal;
}

基于 VitePress 的本地知识库