前端布局相关面试题整理

95 阅读19分钟

一、行内元素与块状元素

1. 概念区分

  • 块状元素(Block Element) :独占一行,宽度默认占满父容器,可设置宽高(widthheight )、内外边距(marginpadding )等样式,如 <div><p><h1> - <h6> 、<ul><li> 等 。
  • 行内元素(Inline Element) :与其他行内元素在同一行显示,宽度由内容决定,不能直接设置宽高,水平方向的内外边距(margin-left/rightpadding-left/right )可设置,垂直方向不影响布局,如 <span><a><img>(可替换行内元素,特殊处理)、<strong> 等 。
  • 行内块状元素(Inline - Block Element) :结合两者特点,既可以在一行显示,又能设置宽高、内外边距,如 inputbutton ,也可通过 display: inline-block 让元素具备该特性 。

2. 相互转换

通过 display 属性切换,如块状元素设 display: inline 变为行内元素;行内元素设 display: block 变为块状元素;设 display: inline-block 则为行内块状表现 。

二、flex 布局相关

1. 介绍一下 flex 布局

Flex(弹性盒布局)是 CSS3 引入的一种高效布局方式,用于为容器内的项目(子元素)提供灵活的排列、对齐和空间分配能力,可适配不同屏幕尺寸和设备。

  • 核心组成

    • 容器(Flex Container) :通过给父元素设置 display: flex 或 display: inline-flex 开启,决定子元素的布局规则。
    • 项目(Flex Item) :容器的直接子元素,会按照 flex 规则排列。
  • 常用属性(容器上)

    • flex-direction:设置主轴方向,值有 row(默认,水平从左到右 )、row-reverse(水平从右到左 )、column(垂直从上到下 )、column-reverse(垂直从下到上 )。
    • flex-wrap:控制项目是否换行,nowrap(默认,不换行 )、wrap(换行 )、wrap-reverse(反向换行 )。
    • justify-content:主轴上项目的对齐方式,如 flex-start(默认,主轴起始端 )、flex-end(主轴结束端 )、center(居中 )、space-between(两端对齐,项目间等距 )、space-around(项目两侧等距,整体两端间距是中间的一半 )等。
    • align-items:交叉轴上项目的对齐方式,stretch(默认,拉伸填充交叉轴 )、flex-start(交叉轴起始端 )、flex-end(交叉轴结束端 )、center(交叉轴居中 )、baseline(项目第一行文字基线对齐 )。
    • align-content:多根轴线(多行时)在交叉轴的对齐,类似 justify-content 作用于交叉轴,值有 flex-startflex-endcenterspace-betweenspace-aroundstretch 等。
  • 常用属性(项目上)

    • flex-grow:项目的放大比例,默认 0(不放大 ),容器有剩余空间时,按比例分配。
    • flex-shrink:项目的缩小比例,默认 1(空间不足时缩小 ),为 0 则不缩小。
    • flex-basis:项目在主轴上的初始尺寸,默认 auto(按自身内容或宽高 ),可设具体值(如 200px )。
    • flexflex-growflex-shrinkflex-basis 的简写,常用 flex: 1 等形式。
    • align-self:覆盖容器的 align-items,单独设置项目在交叉轴的对齐,值同 align-items 。

2. 如何用 flex 实现九宫格布局

需求:9 个项目,每行 3 个,均匀排列,行列间距合适。

HTML 结构

html

预览

<div class="grid-container">
  <div class="grid-item">1</div>
  <div class="grid-item">2</div>
  <div class="grid-item">3</div>
  <div class="grid-item">4</div>
  <div class="grid-item">5</div>
  <div class="grid-item">6</div>
  <div class="grid-item">7</div>
  <div class="grid-item">8</div>
  <div class="grid-item">9</div>
</div>

CSS 样式

css

.grid-container {
  display: flex;
  flex-wrap: wrap; /* 换行 */
  justify-content: space-between; /* 主轴(水平)均匀分布,两端对齐 */
}
.grid-item {
  width: 30%; /* 每行 3 个,占比约 30%,留出间距 */
  height: 100px;
  background-color: lightblue;
  margin-bottom: 10px; /* 行间距 */
}

或更灵活控制间距,用 justify-content: space-around ,且给 grid-item 设 flex: 0 0 30%; (固定初始尺寸,不放大缩小 ),结合 box-sizing: border-box 处理内边距等,也可搭配 gap 属性(gap: 10px ,设置项目间间距,替代 margin ,更简洁 ),如:

css

.grid-container {
  display: flex;
  flex-wrap: wrap; 
  gap: 10px; /* 行列间距统一 */
  justify-content: flex-start; 
}
.grid-item {
  flex: 0 0 calc(33.333% - 10px); /* 计算宽度,扣除间距 */
  height: 100px;
  background-color: lightblue;
  box-sizing: border-box;
}

3. flex: 1 指的是什么 & flex 属性默认值是什么

  • flex: 1 的含义
    flex: 1 是 flex-grow: 1; flex-shrink: 1; flex-basis: 0%; 的简写。表示项目在容器有剩余空间时会按比例放大(flex-grow: 1 ),空间不足时会按比例缩小(flex-shrink: 1 ),且项目在主轴上的初始基准尺寸为 0%(优先按放大 / 缩小分配空间 )。
  • flex 属性默认值
    flex 的默认值是 flex: 0 1 auto ,即 flex-grow: 0(不主动放大 )、flex-shrink: 1(空间不足时缩小 )、flex-basis: auto(项目初始尺寸由自身宽高或内容决定 )。

4. 分别介绍一下 flex-shrink 和 flex-basis 属性

  • flex-shrink

    • 作用:定义项目在主轴方向上空间不足时的缩小比例,仅在容器宽度小于项目总宽度(flex-wrap: nowrap 时 )生效。
    • 取值:数值(0 、1 、2 等 ),默认 1 。若设为 0 ,项目不会缩小,可能溢出容器;多个项目时,按 flex-shrink 数值比例分配缩小的空间。例如,容器宽度 300px ,两个项目 flex-basis 都是 200px ,总宽 400px ,需缩小 100px 。项目 1 flex-shrink: 1 ,项目 2 flex-shrink: 2 ,则项目 1 缩小 100 * (1/(1+2)) ≈ 33.33px ,项目 2 缩小 100 * (2/(1+2)) ≈ 66.67px 。
  • flex-basis

    • 作用:设置项目在主轴上的初始尺寸,优先级高于 widthflex-direction: row 时 )或 heightflex-direction: column 时 )。
    • 取值:auto(默认,按元素自身宽高或内容定 )、具体长度值(如 100px 、20% 等 )。若设为 0 ,项目尺寸更依赖 flex-grow 分配空间;设为 auto ,则先按自身宽高,再参与弹性分配。

三、grid 布局相关

Grid(网格布局)是 CSS3 另一种强大布局方式,将容器划分为行和列的网格,精准控制项目位置、大小和排列,适合复杂二维布局。

1. 核心概念

  • 容器(Grid Container) :通过 display: grid 或 display: inline-grid 定义,包含网格项目。
  • 项目(Grid Item) :容器的直接子元素,放置在网格线划分的单元格中。
  • 网格线(Grid Lines) :划分行和列的线,水平(行网格线 )和垂直(列网格线 )方向。
  • 网格轨道(Grid Track) :两条相邻网格线间的区域,即行或列。
  • 网格单元格(Grid Cell) :行和列网格线围成的最小区域,类似表格单元格。
  • 网格区域(Grid Area) :由多个单元格组成的矩形区域。

2. 常用容器属性

  • grid-template-columns / grid-template-rows:定义列和行的轨道尺寸,如 grid-template-columns: 100px 1fr 200px;(3 列,第一列 100px 、第二列按剩余空间比例、第三列 200px );grid-template-rows: repeat(3, 1fr);(3 行,每行等分空间 ) 。

  • grid-gapgrid-row-gapgrid-column-gap ) :设置行与行、列与列之间的间距,现代写法可用 gap 统一,如 gap: 10px 。

  • grid-template-areas:通过命名区域布局,配合项目的 grid-area 使用,如:

css

.grid-container {
  grid-template-areas: 
    "header header header"
    "sidebar main main"
    "footer footer footer";
}
.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
/* 以此类推 */
  • justify-items / align-items:分别控制项目在单元格内水平(主轴,网格行方向 )和垂直(交叉轴,网格列方向 )的对齐,值有 startendcenterstretch(默认,拉伸填充 )等。
  • justify-content / align-content:当网格轨道总尺寸小于容器尺寸时,控制轨道整体在容器内的对齐,类似 flex 布局的同名属性,针对网格轨道的排列。

3. 常用项目属性

  • grid-column / grid-row:指定项目占据的列 / 行范围,通过网格线编号,如 grid-column: 1 / 3;(从第 1 列线到第 3 列线,占 2 列 );grid-row: 2 / 4;(占 2 行 ) 。
  • grid-area:可用于指定项目所属命名区域(配合 grid-template-areas ),或直接写行列范围(如 grid-area: 2 / 1 / 4 / 3; ,对应 grid-row-start / grid-column-start / grid-row-end / grid-column-end )。
  • justify-self / align-self:覆盖容器的 justify-items / align-items ,单独设置项目在单元格内的对齐方式。

4. 与 flex 布局对比

  • 适用场景

    • Flex 擅长一维(单行 / 单列 )布局,处理方向上的排列、对齐和空间分配,如导航栏、列表行等。
    • Grid 专注二维(多行多列 )布局,能精准控制行列结构、单元格合并等,如复杂的页面网格(header、sidebar、main、footer 组合 )、卡片网格排列等。
  • 布局思路

    • Flex 基于 “轴”(主轴、交叉轴 ),动态分配空间,项目顺序易调整。

    • Grid 基于 “网格线” 和 “单元格”,先定义网格结构,再放置项目,结构更直观固定。

四、移动端 1px 问题

1. 移动端 1px 问题是怎么产生的,如何解决?

产生原因

移动端存在设备像素比(devicePixelRatio,简称 dpr ),公式为 dpr = 物理像素 / CSS 像素 。高清屏(如 Retina 屏 )dpr 可能为 2 或 3 ,此时 1 个 CSS 像素会对应多个物理像素。比如 dpr=2 时,1px 的 CSS 边框,实际会用 2×2 个物理像素绘制,视觉上边框会比期望的 “细 1px” 更粗,出现 “移动端 1px 显示变粗” 的问题 。

解决方法

  • 伪元素 + transform 缩放
    给目标元素添加伪元素(::before 或 ::after ),设置伪元素为绝对定位覆盖边框位置,利用 transform: scale 按 dpr 缩放。示例(dpr=2 时 ):

    css

    .border-1px {
      position: relative;
    }
    .border-1px::after {
      content: '';
      position: absolute;
      left: 0;
      bottom: 0;
      width: 100%;
      height: 1px;
      background-color: #000;
      transform: scaleY(0.5); /* dpr=2,垂直方向缩放 0.5 */
      transform-origin: 0 0;
    }
    

    可结合媒体查询适配不同 dpr 设备,动态设置缩放比例。

  • 使用 border-image
    准备对应 dpr 的细边框图片(如 2px 宽包含 1px 实边和 1px 透明的图片,用于 dpr=2 场景 ),通过 border-image 设置。但维护多倍图较麻烦,灵活性稍差。

  • CSS 渐变(linear-gradient )模拟
    利用渐变绘制细边框,如 dpr=2 时,绘制高度为 1px(CSS 像素 ),实际物理像素占 2px ,通过渐变让一半高度有颜色、一半透明。示例:

    css

    .border-1px {
      border-bottom: 1px solid transparent;
      background: linear-gradient(to bottom, #000 50%, transparent 50%) 0 0/100% 1px no-repeat;
    }
    

    不同 dpr 需调整渐变参数,可结合媒体查询。

  • 直接使用 viewport 缩放
    通过 meta 标签的 viewport 设置 initial-scale 、devicePixelRatio 等,让 CSS 像素与物理像素更匹配,但会影响整个页面布局,需整体考虑,一般较少单独用于 1px 问题。

五、rem 与 vw 方案

1. 介绍一下 rem 方案和 vw 方案,分别有什么优点和缺点

rem 方案

  • 原理rem 是相对单位,相对于根元素(html )的 font-size 。通过动态设置 html 的 font-size(一般结合 JS 监听设备宽度,计算并设置 ),实现页面元素尺寸随设备宽度等比缩放。

  • 优点

    • 灵活性高,可精准控制不同设备下的布局缩放,适配多种屏幕(手机、平板等 )。
    • 可结合媒体查询或 JS 灵活调整 html 的 font-size ,应对复杂适配需求(如区分横竖屏、不同 dpr 设备 )。
    • 对旧版浏览器兼容性较好(需 JS 动态设置时,注意脚本加载顺序 )。
  • 缺点

    • 依赖 JS 动态计算 html 的 font-size ,若 JS 执行异常或延迟,可能导致布局错乱。
    • 需额外处理字体大小(通常部分关键字体用 rem ,或单独设置固定 px ,避免字体缩放过度影响阅读 )。
    • 计算稍繁琐,需将设计稿尺寸转换为 rem 单位(一般需除以基准值,如设计稿 750px 宽,设 html font-size 为 75px ,则 100px 设计稿尺寸对应 1.333rem )。

vw 方案

  • 原理vw 是相对单位,1vw 等于视口宽度的 1% ;vh 对应视口高度的 1% 。以视口宽度为基准,直接按设计稿比例转换为 vw 单位,实现响应式布局。

  • 优点

    • 纯 CSS 方案,无需依赖 JS ,天然响应式,适配逻辑简单直接。
    • 与设计稿结合紧密,转换方便(如设计稿 750px 宽,1px 对应 100/750 ≈ 0.1333vw ,可借助 PostCSS 等工具自动转换 )。
    • 对现代浏览器兼容性较好,适合移动端及支持 CSS3 的环境。
  • 缺点

    • 旧版浏览器(如 Android 4.4 以下 )兼容性差,若需兼容需做降级处理。
    • 当页面包含滚动条、或视口大小受其他因素影响时,可能导致布局细微偏差。
    • 过度依赖 vw 可能引发元素尺寸失控(如字体过大 / 过小 ),需合理搭配 rem 、px 等单位,尤其注意字体、关键组件尺寸的适配。

2. rem 方案的 font-size 是挂在哪的

rem 方案中,font-size 是挂载在 根元素(html 标签 )  上的。所有使用 rem 单位的元素,都会根据 html 的 font-size 计算自身实际像素值。例如:

css

html {
  font-size: 16px; /* 基准值,1rem = 16px */
}
.box {
  width: 2rem; /* 实际宽度 32px */
}

3. rem 方案时移动端字体是怎么处理的

在 rem 布局中,字体处理需平衡适配性和可读性:

  • 方案一:部分字体用 rem
    对于需随屏幕等比缩放的标题、大段文本(如页面 Banner 文字 ),可使用 rem 单位,让字体大小随 html font-size 变化。但需注意设置合理的基准值,避免字体在小屏幕上过小、大屏幕上过大。
  • 方案二:关键字体用 px 固定
    对于阅读性要求高的正文、按钮文字等,建议用 px 固定尺寸(如 14px 、16px ),保证不同设备下字体清晰易读,不受 rem 缩放过度影响。
  • 方案三:结合媒体查询或 JS 动态调整
    根据设备宽度区间,通过媒体查询设置不同的 px 字体大小;或用 JS 监听屏幕变化,动态修改特定元素的字体尺寸,兼顾适配与阅读体验。

六、重绘(Repaint)与回流(Reflow)

1. 介绍一下重绘和回流

回流(Reflow)

  • 定义:也叫重排,当 DOM 结构变化(如元素尺寸、位置、数量改变 )或页面布局相关属性(如 widthheightmarginpadding 、display 等 )修改时,浏览器需重新计算元素的几何属性(位置、大小 ),并重新构建渲染树,这个过程称为回流。
  • 影响范围:回流代价高,会触发整个渲染树的重新计算,可能导致页面卡顿。例如,修改元素 width ,其父元素、兄弟元素等可能都需重新计算布局。

重绘(Repaint)

  • 定义:当元素的外观样式变化(如 colorbackgroundbox-shadow 等 ),但不影响布局和几何属性时,浏览器只需重新绘制元素的视觉样式,这个过程叫重绘。
  • 与回流关系:回流一定会触发重绘(布局变了,外观必然要重绘 ),但重绘不一定触发回流(仅改颜色等,不影响布局 )。重绘代价相对回流较小,但频繁触发也会影响性能。

2. 如何避免重绘和回流

减少回流触发

  • 批量操作 DOM
    避免频繁修改 DOM 样式,可先将元素脱离文档流(如 display: none ),批量修改样式后再放回;或使用文档片段(DocumentFragment ),先在内存中操作 DOM ,再一次性插入页面。示例:

    js

    const fragment = document.createDocumentFragment();
    // 循环创建/修改元素,添加到 fragment
    for (let i = 0; i < 10; i++) {
      const div = document.createElement('div');
      div.style.width = '100px';
      fragment.appendChild(div);
    }
    document.body.appendChild(fragment); // 一次性插入
    
  • 避免频繁获取布局属性
    连续获取 offsetWidthscrollTop 等布局属性(会强制浏览器同步回流 )时,可缓存结果。例如:

    js

    // 避免这样写(多次触发回流)
    for (let i = 0; i < 10; i++) {
      const width = box.offsetWidth; 
      box.style.width = width + 10 + 'px';
    }
    // 优化:缓存值
    const width = box.offsetWidth; 
    for (let i = 0; i < 10; i++) {
      box.style.width = width + 10 * i + 'px';
    }
    
  • 使用 CSS3 transform 替代位移
    修改元素位置时,用 transform: translate() 替代 topleft 等(transform 触发合成层,不会触发回流 )。例如:

    css

    /* 好的方式 */
    .box {
      transform: translate(100px, 0); 
    }
    /* 差的方式(触发回流) */
    .box {
      left: 100px; 
      position: relative;
    }
    

减少重绘触发

  • 避免频繁修改样式
    合并样式修改,用 class 批量切换样式,而非逐个修改 style 属性。例如:

    js

    // 差的方式(多次重绘)
    box.style.color = 'red';
    box.style.background = 'blue';
    // 好的方式(一次重绘)
    box.className = 'active'; 
    // 或用 cssText
    box.style.cssText = 'color: red; background: blue;';
    

  • 优化动画与过渡
    动画元素尽量使用 will-change 提前告知浏览器优化,或让动画元素脱离文档流(如 position: absolute/fixed ),减少对其他元素的影响。例如:

    css

    .animated-box {
      will-change: transform; /* 告知浏览器准备优化 transform 动画 */
    }
    

    实际开发中,两者常配合使用,比如页面整体用 Grid 划分大区域,区域内部用 Flex 处理细节排列 。

七、居中 / 常见布局

1. 水平居中实现方式

  • 行内元素(inline/inline-block )
    给父元素设置 text-align: center; ,即可让行内元素(如 spanaimg 等 )水平居中。

    css

    .parent {
      text-align: center;
    }
    
  • 块状元素(block ),已知宽度
    给元素设置 margin: 0 auto; ,需保证元素有明确宽度(width )。

    css

    .child {
      width: 200px;
      margin: 0 auto;
    }
    
  • 块状元素,未知宽度(Flex 布局 )
    父元素开启 Flex 布局,设置 justify-content: center; 。

    css

    .parent {
      display: flex;
      justify-content: center;
    }
    
  • 块状元素,未知宽度(Grid 布局 )
    父元素设 display: grid; ,子元素设 margin: auto; ;或父元素用 justify-items: center; 。

    css

    .parent {
      display: grid;
      justify-items: center; 
    }
    /* 或 */
    .child {
      margin: auto;
    }
    
  • 绝对定位元素
    结合 left: 50%; 和 transform: translateX(-50%); ,无需知道元素宽度。

    css

    .child {
      position: absolute;
      left: 50%;
      transform: translateX(-50%);
    }
    

2. 垂直居中实现方式

  • 单行文本(行内元素 )
    设置父元素 line-height 等于自身 height 。

    css

    .parent {
      height: 50px;
      line-height: 50px;
    }
    
  • 多行文本(inline-block 等 ),已知父元素高度(Flex 布局 )
    父元素开启 Flex ,设置 align-items: center; 。

    css

    .parent {
      display: flex;
      align-items: center;
      height: 200px;
    }
    
  • 块状元素,未知高度(Grid 布局 )
    父元素设 display: grid; ,子元素 margin: auto; ;或父元素用 align-items: center; 。

    css

    .parent {
      display: grid;
      align-items: center;
      height: 200px;
    }
    
  • 绝对定位元素
    结合 top: 50%; 和 transform: translateY(-50%); 。

    css

    .child {
      position: absolute;
      top: 50%;
      transform: translateY(-50%);
    }
    

3. 水平垂直居中(经典组合 )

  • Flex 布局方案

    css

    .parent {
      display: flex;
      justify-content: center; /* 水平居中 */
      align-items: center;     /* 垂直居中 */
      height: 300px;
    }
    
  • Grid 布局方案

    css

    .parent {
      display: grid;
      place-items: center; /* 水平+垂直居中,等价于 justify-items + align-items */
      height: 300px;
    }
    
  • 绝对定位 + transform 方案

    css

    .child {
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
    }
    
  • Table 模拟方案(旧版兼容 )
    父元素设 display: table-cell; ,配合 text-align: center; 和 vertical-align: middle; 。

    css

    .parent {
      display: table-cell;
      text-align: center;
      vertical-align: middle;
      width: 300px;
      height: 300px;
    }
    

4. 常见布局(两栏、三栏 )

两栏布局(左侧固定,右侧自适应 )

  • Flex 实现

    css

    .container {
      display: flex;
    }
    .left {
      width: 200px; /* 固定宽度 */
    }
    .right {
      flex: 1;      /* 自适应 */
    }
    
  • Grid 实现

    css

    .container {
      display: grid;
      grid-template-columns: 200px 1fr; /* 左侧固定,右侧占满剩余 */
    }
    
  • 浮动 + margin 实现

    css

    .left {
      float: left;
      width: 200px;
    }
    .right {
      margin-left: 200px; /* 让出左侧固定宽度 */
    }
    

三栏布局(两侧固定,中间自适应 )

  • Flex 实现

    css

    .container {
      display: flex;
    }
    .left {
      width: 100px;
    }
    .middle {
      flex: 1;
    }
    .right {
      width: 150px;
    }
    
  • Grid 实现

    css

    .container {
      display: grid;
      grid-template-columns: 100px 1fr 150px;
    }
    
  • 圣杯布局(浮动 + 负边距 )
    利用 float 、margin 负值和 padding 配合,实现中间栏优先加载(SEO 友好 ),较复杂,现代多被 Flex/Grid 替代。

八、层叠上下文与 z-index

1. 什么是层叠上下文(Stacking Context )?

层叠上下文是 HTML 元素的一个三维概念(Z 轴 ),决定元素在页面垂直方向(Z 轴 )的显示顺序。具备层叠上下文的元素,会形成独立的渲染层,其子元素的层叠顺序受限于该上下文,不会突破到外部。

触发层叠上下文的常见情况

  • 根元素(html )默认创建根层叠上下文。
  • 元素设置 position: relative/absolute/fixed/sticky 且 z-index ≠ auto 。
  • 元素设置 opacity < 1 、transform ≠ none 、filter ≠ none 等 CSS3 属性。
  • 元素设置 display: flex 或 grid ,子元素 z-index ≠ auto 。

2. 说一下 z-index 的作用与注意事项

作用

z-index 用于控制同一层叠上下文内元素的层叠顺序,值越大,元素在 Z 轴上越靠上(显示越靠前 )。仅在元素开启定位(position: relative/absolute/fixed/sticky )或属于 Flex/Grid 子元素时生效。

注意事项

  • 层叠上下文限制z-index 仅在当前层叠上下文内有效。若父元素和子元素属于不同层叠上下文,子元素 z-index 无法突破父元素的层叠等级。例如:

    html

    预览

    <div style="position: relative; z-index: 1;">
      <!-- 父层叠上下文,z-index:1 -->
      <div style="position: relative; z-index: 999;">
        <!-- 子元素,虽 z-index 大,但无法超过父元素的层叠等级 -->
      </div>
    </div>
    <div style="position: relative; z-index: 2;">
      <!-- 该元素会覆盖上面的父元素及子元素 -->
    </div>
    
  • 默认值与 autoz-index: auto 时,元素不会创建新层叠上下文(继承父级 );若设为数值(如 z-index: 1 ),则创建层叠上下文(当元素满足定位等条件时 )。

  • Flex/Grid 特殊处理:Flex/Grid 容器的子元素,即使未显式定位,设置 z-index 也会创建层叠上下文,影响层叠顺序。

九、Sass/Less 预处理器

1. 介绍 Sass/Less 的核心特性与区别

核心特性(共性 )

  • 变量(Variables ) :复用颜色、尺寸等值,方便维护。

    scss

    // Sass
    $primary-color: #007bff;
    .btn { color: $primary-color; }
    
    // Less
    @primary-color: #007bff;
    .btn { color: @primary-color; }
    
  • 嵌套(Nesting ) :模拟 HTML 层级结构,简化选择器编写。

    scss

    // Sass
    .nav {
      li { float: left; }
      a { color: #333; 
          &:hover { color: #000; } // & 代表父选择器
        }
    }
    
  • 混合(Mixins ) :复用代码片段,可带参数。

    scss

    // Sass
    @mixin flex-center {
      display: flex;
      justify-content: center;
      align-items: center;
    }
    .box { @include flex-center; }
    
    // Less
    .flex-center() {
      display: flex;
      justify-content: center;
      align-items: center;
    }
    .box { .flex-center; }
    
  • 继承(Extend ) :让选择器继承其他样式,减少冗余。

    scss

    // Sass
    .btn { padding: 8px 16px; }
    .btn-primary { @extend .btn; background: #007bff; }
    
    // Less(类似,用 &:extend )
    .btn { padding: 8px 16px; }
    .btn-primary { &:extend(.btn); background: #007bff; }
    
  • 运算(Operations ) :支持数值、颜色计算。

    scss

    // Sass
    $width: 100px;
    .box { width: $width + 50px; } // 150px
    
    // Less
    @width: 100px;
    .box { width: @width + 50px; }
    

主要区别

特性SassLess
语法风格支持 .scss(类 CSS 语法 )和 .sass(缩进语法 )仅 .less(类 CSS 语法 )
编译环境依赖 Ruby(旧版 )或 Dart Sass(新版 )基于 JavaScript ,可浏览器端编译
高级功能支持控制指令(@if@for@each 等 )控制指令较弱,依赖 Mixins 模拟
社区生态后端(Ruby on Rails )场景更流行前端工程化(Webpack 等 )集成方便

2. Sass/Less 的使用价值(为什么用预处理器 )

  • 提升可维护性:变量、混合、继承等特性,让样式代码复用性更高,修改主题色、通用样式时更高效。
  • 增强可读性:嵌套语法贴合 HTML 结构,代码层级清晰,降低复杂选择器的维护成本。
  • 适配复杂逻辑:通过条件判断(Sass 的 @if )、循环(@for )等,生成动态样式(如自动生成栅格列数 )。
  • 工程化必备:现代前端构建工具(Webpack、Vite )无缝集成,配合 PostCSS 等,实现自动化前缀添加、压缩等流程。