一、有哪些 CSS 选择器?请分别介绍
-
元素选择器
p、div等,选中所有指定标签。 -
类选择器
.className,选中 class 属性包含该名称的元素,可复用。 -
ID 选择器
#idName,选中 id 唯一匹配的元素,唯一性高,优先级高。 -
通配符选择器
*,选中页面所有元素,常用于重置样式。 -
属性选择器
[type="text"],选中具有指定属性的元素。 -
后代选择器
div p,选中 div 内所有后代 p 元素(含嵌套层级)。 -
子元素选择器
div > p,仅选中 div 的直接子元素 p。 -
相邻兄弟选择器
h1 + p,选中紧跟在 h1 后的第一个同级 p 元素。 -
通用兄弟选择器
h1 ~ p,选中与 h1 同级且在其后的所有 p 元素。 -
伪类选择器
:hover、:nth-child(n)、:first-of-type等,选中特定状态或位置的元素。 -
伪元素选择器
::before、::after、::first-line,创建虚拟元素并样式化。
总结
常用选择器包括标签、类、ID、后代、子代、属性和伪类/伪元素,掌握优先级和性能(避免过度使用通用选择器)是关键。
二、如何计算 CSS 的优先级?
CSS 优先级(Specificity)决定样式冲突时哪个规则生效。计算规则如下(按权重从高到低):
优先级权重:
- 内联样式(
style="")→1000 - ID 选择器(
#id)→100每个 - 类、属性、伪类选择器(
.class、[type]、:hover)→10每个 - 元素、伪元素选择器(
div、::before)→1每个
计算方法: 将各类选择器数量按权重相加,形成一个“四元组”: [内联, ID, 类/属性/伪类, 元素/伪元素]
示例:
p→0,0,0,1.nav li→0,0,1,1= 11#header .nav a:hover→0,1,2,1= 121- 内联样式 →
1,0,0,0= 1000
最终规则:
- 优先级高者胜出
- 相同优先级时,后写的样式覆盖前面的
!important最高(慎用),会覆盖内联样式
总结
CSS 优先级按
内联 > ID > 类/属性/伪类 > 元素/伪元素计算权重,数值越高优先级越高;相同则后定义的生效;!important最高但不推荐滥用。
三、CSS 中可继承与不可继承属性有哪些?
一、可继承的属性(常见)
通常与文本内容相关的属性可继承:
-
字体相关
font-family、font-size、font-weight、font-style -
文本相关
color、text-align、text-indent、line-height、letter-spacing、word-spacing -
列表相关
list-style(包括list-style-type、list-style-position、list-style-image) -
光标样式
cursor
典型例子:给
body设置font-family和color,整个页面文本都会继承。
二、不可继承的属性(常见)
大多数布局、盒模型、定位相关的属性不可继承:
-
盒模型
width、height、padding、margin、border -
背景
background、background-color、background-image -
定位
position、top、left、z-index -
浮动与显示
float、display、overflow -
弹性布局 / 网格布局
flex、grid-template-columns、align-items等
如何强制继承?
使用 inherit 关键字:
.child {
color: inherit; /* 强制继承父元素颜色 */
margin: inherit; /* 强制继承父元素 margin(即使默认不继承) */
}
总结
可继承属性:
color、font-*、text-align、line-height、list-style等文本相关属性。
不可继承属性:width、height、margin、padding、border、background、display、position等布局和盒模型属性。
可用inherit强制继承,initial重置为默认值。
四、CSS 中 display 属性的值及其作用
常见 display 取值及作用:
| 值 | 作用 |
|---|---|
block | 块级元素,独占一行,可设置宽高(如 div, p) |
inline | 行内元素,不换行,宽高由内容决定(如 span, a) |
inline-block | 行内块元素,同行显示但可设宽高、margin/padding |
none | 隐藏元素,不占空间(文档流中移除) |
flex | 启用弹性布局,子元素通过 flex 模型布局(现代布局首选) |
grid | 启用网格布局,二维布局,强大灵活 |
table / table-row / table-cell | 模拟表格显示(不推荐用于结构,可用于布局) |
list-item | 像列表项一样显示(如 li,带项目符号) |
总结:
常见
display值:
block:块级,独占行,可设宽高;inline:行内,不换行,宽高无效;inline-block:行内块,同行可设宽高;none:隐藏元素,不占空间;flex/grid:现代布局模型,用于复杂排布;list-item:像列表项显示。注意:
display影响元素在文档流中的表现,是布局基础。
五、利用 CSS 隐藏元素的方法有哪些?
常见隐藏元素的方法:
| 方法 | 是否占空间 | 是否渲染 | 是否可访问(无障碍) | 用途 |
|---|---|---|---|---|
display: none; | 不占空间 | 不渲染 | 屏幕阅读器不可见 | 完全隐藏,最常用 |
visibility: hidden; | 占空间 | 渲染(不可见) | 屏幕阅读器可能仍可读 | 隐藏但保留位置 |
opacity: 0; | 占空间 | 渲染(全透明) | 可交互、可访问 | 透明隐藏,仍可点击 |
position: absolute; left: -9999px; | 移出视区 | 渲染 | 可访问 | 用于隐藏文本(如SEO) |
clip-path: inset(100%); 或 clip | 不显示 | 渲染 | 推荐用于无障碍隐藏 | 现代隐藏技巧 |
hidden 属性(HTML) | 类似 display: none | ❌ | ❌ | 语义化隐藏 |
总结
常见隐藏方法:
display: none:完全隐藏,不占空间,最常用;visibility: hidden:隐藏但保留空间;opacity: 0:透明隐藏,仍占空间、可交互;- 定位移出屏幕:如
left: -9999px,用于隐藏文本;clip-path:裁剪隐藏,推荐用于无障碍场景。
关键区别:是否保留布局空间、是否可访问、是否可触发事件。
一般用display: none;需保留空间用visibility: hidden;需保持交互用opacity: 0。
六、使用 link 和 @import 引用 CSS 的区别
主要区别:
| 对比项 | link(HTML 标签) | @import(CSS 规则) |
|---|---|---|
| 位置 | 写在 HTML 的 <head> 中 | 写在 CSS 文件或 <style> 中 |
| 加载时机 | 页面加载时并行下载CSS,较快 | 页面加载完成后才加载,较慢 |
| 兼容性 | 所有浏览器支持 | IE5+,低版本 IE 有兼容问题 |
| DOM 操作 | 可通过 JavaScript 动态控制(如切换主题) | 不易通过 JS 控制 |
| 媒体查询支持 | 支持 <link media="..."> | 支持 @import url("...") screen and (max-width: 768px) |
| 性能 | 更优,推荐使用 | 较差,阻塞渲染 |
总结
link是 HTML 标签,在<head>中引入,页面加载时并行下载 CSS,性能好,支持 JS 控制,推荐使用。@import是 CSS 方式,写在样式文件中,加载完页面后再加载 CSS,有延迟,不支持低版本 IE,且难以用 JS 操作。优先使用
link;@import仅用于在 CSS 文件中条件引入其他 CSS。
七、CSS 中transition和animation 的区别
主要区别:
| 对比项 | transition(过渡) | animation(动画) |
|---|---|---|
| 触发方式 | 需属性变化触发(如 :hover、JS 修改) | 自动播放,或通过 animation-play-state 控制 |
| 执行次数 | 只能执行一次(进入和返回各一次) | 可设置 animation-iteration-count 无限循环 |
| 关键帧 | ❌ 不支持关键帧 | ✅ 支持 @keyframes 定义复杂动画过程 |
| 开始时间 | 只能延迟开始(transition-delay) | 可设置延迟、反向播放、填充模式等 |
| 控制灵活性 | 简单,仅限两个状态间过渡 | 强大,可定义多阶段动画 |
| 适用场景 | 简单交互效果:按钮悬停、菜单展开 | 复杂动画:loading 动效、元素移动路径 |
总结
transition:用于两个状态间的平滑过渡,需触发(如 hover),简单易用,适合交互反馈。animation:通过@keyframes定义复杂动画序列,可自动播放、循环、控制节奏,适合精细动画。关键区别:
transition要“变化”才触发,animation可自动执行;
animation功能更强大,支持关键帧和循环。一般:交互效果用
transition,复杂动效用animation。
八、display:none 与 visibility:hidden 的区别
主要区别:
| 对比项 | display: none | visibility: hidden |
|---|---|---|
| 是否占空间 | 不占布局空间,文档流中移除 | 保留空间,其他元素位置不变 |
| 是否渲染 | 元素不渲染(不绘制、不布局) | 元素仍渲染,只是不可见 |
| 子元素影响 | 所有子元素也被隐藏 | 可通过 visibility: visible 显示子元素 |
| 触发重排(reflow) | 会触发页面重排 | 不触发重排,只触发重绘(repaint) |
| 继承性 | 不可继承 | 可继承(子元素默认也隐藏,除非显式设置 visible) |
| JavaScript 访问 | 无法触发事件,offsetHeight 为 0 | 仍可绑定事件,尺寸属性正常 |
总结
display: none:彻底隐藏,不占空间,不渲染,触发重排,子元素全隐藏。visibility: hidden:视觉隐藏,保留空间,仍渲染,不触发重排,子元素可单独显示。使用场景:
- 需要“消失”效果 →
display: none- 需保留占位(如动画占位)→
visibility: hidden
display: none是“移除”,visibility: hidden是“隐身”。
九、说说你对盒模型的理解
CSS 盒模型是页面布局的基础,每个元素都被视为一个矩形盒子,由四个部分组成(从内到外):
- content(内容区):实际内容(文字、图片等)。
- padding(内边距):内容与边框之间的空间,背景可见。
- border(边框):围绕内容和内边距的边框。
- margin(外边距):盒子与其他元素之间的空白,透明不可见。
两种盒模型类型:
| 类型 | 设置的 width/height 包含 | 特点 |
|---|---|---|
box-sizing: content-box(默认) | 仅 content | width = content,padding + border 额外增加总尺寸 |
box-sizing: border-box | content + padding + border | width = content + padding + border,更直观,推荐使用 |
示例:
div { width: 200px; padding: 20px; border: 5px solid; }
content-box:总宽 =200 + 40 + 10 = 250pxborder-box:内容宽自动压缩为150px,总宽保持200px
总结
盒模型是每个元素的布局结构,包含
content、padding、border、margin。
默认为content-box,推荐使用box-sizing: border-box,使尺寸更可控,避免布局错乱。
理解盒模型是掌握 CSS 布局、居中、间距计算的基础。
十、为什么有时候用 translate 来改变位置而不是定位?
为什么用 translate() 而不是 定位?
| 对比项 | transform: translate() | position: relative/top/left |
|---|---|---|
| 是否脱离文档流 | 不影响布局,不触发重排(reflow) | 改变位置可能影响其他元素布局,触发重排 |
| 性能 | 由 GPU 加速,动画更流畅(合成层) | 由 CPU 处理,频繁变化性能差 |
| 触发重绘/重排 | 不触发重排,只触发复合(composite) | 修改 top/left 会触发重排和重绘 |
| 适用场景 | 动画、过渡、临时位移 | 静态布局、常规定位 |
| 层级影响 | 可能创建新的层叠上下文 | 不自动创建新层 |
总结
使用
translate()而非position的主要原因:
- 性能更好:
translate由 GPU 加速,不触发重排,动画更流畅;- 不影响布局:元素仍占据原空间,不会导致其他元素位置跳动;
- 适合动画:在
transition或animation中使用更高效。
- 布局定位用
position;- 动效或临时位移用
transform: translate(),性能更优。- 例如:按钮悬停移动、轮播图滑动、元素淡入位移,都推荐用
translate。
十一、为什么 1i 与 ii 元素之间有看不见的空白间隔?如何解决?
当 HTML 中的 inline-block 元素(如 span、a、img、button 等)写在多行并有换行或空格时,浏览器会将换行符、空格解析为一个空白字符,导致元素之间出现看不见的间隙(通常约 4px)。
<div>
<span>1</span>
<span>2</span>
<span>3</span>
</div>
虽然代码中没写空格,但换行 + 缩进 = 空白字符,像文本一样被渲染。
解决方法(任选其一):
1. HTML 中去除空格/换行
<div>
<span>1</span><span>2</span><span>3</span>
</div>
2. 父元素设置 font-size: 0,子元素再重置
.parent {
font-size: 0;
}
.parent span {
font-size: 16px; /* 重置字体 */
display: inline-block;
}
3. 使用 flex 布局(推荐)
.parent {
display: flex;
gap: 0; /* 可控间距 */
}
.parent span {
display: inline-block; /* 或 block */
}
4. 注释掉空白
<div>
<span>1</span><!--
--><span>2</span><!--
--><span>3</span>
</div>
5. 设置 margin 为负值(不推荐)
span {
margin-right: -4px;
}
总结
inline-block元素间的空白是由于 HTML 换行和空格被解析为文本空白字符导致的。解决方法:
- HTML 中去除空格;
- 父元素
font-size: 0;- 改用
display: flex布局(推荐);- 使用 HTML 注释消除空白。
推荐使用 Flex 布局,现代、灵活、无间隙问题。
十二、CSS3 中有哪些新特性?
一、选择器增强
- 属性选择器:
[type="text"] - 伪类选择器:
:nth-child(n)、:first-of-type、:last-child、:not() - 伪元素:
::before、::after(双冒号区分伪类)
作用:更精确地选中元素,减少 class 依赖。
二、盒模型与布局
box-sizing: border-box:控制宽高是否包含 padding 和 border。- Flex 布局(
display: flex):一维弹性布局,轻松实现居中、对齐、自适应。 - Grid 布局(
display: grid):二维网格布局,复杂页面结构利器。 calc():动态计算尺寸,如width: calc(100% - 20px)。
三、视觉效果
border-radius:圆角边框。box-shadow/text-shadow:元素和文本阴影。- 渐变背景:
linear-gradient()、radial-gradient()。 - 多背景图:
background-image: url(1.png), url(2.png); background-size、background-clip:更灵活的背景控制。
四、变换、过渡与动画
transform:2D/3D 变换(旋转、缩放、倾斜、位移)。transition:属性平滑过渡(如 hover 效果)。animation+@keyframes:关键帧动画,可循环、延迟播放。
五、响应式设计
- 媒体查询(
@media):根据屏幕尺寸应用不同样式,实现响应式布局。 - 支持高分辨率屏幕(
@media (min-resolution: 2dppx))。
六、字体与文本
@font-face:引入自定义字体。text-overflow: ellipsis:文本溢出显示省略号。word-wrap/white-space:控制换行与空白。
七、其他重要特性
- CSS 变量(自定义属性):
--color: red; color: var(--color); filter:滤镜效果(模糊、灰度、对比度等)。flexible box和grid布局彻底改变传统布局方式。
总结
CSS3 主要新特性包括:
- 选择器增强(
:nth-child)- Flex 和 Grid 布局
- 圆角、阴影、渐变
- 过渡(transition)和动画(animation)
- 媒体查询实现响应式
- 自定义字体(@font-face)
- CSS 变量和滤镜
这些特性让开发者无需依赖图片或 JavaScript 即可实现丰富视觉效果和灵活布局。
十三、什么是替换元素?说说其概念及计算规则
一、概念
- 替换元素(Replaced Element)指的是其内容不由CSS控制,而是由外部资源决定的HTML元素。常见的替换元素包括
<img>、<video>、<object>、<iframe>和部分表单元素如<input>和<textarea>等。 - 替换元素的关键特性在于它们展示的内容不是纯HTML文本或通过CSS样式化的内容,而是由其他数据源或编码决定的。
二、计算规则
- 固有尺寸:替换元素通常具有固有的宽高比和默认尺寸(例如图片的实际像素尺寸)。这些尺寸在没有明确设置宽高时将被使用。
- 布局影响:由于替换元素的内容不由CSS直接控制,因此它们在布局中表现为具有确定尺寸的盒子模型,这影响了其在页面中的排列方式。
- 盒模型属性的应用:
width和height可以显式设置替换元素的尺寸,覆盖其固有尺寸。padding和border会增加替换元素的整体尺寸,但不会改变其内容显示区域的尺寸。margin影响替换元素与其他元素之间的间距。
- 特殊行为:某些替换元素可能表现出特殊的布局行为。例如,
<img>标签如果没有指定宽度和高度,并且加载失败,则可能会导致布局塌陷或闪烁。
总结
理解替换元素对于掌握网页布局至关重要,尤其是在处理响应式设计和优化页面加载性能时。合理设置替换元素的尺寸和样式,可以避免不必要的布局重绘和提高用户体验。
十四、说说你对 CSS Sprites 的理解
一、概念
- CSS Sprites(CSS 精灵)是一种将多个小图标或背景图像合并到一张大图上的技术。通过调整
background-position属性来显示图像的特定部分,从而实现不同图标的展示。
二、工作原理
- 合并图像:将网站中常用的图标(如导航图标、按钮状态等)整合成一张大的背景图。
- 定位显示:利用 CSS 的
background-image指向这张大图,并使用background-position来精确控制显示哪一部分图像。 - 尺寸匹配:确保元素的宽高与所需显示的图标区域大小一致,以正确裁剪出目标图像。
三、优点
- 减少HTTP请求:原本每个小图标都需要一次独立的HTTP请求,而使用Sprites后只需加载一张图片,显著减少了请求数量,提升了页面加载速度。
- 提高性能:特别是在网络环境较差的情况下,减少请求能有效降低延迟,加快页面渲染。
- 便于维护:所有图标集中管理,更新时只需修改一张图和相应的CSS代码,简化了维护流程。
四、缺点
- 图像复杂度增加:需要手动或借助工具将多个图标排列整齐地合并成一张图,增加了前期准备工作量。
- 缓存问题:如果某个图标更新,整个Sprites图片都需要重新下载,即使其他图标未变。
- 响应式挑战:在高分辨率屏幕下,可能需要提供两套Sprites图(普通和高清),增加了资源负担。
五、应用场景
- 适用于包含大量小图标且这些图标不经常变动的网站,如导航栏、工具栏、按钮状态等。
- 常见于传统Web项目中,随着现代前端技术的发展(如SVG、Icon Font、WebP等),Sprites的使用有所减少,但在某些场景下仍具优势。
总结
CSS Sprites 是一种经典的性能优化技术,通过合并图像减少HTTP请求,提升页面加载效率。尽管现代技术提供了更多替代方案,但在合适场景下,Sprites依然是有效的解决方案之一。
十五、什么是物理像素,逻辑像素和像素密度?为什么在移动端开发时需要用到 @3x, @2x 这种图片?
一、核心概念
-
物理像素(Physical Pixel)
屏幕上真实的像素点,是显示设备的最小物理单位。例如:iPhone 14 Pro 的屏幕有 2556 × 1179 个物理像素点。 -
逻辑像素(Logical Pixel / CSS Pixel)
CSS 中使用的像素单位(px),是浏览器用于布局的抽象单位。在标准屏上,1逻辑像素 = 1物理像素;但在高清屏上,比例不同。 -
像素密度(PPI / DPI)
每英寸包含的物理像素数量(Pixels Per Inch)。数值越高,屏幕越清晰。如 Retina 屏的 PPI 远高于普通屏。
二、设备像素比(Device Pixel Ratio, DPR)
- 定义:物理像素 / 逻辑像素 的比值。
- 示例:
- 普通屏:DPR = 1(1逻辑像素 = 1物理像素)
- Retina 屏:DPR = 2 或 3(1逻辑像素 = 4 或 9 物理像素)
浏览器用多个物理像素渲染一个 CSS 像素,使图像更细腻。
三、为什么需要 @2x、@3x 图片?
- 在 DPR=2 的设备上,一个
100px × 100px的图片区域,实际由200×200个物理像素渲染。 - 如果只提供
100×100的原始图,浏览器会拉伸它去填充,导致模糊、失真。 - 提供
@2x(200×200)、@3x(300×300)等高分辨率图片,确保在高清屏上显示清晰。
四、解决方案(响应式图片)
<!-- 使用 srcset -->
<img src="logo.png"
srcset="logo@2x.png 2x,
logo@3x.png 3x"
alt="Logo">
或通过 CSS:
.icon {
background-image: url(logo.png);
}
@media (-webkit-min-device-pixel-ratio: 2) {
.icon {
background-image: url(logo@2x.png);
background-size: 100px 100px;
}
}
总结
- 物理像素是硬件真实点,逻辑像素是CSS布局单位,像素密度决定清晰度。
- 移动端高清屏(DPR > 1)需要
@2x、@3x图片,避免图像模糊,保证视觉质量。 - 使用
srcset或媒体查询适配不同设备,提升用户体验。
十六、说说 margin 和 padding 的使用场景
一、概念回顾
margin:元素的外边距,是盒子与其他元素之间的空白区域,透明、不可见,属于元素外部空间。padding:元素的内边距,是内容与边框之间的空间,受背景色/背景图影响,属于元素内部空间。
二、使用场景对比
| 场景 | 推荐使用 | 说明 |
|---|---|---|
| 控制元素之间的距离 | margin | 如两个段落之间、相邻按钮、左右布局间距等。 |
| 居中块级元素(水平) | margin: 0 auto | 经典居中技巧,需配合宽度使用。 |
| 设置元素与父容器的间距 | 通常不用 margin(可能导致塌陷或溢出)推荐用 padding | 用父元素的 padding 更安全,避免外边距塌陷。 |
| 背景/边框需要包含的空间 | padding | 如文字离边框太近,加 padding 增加内部留白,背景色会延伸。 |
| 按钮、输入框内部留白 | padding | 让文字不贴边,提升可读性和点击体验。 |
| 避免外边距合并(Margin Collapse) | 用 padding 或 border 隔开 | 块级元素垂直 margin 会合并,可用 padding 控制父容器内距。 |
三、经典示例
/* 按钮:用 padding 增加点击区域和视觉舒适度 */
.btn {
padding: 10px 20px;
background: #007bff;
color: white;
}
/* 卡片之间用 margin 分隔 */
.card {
margin-bottom: 20px;
background: white;
border: 1px solid #ddd;
}
/* 卡片内容与边框留白,用 padding */
.card-body {
padding: 15px;
}
总结
margin用于“对外”关系:控制元素与外部元素的距离、布局定位(如居中、间隔)。padding用于“对内”关系:控制内容与边框的距离,保证视觉舒适和背景完整。简单记:
- 要“隔开别人” → 用
margin- 要“保护自己内容” → 用
padding
十七、说说你对 line-height 的理解及其赋值方式
一、line-height 的概念
line-height 用于设置行高,即文本行基线之间的距离,直接影响文字的垂直间距和可读性。
- 它决定了行框(line box)的高度,影响文字在行内的垂直对齐。
- 常用于控制段落行距、垂直居中文本、调整按钮或容器内的文字位置。
关键点:
line-height与font-size共同决定文字的垂直空间。
二、line-height 的赋值方式
| 赋值方式 | 示例 | 特点 |
|---|---|---|
| 无单位数值(推荐) | line-height: 1.5 | 相对于当前元素的 font-size 计算,继承时更安全,子元素基于自身字号计算行高。 |
| 百分比 | line-height: 150% | 相对于当前元素的 font-size 计算,但继承的是计算后的值,可能导致子元素行高异常。 |
| 像素值(px) | line-height: 20px | 固定行高,不随字体缩放,不利于响应式和可访问性。 |
| em | line-height: 1.5em | 相对于当前元素的 font-size,但继承行为类似百分比,不推荐。 |
| normal | line-height: normal | 浏览器默认行高,通常为 1.0~1.2,依赖字体和元素。 |
三、推荐使用无单位数值的原因
p {
font-size: 16px;
line-height: 1.5; /* = 16px × 1.5 = 24px */
}
p span {
font-size: 12px; /* 继承 line-height: 1.5 */
/* 实际行高 = 12px × 1.5 = 18px */
}
- 使用无单位值时,子元素会基于自己的
font-size重新计算行高,更灵活、安全。 - 使用
%或px时,子元素继承的是固定值,可能导致小字号文字行距过大或重叠。
四、常见应用场景
- 段落排版:
line-height: 1.5或1.6提升可读性。 - 垂直居中单行文本:设置
line-height等于容器高度。.btn { height: 40px; line-height: 40px; /* 文字垂直居中 */ } - 避免文字重叠:在
font-size较大时,适当增加line-height。
总结
line-height控制行高,影响文本间距和布局。- 推荐使用无单位数值(如
1.5),继承行为更合理,响应式友好。- 避免使用
px固定值,不利于可访问性和缩放。- 理解
line-height是排版优化的关键之一。
十八、CSS 优化和提高性能的方法有哪些?
一、减少渲染阻塞
- 关键 CSS 内联:将首屏关键样式通过
<style>标签内联到 HTML<head>,避免额外请求。 - 非关键 CSS 异步加载:使用
media="print"或动态插入方式延迟加载非首屏样式。
二、优化选择器性能
- 避免深层嵌套和复杂选择器:如
div ul li a:hover,浏览器需从右向左匹配,层级越深越慢。 - 推荐使用类选择器:
.btn比#header > div > span + a更高效。 - 避免使用通配符
*和标签选择器过度限定。
三、减少重排(Reflow)与重绘(Repaint)
- 优先使用
transform和opacity实现动画:触发 GPU 加速,不引起布局变化。 - 避免频繁操作样式:用
class批量切换,而非逐个修改style属性。 - 离线 DOM 操作:先修改再批量插入,减少回流次数。
四、合理使用属性
- 用
flex或grid替代浮动布局:更清晰、性能更好。 - 图片使用多倍图或
srcset:适配高清屏,避免模糊。 - 启用
will-change提示浏览器优化(谨慎使用):.animate { will-change: transform; }
五、压缩与合并资源
- 压缩 CSS 文件:去除空格、注释,使用工具如 Webpack、PostCSS。
- 合并小文件:减少 HTTP 请求数量(注意 HTTP/2 环境下可适度拆分)。
- 使用雪碧图(Sprites)或 SVG Sprite:减少图标请求。
六、其他最佳实践
- 避免
@import引入 CSS:会阻塞并增加请求链。 - 删除未使用 CSS:借助工具(如 PurgeCSS)清理冗余代码。
- 使用 CSS 变量统一管理主题色、间距等,提高维护性。
- 设置
box-sizing: border-box全局生效,简化盒模型计算。
总结
CSS 性能优化核心在于:
- 快速加载(内联关键、异步非关键)
- 高效渲染(简化选择器、避免重排)
- 良好维护(压缩、去冗余、模块化)
推荐策略:关键路径优化 + 合理动画 + 资源压缩 + 工具辅助。
十九、CSS 预处理器/后处理器是什么?为什么要使用它们?
一、CSS 预处理器(Preprocessor)
1. 是什么?
预处理器是一种扩展 CSS 语法的工具,允许使用编程特性编写更高效、可维护的样式代码。常见的有:Sass(SCSS)、Less、Stylus。
2. 核心功能:
- 变量:定义颜色、尺寸等复用值。
$primary-color: #007bff; .btn { color: $primary-color; } - 嵌套:按结构嵌套选择器,提升可读性。
.nav { ul { margin: 0; } li { float: left; } } - 混合(Mixins):定义可复用的样式块。
@mixin center { display: flex; justify-content: center; align-items: center; } .box { @include center; } - 函数与运算:支持颜色操作、数学计算。
- 模块化:通过
@import或@use拆分文件,便于团队协作。
3. 使用流程:
编写 .scss/.less 文件 → 编译 → 生成标准 .css 文件 → 浏览器加载。
二、CSS 后处理器(Postprocessor)
1. 是什么?
后处理器在 CSS 编译完成后进行自动优化和增强,最典型的是 PostCSS。
2. 核心功能:
- 自动添加浏览器前缀(如
autoprefixer):/* 输入 */ display: flex; /* 输出 */ display: -webkit-box; display: -webkit-flex; display: -ms-flexbox; display: flex; - CSS 模块化支持
- 语法转换(如将未来的 CSS 语法转为当前兼容版本)
- 压缩与优化(如
cssnano)
三、为什么要使用它们?
| 类型 | 优势 |
|---|---|
| 预处理器 | - 提升代码可维护性(变量、函数) - 支持嵌套与模块化,结构清晰 - 减少重复代码,提高开发效率 |
| 后处理器 | - 自动兼容老浏览器(加前缀) - 优化输出(压缩、清理) - 支持未来 CSS 语法(如 CSS Custom Properties) |
总结
- 预处理器(如 Sass):让 CSS 支持变量、嵌套、混合,适合开发阶段提升效率。
- 后处理器(如 PostCSS):在构建后自动优化和兼容处理,保障生产环境质量。
现代前端开发中,结合使用预处理 + 后处理(如:SCSS → 编译 → PostCSS → 压缩),是标准实践,显著提升开发体验与代码质量。
二十、::before 和 :after 的双冒号和单冒号有什么区别?
一、核心区别
-
::before和::after(双冒号):
是 CSS3 引入的语法,用于定义伪元素(Pseudo-elements),表示创建一个虚拟的子元素。 -
:before和:after(单冒号):
是 CSS2 的旧语法,功能与双冒号相同。
功能完全一样,只是语法上的演进。
二、为什么改为双冒号?
CSS3 为了明确区分:
- 伪类(Pseudo-classes)→ 使用 单冒号,如
:hover、:first-child、:focus - 伪元素(Pseudo-elements)→ 使用 双冒号,如
::before、::after、::first-line
目的:提高代码可读性,语义更清晰。
三、兼容性说明
- 所有现代浏览器都支持
::before和::after。 - 为了兼容非常旧的浏览器(如 IE8),部分项目仍使用单冒号。
- 但 IE8 已淘汰,当前开发推荐使用双冒号。
总结
::before和::after是 CSS3 的标准写法,表示伪元素;:before和:after是旧语法,功能相同;- 双冒号是为了与伪类(如
:hover)区分开,语义更清晰;- 推荐使用双冒号写法,符合现代规范。
二十一、display:inline-block 什么时候会显示间隙?
一、什么时候会显示间隙?
当 inline-block 元素在 HTML 中以换行或空格分隔时,浏览器会将这些空白字符解析为一个空格,从而在元素之间产生看不见的间隙(通常约 4px)。
<div>
<span class="box">1</span>
<span class="box">2</span>
<span class="box">3</span>
</div>
虽然代码中没有显式空格,但换行 + 缩进 = 空白字符,被当作文本处理。
二、根本原因
inline-block元素的布局行为类似于行内元素(inline),会受文本空白的影响。- 浏览器将 HTML 中的换行符、制表符、空格视为文本节点,渲染时显示为空格。
三、常见场景
| 场景 | 是否有间隙 |
|---|---|
| 元素间换行书写(有缩进) | 有 |
| 元素间写空格或制表符 | 有 |
| 元素紧挨着写(无空格/换行) | 无 |
| 使用注释连接 | 无 |
父元素 font-size: 0 | 无(子元素需重置字体) |
四、如何避免?
推荐方法:
- HTML 中元素紧挨着写:
<span>1</span><span>2</span><span>3</span> - 父元素设置
font-size: 0,子元素重置字体:.parent { font-size: 0; } .parent span { font-size: 14px; display: inline-block; } - 使用 Flex 布局(推荐):
.parent { display: flex; gap: 0; } - 使用 HTML 注释消除空白:
<span>1</span><!-- --><span>2</span><!-- --><span>3</span>
总结
display: inline-block的间隙出现在 HTML 元素间有换行或空格时,本质是空白字符被渲染为文本空格。
推荐使用 Flex 布局 或font-size: 0方案彻底解决,避免布局错乱。
二十二、CsS 怎么实现单行、多行文本溢出隐藏?
一、单行文本溢出隐藏
适用于标题、列表项等单行文本。
.single-line {
white-space: nowrap; /* 不换行 */
overflow: hidden; /* 超出隐藏 */
text-overflow: ellipsis; /* 溢出显示省略号(...) */
}
关键三要素:
white-space: nowrap:强制文本在一行内显示overflow: hidden:超出部分隐藏text-overflow: ellipsis:显示省略号
必须设置宽度(或父容器有宽度限制),否则无法触发溢出。
二、多行文本溢出隐藏
适用于文章摘要、简介等需要限制行数的场景。
方法一:-webkit-line-clamp(兼容性好,推荐)
.multi-line {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3; /* 限制显示3行 */
overflow: hidden;
/* 可选:避免 Safari 换行 */
word-break: break-all;
}
优点:简单高效,主流浏览器支持(包括移动端)。
方法二:line-height + height 计算(兼容性最佳)
.multi-line {
line-height: 1.5;
height: 4.5em; /* 3行:3 × 1.5em */
overflow: hidden;
word-break: break-word;
}
优点:兼容所有浏览器,无需私有属性。
缺点:行数固定,需手动计算高度。
总结
| 类型 | 推荐方案 | 关键属性 |
|---|---|---|
| 单行溢出 | 标准方法 | white-space: nowrap; overflow: hidden; text-overflow: ellipsis; |
| 多行溢出 | -webkit-line-clamp | display: -webkit-box; -webkit-line-clamp: n; overflow: hidden; |
实际开发中:
- 单行:直接使用三属性组合;
- 多行:优先使用
-webkit-line-clamp,必要时降级为height + line-height方案。
二十三、Sass、Less 是什么?为什么要使用它们?
一、Sass 和 Less 是什么?
- Sass(Syntactically Awesome Style Sheets)和 Less(Leaner CSS)是两种主流的 CSS 预处理器。
- 它们扩展了 CSS 的语法,提供了变量、嵌套、混合、函数等编程特性,最终编译成标准 CSS 文件供浏览器使用。
开发时写
.scss或.less文件 → 编译 → 生成.css文件。
二、核心功能对比
| 特性 | Sass | Less |
|---|---|---|
| 变量 | $primary-color: #007bff; | @primary-color: #007bff; |
| 嵌套 | 支持,语法清晰 | 支持 |
| 混合(Mixins) | @mixin, @include | .mixin() |
| 函数与运算 | 内置丰富函数,支持自定义 | 支持基本运算和函数 |
| 模块化 | @use / @import | @import |
| 工具链 | 基于 Ruby 或 Dart(Dart Sass 推荐) | 基于 Node.js |
两者功能相似,Sass 功能更强大,生态更成熟。
三、为什么要使用它们?(核心优势)
-
变量管理
统一定义颜色、字体、间距等,便于主题切换和维护。$theme-color: #007bff; .btn { background: $theme-color; } -
代码复用(Mixins)
封装可复用样式,如 flex 居中、圆角阴影等。@mixin center { display: flex; justify-content: center; align-items: center; } .box { @include center; } -
嵌套语法,结构清晰
模拟 HTML 结构,提升可读性。.nav { ul { margin: 0; } li { float: left; } } -
模块化开发
拆分样式文件(如_variables.scss,_mixins.scss),便于团队协作。 -
函数与条件控制(Sass 更强)
支持循环、条件判断,实现动态样式生成。
总结
- Sass 和 Less 是 CSS 预处理器,让 CSS 具备编程能力。
- 使用它们能提升开发效率、代码可维护性和团队协作性。
- 推荐使用 Sass(尤其是 SCSS 语法),功能更强大,生态更完善。
现代前端项目中,结合 Webpack/Vite 等工具,Sass/Less 已成为标准开发实践。
二十四、说说你对媒体查询的理解?
一、什么是媒体查询(Media Queries)?
媒体查询是 CSS3 提供的一种技术,允许根据设备的特征或环境条件(如屏幕宽度、分辨率、方向等)来应用不同的样式规则。
它是实现响应式设计(Responsive Design)的核心工具。
二、基本语法
@media 媒体类型 and (媒体特性) {
/* 满足条件时的样式 */
}
常见用法(按屏幕宽度):
/* 小屏幕(手机) */
@media (max-width: 767px) {
.container { width: 100%; }
}
/* 平板 */
@media (min-width: 768px) and (max-width: 1023px) {
.container { width: 90%; }
}
/* 桌面大屏 */
@media (min-width: 1024px) {
.container { width: 1200px; margin: 0 auto; }
}
三、常用媒体特性
| 特性 | 说明 |
|---|---|
width / height | 视口宽度/高度 |
min-width / max-width | 最小/最大视口宽度(最常用) |
orientation | 设备方向:portrait(竖屏)或 landscape(横屏) |
resolution | 设备分辨率(如 2dppx 适配 Retina 屏) |
hover | 是否支持悬停(区分触屏与鼠标设备) |
四、媒体类型(已较少使用)
all:所有设备screen:屏幕设备(最常用)print:打印设备speech:屏幕阅读器
现代开发中通常省略类型,默认为
screen。
五、为什么使用媒体查询?
- 实现响应式布局:一套代码适配手机、平板、桌面等不同设备。
- 提升用户体验:在小屏幕上自动调整字体、布局、导航方式。
- 优化性能:为高分辨率设备加载
@2x图片,为低分辨率节省流量。 - 增强可访问性:根据设备能力调整交互方式(如禁用 hover 效果)。
六、最佳实践
- 使用移动优先(Mobile First)策略:先写小屏样式,再用
min-width逐步增强。 - 选择合理的断点(Breakpoints),基于内容而非设备。
- 结合 Flexbox 和 Grid 布局,提升灵活性。
总结
媒体查询是响应式设计的基石,通过检测设备特征动态应用样式,让网页在各种设备上都能良好显示。
掌握min-width、max-width等关键特性,是现代前端开发的必备技能。
二十五、说说你对 CSS 工程化的理解
一、什么是 CSS 工程化?
CSS 工程化是指将 CSS 开发从简单的样式编写,转变为可维护、可扩展、可协作、可自动化的工程体系。它通过工具、规范和架构设计,解决传统 CSS 开发中的命名冲突、依赖混乱、维护困难等问题。
核心目标:提升开发效率、保证代码质量、降低维护成本。
二、CSS 工程化的主要内容
-
模块化与组件化
- 将样式按组件拆分(如
_button.scss,_header.scss) - 避免全局污染,实现高内聚、低耦合
- 配合
@import或@use(Sass)组织依赖
- 将样式按组件拆分(如
-
预处理器 / 后处理器
- 使用 Sass/Less 实现变量、嵌套、混合
- 使用 PostCSS 自动添加前缀、兼容处理、压缩优化
-
命名规范
- 采用 BEM(Block__Element--Modifier)等规范,避免命名冲突
- 示例:
.btn__price--disabled
-
构建与自动化
- 使用 Webpack、Vite、Gulp 等工具:
- 编译
.scss→.css - 压缩、合并、版本控制
- 提取公共样式
- 删除未使用 CSS(Tree Shaking)
- 编译
- 使用 Webpack、Vite、Gulp 等工具:
-
CSS in JS / CSS Modules
- CSS Modules:局部作用域,避免全局污染
- CSS in JS:如 styled-components,样式与组件绑定,动态生成
-
性能优化
- 关键 CSS 内联
- 异步加载非关键样式
- 使用雪碧图、字体图标、响应式图片
-
代码质量与协作
- 使用 Stylelint 统一代码风格
- 自动化测试(视觉回归测试)
- 文档化组件样式
三、为什么需要 CSS 工程化?
| 传统 CSS 问题 | 工程化解决方案 |
|---|---|
| 全局污染、命名冲突 | CSS Modules、BEM、作用域隔离 |
| 难以维护、重复代码 | 预处理器变量、混合、模块化 |
| 兼容性处理繁琐 | PostCSS 自动加前缀 |
| 性能差 | 压缩、按需加载、Tree Shaking |
| 团队协作困难 | 规范 + 工具 + 自动化 |
总结
CSS 工程化就是让样式开发从‘写代码’走向‘做工程’。通过预处理、模块化、自动化构建和规范化的手段,解决传统 CSS 维护难、易冲突、性能差的问题,实现高效率、高质量、可协作的开发流程。它是现代前端项目不可或缺的一环。
二十六、z-index 属性在什么情况下会失效?
z-index 用于控制元素的堆叠顺序,但只在特定条件下生效。以下情况会导致 z-index 失效:
一、没有建立定位上下文(最常见原因)
- 问题:
z-index只对定位元素(position不为static)生效。 - 错误示例:
.box { z-index: 999; /* 无效!默认 position: static */ } - 解决:必须配合
position: relative / absolute / fixed / sticky.box { position: relative; z-index: 999; }
二、父元素形成堆叠上下文,限制子元素层级
- 问题:父元素设置了
z-index、opacity < 1、transform、will-change等属性,会创建新的堆叠上下文,子元素的z-index只在该父容器内比较,无法突破父级层级。 - 示例:
.parent-a { z-index: 10; position: relative; } .parent-b { z-index: 5; position: relative; } .child { z-index: 999; position: absolute; } /* 仍低于 parent-a */ - 解决:调整父级的
z-index,而非仅提升子元素。
三、元素被其他非 z-index 因素覆盖
- 某些 CSS 属性会隐式创建堆叠上下文或影响层级:
opacity < 1transform(如translate,scale)filter(如blur())will-changeisolation: isolate
- 这些元素即使
z-index较低,也可能覆盖其他元素。
四、z-index 值相同,遵循 DOM 顺序
- 当多个定位元素
z-index相同,后渲染的元素(DOM 中靠后的)在上层。 - 若想改变顺序,需显式设置更高
z-index。
总结
z-index失效主要有三个原因:
- 元素未设置
position(必须是relative、absolute等);- 父元素创建了堆叠上下文,限制了子元素的层级范围;
- 被
opacity、transform等属性隐式创建的层覆盖。使用时要确保:定位 + 正确的堆叠上下文层级 + 避免意外创建新层。
二十七、CSS3 中的 transform 有哪些属性?
一、2D 变换属性
| 函数 | 说明 |
|---|---|
translate(x, y) | 位移:沿 X/Y 轴移动元素(推荐替代 top/left) |
translateX(x) | 仅在 X 轴移动 |
translateY(y) | 仅在 Y 轴移动 |
scale(sx, sy) | 缩放:sx 为水平缩放倍数,sy 为垂直(可选) |
scaleX(s) | 水平缩放 |
scaleY(s) | 垂直缩放 |
rotate(angle) | 旋转:如 rotate(45deg),绕中心点顺时针旋转 |
skew(ax, ay) | 倾斜(斜切):ax 为 X 轴倾斜角度,ay 为 Y 轴 |
skewX(a) | 仅 X 轴倾斜 |
skewY(a) | 仅 Y 轴倾斜 |
二、3D 变换属性(需配合 perspective)
| 函数 | 说明 |
|---|---|
translateZ(z) | 在 Z 轴位移(靠近或远离屏幕) |
translate3d(x, y, z) | 同时在 X/Y/Z 三轴移动(性能更好) |
scaleZ(sz) | Z 轴缩放(常用于 3D 效果) |
scale3d(sx, sy, sz) | 三维缩放 |
rotateX(angle) | 绕 X 轴旋转(翻转) |
rotateY(angle) | 绕 Y 轴旋转(翻书效果) |
rotateZ(angle) | 绕 Z 轴旋转(等同于 2D rotate) |
rotate3d(x, y, z, angle) | 自定义轴旋转 |
matrix3d() | 3D 变换矩阵(高级用法) |
三、关键配合属性
transform-origin:设置变换的原点(默认是中心50% 50%)transform-origin: 0 0; /* 从左上角变换 */perspective:设置 3D 透视距离,让 3D 效果更真实perspective: 1000px; /* 值越小,透视感越强 */transform-style: preserve-3d:让子元素也参与 3D 空间
总结
transform支持 2D 和 3D 变换,常用属性包括:
- 位移:
translate/translateX/Y/Z- 缩放:
scale/scaleX/Y/Z- 旋转:
rotate/rotateX/Y/Z- 倾斜:
skew- 3D 特有:
perspective、translate3d、rotate3d等。它性能好、不触发重排,广泛用于动画、交互和视觉效果。
二十八、常见的 CSS 布局单位有哪些?
一、绝对单位(固定尺寸)
| 单位 | 说明 |
|---|---|
px(像素) | 最常用,相对像素,基于屏幕分辨率,1px 通常为一个设备像素点。 |
cm、mm | 厘米、毫米,物理长度单位,用于打印样式。 |
in(英寸) | 1in = 96px(标准屏幕),用于打印或固定输出。 |
pt(点) | 1pt = 1/72in,常用于字体大小(如 12pt)。 |
绝对单位在不同设备上显示大小固定,不利于响应式设计。
二、相对单位(推荐用于响应式)
| 单位 | 相对于 | 说明 |
|---|---|---|
em | 父元素的 font-size | 继承并相对计算,易产生级联放大问题。 |
rem | 根元素(<html>)的 font-size | 推荐用于响应式布局,统一控制基准。 |
% | 父元素的对应属性 | 如 width: 50% 表示父容器宽度的一半。 |
vw | 视口宽度的 1% | 1vw = 视口宽度的 1%,适合全屏布局。 |
vh | 视口高度的 1% | 1vh = 视口高度的 1%,如 height: 100vh = 全屏高。 |
vmin | vw 和 vh 中的较小值 | 适配移动端旋转。 |
vmax | vw 和 vh 中的较大值 | |
ch | “0”字符的宽度 | 基于字体的等宽特性,适合文本布局。 |
ex | “x”字符的高度 | 较少使用。 |
三、弹性单位(Flex 布局专用)
| 单位 | 说明 |
|---|---|
fr | 网格中的“份数”单位,用于 grid-template-columns/rows,如 1fr 2fr 表示 1:2 分配剩余空间。 |
总结
常见 CSS 布局单位有:
px:固定像素,最常用;%:相对父元素,用于宽度;em/rem:字体相关,rem更适合响应式;vw/vh:相对视口,适合全屏布局;fr:Grid 布局中的弹性份额。推荐:响应式设计优先使用
rem、vw、fr等相对单位,提升适配能力。
二十九、说说 px、rpx、em、rem、vw、vh 的区别及使用场景
一、单位详解与对比
| 单位 | 相对于 | 特点 | 使用场景 |
|---|---|---|---|
px | 设备像素(固定值) | 绝对单位,不随缩放变化 | 固定边框、图标尺寸;简单布局 |
rpx | 微信小程序中的屏幕宽度 750 等分 | 1rpx = 屏幕宽度 / 750 | 微信小程序开发专用,实现跨设备适配 |
em | 父元素的 font-size | 相对单位,会继承并级联放大 | 文本间距、按钮内边距(局部相对) |
rem | 根元素 <html> 的 font-size | 相对单位,全局统一基准,无级联问题 | 响应式布局首选,字体、间距、组件尺寸 |
vw | 视口宽度的 1%(1vw = 视口宽的 1%) | 响应式强,随屏幕宽度变化 | 全屏背景、宽度布局、移动端适配 |
vh | 视口高度的 1%(1vh = 视口高的 1%) | 垂直方向响应式 | 全屏页面、登录页、弹窗高度 |
二、核心区别总结
px:固定不变,不利于缩放。rpx:小程序专用单位,类似vw,但基于 750 设计稿。em:相对父级,易因嵌套导致尺寸失控。rem:相对根元素,可控性强,适合响应式。vw/vh:相对视口,真正实现“屏幕越大,元素越大”。
三、使用场景推荐
| 场景 | 推荐单位 |
|---|---|
| 移动端 Web 响应式布局 | rem 或 vw |
| 小程序开发 | rpx |
| 字体大小 | rem(可缩放)或 px(固定) |
| 全屏高度(如登录页) | 100vh |
| 宽度占满或等分 | vw 或 % |
| 按钮/组件内部间距 | em 或 rem |
| 边框、小图标 | px(保持清晰) |
总结
px:固定像素,适合边框等细节;rpx:小程序专用,750 设计稿适配;em:相对父级字体,慎用级联;rem:相对根字体,响应式首选;vw/vh:相对视口,实现真正流式布局。现代开发推荐:Web 用
rem+vw,小程序用rpx,提升跨设备适配能力。
三十、怎么实现网页两栏布局?
方法一:float + margin(传统方案)
.sidebar {
float: left;
width: 200px;
background: #f0f0f0;
}
.main {
margin-left: 200px; /* 避开浮动元素 */
background: #fff;
}
注意:需清除浮动(如父元素
overflow: hidden)。
方法二:flex 布局(推荐)
.container {
display: flex;
}
.sidebar {
width: 200px;
flex-shrink: 0; /* 防止压缩 */
background: #f0f0f0;
}
.main {
flex: 1; /* 占据剩余空间 */
background: #fff;
}
方法三:grid 布局(强大灵活)
.container {
display: grid;
grid-template-columns: 200px 1fr; /* 左栏固定,右栏自适应 */
gap: 10px;
}
方法四:position 定位(特殊场景)
.container { position: relative; }
.sidebar {
position: absolute;
left: 0;
top: 0;
width: 200px;
height: 100%;
}
.main {
margin-left: 200px;
}
方法五:table-cell(已不推荐)
.container { display: table; width: 100%; }
.sidebar, .main {
display: table-cell;
vertical-align: top;
}
.sidebar { width: 200px; }
总结
实现两栏布局最推荐使用 Flex 布局:
- 左栏设固定宽度 +
flex-shrink: 0- 右栏用
flex: 1占满剩余空间兼容性要求高可用
float,复杂布局可用Grid。
flex方案简洁、等高、易响应式,是当前最佳实践。
三十一、怎么实现网页三栏布局?
方法一:flex 布局(推荐)
.container {
display: flex;
}
.left {
width: 200px;
flex-shrink: 0; /* 防止压缩 */
background: #f0f0f0;
}
.main {
flex: 1; /* 占据所有剩余空间 */
background: #fff;
}
.right {
width: 150px;
flex-shrink: 0;
background: #f0f0f0;
}
方法二:grid 布局(最简洁)
.container {
display: grid;
grid-template-columns: 200px 1fr 150px; /* 左、中、右 */
gap: 10px;
}
方法三:浮动布局(传统方案)
.left {
float: left;
width: 200px;
background: #f0f0f0;
}
.right {
float: right;
width: 150px;
background: #f0f0f0;
}
.main {
margin: 0 150px 0 200px; /* 左右留出空间 */
background: #fff;
}
父容器需清除浮动(如
overflow: hidden)
方法四:position 定位(特殊场景)
.container { position: relative; }
.left {
position: absolute;
left: 0; top: 0;
width: 200px; height: 100%;
}
.right {
position: absolute;
right: 0; top: 0;
width: 150px; height: 100%;
}
.main {
margin: 0 150px 0 200px;
}
方法五:圣杯布局 / 双飞翼布局(经典面试题)
- 圣杯布局:通过
margin负值 +float+padding实现 - 双飞翼布局:在圣杯基础上增加一个包裹层
已过时,主要用于考察 CSS 理解
总结
实现三栏布局最推荐使用 Flex 或 Grid:
flex:左栏固定 + 中栏 flex:1 + 右栏固定,兼容性好;grid:grid-template-columns: 200px 1fr 150px,一行代码搞定。传统方案如浮动、定位已逐渐淘汰。
flex和grid方案简洁、等高、易响应式,是当前最佳实践。
三十二、怎么实现元素的水平垂直居中?
方法一:flex 布局(推荐,现代首选)
.container {
display: flex;
justify-content: center; /* 水平居中 */
align-items: center; /* 垂直居中 */
height: 100vh; /* 父容器需有高度 */
}
.item {
/* 子元素无需额外设置 */
}
方法二:grid 布局(同样推荐)
.container {
display: grid;
place-items: center; /* 水平 + 垂直居中(简写) */
height: 100vh;
}
或
.container {
display: grid;
justify-items: center;
align-items: center;
}
方法三:position + transform(兼容性好)
.container {
position: relative;
height: 100vh;
}
.item {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%); /* 偏移自身宽高的一半 */
}
方法四:position + margin(固定尺寸,必须设置固定宽高)
.item {
position: absolute;
top: 0; left: 0; right: 0; bottom: 0;
width: 200px;
height: 100px;
margin: auto; /* 关键:自动外边距 */
}
方法五:table-cell(旧方案,了解即可)
.container {
display: table-cell;
text-align: center;
vertical-align: middle;
width: 300px; height: 300px;
}
.item {
display: inline-block;
}
总结
实现水平垂直居中最推荐:
flex方案:justify-content + align-items,简洁现代;position + transform:兼容性好,适合定位场景;固定尺寸可用
margin: auto,但局限大。
flex和grid是当前最佳实践,代码少、语义清、兼容好。
三十三、如何根据设计稿进行移动端适配?
一、明确设计稿基准
- 常见设计稿宽度:750px(iPhone 6/7/8)或 640px、1125px(高清屏)。
- 设计师通常基于 iPhone 6/7/8(375px 视口宽) 出图。
目标:将 750px 设计稿等比缩放到不同设备。
方法一:使用 rem + 动态根字体(推荐)
原理:
通过 JS 动态设置 <html> 的 font-size,将 rem 变成“弹性单位”,实现等比缩放。
// 动态设置根字体大小
function setRem() {
const designWidth = 750; // 设计稿宽度
const rem = 100; // 1rem = 100px (基准)
const scale = document.documentElement.clientWidth / designWidth;
document.documentElement.style.fontSize = rem * scale + 'px';
}
window.addEventListener('resize', setRem);
setRem(); // 初始化
/* 设计稿上元素宽 100px → 写成 1rem */
.box {
width: 1rem; /* = 100px 在 750px 设备上 */
font-size: 0.28rem; /* 28px */
}
方法二:使用 vw 单位(简洁现代)
原理:
1vw = 视口宽度的 1%,750px 设计稿 → 100vw = 750px → 1px = 1/7.5 vw
/* 计算:100px / 750 * 100 = 13.333333vw */
.box {
width: 13.333333vw;
font-size: 3.733333vw; /* 28px = 28/750*100vw */
}
可配合 PostCSS 插件(如
postcss-px-to-viewport)自动转换。
方法三:使用 rpx(微信小程序专用)
- rpx:微信小程序中的响应式单位,750rpx = 设备屏幕宽度
- 设计稿 750px → 1px = 1rpx,直接使用即可
.box {
width: 100rpx; /* 在任意设备上自动缩放 */
font-size: 28rpx;
}
方法四:媒体查询 + flex 布局(响应式设计)
.container {
display: flex;
gap: 10px;
}
@media (max-width: 375px) {
.box { width: 100px; }
}
@media (min-width: 414px) {
.box { width: 120px; }
}
适用:内容型网站(如新闻、电商),追求“流式体验”而非像素级还原。
总结
移动端适配常用方案:
- H5 项目:
rem+ JS 动态设置根字体,或vw+ 自动转换工具;- 小程序:直接使用
rpx;- 响应式网站:
flex/grid+ 媒体查询。推荐:
rem方案精确还原设计稿,vw方案更现代简洁,根据项目需求选择。
三十四、说说你对 Flex 布局的理解及其使用场景
一、什么是 Flex 布局?
Flex(Flexible Box)布局,即“弹性盒子布局”,是 CSS3 提供的一种一维布局模型,旨在提供一种更高效、灵活的方式来分配容器内子元素的空间,无论其尺寸是否已知或动态变化。
核心目标:轻松实现对齐、排列、空间分配和响应式布局。
二、核心概念
Flex 布局涉及两个层级:
-
容器(Flex Container)
设置display: flex或display: inline-flex的父元素。 -
项目(Flex Items)
容器的直接子元素,自动成为弹性项目。
三、容器常用属性
| 属性 | 作用 |
|---|---|
flex-direction | 主轴方向:row(默认) / column / row-reverse / column-reverse |
justify-content | 主轴对齐方式:flex-start、center、space-between、space-around 等 |
align-items | 交叉轴对齐方式:flex-start、center、stretch(默认)等 |
flex-wrap | 是否换行:nowrap(默认) / wrap / wrap-reverse |
align-content | 多行时的交叉轴对齐(需 flex-wrap: wrap) |
四、项目常用属性
| 属性 | 作用 |
|---|---|
flex-grow | 放大比例(默认 0) |
flex-shrink | 缩小比例(默认 1) |
flex-basis | 基础大小(可替代 width) |
flex | 复合属性:flex: 0 1 auto(推荐简写) |
order | 排序(可改变视觉顺序) |
align-self | 单个项目覆盖 align-items |
五、经典使用场景
| 场景 | Flex 解决方案 |
|---|---|
| 水平垂直居中 | justify-content: center; align-items: center; |
| 两栏/三栏布局 | 固定栏 + flex: 1 自适应栏 |
| 等高布局 | 子元素自动等高,无需设置高度 |
| 空间均匀分布 | space-between、space-around |
| 响应式导航栏 | flex-wrap: wrap 实现换行 |
| 圣杯布局 | order 改变 DOM 顺序,提升语义化 |
| 卡片内部对齐 | 内容动态时仍能良好对齐 |
总结
Flex 布局是一种强大的一维弹性布局模型,通过“容器 + 项目”的方式,轻松实现对齐、分布、自适应和响应式效果。
适用于居中、两栏/三栏、导航、卡片布局等常见场景。
它是现代 CSS 布局的基石,取代了浮动和定位的复杂实现,推荐作为默认布局方案。
三十五、说说响应式设计的概念及基本原理
一、什么是响应式设计(Responsive Design)?
响应式设计是一种网页设计方法,旨在让网站在不同设备(如手机、平板、桌面电脑)和不同屏幕尺寸上都能提供良好、一致的用户体验。
核心目标:一套代码,适配所有设备。
二、基本原理
响应式设计依赖三大核心技术:
1. 流式布局(Fluid Grids)
- 使用相对单位(如
%、rem、vw)替代固定单位(如px),让布局随屏幕尺寸弹性伸缩。 - 示例:
.container { width: 100%; max-width: 1200px; margin: 0 auto; } .column { width: 50%; /* 两栏等分,自动适应 */ }
目的:布局不“断层”,平滑过渡。
2. 弹性图片与媒体(Flexible Images)
- 图片、视频等媒体元素设置最大宽度,防止溢出容器。
img, video { max-width: 100%; height: auto; }
目的:媒体内容随父容器缩放,不破坏布局。
3. 媒体查询(Media Queries)
- 根据设备特性(如屏幕宽度、分辨率、方向)应用不同样式。
- 常用断点(Breakpoints):
/* 手机(小屏) */ @media (max-width: 767px) { .nav { display: none; } .column { width: 100%; } } /* 平板 */ @media (min-width: 768px) and (max-width: 1023px) { .column { width: 50%; } } /* 桌面大屏 */ @media (min-width: 1024px) { .container { width: 1200px; } }
目的:在关键尺寸点优化布局结构。
三、常见实现方式
- 移动优先(Mobile First):先设计小屏样式,再通过
min-width逐步增强。 - 使用 Flexbox / Grid 布局:天然支持弹性与响应式。
- Viewport 元标签:确保移动端正确缩放。
<meta name="viewport" content="width=device-width, initial-scale=1.0">
总结
响应式设计是让网页自适应不同设备的布局方法,核心原理是:
- 流式网格:用
%、rem等相对单位实现弹性布局;- 弹性媒体:
max-width: 100%让图片不溢出;- 媒体查询:根据屏幕尺寸调整样式。
结合 移动优先 + Flex/Grid + Viewport,即可实现一套代码适配全设备,是现代 Web 开发的标准实践。
三十六、为什么需要清除浮动?清除浮动的方式有哪些?
一、为什么需要清除浮动?
当元素使用 float: left/right 时,会脱离文档流,导致父容器无法感知其高度,从而引发高度塌陷(父元素高度为 0),影响后续布局。
<div class="container">
<div class="box">浮动元素</div>
</div>
<p>后面的元素会错位</p>
.box { float: left; height: 100px; }
.container { background: #f0f0f0; }
问题:
.container高度为 0,背景不显示,后续元素上移重叠。
清除浮动的目的:解决父容器高度塌陷,恢复正常的文档流布局。
二、清除浮动的方式
方法一:overflow: hidden(推荐,简单常用)
.container {
overflow: hidden; /* 触发 BFC,包含浮动 */
}
方法二:::after 伪元素 + clear(经典方案)
.container::after {
content: "";
display: block;
clear: both;
height: 0;
visibility: hidden;
}
.container {
zoom: 1; /* 兼容 IE6/7 */
}
方法三:使用 display: flow-root(现代标准)
.container {
display: flow-root; /* 创建新的块级格式化上下文 */
}
方法四:父元素也浮动(不推荐 导致父元素也脱离文档流,问题传递)
.container { float: left; }
方法五:使用 flex 或 grid 布局(根本解决)
.container {
display: flex; /* 不需要浮动,自然包含子元素 */
}
现代开发建议:用 Flex/Grid 替代浮动布局,从根本上避免清除浮动问题。
总结
清除浮动是为了解决父容器高度塌陷,因为浮动元素脱离文档流。
常见方法:
overflow: hidden(简单有效)::after伪元素 +clear: both(经典兼容)display: flow-root(现代标准)但更推荐使用 Flex 或 Grid 布局,避免使用浮动,从源头解决问题。
三十七、使用 clear 属性清除浮动的原理?
一、clear 属性的作用
clear 属性用于控制元素在浮动元素旁边的位置,确保该元素不会与前面的浮动元素在同一行显示。
常见取值:
clear: left:不允许左边有浮动元素clear: right:不允许右边有浮动元素clear: both:不允许左右有浮动元素(最常用)
二、清除浮动的原理
当一个元素设置了 clear: both(或 left/right),浏览器会:
- 检查前面的浮动元素
- 强制将该元素移动到浮动元素的下方
- 形成“隔离”效果,阻止后续内容环绕浮动元素
本质:通过生成一个“屏障”,让后续元素避开浮动区域。
三、经典用法:::after 伪元素 + clear
.clearfix::after {
content: "";
display: block;
clear: both;
height: 0;
visibility: hidden;
}
工作原理:
::after在父容器末尾插入一个不可见的块级元素- 该元素设置
clear: both,强制“下沉”到所有浮动子元素之下 - 父容器因此“包含”了这个下沉的伪元素,从而撑开高度,解决塌陷问题
相当于在浮动元素后加了一个“清道夫”,告诉浏览器:“从这里开始,下面不能再和浮动元素同行”。
四、底层机制:块格式化上下文(BFC)的间接触发
虽然 clear 本身不直接创建 BFC,但通过迫使元素换行并占据整行空间,间接实现了包含浮动的效果,使父容器能够正确计算高度。
总结
clear属性通过强制元素避开浮动区域、换行显示,来阻止内容环绕。
在清除浮动时,常结合::after伪元素使用:在父容器末尾插入一个clear: both的块元素,使其“下沉”到所有浮动元素之下,从而撑开父容器高度,解决高度塌陷问题。它是一种基于文档流的“视觉隔离”机制,是 CSS 早期解决浮动问题的核心手段。
三十八、说说你对 BFC 的理解,如何创建 BFC?
一、什么是 BFC?(Block Formatting Context)
BFC(块级格式化上下文) 是 CSS 渲染中的一种独立的布局环境,是一个元素内部的块级盒子布局规则的“作用域”。
可以理解为:一个隔离的容器,内部元素的布局不会影响外部,外部也不会影响内部。
二、BFC 的核心特性
- 内部块级元素垂直排列
- 内部盒子的
margin会折叠,但与外部的margin不折叠 - 不会与浮动元素重叠(可用于两栏布局)
- 包含内部所有子元素,包括浮动元素(解决高度塌陷)
- BFC 是独立容器,不影响外部布局
三、BFC 的常见应用场景
| 问题 | BFC 解决方案 |
|---|---|
| 父容器高度塌陷 | 创建 BFC 包含浮动子元素 |
| 外边距(margin)重叠 | 在两个块之间创建 BFC 隔离 |
| 文字环绕浮动元素 | 让文字容器形成 BFC,避免环绕 |
| 两栏布局(侧边固定 + 主内容自适应) | 主内容创建 BFC,自动占据剩余空间 |
四、如何创建 BFC?
满足以下任意一个条件即可创建 BFC:
| CSS 属性/值 | 说明 |
|---|---|
float: left/right | 浮动元素自身形成 BFC |
position: absolute/fixed | 绝对定位元素 |
display: inline-block | 行内块元素 |
display: flex / grid / flow-root | Flex/Grid 容器和 flow-root |
overflow: hidden / scroll / auto | 常用且简单的方式 |
contain: layout / content / paint | 新增属性,用于性能优化 |
column-count: 1 或 column-width | 多列布局容器 |
最常用方法:
overflow: hidden或display: flow-root
五、示例:用 BFC 解决浮动塌陷
<div class="container">
<div class="float-box">浮动元素</div>
</div>
.float-box {
float: left;
width: 100px;
height: 100px;
}
.container {
overflow: hidden; /* 创建 BFC,包含浮动元素 */
/* 现在 container 高度为 100px,不再塌陷 */
}
总结
BFC 是一个独立的块级布局环境,具有隔离性和包含性,能解决高度塌陷、margin 重叠、文字环绕等问题。
创建 BFC 的方式包括:overflow: hidden、display: flex/grid/flow-root、float、position等。
推荐使用overflow: hidden或display: flow-root来主动创建 BFC,提升布局控制力。
三十九、什么是 margin 重善问题?如何解决?
一、什么是 margin 重叠(Margin Collapse)?
margin 重叠是 CSS 中的一种特殊行为:当两个垂直方向的块级元素相邻时,它们之间的垂直外边距(margin-top 与 margin-bottom)不会相加,而是合并为一个边距,取其中较大的那个值。
只发生在 块级元素的垂直方向,且在同一个 BFC 内。
二、常见场景
-
相邻兄弟元素
.box1 { margin-bottom: 20px; } .box2 { margin-top: 30px; }实际间距:30px(不是 50px),取最大值。
-
父元素与第一个/最后一个子元素
.parent { margin-top: 0; } .child { margin-top: 20px; }父元素会“被带着”下移 20px,子元素贴顶。
-
空块元素
- 上下
margin会合并为一个。
- 上下
三、为什么会有 margin 重叠?
- 设计初衷:用于段落文本的自然排版,避免
p标签之间间距过大。 - 例如:
连续段落之间只保留 1em 间距,而非 2em。p { margin: 1em 0; }
四、如何解决 margin 重叠?
方法一:创建新的 BFC(推荐)
让子元素或其中一个元素形成独立的布局环境:
.parent {
overflow: hidden; /* 创建 BFC */
}
子元素的
margin不再与父元素重叠。
方法二:使用 padding 或 border 替代
给父元素添加 padding-top 或 border-top:
.parent {
padding-top: 1px;
border-top: 1px solid transparent;
}
只要父元素有“高度”或边框,就不会发生重叠。
方法三:使用 flex / grid / inline-block 容器
.parent {
display: flex;
flex-direction: column;
}
Flex 容器内部不发生垂直 margin 重叠。
方法四:使用非块级布局
- 将元素改为
inline-block、float等,脱离普通文档流。
方法五:使用 padding 替代 margin(语义允许时)
.box1 { margin-bottom: 20px; }
.box2 { padding-top: 30px; } /* 用 padding 代替 margin-top */
padding不参与重叠。
总结
margin 重叠是指相邻块级元素的垂直外边距合并为较大值的现象,主要发生在普通文档流中。
解决方法:
- 创建 BFC(如
overflow: hidden)- 使用 flex/grid 布局
- 给父元素加
border或padding- 避免使用
margin,改用padding推荐:用 BFC 或 Flex 布局从根本上避免问题,尤其在组件化开发中。
四十、说说网页元素的层善顺序
一、标准层叠顺序(从下到上)
在一个 层叠上下文(Stacking Context) 内,元素的渲染顺序如下:
-
背景和边框(Background and borders)
→ 父元素的背景、边框 -
负 z-index 的子元素
→z-index: -1等,在背景之下 -
普通流内块级元素(Block-level, non-positioned)
→ 没有position的普通元素 -
普通流内行内元素(Inline-level, non-positioned)
→span、a等 -
z-index: auto或0的定位元素
→position: relative/absolute/fixed且未设置z-index或为0 -
z-index > 0的定位元素
→ 正z-index元素,数值越大越靠上
注意:
z-index < 0的元素在背景之下,容易被忽略。
二、关键概念解析
-
层叠上下文(Stacking Context)
某些元素会创建新的层叠上下文(如z-index不为auto的定位元素、opacity < 1、transform等),其内部的z-index只在该上下文中比较。 -
z-index只对定位元素生效
必须设置position: relative/absolute/fixed/sticky才能使用z-index。
三、常见影响层叠上下文的因素
以下属性会创建新的层叠上下文:
z-index+position(不为static)opacity < 1transformfilterwill-changeisolation: isolatemix-blend-mode(非normal)perspective
四、经典问题示例
.parent { z-index: 1; position: relative; }
.child { z-index: 999; position: relative; }
.sibling { z-index: 2; position: relative; }
即使
.child的z-index很大,它仍属于.parent创建的层叠上下文,整体层级由.parent决定,可能低于.sibling。
总结
元素的层叠顺序从下到上是:
- 背景边框 →
- 负 z-index →
- 普通元素 →
- 定位元素(z-index: auto/0)→
- 正 z-index 元素
注意:
z-index需配合position使用,且受层叠上下文限制。
四十一、CSS 的 position 有哪些属性值,区别是什么?
一、position 的属性值及区别
| 值 | 定位方式 | 是否脱离文档流 | 相对基准 | 是否受 top/right/bottom/left/z-index 影响 |
|---|---|---|---|---|
static(默认) | 静态定位 | 否 | 正常文档流 | 不受影响 |
relative | 相对定位 | 否 | 自身原始位置 | 可偏移,可设置 z-index |
absolute | 绝对定位 | 是 | 最近的已定位祖先元素(relative/absolute/fixed/sticky),无则相对初始包含块(通常是视口) | 可偏移,可设置 z-index |
fixed | 固定定位 | 是 | 视口(viewport),不随滚动移动 | 可偏移,可设置 z-index |
sticky | 粘性定位 | 否(特殊) | 自身原始位置,在滚动时“吸附”到指定位置 | 受 top/left/bottom/right 控制,达到阈值后变为固定定位 |
二、详细说明
-
static- 默认值,元素按正常文档流排列。
top、left等属性无效。- 无法进行偏移或层级控制。
-
relative- 元素仍在文档流中,占据原始空间。
- 偏移是相对于自己原来的位置。
- 常用于为
absolute子元素提供定位基准。
-
absolute- 脱离文档流,不占据空间。
- 相对于最近的非
static定位祖先元素。 - 常用于弹窗、下拉菜单、精确布局。
-
fixed- 脱离文档流,相对于浏览器视口固定。
- 滚动页面时元素不移动。
- 常用于顶部导航、侧边栏、回到顶部按钮。
-
sticky- 行为像
relative和fixed的结合。 - 在滚动到某个阈值前是相对定位,之后变为固定定位。
- 示例:
.header { position: sticky; top: 0; /* 滚动到顶部时吸附 */ } - 常用于吸顶导航、表格表头固定。
- 行为像
总结
position有 5 个值:
static:默认,不支持偏移;relative:相对自身位置偏移,不脱离文档流;absolute:相对于最近定位祖先,脱离文档流;fixed:相对于视口固定,常用于导航;sticky:滚动到阈值后“吸附”,如吸顶导航。
四十二、CSS 中 display、float、position 的关系是什么?
一、三者的基本作用
| 属性 | 主要作用 |
|---|---|
display | 决定元素的显示类型(块级、行内、弹性、网格等) |
float | 将元素脱离文档流,向左/右浮动,允许文本环绕 |
position | 控制元素的定位方式(静态、相对、绝对、固定等) |
二、三者的优先级与覆盖规则(根据 CSS 规范)
当一个元素同时设置了 display、float、position,浏览器会按照 特定优先级 计算最终的 display 类型:
规范规定:
position和float会覆盖原始的display值。
具体规则如下:
-
如果
position不是static(即relative/absolute/fixed/sticky)- 元素成为“定位元素”
float的值会被忽略(视为none)display的计算值可能被修改:- 若原
display: inline→ 计算为block - 即:定位元素默认表现为块级
- 若原
-
如果
float不是none- 元素成为“浮动元素”
display的计算值会被强制修改:- 若原
display: inline→ 计算为block
- 若原
- (注:
position: static时生效)
-
如果
display: none- 元素不渲染,
float和position失效
- 元素不渲染,
三、通俗总结(面试口诀)
记住一句话:
"定位 > 浮动 > 显示类型"
- 一旦用了
position: absolute/fixed,float就失效;- 用了
float或position,inline元素会变成block表现;display: none最大,直接隐藏一切。
四、示例说明
.box1 {
display: inline;
float: left;
}
/* 最终表现:display 计算为 block(浮动强制块级化) */
.box2 {
display: inline;
position: absolute;
top: 10px;
}
/* 最终表现:display 计算为 block,float 被忽略 */
五、现代布局建议
- 传统布局曾用
float + margin实现多栏; - 现代开发推荐:
- 用
flex或grid替代float布局; - 用
position处理弹层、吸顶等特殊定位; - 明确
display类型,避免隐式转换。
- 用
总结
display、float、position的关系遵循 CSS 优先级规则:
position不为static时,float失效,display可能变为block;float不为none时,display会强制块级化;display: none时,其他两个属性无效。
四十三、说说 CSS 中 position: absolute 与fixed 的共同点和区别
一、共同点
| 特性 | 说明 |
|---|---|
| 脱离文档流 | 两者都不占据原始空间,后续元素会“上移”填充位置。 |
| 可使用偏移属性 | 都支持 top、right、bottom、left 进行精确定位。 |
可设置 z-index | 都能通过 z-index 控制层叠顺序(层级)。 |
| 默认表现为块级 | 即使原 display: inline,也会被强制视为 block 类型。 |
简记:都是“定位元素”,具备强大的布局控制能力。
二、核心区别
| 对比项 | position: absolute | position: fixed |
|---|---|---|
| 定位基准 | 相对于最近的已定位祖先元素(position 不为 static),若无则相对初始包含块(通常是视口) | 相对于浏览器视口(viewport),固定不动 |
| 是否随页面滚动 | 会随页面一起滚动 | 不随页面滚动,始终固定在屏幕某一位置 |
| 常见用途 | 弹窗、下拉菜单、精确布局、子元素相对于父容器定位 | 吸顶导航、侧边栏、回到顶部按钮、广告悬浮框 |
| 是否创建新的包含块 | 是,其子元素的 absolute 定位会以它为基准 | 是,同样创建包含块 |
三、示例对比
/* absolute:相对于父容器定位 */
.parent {
position: relative;
width: 300px; height: 200px;
}
.child-abs {
position: absolute;
top: 10px; left: 10px; /* 相对 .parent 偏移 */
}
/* fixed:相对于视口定位 */
.fixed-nav {
position: fixed;
top: 0; left: 0; /* 始终在屏幕左上角,不随滚动 */
width: 100%;
}
总结
共同点:都脱离文档流,支持偏移和
z-index,默认块级化。
核心区别:
absolute相对于最近的定位祖先,随页面滚动;fixed相对于视口,固定不动,不随滚动。
四十四、说说你对 sticky 定位的理解
一、核心概念
sticky 定位的元素:
- 在未达到触发条件时:表现为
relative,随页面正常滚动; - 当滚动到某个阈值时(如
top: 0):表现为fixed,固定在指定位置,不再随页面滚动; - 当父容器离开视口时:恢复为
relative,继续滚动。
简记:“不到点相对,到点就固定”。
二、关键特性
| 特性 | 说明 |
|---|---|
| 不脱离文档流 | 元素仍占据原始空间,不会影响布局流 |
| 必须设置偏移量 | 必须设置 top、bottom、left 或 right 才能生效(常用 top: 0) |
| 受父容器限制 | 一旦父容器滚动出视口,sticky 效果会停止 |
可设置 z-index | 可通过 z-index 控制层级,避免被其他元素覆盖 |
| 创建层叠上下文 | 会创建新的层叠上下文 |
三、常见使用场景
-
吸顶导航栏
.navbar { position: sticky; top: 0; background: white; z-index: 100; } -
表格表头固定
th { position: sticky; top: 0; background: #f0f0f0; } -
侧边目录吸附
.sidebar { position: sticky; top: 10px; } -
标签页/选项卡切换吸顶
四、注意事项
- 父元素不能有
overflow: hidden/scroll/auto
否则sticky会失效(因为被裁剪或创建了新的滚动上下文)。 - 需确保父容器足够高,否则无法触发“滚动到阈值”的条件。
- 兼容性良好:现代浏览器均支持(IE 不支持)。
总结
sticky定位是一种“智能”定位方式,元素在滚动时先相对定位,到达设定阈值(如top: 0)后变为固定定位,常用于吸顶导航、表格表头等场景。
特点:不脱离文档流、必须设置偏移量、受父容器滚动限制。
四十五、如何用 CSS 实现一个三角形、扇形、宽高自适应的正方形?
一、实现三角形
原理:利用 border 的渲染机制,将元素宽高设为 0,通过设置不同方向的 border 并隐藏其他边,形成三角形。
.triangle {
width: 0;
height: 0;
border: 50px solid transparent;
border-top-color: #000; /* 向上的三角形 */
/* border-right-color: #000; 向右的三角形 */
/* border-bottom-color: #000; 向下的三角形 */
/* border-left-color: #000; 向左的三角形 */
}
技巧:只保留一个方向的
border-color,其余为transparent。
二、实现扇形
原理:在三角形基础上,使用 border-radius 圆角 + overflow: hidden 或 clip-path 裁剪。
方法一:border-radius + 圆形裁剪(近似扇形)
.sector {
width: 100px;
height: 100px;
background: #000;
border-radius: 50%;
clip-path: inset(0 50% 50% 0); /* 裁剪为 1/4 圆(扇形) */
}
方法二:radial-gradient 渐变背景
.sector {
width: 100px;
height: 100px;
background: radial-gradient(
circle at 50% 50%,
#000 50%,
transparent 50.5%
);
/* 或使用 conic-gradient 实现更精确的扇形 */
background: conic-gradient(from 0deg, #000 0deg 90deg, transparent 90deg);
}
推荐:
conic-gradient最直观,支持任意角度扇形。
三、实现宽高自适应的正方形
目标:宽高始终相等,且随容器变化。
方法一:padding-bottom: 100%(经典方案)
.square {
width: 50%; /* 宽度为父容器的 50% */
padding-bottom: 50%; /* 高度 = 宽度(100% 宽) */
background: #f0f0f0;
/* 内部内容需绝对定位 */
}
原理:
padding的百分比是相对于父容器宽度计算的。
方法二:aspect-ratio(现代推荐)
.square {
width: 50%;
aspect-ratio: 1 / 1; /* 宽高比 1:1 */
background: #f0f0f0;
}
优势:语义清晰,支持任意宽高比(如
4/3、16/9),现代浏览器支持良好。
方法三:vw 单位(视口相关)
.square {
width: 50vw;
height: 50vw; /* 高度等于宽度 */
}
适用于全屏或视口相关布局。
总结
- 三角形:
width:0; height:0; border+ 单边着色;- 扇形:推荐
conic-gradient渐变或clip-path裁剪;- 自适应正方形:
- 经典:
padding-bottom: 100%- 现代:
aspect-ratio: 1/1
四十六、如何在网页中画一条 0.5px 的线?
方法一:使用 CSS 变换缩放
一种常见的做法是创建一个高度为1px的元素,然后通过CSS变换将其垂直方向缩小到原来的0.5倍。
.half-pixel-line {
background: #000; /* 线条的颜色 */
height: 1px; /* 初始高度设为1px */
transform: scaleY(0.5); /* 在Y轴上缩放至0.5倍 */
transform-origin: 0 0; /* 缩放原点设置为左上角 */
}
需要注意的是,transform属性可能需要添加前缀以兼容某些旧版浏览器(如 -webkit-transform)。
方法二:利用伪元素
另一个方法是使用伪元素 ::before 或 ::after,并结合缩放来达到目的。
.half-pixel-line-container {
position: relative;
}
.half-pixel-line-container::after {
content: '';
position: absolute;
left: 0;
right: 0;
bottom: 0;
background: #000;
height: 1px;
transform: scaleY(0.5);
transform-origin: 0 0;
}
四十七、如何给网页设置小于 12px 的字体?
方法一:使用 CSS 的 font-size 属性
最直接的方法是使用CSS中的font-size属性,并指定所需的像素值。
.small-text {
font-size: 10px; /* 将字体大小设置为10px */
}
方法二:使用 transform 缩放
如果直接设置小字体遇到问题,可以通过首先将字体大小设置为一个较大的值,然后使用CSS的transform属性来缩放元素,达到实际显示更小字体的效果。
.small-text {
font-size: 20px; /* 初始字体大小 */
transform: scale(0.5); /* 缩放到原来的一半大小,即相当于10px */
display: inline-block; /* 确保transform生效 */
}
请注意,这种方法会改变元素的布局尺寸,因此你可能需要调整父容器或其他相关样式来适应这种变化。
方法三:使用相对单位
除了使用绝对单位(如px),还可以考虑使用相对单位,比如em、rem等。但是,对于小于12px的需求,这通常还需要结合上面提到的缩放方法一起使用。
.small-text {
font-size: 0.625em; /* 假设父元素字体大小为16px,则此设置为10px */
}
四十八、什么是 1px 问题?如何解决 1px 问题?
一、什么是 1px 问题?
1px 问题是指在高分辨率屏幕(如 Retina 屏)上,CSS 中设置的 1px 边框或线条看起来比实际更粗,显得模糊或不清晰。
原因:设备物理像素(device pixel)与 CSS 逻辑像素(CSS pixel)不一致。
- 普通屏幕:1 CSS px = 1 物理像素
- Retina 屏(如 iPhone):1 CSS px = 2×2 或 3×3 物理像素(即
dpr = 2或3)
当你写 border: 1px solid black,浏览器会在 2×2 的物理像素区域渲染,导致视觉上变粗、发虚。
二、解决方案
方法一:使用 transform: scale()(推荐)
利用 CSS3 缩放,将元素缩小 0.5 倍(适用于 dpr=2):
.border-1px {
position: relative;
}
.border-1px::after {
content: "";
position: absolute;
left: 0; bottom: 0;
width: 100%;
height: 1px;
background: #000;
transform: scaleY(0.5);
transform-origin: 0 0;
}
优点:兼容性好,清晰锐利
注意:transform不影响布局,需用伪元素避免干扰内容
方法二:使用 border-image 或 box-shadow
/* 使用 border-image */
.border-1px {
border-bottom: 1px solid transparent;
border-image: linear-gradient(to right, #000, #000) 1;
}
/* 使用 box-shadow(模拟细线) */
.border-1px {
box-shadow: 0 1px 0 #000;
}
box-shadow可能影响性能,且不支持多边
方法三:使用 @media 查询 + dpr 判断
根据不同设备像素比设置不同样式:
/* 默认 1px */
.border {
border: 1px solid #000;
}
/* Retina 屏,使用 0.5px(部分浏览器支持) */
@media (-webkit-min-device-pixel-ratio: 2) {
.border {
border-width: 0.5px;
}
}
/* dpr=3 */
@media (-webkit-min-device-pixel-ratio: 3) {
.border {
border-width: 0.33px;
}
}
0.5px支持有限(iOS Safari 支持,Android 多数不支持)
方法四:使用 SVG 背景图
.border-line {
background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' height='1' width='100%'><line x1='0' y1='0' x2='100%' y2='0' stroke='#000' stroke-width='1'/></svg>");
}
高清不失真,适合复杂线条
总结
1px 问题是因高清屏
dpr > 1导致 CSS 的1px实际占多个物理像素,显得粗且模糊。
常见解决方案:
- 推荐:
::after伪元素 +transform: scaleY(0.5),清晰兼容;- 其他:
border-image、box-shadow、0.5px(限 iOS)、SVG 背景。
四十九、CSS 中是否存在父选择器?其背后的原因是什么?
一、CSS 原生不支持父选择器
目前标准的 CSS 中,没有直接的“父选择器”。
例如,你不能这样写:
/* 不存在的语法 */
.child:parent(.parent) {
/* 选中 class 为 parent 的父元素 */
}
CSS 选择器只能从上到下匹配(祖先 → 后代),不能反向匹配(后代 → 父/祖先)。
二、但有“相对选择器”(CSS Selectors Level 4)
2022 年起,现代浏览器逐步支持 :has() 伪类,它实现了“父选择器”的功能。
/* 选中包含 .child 的 .parent */
.parent:has(.child) {
background: yellow;
}
/* 选中前面有 .prev 的元素 */
.item:has(+ .next) {
margin-bottom: 0;
}
:has()被称为“容器查询选择器”,是目前最接近“父选择器”的标准方案。
兼容性:Chrome 105+、Safari 15.4+、Firefox 121+(逐步普及中)
三、为什么长期没有父选择器?
1. 性能问题(核心原因)
- 正向选择(
div .child):从上到下遍历,可快速剪枝。 - 反向选择(“找包含 .child 的父元素”):需为每个元素逆向遍历 DOM 树,性能开销大,影响页面渲染速度。
2. 渲染引擎设计
- 浏览器采用“流式渲染”,从上到下解析 HTML 和 CSS。
- 支持父选择器会导致“回溯”,破坏渲染流水线。
3. 维护复杂性
- 容易写出低效、难以维护的 CSS 规则。
- 开发者可能滥用,导致样式性能瓶颈。
四、替代方案
在 :has() 不可用时,可通过以下方式间接实现:
-
JavaScript 动态添加类
document.querySelectorAll('.child').forEach(child => { child.parentElement.classList.add('has-child'); }); -
结构优化
- 使用 BEM 命名,避免依赖父状态。
- 将状态类直接加在父元素上。
-
使用
:is()或:where()(简化选择器,但非父选择)
总结
传统 CSS 没有父选择器,主要是出于性能和渲染效率考虑:反向匹配会显著降低渲染速度。
但现代 CSS 已引入:has()伪类(如.parent:has(.child)),实现了父选择器功能,已在主流浏览器支持。
五十、有哪些默认 display: block 元素和display: inline 元素?你还知道哪些display 取值?
一、默认 display: block 的常见元素
这些元素独占一行,可以设置宽高、margin、padding。
常见块级元素:
<div><p><h1>~<h6><ul>,<ol>,<li><section>,<article>,<header>,<footer>,<nav>,<aside><form><table><hr><blockquote>,<pre>
特点:默认宽度为父容器 100%,可设置宽高。
二、默认 display: inline 的常见元素
这些元素在行内排列,不能设置宽高,margin 和 padding 只在水平方向生效。
常见行内元素:
<span><a><strong>,<b><em>,<i><img><input>,<button>,<select>,<textarea>(表单控件)<label><code>,<small>,<mark>
特点:只占据内容所需宽度,多个元素在同一行显示。
三、其他常用的 display 取值
| 取值 | 说明 |
|---|---|
inline-block | 行内块元素:可设置宽高,但与其他元素同行显示(如 <input>) |
flex | 弹性布局容器,创建 Flex 布局上下文 |
inline-flex | 行内弹性容器,不独占一行 |
grid | 网格布局容器,创建 Grid 布局上下文 |
inline-grid | 行内网格容器 |
none | 不显示,不占空间(隐藏元素) |
table / table-row / table-cell | 模拟表格布局 |
list-item | 列表项(如 <li>),可显示项目符号 |
contents | 元素本身不渲染,只渲染其子元素(可用于消除无意义包裹) |
flow-root | 创建新的块格式化上下文(BFC),用于清除浮动等 |
四、现代布局常用值
flex/grid:现代响应式布局的核心,推荐作为首选。inline-block:替代float实现行内排列(如按钮组)。none:控制元素显示隐藏(配合 JS 或伪类)。
总结
- 块级元素:
div,p,h1~h6,ul,li,section等,独占一行,可设宽高;- 行内元素:
span,a,img,strong,em,input等,同行排列,不可设宽高;- 其他常用
display值:inline-block、flex、grid、none、table-*、flow-root、contents。
五十一、line-height: 100% 和 line-height: 1 有什么区别?
一、核心区别
| 属性值 | 类型 | 计算方式 | 是否继承 | 示例说明 |
|---|---|---|---|---|
line-height: 100% | 百分比(%) | 相对于**当前元素的字体大小(font-size)**计算 | 继承的是计算后的值 | 若 font-size: 16px,则 line-height = 16px |
line-height: 1 | 无单位数值(unitless) | 作为缩放因子,子元素继承该因子并乘以其自身的 font-size | 继承的是原始数值 1 | 若父元素 font-size: 16px,子元素 20px,子元素行高为 20px |
二、详细解释
1. line-height: 100%
- 是一个百分比值,会立即根据当前元素的
font-size计算出行高。 - 继承的是计算后的像素值,不是百分比本身。
- 问题:子元素即使字体更大,也可能继承较小的行高,导致文字拥挤。
.parent {
font-size: 16px;
line-height: 100%; /* 计算为 16px */
}
.child {
font-size: 24px; /* 继承 line-height: 16px */
}
结果:子元素字体 24px,行高却只有 16px,文字重叠!
2. line-height: 1
- 是一个无单位数值,表示
line-height = font-size × 1。 - 子元素继承的是
1这个数值,然后用自己的font-size重新计算。 - 推荐:更符合“相对缩放”的预期,避免子元素行高过小。
.parent {
font-size: 16px;
line-height: 1; /* 缩放因子 1 */
}
.child {
font-size: 24px; /* 继承因子 1,行高 = 24px × 1 = 24px */
}
结果:子元素行高自动适配字体大小,布局更合理。
三、对比总结
| 场景 | line-height: 100% | line-height: 1 |
|---|---|---|
父元素 font-size: 16px | line-height = 16px | line-height = 16px(临时) |
子元素 font-size: 24px | 继承 16px,行高不足 | 继承因子 1,行高 = 24px |
| 继承行为 | 继承计算后的值(如 16px) | 继承缩放因子(1) |
| 推荐程度 | 不推荐用于全局行高 | 强烈推荐,更安全、可维护 |
总结
line-height: 100%是百分比,基于当前font-size计算,继承的是像素值,子元素可能行高不足;line-height: 1是无单位数值,作为缩放因子,子元素会根据自身字体重新计算,更安全;
五十二、如果在伪元素中不写 content 会发生什么?
一、为什么必须写 content?
::before和::after的作用是在元素内容前后插入新内容。content属性定义了要插入的内容,即使为空也需要声明。- 浏览器渲染引擎规定:只有
content存在时,伪元素才会被创建和显示。
二、示例对比
.box::before {
content: "★"; /* 显示:插入一个星号 */
color: red;
}
.box::before {
/* 没有 content */
background: red;
width: 10px;
height: 10px;
}
结果:什么也不会显示!即使设置了宽高、背景,伪元素也不会生成。
.box::before {
content: ""; /* 空内容,但存在 */
display: block;
width: 10px;
height: 10px;
background: red;
}
结果:显示一个红色小方块。
content: ""虽然无内容,但触发了伪元素的创建。
三、content 的常见取值
| 值 | 说明 |
|---|---|
content: "文本" | 插入纯文本 |
content: "" | 空内容,常用于装饰性图形(如三角形、圆点) |
content: attr(href) | 插入元素的属性值(如链接地址) |
content: url(image.png) | 插入图片 |
content: open-quote / close-quote | 配合 quotes 插入引号 |
总结
在
::before和::after中,content是必需属性。
如果不写content,伪元素不会被创建和渲染,即使设置了宽高、背景也无效。即使不需要内容,也必须写
content: ""来“激活”伪元素。
五十三、flex-shrink和 flex-grow 的默认值是多少?作用是什么?
一、默认值
| 属性 | 默认值 | 类型 |
|---|---|---|
flex-grow | 0 | 无单位数值 |
flex-shrink | 1 | 无单位数值 |
可通过
flex简写属性统一设置:flex: 1 1 auto(默认)
二、作用详解
1. flex-grow:控制“放大”能力
- 作用:当容器有剩余空间时,决定子元素按比例放大的权重。
- 取值:无单位数值,
0表示不放大,1或更大表示可放大。 - 计算方式:按
flex-grow值的比例分配剩余空间。
.container {
display: flex;
}
.item1 { flex-grow: 1; }
.item2 { flex-grow: 2; }
结果:剩余空间按 1:2 分配,
item2占比更大。
2. flex-shrink:控制“收缩”能力
- 作用:当子元素总宽度超出容器时,决定子元素按比例缩小的权重。
- 取值:无单位数值,
1表示可正常收缩,0表示不收缩。 - 计算方式:按
flex-shrink值和自身尺寸加权收缩。
.container {
display: flex;
width: 300px;
}
.item1 { width: 200px; flex-shrink: 1; }
.item2 { width: 200px; flex-shrink: 2; }
结果:超出 100px,
item2收缩量是item1的 2 倍。
三、常见使用场景
| 场景 | 推荐设置 |
|---|---|
| 固定宽度 + 自适应填充 | flex-grow: 1(让一个元素撑满剩余空间) |
| 禁止收缩(防止被压扁) | flex-shrink: 0(如图标、按钮) |
| 等分空间 | flex: 1(等价于 flex-grow: 1,flex-shrink: 1, flex-basis: 0) |
总结
flex-grow:默认0,控制子元素在容器有剩余空间时的放大比例;flex-shrink:默认1,控制子元素在超出容器时的收缩比例;简记:
grow= “能撑多大”(空余空间分配)shrink= “能缩多小”(超长时压缩)实际开发中常用
flex: 1(等分)或flex-shrink: 0(禁止收缩)。
五十四、如何消除 inline-block 元素之间的间隙?
一、问题原因
<div class="container">
<span class="item">A</span>
<span class="item">B</span>
<span class="item">C</span>
</div>
.item {
display: inline-block;
width: 50px;
height: 50px;
}
结果:A、B、C 之间有 约 4px 的空白间隙(相当于一个空格的宽度)。
二、解决方案(推荐 & 常用)
方法 1:HTML 注释法(兼容性好)
将标签“挤”在一起,用注释“吃掉”空格:
<div class="container">
<span class="item">A</span><!--
--><span class="item">B</span><!--
--><span class="item">C</span>
</div>
优点:兼容所有浏览器,无需 CSS 修改。
方法 2:父元素 font-size: 0 + 子元素重设字体
.container {
font-size: 0; /* 消除空格字符 */
}
.item {
display: inline-block;
font-size: 16px; /* 重新设置字体大小 */
width: 50px;
height: 50px;
}
优点:简洁有效,适合图标、按钮组等场景。
方法 3:移除 HTML 空白
<div class="container">
<span class="item">A</span><span class="item">B</span><span class="item">C</span>
</div>
缺点:代码可读性差,不便于维护。
方法 4:使用 flex 布局替代(现代推荐)
.container {
display: flex;
}
.item {
/* 无需 inline-block */
width: 50px;
height: 50px;
}
推荐:
flex布局天然无间隙,是更现代、灵活的解决方案。
方法 5:负 margin 修正(不推荐)
.item {
display: inline-block;
margin-right: -4px; /* 修正间隙 */
}
缺点:数值不精确,受字体影响,维护困难。
总结
inline-block间隙是因 HTML 换行/空格被渲染为文本空格所致。
常见解决方法:
- HTML 注释法(兼容性好)
- 父元素
font-size: 0(常用)- 移除标签间空格(简单但难维护)
- 使用
flex布局替代(现代推荐方案)
五十五、请解读 font-family: system-ui,-apple-system,BlinkMacSystemFont,segoeui,Roboto, Helvetica,Arial, sans-serif这个字体设置
一、逐项解读(从左到右,优先级递减)
| 字体名 | 适用平台/浏览器 | 说明 |
|---|---|---|
system-ui | 跨平台 | 通用系统字体,现代浏览器优先使用系统默认 UI 字体(如 macOS 的 San Francisco,Windows 的 Segoe UI) |
-apple-system | macOS / iOS Safari | 苹果系统优先使用 San Francisco(SF Pro)字体,清晰现代 |
BlinkMacSystemFont | macOS 上的 Chrome/Edge | Chrome 内核浏览器在 Mac 上使用的系统字体(同样是 San Francisco) |
segoe ui | Windows | Windows 系统默认 UI 字体,清晰易读 |
Roboto | Android / Chrome OS | Google 的现代字体,广泛用于 Material Design |
Helvetica | macOS(旧系统) | 苹果旧系统常用字体,无衬线,简洁 |
Arial | 跨平台(通用备选) | 几乎所有系统都支持的经典无衬线字体 |
sans-serif | 最终兜底 | 无衬线字体的通用类别,确保总有字体可用 |
二、设计思路解析
-
优先使用系统原生字体
- 让网页“看起来像原生应用”,提升用户体验。
- 系统字体经过精心优化,渲染性能好、可读性强。
-
按平台精准匹配
- 区分 macOS(
-apple-system,BlinkMacSystemFont) - 区分 Windows(
segoe ui) - 区分 Android(
Roboto)
- 区分 macOS(
-
渐进降级,确保兼容
- 从最精确的系统字体 → 通用无衬线字体,层层兜底。
- 即使用户系统缺失某些字体,也能优雅降级。
三、为什么这样写?
- 性能好:使用系统字体,无需下载 Web 字体,加载快。
- 体验佳:字体与操作系统风格一致,更“原生”。
- 兼容强:覆盖主流平台,确保文字始终可读。
总结
这条
font-family设置的目的是:
- 优先使用各操作系统的原生 UI 字体(如 macOS 的 San Francisco,Windows 的 Segoe UI);
- 通过
system-ui、-apple-system、BlinkMacSystemFont等精确匹配不同平台;- 用
Roboto、Helvetica、Arial作为备选,最终以sans-serif兜底;
五十六、CSS 如何快速选取同组兄弟元素的偶数序号元素?
一、核心语法
/* 选中所有偶数位置的子元素(2, 4, 6...) */
li:nth-child(even) {
background: #f0f0f0;
}
even表示偶数;odd表示奇数(1, 3, 5...)
二、示例说明
<ul>
<li>第1项(奇数)</li>
<li>第2项(偶数)</li>
<li>第3项(奇数)</li>
<li>第4项(偶数)</li>
</ul>
li:nth-child(even) {
background: #eee; /* 第2、4项背景变灰 */
}
三、注意事项
-
:nth-child()是基于父元素的所有子元素计数- 即使兄弟元素类型不同,也参与序号计算。
- 示例:
<div> <p>段落1</p> <!-- 位置1 --> <span>文字</span> <!-- 位置2 --> <p>段落2</p> <!-- 位置3 --> </div>p:nth-child(even)→ 不会选中任何元素,因为<p>分别在位置 1 和 3(奇数)。
-
如需按同类元素计数,使用
:nth-of-type()/* 选中第2、4、6...个 <p> 元素 */ p:nth-of-type(even) { color: blue; }
四、其他用法(扩展)
:nth-child(2n)→ 等价于even:nth-child(4)→ 选第4个:nth-child(2n+2)→ 从第2个开始,每隔2个选一次(2, 4, 6...)
总结
使用
:nth-child(even)可快速选中同组兄弟元素中的偶数项。
注意:它是基于父元素所有子元素的总序号,而非同类元素。
若需按同类元素计数,应使用:nth-of-type(even)。
五十七、如何检测 CSS 动画的 FPS 值?
一、使用浏览器开发者工具(推荐)
现代浏览器(Chrome、Edge、Firefox)提供了强大的性能分析工具:
1. Chrome DevTools - Performance 面板
- 打开 DevTools →
Performance标签 - 点击录制(●)→ 播放动画 → 停止录制
- 查看 FPS 图表(绿色条越高越好,60fps 为理想值)
- 分析
Rendering和Painting是否有瓶颈
优点:直观、精确、可定位性能问题
2. Chrome DevTools - Rendering 面板
- 打开
Rendering→ 勾选 "FPS meter" - 页面角落会显示实时 FPS 指示器
- 颜色含义:
- 绿色:50-60fps(流畅)
- 黄色:30-50fps(可接受)
- 红色:<30fps(卡顿)
二、使用 JavaScript 监控 FPS(编程方式)
通过 requestAnimationFrame 计算帧率:
let frameCount = 0;
let lastTime = performance.now();
let fps = 0;
function tick() {
frameCount++;
const now = performance.now();
// 每秒更新一次 FPS
if (now - lastTime >= 1000) {
fps = Math.round(frameCount * 1000 / (now - lastTime));
console.log(`FPS: ${fps}`);
frameCount = 0;
lastTime = now;
}
requestAnimationFrame(tick);
}
requestAnimationFrame(tick);
优点:可集成到性能监控系统,实时反馈
三、使用第三方库
- Stats.js:轻量级性能监控库,可在页面显示 FPS 面板
<script src="https://cdn.jsdelivr.net/npm/stats.js"></script> <script> const stats = new Stats(); document.body.appendChild(stats.dom); function animate() { stats.update(); requestAnimationFrame(animate); } animate(); </script>
四、优化建议(当 FPS < 60)
- 避免频繁操作
layout属性(如width,height,top,left) - 使用
transform和opacity实现动画(可被 GPU 加速) - 减少重绘(
repaint)和回流(reflow) - 使用
will-change提示浏览器优化
总结
检测 CSS 动画 FPS 的方法:
- 推荐:使用 Chrome DevTools 的
Performance面板和FPS meter;- 编程监控:通过
requestAnimationFrame计算帧率;- 第三方库:如 Stats.js 显示实时 FPS。
五十八、预处理器如 scss 和 less,与 CSS 有什么区别?
一、核心区别对比
| 特性 | CSS(原生) | Sass/SCSS、Less(预处理器) |
|---|---|---|
| 语法 | 标准 CSS 语法 | 扩展语法(支持变量、嵌套、函数等) |
| 浏览器支持 | 直接支持 | 不支持,需编译为 CSS |
| 开发效率 | 基础功能,重复代码多 | 更高,支持模块化、复用 |
| 维护性 | 复杂项目难维护 | 更好,结构清晰,易于组织 |
| 调试 | 直接调试 | 需启用 Source Map 映射回源码 |
二、预处理器的核心优势(Sass/SCSS 和 Less 共有)
1. 变量(Variables)
// SCSS
$primary-color: #007bff;
.button {
background: $primary-color;
}
// Less
@primary-color: #007bff;
.button {
background: @primary-color;
}
优势:统一管理颜色、字体等,修改一处,全局生效。
2. 嵌套(Nesting)
.nav {
ul {
margin: 0;
li {
display: inline-block;
}
}
}
优势:结构更清晰,减少重复选择器。
3. 混合(Mixins)
@mixin center {
display: flex;
justify-content: center;
align-items: center;
}
.box {
@include center;
}
优势:复用样式块,类似“函数”。
4. 函数与运算
.width {
width: 100px / 960px * 100%; // 计算百分比
}
5. 导入(@import)与模块化
- 支持拆分文件,
@import合并,便于团队协作。
三、Sass(SCSS) vs Less 简要对比
| 特性 | Sass(SCSS) | Less |
|---|---|---|
| 语法风格 | 类似 CSS(.scss) | 类似 CSS |
| 编译语言 | Ruby(早期)/ Dart(现主流) | JavaScript |
| 工具链 | sass / dart-sass | lessc(Node.js) |
| 社区生态 | 更成熟,广泛用于大型项目(如 Bootstrap 4+) | 较早出现,社区活跃 |
| 高级功能 | 支持 @extend、@if、@for 等更强大逻辑 | 逻辑控制较弱 |
SCSS 更强大灵活,是目前前端主流选择。
四、缺点与注意事项
- 需要构建工具:必须配置编译流程(Webpack、Vite、CLI 等)
- 学习成本:需掌握新语法
- 调试依赖 Source Map:否则只能看到编译后的 CSS
总结
- CSS 是浏览器原生语言,功能有限;
- Sass/SCSS、Less 是预处理器,提供变量、嵌套、混合、函数等高级功能,提升开发效率和维护性;
- 它们必须编译成 CSS 才能运行;
- SCSS 功能更强大,生态更成熟,是当前主流;
五十九、Css 的 flex 布局有什么好处?
一、核心优势(Flex 布局的 5 大好处)
1. 真正实现“垂直居中”
传统 CSS 垂直居中复杂,而 Flex 一行代码搞定:
.container {
display: flex;
justify-content: center; /* 水平居中 */
align-items: center; /* 垂直居中 */
}
无需计算
margin、position或line-height。
2. 灵活的空间分配
通过 flex-grow、flex-shrink、flex-basis,子元素可自动伸缩,完美适配不同屏幕。
.item1 { flex: 1; } /* 占满剩余空间 */
.item2 { flex: 2; } /* 占比是 item1 的 2 倍 */
适合“侧边栏 + 内容区”、“等分布局”等场景。
3. 响应式布局更简单
无需媒体查询,元素可自动换行、调整顺序:
.container {
display: flex;
flex-wrap: wrap; /* 超出自动换行 */
}
移动端适配更轻松。
4. 摆脱浮动(float)的困扰
- 无需清除浮动(
clearfix) - 子元素高度自动对齐,不会“塌陷”
- 布局更清晰,代码更简洁
5. 控制子元素顺序(不依赖 DOM 结构)
.item1 { order: 2; }
.item2 { order: 1; }
视觉顺序可与 HTML 结构分离,提升可访问性或移动端适配。
二、适用场景(Flex 的典型用途)
| 场景 | 实现方式 |
|---|---|
| 水平/垂直居中 | justify-content + align-items |
| 等分布局 | display: flex; .item { flex: 1 } |
| 圣杯布局 / 圣杯三栏 | left 固定,center 自适应(flex: 1) |
| 导航栏、按钮组 | flex-wrap: wrap + gap |
| 卡片列表自适应 | flex-wrap: wrap + flex: 1 1 200px |
三、Flex vs Grid 简要对比
| Flex 布局 | Grid 布局 | |
|---|---|---|
| 维度 | 一维布局(行或列) | 二维布局(行和列同时控制) |
| 适用 | 主轴方向的线性布局 | 复杂网格、表格、杂志式布局 |
| 推荐 | 大多数常规布局(推荐优先尝试) | 复杂页面结构 |
建议:先用 Flex,复杂用 Grid。
总结
Flex 布局的好处:
- 简化布局:轻松实现居中、等分、自适应;
- 响应式友好:自动换行、伸缩空间;
- 摆脱浮动:无需清除浮动,避免布局塌陷;
- 控制灵活:可调整子元素顺序、对齐方式;
- 开发高效:代码简洁,维护性强。
六十、CSS 中 flex: 1 是什么意思?
一、核心作用
当多个子元素设置 flex: 1 时,它们会平分父容器的剩余空间,实现等分布局。
<div class="container">
<div class="item">A</div>
<div class="item">B</div>
<div class="item">C</div>
</div>
.container {
display: flex;
}
.item {
flex: 1; /* A、B、C 宽度相等,撑满容器 */
}
结果:三等分容器宽度,自动适应。
二、为什么 flex-basis: 0% 很关键?
- 如果
flex-basis是auto(默认),会先按内容或width占据空间,再分配剩余空间。 flex-basis: 0%表示忽略内容大小,所有子元素从 0 开始,按flex-grow比例分配空间。
/* 对比:flex: 1 vs flex: 1 1 auto */
.item {
flex: 1; /* 等分,忽略内容长度 */
}
.item {
flex: 1 1 auto; /* 先按内容占位,再分剩余空间 → 不等分 */
}
所以
flex: 1能实现真正的“等分”,正是因为flex-basis: 0%。
三、常见使用场景
| 场景 | 用法 |
|---|---|
| 等分布局 | .item { flex: 1 } |
| 侧边栏 + 内容区 | sidebar { width: 200px; } content { flex: 1; } |
| 响应式卡片 | card { flex: 1 1 200px; }(最小 200px,可伸缩) |
总结
flex: 1等价于flex: 1 1 0%,表示:
- 允许放大和收缩;
- 基础大小为 0,按比例平分父容器剩余空间;
六十一、如何在浏览器可视区域画一个最大的正方形?
一、核心思路
- 浏览器可视区域是矩形(
window.innerWidth × window.innerHeight) - 最大正方形的边长 =
min(宽, 高) - 例如:在 1920×1080 屏幕上,最大正方形为
1080×1080
二、纯 CSS 实现(推荐)
使用 vmin 单位:1vmin = 视口宽高中较小值的 1%
.square {
width: 100vmin;
height: 100vmin;
background: #007bff;
margin: 0 auto; /* 水平居中 */
}
解释:
100vmin=min(100vw, 100vh),自动取宽高中较小者。
三、HTML + CSS 完整示例
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>最大正方形</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.square {
width: 100vmin;
height: 100vmin;
background: #007bff;
margin: 0 auto;
/* 可选:垂直居中 */
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
</style>
</head>
<body>
<div class="square"></div>
</body>
</html>
四、JavaScript 动态设置(兼容旧浏览器)
function createMaxSquare() {
const size = Math.min(window.innerWidth, window.innerHeight);
const square = document.createElement('div');
square.style.width = `${size}px`;
square.style.height = `${size}px`;
square.style.background = '#007bff';
square.style.position = 'absolute';
square.style.top = '50%';
square.style.left = '50%';
square.style.transform = 'translate(-50%, -50%)';
document.body.appendChild(square);
}
// 页面加载和窗口大小变化时执行
window.addEventListener('load', createMaxSquare);
window.addEventListener('resize', createMaxSquare);
五、注意事项
- 移动端适配:确保
<meta name="viewport">存在,否则vw/vh可能不准确。 vmin兼容性:现代浏览器均支持(IE9+),旧项目可降级用 JS。- 居中:可用
margin: auto(需display: block)或transform居中。
总结
最大正方形边长 =
min(视口宽度, 视口高度)
推荐方案:使用width: 100vmin; height: 100vmin,简洁高效,自动适配。
可配合transform居中,无需 JavaScript。
六十二、CSS display 属性值 block、inline 和inline-block的区别
1. block
- 行为:块级元素从新的一行开始,并且其后的内容也会从新的一行开始。
- 宽度:默认情况下,块级元素的宽度是其父元素宽度的100%,除非被其他CSS规则改变。
- 高度:可以设置具体的高度。
- 内外边距(margin/padding):上下左右都可生效。
- 典型元素:
<div>、<p>、<h1>等。
2. inline
- 行为:内联元素不会以新行开始,而是跟随文本流直接显示在其所在的行内,直到达到容器边界才会换行。
- 宽度:仅由其内容决定,无法显式设置宽度和高度。
- 高度:同样地,高度也是根据内容自动调整,不能显式设定。
- 内外边距(margin/padding):水平方向(left/right)的内外边距有效,垂直方向(top/bottom)的内外边距无效。
- 典型元素:
<span>、<a>、<img>等。
3. inline-block
- 行为:内联块状元素结合了
inline和block的特点。它们像内联元素一样排列在同一行,但同时允许设置宽高及内外边距等属性,就像块级元素那样。 - 宽度:可以设置具体宽度。
- 高度:可以设置具体高度。
- 内外边距(margin/padding):上下左右均生效。
- 用途:常用于需要在一行内展示多个元素并希望对这些元素进行精确控制时使用,比如导航栏中的按钮或图片库中的缩略图。
总结
选择哪种
display值取决于你想要实现的具体布局效果。如果需要元素占据整行或定义宽高,则使用block;如果只需在文本流中插入不影响排版的小部件,则选择inline;而当既想保持内联元素的行为又需要设置尺寸时,inline-block就是理想的选择。
六十三、CSS 伪元系和伪类的作用和区别?
一、核心区别一句话
- 伪类(Pseudo-classes):用于选择元素的特定状态或位置(如
:hover,:first-child)- 伪元素(Pseudo-elements):用于创建并选择元素的虚拟部分或内容(如
::before,::after)
二、伪类(Pseudo-classes)
作用:选择处于某种状态或特定位置的元素。
常见伪类示例:
| 伪类 | 说明 |
|---|---|
:hover | 鼠标悬停时 |
:focus | 元素获得焦点时(如输入框) |
:active | 元素被激活时(如点击按钮) |
:first-child | 第一个子元素 |
:last-child | 最后一个子元素 |
:nth-child(2n) | 偶数位置的子元素 |
:not(.class) | 不包含某类的元素 |
:checked | 被选中的表单元素(如 checkbox) |
button:hover {
background: blue;
}
li:nth-child(odd) {
background: #f0f0f0;
}
特点:不创建新内容,只是选择已有元素的“状态”。
三、伪元素(Pseudo-elements)
作用:创建并选择元素的虚拟部分,通常用于插入装饰性内容或样式。
常见伪元素示例:
| 伪元素 | 说明 |
|---|---|
::before | 在元素内容前插入虚拟内容 |
::after | 在元素内容后插入虚拟内容 |
::first-line | 选择元素的第一行文本 |
::first-letter | 选择元素的第一个字母(常用于首字下沉) |
::selection | 选择用户选中的文本部分 |
.tip::before {
content: "ℹ️";
margin-right: 4px;
}
.quote::first-letter {
font-size: 2em;
float: left;
}
特点:可生成新内容(需
content属性),常用于装饰、图标、布局辅助。
四、关键区别对比
| 特性 | 伪类(Pseudo-class) | 伪元素(Pseudo-element) |
|---|---|---|
| 语法 | 单冒号 :(如 :hover) | 双冒号 ::(如 ::before),但单冒号也兼容 |
| 是否创建新内容 | 否,只选择状态 | 是,可插入内容(需 content) |
| 用途 | 状态选择、结构选择 | 生成虚拟内容、装饰文本 |
| 典型场景 | 悬停效果、奇偶行 | 添加图标、首字下沉、清除浮动 |
五、常见误区
-
:before和:after是伪类?
→ 错!它们是伪元素,应写为::before/::after(但:before仍兼容) -
伪元素能被 JavaScript 获取?
→ 不能!伪元素不在 DOM 中,无法用document.querySelector选中,但可通过getComputedStyle(el, '::before')获取样式。
总结
- 伪类:选择元素的状态或位置,如
:hover,:first-child,不生成内容;- 伪元素:创建元素的虚拟部分,如
::before,::after,可插入内容;区分关键:
- 语法:伪元素用
::(推荐)- 功能:伪元素可
content生成内容,伪类不能。

被折叠的 条评论
为什么被折叠?



