Skip to content

CSS 与页面样式 ​

1. CSS 选择器的优先级和权重怎么算? ​

  1. 先看层叠规则,再比选择器:声明来源、!important、层叠层等都会影响结果,不能只比较选择器长短。
  2. 同一层叠条件下,按三组比较:ID 选择器;类、属性选择器和伪类;标签和伪元素。先比第一组,再比第二组,最后比第三组。
  3. 不是十进制加分:可以记成 (ID, 类, 标签),例如 #app .item p 是 (1, 1, 1)。很多个类选择器也不能“进位”变成一个 ID。
  4. 通配符和组合符不增加权重:*、空格、> 等不计分;:where() 权重为零,:is()、:not()、:has() 采用参数列表中的最高权重。
  5. 同权重还要看作用域与顺序:普通未使用 @scope 的场景,通常后写的覆盖先写的。行内普通样式一般高于样式表普通声明,但不是高于一切。
  6. 不要到处加 !important:它不是给选择器加分,而是改变声明的优先级。先理顺选择器和层叠关系更好维护。

参考:CSS 优先级。

2. 如何设置文字省略号? ​

  1. 单行需要限制可用宽度:同时设置不换行、隐藏溢出和省略号。
  2. 多行常用行数截断:通过 -webkit-line-clamp 指定行数,配合相应盒模型和溢出隐藏;实际项目要确认目标浏览器支持。
  3. Flex 子项要注意最小宽度:必要时加 min-width: 0,否则子项可能被文字撑开,无法产生预期的溢出。
  4. 省略不等于删除内容:完整文本仍在,可以按需提供展开按钮,让手机和键盘用户也能看到全文。
css
.single-line {
  max-width: 240px;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.multiple-lines {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  overflow: hidden;
}

3. "use strict" 有什么作用? ​

这是一道 JavaScript 题,不是 CSS 语法。

  1. 开启严格模式:让一些原来被忽略或容易出错的写法直接报错,例如给未声明的变量赋值。
  2. 普通函数调用中的 this 不自动指向全局对象:严格模式下,未绑定接收者的普通函数调用,this 是 undefined。
  3. 限制部分不合理写法:例如禁止 with,限制某些重复声明和不安全行为。
  4. 模块和类已经处于严格模式:ES Module 和 class 内部通常不需要重复添加。
  5. 不是性能开关或安全沙箱:它能暴露一些错误,但不会自动解决所有问题。

4. 如何实现渐变色边框? ​

  1. 渐变不能直接写给 border-color:通常用多层背景、border-image 或伪元素实现。
  2. 圆角边框常用多层背景:内层覆盖内容区域,外层渐变铺到透明边框下面。
  3. border-image 适合部分简单场景:但和圆角的配合不一定符合预期,需要实际检查。
  4. 伪元素更灵活:可以独立设置边框装饰,但要处理层级、圆角和点击穿透。
css
.gradient-border {
  border: 2px solid transparent;
  border-radius: 12px;
  background:
    linear-gradient(white, white) padding-box,
    linear-gradient(90deg, #2563eb, #9333ea) border-box;
}

5. 如何用正方形图片实现圆头像? ​

  1. 宽高相等:只有正方形显示区域配合 50% 圆角才是圆,长方形会变成椭圆。
  2. 设置 border-radius: 50%:把显示区域裁成圆形。
  3. 使用 object-fit: cover:图片保持比例填满区域,必要时裁掉边缘,不会被拉变形。
  4. 调整人像位置:可以通过 object-position 控制裁切中心。
css
.avatar {
  width: 64px;
  height: 64px;
  border-radius: 50%;
  object-fit: cover;
  object-position: center;
}

6. CSS 响应式怎么做? ​

  1. 让布局适应空间:优先用百分比、Flex、Grid 和 max-width,少把所有宽度写死。
  2. 通过媒体查询切换布局:空间不足时,把三列改成两列或一列。断点按内容是否放得下决定,不只按某款手机尺寸决定。
  3. 移动端配置 viewport:通常使用 width=device-width, initial-scale=1,不要为了布局禁止用户缩放。
  4. 组件可以使用容器查询:根据组件所在容器的宽度调整,而不只看整个浏览器窗口。
  5. 不只检查宽度:还要检查字号、点击区域、长文本、横屏和文字放大,避免内容被截断。
css
.cards {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 16px;
}
@media (max-width: 900px) {
  .cards { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 600px) {
  .cards { grid-template-columns: 1fr; }
}

7. 怎么理解 Flex? ​

  1. Flex 是一维布局:主要沿一条轴排列子项,适合导航、工具栏和一行卡片。
  2. 先区分主轴和交叉轴:默认 row 主轴是水平方向;改为 column 后主轴变成垂直方向。
  3. 主轴分配用 justify-content:交叉轴对齐用 align-items。不要死记成“一个永远水平、一个永远垂直”。
  4. 空间分配看 grow、shrink、basis:分别控制剩余空间怎么分、不够时怎么缩、初始基准尺寸是什么。
  5. 换行需要 flex-wrap:多行之间的分布可用 align-content,单行时它通常不起作用。
  6. 内容撑开时检查最小尺寸:子项默认可能不愿缩到内容最小宽度以下,可以根据布局设置 min-width: 0。

8. 水平、垂直居中有哪些方法? ​

  1. Flex 居中:父元素设置 display: flex,再设置两条轴上的居中,适合大部分容器内居中。
  2. Grid 居中:display: grid; place-items: center,适合一个内容块放在容器中央。
  3. 定位加位移:绝对定位到 50%,再 translate(-50%, -50%),适合弹层等脱离普通文档流的元素。
  4. 普通块水平居中:给块设置宽度或最大宽度,再用 margin-inline: auto;它不会自动垂直居中。
  5. 先确认父容器有可分配空间:父元素和子元素一样高时,写垂直居中也看不出效果。
css
.center {
  min-height: 240px;
  display: flex;
  justify-content: center;
  align-items: center;
}

9. Flex 和 Grid 的区别,怎么选择? ​

  1. Flex 主要控制一条轴:适合按钮组、导航条、图标加文字等内容驱动的排列。
  2. Grid 同时控制行和列:适合仪表盘、规则卡片网格、需要跨行跨列的布局。
  3. Flex 换行不等于二维网格:各行通常独立分配空间,不保证所有列严格对齐。
  4. 可以组合使用:页面整体用 Grid 分栏,卡片内部用 Flex 排列图标、标题和按钮。

10. Tailwind CSS 是什么?优缺点是什么? ​

  1. 它提供组合式的工具类:用类名表达间距、颜色、布局等样式,例如 flex、items-center。
  2. 好处是减少反复命名样式:常见页面可以快速搭建,设计值也容易统一。
  3. 响应式和状态可以用变体表达:例如 md: 表示某个断点条件,hover: 表示悬停状态。
  4. 缺点是模板可能变长:重复结构应该抽成组件,复杂样式也可以保留普通 CSS,不必把所有内容都塞进类名。
  5. 动态类名需要注意构建识别:不要只靠字符串拼接生成类名,可以建立完整类名映射;具体配置方式要结合使用的 Tailwind 版本。

11. 如何实现图片宽或高自适应? ​

  1. 按宽度缩放:设置 width: 100%; height: auto,高度按图片原始比例变化。
  2. 只限制最大宽度:使用 max-width: 100%; height: auto,可以避免小图片被强行放大。
  3. 按固定高度缩放:设置明确高度、width: auto,再结合父容器检查是否溢出。
  4. 固定框里用 object-fit:cover 填满但可能裁切,contain 完整展示但可能留白。
  5. 避免布局跳动:提前提供图片宽高或 aspect-ratio,让浏览器在图片加载前预留空间。

12. 如何实现高度是宽度的 75%? ​

  1. 优先使用 aspect-ratio: 4 / 3:宽高比为 4:3,高度就是宽度的 75%。
  2. 让一个方向保持自动尺寸:例如宽度随容器变化,高度自动计算;宽高都固定时,比例不一定发挥预期作用。
  3. 旧方案是百分比 padding:普通横向书写模式下,垂直百分比 padding 按包含块宽度计算,常用 padding-top: 75% 做占位。
  4. 理解旧方案的前提:padding 的百分比不是按元素自身高度计算;用于比例盒子时,通常让盒子宽度与包含块匹配,内容再绝对定位。
css
.preview {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
}

13. 文案高亮怎么实现?有几种方式? ​

  1. 已知片段用标签包裹:例如 <mark> 表示需要突出显示的文本,也可以用带样式的 span。
  2. 搜索高亮先拆分文本:把命中和未命中的部分分成数组,分别渲染成节点,避免直接拼接不可信 HTML。
  3. 不想改 DOM 可考虑 CSS Custom Highlight API:用 Range 标记范围再定义样式,但要检查目标浏览器支持。
  4. 用户选中文本用 ::selection:它只改变选中效果,不会自动查找并高亮关键词。
  5. 注意安全和性能:正则搜索要转义用户输入,长文章不要每输入一个字就无节制重建全部节点;颜色也要保证对比度。

14. rem 和 em 的区别 ​

  1. rem 参考根元素字号:一般是 html 的 font-size,适合统一字号、间距尺度。
  2. em 要看用在哪:用于 font-size 时通常参考父元素字号;用于 padding、margin 等时参考当前元素的计算字号。
  3. 嵌套 em 字号可能累乘:父级和子级都设置 1.2em,会一层层放大,rem 不会这样跟随父级累乘。
  4. 选择看目的:全站统一尺度常用 rem,按钮内边距随自身文字大小变化可以用 em。

15. px 怎么转 rem? ​

  1. 公式是 px 除以根字号:如果根字号是 16px,24px 就是 1.5rem。
  2. 不能默认所有项目根字号一样:先看项目实际的 html 样式和用户设置。
  3. 可以用构建工具转换:但需要约定转换哪些属性、哪些值要保留,避免第三方组件尺寸被意外修改。
  4. rem 不自动等于响应式:根字号不变时,它不会因为窗口变窄就自动缩放,还需要配合弹性布局和断点。
  5. 尊重用户字号设置:常见做法是保留根字号为默认或百分比,再使用 rem,不要只为换算方便随意限制阅读字号。

16. CSS Modules 怎么实现样式隔离? ​

  1. 构建时转换局部类名:同样叫 .title,不同模块可以生成不同的类名,减少命名冲突。
  2. 通过映射使用类名:导入 styles 后,用 styles.title 取得实际生成的类名。
  3. 不是完全的浏览器隔离:全局标签选择器、继承样式和显式全局规则仍可能影响元素,不等于 Shadow DOM。
  4. 全局样式要明确管理:基础样式、主题变量可以集中定义,局部组件样式尽量放在模块中。
  5. 和 Vue scoped 不同:scoped 通常通过添加属性选择器限制作用范围;CSS Modules 主要通过转换类名避免冲突。
css
/* card.module.css */
.title { color: #3451b2; }
js
// 支持 CSS Modules 的构建环境
import styles from './card.module.css';
// React 中可用 className={styles.title},Vue 中可绑定 :class。