【前端面试】HTML篇
【前端面试】CSS篇
【前端面试】JS篇
【前端面试】Vue篇
【前端面试】Git篇
【前端面试】前端性能优化篇
【前端面试】手写题篇
【前端面试】浏览器&网络篇
【前端面试】前端工程化篇
布局与定位
父元素高度塌陷
什么是父元素高度塌陷?为什么会发生?
- 当父元素内部只有浮动(float)的子元素时,子元素脱离文档流。
- 父元素无法感知子元素高度,所以高度表现为 0。
如何解决父元素高度塌陷?
- 父元素设置固定高度(不推荐)
- 父元素触发 BFC(推荐,简单)
- 额外添加空标签清除浮动(不推荐)
- 伪元素清除浮动(推荐,无冗余标签)
- 双伪元素清除浮动(推荐,兼容性更好)
BFC
什么是 BFC?
BFC 是块级格式上下文,触发后父元素会包含浮动子元素,同时避免相邻块元素 margin 重叠,内部布局相对独立。
BFC 的触发条件有哪些?
float不为none(浮动元素会触发 BFC)overflow不为visible(hidden、auto、scroll)display: flow-root、flex、grid、inline-blockposition: absolute或fixedcontain: layout(CSS 新特性)
BFC 的特性和作用是什么?
| 特性 | 解决的问题 | 常用触发方式 |
|---|---|---|
| 包裹浮动子元素 | 父元素高度塌陷 | overflow: hidden / display: flow-root |
| 内部垂直 margin 不重叠 | 元素间距不符合预期 | display: flow-root |
| 不与浮动元素重叠 | 自适应布局(如左侧固定,右侧自适应) | overflow: hidden |
Flex 布局
属性及子属性有哪些?作用是什么?
| 属性 | 作用 |
|---|---|
display: flex |
开启 Flex 布局 |
flex-direction |
主轴方向(row / row-reverse / column / column-reverse) |
justify-content |
主轴对齐(flex-start / flex-end / center / space-between / space-around / space-evenly) |
align-items |
交叉轴对齐(flex-start / flex-end / center / baseline / stretch) |
align-content |
多行容器的交叉轴对齐 |
flex-wrap |
是否换行(nowrap / wrap / wrap-reverse) |
| 子属性 | 作用 |
|---|---|
flex-grow |
剩余空间的放大比例 |
flex-shrink |
缩小比例 |
flex-basis |
元素初始占据空间 |
flex |
shorthand = flex-grow flex-shrink flex-basis |
align-self |
单独设置子项在交叉轴的对齐方式(覆盖父容器 align-items) |
order |
控制子项的排列顺序(默认 0,数值越小越靠前,支持负数) |
flex:1 与 flex:1 0 auto 的区别
flex:1 相当于 1 1 0%,flex:1 0 auto 表示可放大但不缩小,初始宽度为 auto。
flex: 1 是哪些属性组成的?
flex 实际上是 flex-grow、flex-shrink 和 flex-basis 三个属性的缩写。
flex:1 相当于 1 1 0%。
- flex-grow:定义项目的的放大比例;
- flex-shrink:定义项目的缩小比例;
- flex-basis: 定义在分配多余空间之前,项目占据的主轴空间,浏览器根据此属性计算主轴是否有多余空间。
Grid 布局
Grid 布局常用属性及作用
| 属性 | 作用 |
|---|---|
display: grid / inline-grid |
开启 Grid 布局 |
grid-template-columns / grid-template-rows |
定义行列大小 |
gap / row-gap / column-gap |
行列间距 |
grid-auto-rows / grid-auto-columns |
自动生成行/列的大小 |
justify-items / align-items |
单元格内容对齐 |
justify-content / align-content |
整个 grid 容器对齐 |
grid-auto-flow |
元素自动排列方向(row / column / dense) |
Grid 子元素常用属性
| 属性 | 作用 |
|---|---|
grid-column / grid-row |
指定元素跨几列或几行 |
grid-column-start / grid-column-end |
起始列 / 结束列 |
grid-row-start / grid-row-end |
起始行 / 结束行 |
grid-area |
指定子元素所在区域 |
justify-self / align-self |
单个元素对齐 |
grid-column: 1 / span 2 表示什么?
从第 1 列开始,占据 2 列宽度。
Grid 和 Flex 的区别?
- Flex 是一维布局,Grid 是二维布局
- 如果只处理一行一列,Flex 更简单
- 复杂布局推荐 Grid
两栏 / 三栏布局
如何实现两栏布局
- 浮动(float) :早期常用方案,需清除浮动防止高度塌陷
- Flexbox :主流做法,父容器设为
display: flex,两个子项即可并排。 - Grid :定义两列网格(如
grid-template-columns: 1fr 1fr),布局更灵活。
如何实现三栏布局?
- 浮动(float) :左右两栏浮动,中间栏设置自适应宽度,需清除浮动。
- Flexbox :父容器设为
display: flex,通过flex: 1实现中间栏自适应。 - Grid :定义三列网格(如
grid-template-columns: 200px 1fr 200px),结构清晰、控制精确。
百分比 / Rem 布局
百分比布局与 Rem 布局有什么区别?
| 特性 | 百分比 | Rem |
|---|---|---|
| 参考对象 | 父元素 | 根元素(html) |
| 适用场景 | 容器自适应宽度 | 字体大小和全局统一布局 |
| 响应性 | 随父元素变化 | 可通过改变 html font-size 响应式缩放 |
父元素字体改变对 rem 的影响?
不受父元素影响,只受根元素 font-size 控制。
百分比单位的嵌套问题
多层百分比计算是相对父元素的大小,可能导致累计误差。
元素水平垂直居中
如何水平垂直居中一个元素?
- FLex 布局(推荐)
- Absolute + Transform
- Grid 布局
多行文本或动态内容的居中怎么办?
- Flex 或 Grid 都可以自动适应高度。
- Absolute + transform 对内容高度变化敏感,需要容器固定高度。
浮动布局
浮动布局原理
- 脱离文档流,不占父元素高度(可能导致父元素高度塌陷)
- 同一容器内,浮动元素按顺序排列,左右对齐
- 相邻非浮动元素会环绕浮动元素(文字环绕、
inline-block元素环绕)
浮动布局优缺点
- 优点
- 兼容性好,适用于旧版浏览器
- 实现简单的左右排列布局
- 可用于文字环绕效果(如图片与文字排版)
- 缺点
- 容易导致 父元素高度塌陷
- 响应式布局不够灵活,需要计算百分比或清除浮动
- 对复杂布局维护成本高(嵌套多层浮动容易错乱)
- 水平居中、垂直居中不方便
float 左右同时设置会怎样?
元素按顺序排列,左浮动靠左,右浮动靠右,中间内容可能被压缩。
float 与 BFC 有什么关系?
BFC 可以包含浮动元素,从而避免父元素高度塌陷。
什么现代开发很少用浮动布局做主要布局?
因为 Flex / Grid 更灵活,可读性高,响应式适配简单,避免了浮动的坑。
盒模型
box-sizing
- 标准盒模型 (
content-box):total width=width+padding+border - IE 传统怪异盒模型 (
border-box):width包含padding+border。
盒模型场景题
Q1:content 大小为 100px,border 为 100px,问此时怪异盒模型的宽高
在 怪异盒模型 下,width 属性描述的是 总宽度 ,不是 content 宽度。
- 总宽 =
content+border*2= 100 + 100*2 = 300px - 总高 = 同理 = 300px
margin 重叠
什么是 margin 重叠?
- 垂直方向相邻块级元素的
margin会合并 - 合并规则:取最大值,而不是累加
什么时候会发生 margin 重叠?
- 相邻兄弟元素
- 父子上下边距
- 空块元素(无内容、无
padding、无border)
如何避免 margin 重叠?
给父元素加 padding 或触发 BFC 都可以阻止 margin 重叠。
定位与 z-index
position属性及区别
| 属性 | 定位方式 | 特点 |
|---|---|---|
static |
默认 | 正常文档流,top/right/bottom/left 无效 |
relative |
相对定位 | 保留在文档流,占据原位置,可偏移 |
absolute |
绝对定位 | 脱离文档流,相对最近定位父元素偏移 |
fixed |
固定定位 | 脱离文档流,相对视口固定 |
sticky |
粘性定位 | 类 relative,当滚动到指定位置时表现为 fixed |
z-index是干什么的?
- 控制定位元素的堆叠顺序
- 只对定位元素有效(
relative/absolute/fixed/sticky) - 数值越大,越靠前
CSS 选择器与优先级
- CSS 选择器
标签选择器、类选择器、ID 选择器、后代选择器、子元素选择器、相邻兄弟选择器、通用选择器和属性选择器 - 优先级
!important> 行内样式 > ID 选择器 > 类选择器、属性选择器和伪类选择器 > 标签选择器和伪元素选择器
CSS 样式冲突怎么办?
- 控制作用域:使用模块化方案(CSS Module、Scoped CSS、BEM 命名、命名空间前缀)避免全局污染。
- 提高优先级 :通过更具体的选择器或使用
!important(仅在必要时)。 - 加载顺序管理:确保样式文件按依赖顺序导入,后加载的覆盖前加载的。
- 使用工程化工具:CSS-in-JS、Tailwind、PostCSS 等可隔离作用域。
- 样式复用统一:通过变量、主题、组件封装减少冲突来源。
- 调试排查:借助浏览器 DevTools 查看最终样式来源(Computed / Rules),定位冲突点。
渲染
重绘与回流
- 回流(Reflow / Layout) :元素几何属性发生变化,需要重新计算布局
- 影响 :
width/height/margin/padding/position/font-size - 触发:改变尺寸、位置、内容、字体、添加/删除 DOM 元素
- 减少方式 :批量修改 DOM / 使用
documentFragment/requestAnimationFrame
- 影响 :
- 重绘(Repaint / Paint) :样式变化,但不影响布局
- 影响 :
color/background等
- 影响 :
单行 / 多行省略
单行省略
css
/* 单行省略 */
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
多行省略
css
/* 主要 Webkit 内核支持,非 Webkit 可用 JS 或其他方案。 */
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3;
overflow: hidden;
隐藏元素的方法
display: none:不占空间,子元素不可见visibility: hidden:占空间但不可见opacity: 0:透明但仍可响应事件(可结合pointer-events:none)
display:none与 visibility:hidden区别
display:none 会触发回流,visibility:hidden 仅重绘,不影响布局。
CSS3
CSS3 新特性
- Flex / Grid 布局
- 过渡
transition/ 动画animation - 伪类与伪元素增强(
:nth-child,:not,::before,::after) box-sizing:border-box- 媒体查询
@media transform/translate/rotate/scale
单位区别
| 单位 | 说明 | 使用场景 |
|---|---|---|
px |
绝对像素 | 精确尺寸,像素级控制 |
em |
相对父元素字体 | 字体和布局相对父元素 |
rem |
相对根元素字体 | 统一响应式布局 |
% |
相对父元素 | 容器自适应 |
vw/vh |
相对视口 | 全屏宽高布局 |
CSS 预处理器
| 对比维度 | Less | Sass(SCSS) |
|---|---|---|
| 变量声明符号 | 用 @ |
用 $ |
| 语法风格 | 更接近原生 CSS | 有 SCSS 和 Sass 两种语法。SCSS 类似 CSS;Sass 原生语法无花括号和分号,更简洁 |
| 混入(Mixins) | 无需声明,通过类名调用(加()可选),如 .mixin() { ... },然后 .class { .mixin(); } |
需用 @mixin 声明,@include 调用,如 @mixin name($param:value){},调用 @include name(value); |
| 逻辑控制 | 有限支持,逻辑控制能力较弱,循环需递归实现 | 支持完整逻辑控制,如 @if、@for、@each、@while 等 |
| 模块化 | 依赖 @import,功能相对简单 |
支持 @use 和 @forward,是更现代的模块化方案,能避免命名冲突 |
| 编译方式 | 可通过 JS(less.js)、命令行、构建工具编译 | 可通过 Dart Sass(官方推荐)、Node Sass(已弃用)、命令行、构建工具编译 |
| 社区生态 | 较稳定,但发展趋缓 | 更活跃,功能更强大,生态更广,被更多大型框架和工具链采用 |
如何解决 1px
- 使用
transform缩放 - 使用
border-image/box-shadow
will-change 属性
will-change 告诉浏览器元素将要变化的属性,提前优化渲染,提高动画流畅度,但不能滥用,适合 短时间动画或频繁变化元素。
CSS 渲染层/合成层
浏览器如何创建渲染层?
渲染层是浏览器的独立图层,GPU 负责合成,常通过 transform、opacity、will-change、固定定位等触发,用于优化动画和滚动性能。
CSS 怎么开启硬件(GPU)加速?
transform(当 3D 变换的样式出现时会使用 GPU 加速)opacityfilterwill-change
原子化 CSS
基础类问题
什么是原子化 CSS?
原子化 CSS 就是把样式拆成最小的单一功能类,比如 text-red-500 是红色文本、p-4 是内边距 4px,HTML 里直接组合这些类就能实现样式,不用写自定义 CSS,核心是复用和提效。
和传统 CSS、预处理器的区别?
传统 CSS 是"先写样式类再引用",预处理器只是加了变量、嵌套,本质还是手动写样式;原子化是"预设好原子类,直接组合用",不用自己写样式,复用性和效率更高。
工具类问题
主流工具和特点?
最常用的是 Tailwind CSS ,生态全、能自定义配置;Windi CSS 是它的优化版,编译更快;UnoCSS 更轻量,支持多预设,按需选就行。
Tailwind 怎么自定义配置?
改 tailwind.config.js 文件,在 theme.extend 里加自定义颜色、间距、断点,比如加个主色 primary: '#165DFF',之后就能用 text-primary 这种类,贴合项目设计规范。
怎么解决类名冗长?
用 @apply 把常用类合并成自定义类,或者组件化封装,重复的样式组合写到组件里;再就是开 JIT 模式,支持动态类名,也能减少堆砌。
优缺点与场景
优缺点和规避方法?
- 优点:开发快、少冗余、样式统一、打包体积小。
- 缺点:类名长、要记规则、极端个性化支持不足。
- 规避 :用
@apply封装、自定义配置降低记忆成本,特殊样式扩展原子类就行。
适合什么项目?不适合什么?
- 适合:中小型项目、快速迭代的 MVP、组件库,还有需要统一设计规范的团队。
- 不适合:对 HTML 纯净度要求极高的项目,或者极端个性化、样式频繁变的场景。
深度延伸类
实现原理是什么?
核心是"预设规则+编译优化",工具先预设好原子类规则,编译时转成 CSS,再通过 JIT 或 PurgeCSS 剔除没用的类,保证体积最小。
和 CSS Modules、BEM 的区别?
CSS Modules 是加哈希隔离样式,BEM 是按"块-元素-修饰符"命名,两者都要手动写样式;原子化是预设类直接用,不用写样式,天然避免冲突。
怎么处理兼容性?
Tailwind 默认带 Autoprefixer,会自动加浏览器前缀;再配合 PostCSS 插件,配置目标浏览器,特殊属性扩展原子类时加前缀,兼容就没问题.