Appearance
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元素之间的空白符(空格、换行、制表符)会被浏览器解析为一个空格字符,从而产生间距。
解决方法:
- 移除空格
html
<div>item1</div>
<div>item2</div>- 使用font-size: 0
css
.parent {
font-size: 0;
}
.child {
font-size: 14px;
}- 使用margin负值
css
.inline-block {
margin-right: -4px;
}- 使用flexbox
css
.parent {
display: flex;
}- 使用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. 避免频繁读取会引起回流的属性
offsetTop、offsetLeft、offsetWidth、offsetHeightclientTop、clientLeft、clientWidth、clientHeightscrollTop、scrollLeft、scrollWidth、scrollHeight
8. CSS选择器的优先级是怎样的?
参考答案:
优先级计算规则:
- 内联样式:1000
- ID选择器:100
- 类选择器、属性选择器、伪类选择器:10
- 标签选择器、伪元素选择器:1
- 通配符选择器: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的特性:
- 内部的Box会在垂直方向一个接一个地放置
- Box垂直方向的距离由margin决定,同一个BFC的相邻Box的margin会发生重叠
- BFC的区域不会与float box重叠
- BFC是页面上的一个隔离的独立容器
- 计算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. 使用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
层叠顺序(从底到顶):
- 层叠上下文的根
- z-index为负值的定位元素
- 非定位的块级元素
- 非定位的浮动元素
- 非定位的行内元素
- z-index为auto的定位元素
- 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;
}主要区别:
- 概念:伪类选择存在的元素的特定状态,伪元素创建虚拟元素
- 语法:伪类用单冒号,伪元素用双冒号(CSS3)
- 数量:一个元素可以有多个伪类,但只能有一个
::before和一个::after - 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;
}优点:
- 减少HTTP请求:多个图片合并为一个,减少服务器请求次数
- 提高加载速度:减少网络延迟,提升页面性能
- 减少服务器压力:降低并发请求数量
- 缓存友好:一次加载,多次使用
缺点:
- 维护困难:添加或修改图标需要重新生成整个Sprite图
- 内存占用:加载整张大图,即使只使用部分图标
- 不够灵活:图标大小固定,难以适应响应式设计
- 开发复杂:需要精确计算坐标位置
现代替代方案:
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;
}层叠解决冲突的步骤:
- 找出所有相关规则
- 按来源和重要性排序
- 按特殊性排序
- 按源码顺序排序(后来居上)
最佳实践:
- 避免使用
!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;
}