css面试题
约 6187 字大约 21 分钟
2025-05-28
原文链接:https://juejin.cn/post/6905539198107942919
1.CSS盒模型,在不同浏览器的差异
CSS3中的盒模型有以下两种:标准盒子模型、IE盒子模型
盒模型都是由四个部分组成的,分别是margin、border、padding和content。
标准盒模型和IE盒模型的区别在于设置width和height时,所对应的范围不同:
- 标准盒模型的width和height属性的范围只包含了content,
- IE盒模型的width和height属性的范围包含了border、padding和content。
可以通过修改元素的box-sizing属性来改变元素的盒模型:
box-sizeing: content-box
表示标准盒模型(默认值)box-sizeing: border-box
表示IE盒模型(怪异盒模型)当设置宽高时,不用计算。
2. CSS选择器及其优先级
选择器 | 格式 | 优先级权重 |
---|---|---|
id选择器 | #id | 100 |
类选择器 | #classname | 10 |
属性选择器 | a[ref=“eee”] | 10 |
伪类选择器 | li:last-child | 10 |
标签选择器 | div | 1 |
伪元素选择器 | li:after | 1 |
相邻兄弟选择器 | h1+p | 0 |
子选择器 | ul>li | 0 |
后代选择器 | li a | 0 |
通配符选择器 | * | 0 |
!important > 行内样式>id选择器>类选择器>伪类选择器>属性选择器>标签选择器> 通配符选择器(* 应少用)
1.CSS哪些属性可以继承?
css继承特性主要是指文本方面的继承(比如字体、颜色、字体大小等),盒模型相关的属性基本没有继承特性。
不可继承的:display、margin、border、padding、background、height、min-height、max-height、width、min-width、max-width、overflow、position、top、bottom、left、right、z-index、float
可继承的:visibility、cursorcolor、font、font-family、font-size、font-style、font-variant、font-weight、text-decoration、text-transform、direction
2.CSS伪类和伪元素有哪些,它们的区别和实际应用
伪类的例子有:
将特殊的效果添加到特定选择器上。它是已有元素上添加类别的,不会产生新的元素
:hover(鼠标悬停时生效)
:active(元素被激活时生效,如点击瞬间)
:first-child(选择父元素的第一个子元素)
:visited(已访问链接的样式)
伪元素的例子有:(用于创建虚拟元素或修饰元素特定部分,这些内容不存在于DOM树中,但可通过CSS渲染。)
在内容元素的前后插入额外的元素或样式,它们只在外部显示可见,但不会在文档的源代码中找到它们,因此,称为“伪”元素。
::first-line
::first-letter
::after
::before
二、核心区别
特性 | 伪类 | 伪元素 |
---|---|---|
作用对象 | 已有元素的特定状态或结构 | 创建虚拟元素或操作元素特定部分 |
语法 | 单冒号(如 :hover ) | 双冒号(如 ::before ) |
DOM存在性 | 操作文档树中已有元素 | 创建不在文档树中的虚拟元素 |
常见用途 | 交互反馈(悬停、表单状态) | 装饰性内容(插入图标、首行排版) |
3.常用at规则及使用示例:
@charset
功能:定义CSS文件的字符编码,需置于文件首行
@charset "UTF-8"; /* 正确:双引号包裹,无前置字符 */
@import
功能:导入其他CSS文件,可附加媒体查询条件
@import url("print.css") print; /* 仅在打印时生效 */
@namespace
功能:处理混合命名空间文档(如HTML内嵌SVG)
@namespace svg url(http://www.w3.org/2000/svg);
@font-face
功能:加载本地或远程字体文件
@font-face { font-family: 'Open Sans'; src: local('Open Sans'), /* 优先使用本地字体 */ url('/fonts/OpenSans.woff2') format('woff2'), url('/fonts/OpenSans.ttf') format('truetype'); font-weight: 400; font-style: normal; }
@keyframes
功能:定义动画序列,配合
animation
属性使用@keyframes fadeIn { 0% { opacity: 0; transform: translateY(20px); } 100% { opacity: 1; transform: translateY(0); } } .element { animation: fadeIn 1s ease-out; }
@media
功能:响应式设计,根据设备特性应用样式
/* 手机端样式 */ @media (max-width: 600px) { .menu { display: none; } body { font-size: 14px; } } /* 高分辨率屏幕适配 */ @media (min-resolution: 2dppx) { .logo { background-image: url("logo@2x.png"); } }// 打印专用样式 @media print { .seal1 { background-image: url('./image/seal.png') !important; // 强制生效 -webkit-print-color-adjust: exact; // Chrome兼容性设置 print-color-adjust: exact; } }
@page
功能:调整打印页面尺寸、边距和分页符
@page { size: A4 landscape; /* A4横向纸张 */ margin: 2cm; @top-left { content: "公司报告"; } /* 页眉 */ @bottom-right { content: "页码 " counter(page); } /* 页脚 */ }
@supports
功能:检测浏览器是否支持特定CSS特性
/* 支持Grid布局时启用 */ @supports (display: grid) { .container { display: grid; grid-template-columns: 1fr 1fr; } } /* 不支持Flexbox时降级处理 */ @supports not (display: flex) { .nav { float: left; } /* 回退到浮动布局 */ }
4. display的block、inline和inline-block的区别
(1)行内元素
设置宽高无效;
可以设置水平方向的margin和padding属性,不能设置垂直方向的padding和margin;
不会自动换行;
(2)块级元素
可以设置宽高;
设置margin和padding都有效;
可以自动换行;
- 多个块状,默认排列从上到下。
- block:将元素转换为块级元素,独占一行
- inline:将元素设置为行内元素
- inline-block:将元素设置为行内块元素,就是不独占一行的块级元素。
5. 隐藏元素的方法有哪些
- display: none 渲染树中不会再包含这个节点,(相当于没有这个)
- visibility: hidden:元素在页面中仍占据空间,但是不会响应绑定的监听事件。是继承属性,子孙节点消失是由于继承了
hidden
通过设置visibility:visible
可以让子孙节点显示。 - opacity: 0:将元素变为透明 ,元素在页面中仍占据空间,并且能够响应元素绑定的监听事件。
- z-index: 负值:来使其他元素遮盖住该元素,以此来实现隐藏。
- transform: scale(0,0):将元素缩放为 0,来实现元素的隐藏。这种方法下,元素仍在页面中占据位置,但是不会响应绑定的监听事件。
6. link和@import的区别
两者都是外部引用CSS的方式,它们的区别如下:
- link引用CSS时,在页面载入时同时加载;@import需要页面网页完全载入以后加载。
- ink是XHTML标签,无兼容问题;@import是在CSS2.1提出的,低版本的浏览器不支持。
- link支持使用Javascript控制DOM去改变样式;而@import不支持。
7. transition和animation的区别
transition是过度属性:强调过渡,需要有事件触发执行,设置一个开始关键帧,一个结束关键帧。
animation是动画属性:不需要事件触发,可以分成很多针。
8. requestAnimationframe的理解
requestAnimationframe 和js利用setTimeout 和css利用transform、Animation,HTML5 中的 canvas 一样都是执行动画,
此方法是请求动画的API请求动画的API
使用方法
window.requestAnimationframe(callback) 参数是一个回调函数,callback下一次重绘之前更新动画帧所调用的函数,此方法返回一个唯一的id,可用于cancelAnimationFrame(id)关闭动画
该方法属于宏任务,所以会在执行完微任务之后再去执行。
9.为什么有时候⽤translate来改变位置⽽不是定位?
- transform 不会引起页面重新布局,性能比定位高一些。
- transform改变位置时 会占据其原始空间。
10. li 与 li 之间有看不见的空白间隔是什么原因引起的?如何解决?
产生原因:
浏览器会把行内元素间的空白字符(空格、换行、Tab等)渲染成一个空格。为了美观,通常是一个<li>
放在一行,这导致<li>
换行后产生换行字符,它变成一个空格,占用了一个字符的宽度。
解决办法:
- 将
li
标签写在同一行,消除换行符:
<ul>
<li>Item 1</li><li>Item 2</li><li>Item 3</li>
</ul>
2.通过 font-size: 0
消除空白字符宽度,再在 li
中恢复字体:
ul { font-size: 0; }
li { font-size: 16px; }
11. CSS3中有哪些新特性
圆角 (border-radius:8px)
阴影和反射 (Shadoweflect)
文字特效 (text-shadow)
文字渲染 (Text-decoration)
线性渐变 (gradient)
旋转 (transform)
增加了旋转,缩放,定位,倾斜,动画,多背景
12.替换元素的概念及计算规则
概念:
就是一个标签上的 的属性改变,会引起标签的内容改变,比如imgd的src
典型替换元素列表
元素类型 | 示例标签 | 内容决定属性 |
---|---|---|
媒体类 | <img> 、<video> 、<audio> | src |
表单控件 | <input> 、<textarea> | type 、value 、placeholder |
框架类 | <iframe> 、<canvas> | src 、绘制内容 |
替换元素的尺寸计算规则:
- CSS尺寸:通过
width
/height
或max-width
/min-width
设置的尺寸,对应盒模型的content-box
; - HTML尺寸:通过原生HTML属性设置的尺寸,如
<img width="200">
、<textarea rows="3">
; - 固有尺寸:元素内容的原始物理尺寸(如未压缩图片的像素尺寸)。
13.对 CSSSprites(精灵图) 的理解
概念:
将一些 很多小的图片或者是图标集中到 一张大的图上。
可以通过background-image,background-repeat,background-position来设置图片来展示到页面。
优点:
- 可以减少对图片的网络请求。
- 图片的一张字节肯定是小于三张的。
缺点:
- 精灵图需要,有序排列好位置,制作起来比较麻烦。
- 在开发使用的时候,需要借助工具测出,要使用的图片的位置。
14.什么是物理像素,逻辑像素和像素密度,为什么在移动端开发时需要用到@3x, @2x这种图片?
物理像素:物理像素是显示设备的最小发光单元,直接由屏幕硬件决定,不可拆分。例如,分辨率为 1920×1080 的屏幕,表示其横向有 1920 个物理像素,纵向有 1080 个物理像素。
**逻辑像素:**逻辑像素是开发中使用的抽象单位,用于描述界面元素的尺寸和位置,与设备无关。例如,CSS 中的 100px
表示 100 个逻辑像素。逻辑像素通过 设备像素比(DPR) 映射到物理像素: 公式:物理像素 = 逻辑像素 × DPR
例如,DPR 为 2 时,100 逻辑像素会占用 200×200 物理像素的显示空间
**像素密度:**像素密度指每英寸屏幕包含的物理像素数,单位为 PPI。PPI 越高,屏幕越清晰。
移动端为何需要 @2x、@3x 图片: 当物理像素密度(PPI)较高时,若直接使用低分辨率图片(如 @1x),每个逻辑像素需要由多个物理像素渲染,导致图像被拉伸模糊
15.对line-height 的理解及其赋值方式
(1)line-height的概念:
- line-height 指一行文本的高度,包含了字间距,实际上是下一行基线到上一行基线距离
- 把 line-height 值设置为 height 一样大小的值可以实现单行文字的垂直居中;
(2)line-height 的赋值方式:
- 带单位:px 是固定值,而 em 会参考父元素 font-size 值计算自身的行高
- 纯数字:会把比例传递给后代。例如,父级行高为 1.5,子元素字体为 18px,则子元素行高为 1.5 * 18 = 27px
- 百分比:将计算后的值传递给后代
16.CSS 优化和提高性能的方法有哪些?
加载性能:
css压缩:将写好的css进行打包压缩,可以减小文件体积。
2.css单一样式:当需要下边距和左边距的时候,很多时候会选择使用 margin:top 0 bottom 0;但margin-bottom:bottom;margin-left:left;执行效率会更高。
3.减少使用@import,建议使用link,因为后者在页面加载时一起加载,前者是等待页面加载完成之后再进行加载。
尽量少的去使用后代选择器,降低选择器的权重值,当使用后代选择器的时候,浏览器会遍历所有子元素来确定是否是指定的元素等等
避免使用通配规则,如*****{}计算次数惊人,只对需要用到的元素进行选择。
尽量少的去对标签进行选择,而是用class。
15.CSS预处理器/后处理器是什么?为什么要使用它们?
预处理器:
如:
less
,sass
,stylus
,用来预编译sass
或者less
,增加了css
代码的复用性。里面可以写函数和变量和嵌套,增加了css代码的灵活性。**css后处理器:**如 PostCSS,可确保css在不同的浏览器一致性,自动添加浏览器前缀、压缩代码体积。
核心功能与工具对比
类别 | 核心功能 | 常用工具 |
---|---|---|
预处理器 | - 变量管理 - 嵌套规则 - 混合复用代码块 - 模块化导入文件 | Sass(SCSS)、Less |
后处理器 | - 自动添加浏览器前缀(如 -webkit- ) - 压缩代码 - 优化冗余规则 | PostCSS(含 Autoprefixer)、CSSNano246 |
为何需要使用它们?
- 预处理器:通过变量统一管理主题色、字体大小等参数,修改时只需调整一处,避免全局搜索替换。混合(Mixin)可封装复用逻辑(如圆角、阴影),减少代码重复率。
- 可以轻松实现多重继承。 完全兼容 CSS 代码,可以方便地应用到老项目中。
- 后处理器:Autoprefixer 自动生成兼容性代码,无需手动维护厂商前缀,降低因遗漏导致的样式错乱风险
16.单行、多行文本溢出隐藏
- 单行文本溢出
overflow: hidden; // 溢出隐藏
text-overflow: ellipsis; // 溢出用省略号显示
white-space: nowrap; // 规定段落中的文本不进行换行
- 多行文本溢出
overflow: hidden; // 溢出隐藏
text-overflow: ellipsis; // 溢出用省略号显示
display:-webkit-box; // 作为弹性伸缩盒子模型显示。
-webkit-box-orient:vertical; // 设置伸缩盒子的子元素排列方式:从上到下垂直排列
-webkit-line-clamp:3; // 显示的行数
注意:由于上面的三个属性都是 CSS3 的属性,没有浏览器可以兼容,所以要在前面加一个-webkit-
来兼容一部分浏览器。
17.对 CSS 工程化的理解
CSS 工程化是为了解决以下问题:
- 宏观设计:CSS 代码如何组织、如何拆分、模块结构怎样设计?
- 编码优化:怎样写出更好的 CSS?
- 构建:如何处理我的 CSS,才能让它的打包结果最优?
- 可维护性:代码写完了,如何最小化它后续的变更成本?如何确保任何一个同事都能轻松接手?
工程化常用的工具:
- 预处理器:Less、 Sass 等;(css预处理器)
- 重要的工程化插件: PostCss;(css后处理器)
- Webpack loader 等 。(css打包工具)。
预处理器
- 嵌套代码的能力,通过嵌套来反映不同 css 属性之间的层级关系 ;
- 支持定义 css 变量;
- 提供计算函数;
- 允许对代码片段进行 extend 和 mixin;
- 支持循环语句的使用;
- 支持将 CSS 文件模块化,实现复用。
后处理器
- 当我们的 CSS 代码需要适配低版本浏览器时,PostCss 的 Autoprefixer 插件可以帮助我们自动增加浏览器前缀;
Webpack 能处理 CSS 吗?如何实现? Webpack 能处理 CSS 吗:
Webpack:在裸奔的情况下,不可以处理css打包,需要用到两个 loader
- css-loader:导入 CSS 模块,对 CSS 代码进行编译处理 ,将 CSS 中的
@import
语句和url()
引用的资源(如图片、字体)转换为 JavaScript 的require()
调用,使 Webpack 能识别这些依赖并打包; - style-loader: 创建style标签,把 CSS 内容写入标签。
注意:css-loader 的执行顺序一定要安排在 style-loader 的前面。因为只有完成了编译过程,才可以对 css 代码进行插入
18.z-index属性在什么情况下会失效
- z-index元素的position属性需要是relative,absolute或是fixed。
- 元素必须为定位元素的
position
属性需设置为relative
、absolute
、fixed
或sticky
,否则z-index
无效 - 元素在设置z-index的同时还设置了float浮动。不生效。
19. 常见的CSS布局单位
常用的布局单位包括像素(
px
),百分比(%
),em
,rem
,vw/vh
1. rem
主要用途:实现响应式布局与屏幕适配,通过相对根元素(HTML)的字体大小动态调整元素尺寸
REM是CSS中的相对长度单位,其核心特性是始终相对于根元素(HTML)的字体大小
REM的值由根元素(HTML标签)的
font-size
决定。例如,若设置html { font-size: 16px }
,则1rem = 16px
,2rem = 32px
rem值 = px值 / 根字体大小(默认16px)
// 示例:若根字体为16px,24px对应24/16 = 1.5rem
字体与间距统一:用REM定义全局字体、边距、容器尺寸,避免EM的级联误差。例如,设置根字体为
62.5%
(即10px),简化计算(24px →2.4rem
)
html { font-size: 62.5%; } /* 1rem = 10px(基于16px默认值) */
结合
vw/vh
动态设置根字体,实现“REM+视口”双弹性适配。例如:
html { font-size: calc(100vw / 37.5); } /* 375px宽设备中1rem≈10px */
2. em
EM是一种相对长度单位,其值始终基于当前元素或其父元素的字体大小
**字体计算**:`子元素字体大小 = 父元素字体大小 × em值`。
如果父盒子字体为25px 子盒子的1em == 25px
示例:父元素字体为20px,子元素设为`1.5em` → `20px × 1.5 = 30px`
em与REM的对比总结
维度 | EM | REM |
---|---|---|
基准元素 | 父元素或当前元素字体 | 根元素(HTML)字体 |
适用场景 | 局部组件、需继承父级比例的属性 | 全局布局、统一缩放的属性 |
响应式灵活性 | 高(适合模块化设计) | 更高(适合跨设备适配) |
计算复杂度 | 高(嵌套时需逐级计算) | 低(仅依赖根元素) |
3. rpx
一、基本定义与核心原理
rpx(responsive pixel)是由微信小程序提出的响应式像素单位,主要用于解决移动端多设备屏幕适配问题其核心原理是以屏幕宽度为基准进行等比缩放,规定屏幕总宽度恒定为750rpx
换算公式:
一般将ui图设置为750px的大小,这样多少px就是多少rpx
UI设计师可直接以750px宽度的设计稿出图,开发时1:1替换为rpx单位
实际像素值(px)= rpx值 × (屏幕实际宽度 / 750)
4. vw vh
vw(Viewport Width):表示视口宽度的 1/100
例如,视口宽度为 1920px 时,1vw = 19.2px。
vh(Viewport Height):表示视口高度的 1/100 视口高度为 1080px 时,1vh = 10.8px。
vh 一般用于计算中间区域盒子高度 中间滚动
.main {
w750rpx;
heigth: calc(100vh - 125px) // 减去上下头部和底部
// 加滚动
}
视口(Viewport):指浏览器可视区域,不含工具栏和滚动条
- 全屏覆盖布局 使用
width: 100vw
和height: 100vh
实现全屏背景或弹窗遮罩层
.overlay {
width: 100vw;
height: 100vh;
background: rgba(0,0,0,0.5);
position: fixed;
}
20. 两栏布局的实现
一般两栏布局指的是左边一栏宽度固定,右边一栏宽度自适应,两栏布局的具体实现:
- 利用浮动,将左边元素宽度设置为200px,并且设置向左浮动。将右边元素的margin-left设置为200px,宽度设置为auto(默认为auto,撑满整个父元素)。
.outer {
height: 100px;
}
.left {
float: left;
width: 200px;
background: tomato;
}
.right {
margin-left: 200px;
width: auto;
background: gold;
}
- 利用浮动,左侧元素设置固定大小,并左浮动,右侧元素设置overflow: hidden; 这样右边就触发了BFC,BFC的区域不会与浮动元素发生重叠,所以两侧就不会发生重叠。
.left{
width: 100px;
height: 200px;
background: red;
float: left;
}
.right{
height: 300px;
background: blue;
overflow: hidden;
}
- 利用flex布局,将左边元素设置为固定宽度200px,将右边的元素设置为flex:1。
.outer {
display: flex;
height: 100px;
}
.left {
width: 200px;
background: tomato;
}
.right {
flex: 1;
background: gold;
}
- 利用绝对定位,将父级元素设置为相对定位。左边元素设置为absolute定位,并且宽度设置为200px。将右边元素的margin-left的值设置为200px。
.outer {
position: relative;
height: 100px;
}
.left {
position: absolute;
width: 200px;
height: 100px;
background: tomato;
}
.right {
margin-left: 200px;
background: gold;
}
- 利用绝对定位,将父级元素设置为相对定位。左边元素宽度设置为200px,右边元素设置为绝对定位,左边定位为200px,其余方向定位为0。
.outer {
position: relative;
height: 100px;
}
.left {
width: 200px;
background: tomato;
}
.right {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 200px;
background: gold;
}
21. 三栏布局的实现
三栏布局一般指的是页面中一共有三栏,左右两栏宽度固定,中间自适应的布局,三栏布局的具体实现:
- 利用绝对定位,左右两栏设置为绝对定位,中间设置对应方向大小的margin的值。
.outer {
position: relative;
height: 100px;
}
.left {
position: absolute;
width: 100px;
height: 100px;
background: tomato;
}
.right {
position: absolute;
top: 0;
right: 0;
width: 200px;
height: 100px;
background: gold;
}
.center {
margin-left: 100px;
margin-right: 200px;
height: 100px;
background: lightgreen;
}
- 利用flex布局,左右两栏设置固定大小,中间一栏设置为flex:1。
.outer {
display: flex;
height: 100px;
}
.left {
width: 100px;
background: tomato;
}
.right {
width: 100px;
background: gold;
}
.center {
flex: 1;
background: lightgreen;
}
- 利用浮动,左右两栏设置固定大小,并设置对应方向的浮动。中间一栏设置左右两个方向的margin值,注意这种方式**,中间一栏必须放到最后:**
.outer {
height: 100px;
}
.left {
float: left;
width: 100px;
height: 100px;
background: tomato;
}
.right {
float: right;
width: 200px;
height: 100px;
background: gold;
}
.center {
height: 100px;
margin-left: 100px;
margin-right: 200px;
background: lightgreen;
}
- 圣杯布局,利用浮动和负边距来实现。父级元素设置左右的 padding,三列均设置向左浮动,中间一列放在最前面,宽度设置为父级元素的宽度,因此后面两列都被挤到了下一行,通过设置 margin 负值将其移动到上一行,再利用相对定位,定位到两边。
.outer {
height: 100px;
padding-left: 100px;
padding-right: 200px;
}
.left {
position: relative;
left: -100px;
float: left;
margin-left: -100%;
width: 100px;
height: 100px;
background: tomato;
}
.right {
position: relative;
left: 200px;
float: right;
margin-left: -200px;
width: 200px;
height: 100px;
background: gold;
}
.center {
float: left;
width: 100%;
height: 100px;
background: lightgreen;
}
- 双飞翼布局,双飞翼布局相对于圣杯布局来说,左右位置的保留是通过中间列的 margin 值来实现的,而不是通过父元素的 padding 来实现的。本质上来说,也是通过浮动和外边距负值来实现的。
.outer {
height: 100px;
}
.left {
float: left;
margin-left: -100%;
width: 100px;
height: 100px;
background: tomato;
}
.right {
float: left;
margin-left: -200px;
width: 200px;
height: 100px;
background: gold;
}
.wrapper {
float: left;
width: 100%;
height: 100px;
background: lightgreen;
}
.center {
margin-left: 100px;
margin-right: 200px;
height: 100px;
}
22. 如何根据设计稿进行移动端适配?
移动端适配主要有两个维度:
- 适配不同像素密度, 针对不同的像素密度,使用 CSS 媒体查询,选择不同精度的图片,以保证图片不会失真;
- 适配不同屏幕大小, 由于不同的屏幕有着不同的逻辑像素大小,所以如果直接使用 px 作为开发单位,会使得开发的页面在某一款手机上可以准确显示,但是在另一款手机上就会失真。为了适配不同屏幕的大小,应按照比例来还原设计稿的内容。
为了能让页面的尺寸自适应,可以使用 rem,em,vw,vh 等相对单位。
23. 为什么需要清除浮动?清除浮动的方式
**浮动的定义:**当父盒子不设置宽高时候,子元素设置浮动,父盒子不会被撑开,这个被称为浮动溢出。
浮动元素引起的问题?
- 父元素的高度无法被撑开,影响与父元素同级的元素
- 与浮动元素同级的非浮动元素会跟随其后
- 若浮动的元素不是第一个元素,则该元素之前的元素也要浮动,否则会影响页面的显示结构
清除浮动的方式如下:
- 给父级div定义
height
属性 - 最后一个浮动元素之后添加一个空的div标签,并添加
clear:both
样式 - 包含浮动元素的父级标签添加
overflow:hidden
或者overflow:auto
- 使用 :after 伪元素。