主题
移动端适配与 rem(四)
本页对应 移动端适配与 rem,共 7 段视频,约 1 小时 8 分。
学习目标
- 能够使用
@import在 LESS 文件中导入基础样式文件,并说明导入.less文件时可省略后缀。 - 能够使用
out:注释配置 LESS 文件的导出路径和文件名,并设置 VS Code 默认导出路径,将 LESS 编译为指定目录下的 CSS。 - 能够按项目规范创建
less、css、images、js等目录,并在 HTML 中正确引入字体图标、编译后的 CSS 和适配脚本。 - 能够定义 LESS 变量表示 375 设计稿下的基准值,并用变量替换重复的
37.5rem换算写法。 - 能够使用 Flex 布局完成头部左中右三栏及 banner 区域的结构与样式,并实现文字、图片、间距和颜色的适配。
- 能够完成文本列表区域的边框、内边距、垂直居中、图片与文字间距等样式,并在不同移动端设备上验证适配效果。
知识点
先看整体与准备工作

做这个综合案例前,先明确目标:把设计稿拆成“头部、banner、问诊类型列表”三块,再逐块用 flex 布局实现。为什么需要先准备目录?因为页面要引入字体图标、公共样式、适配脚本和图片素材,目录乱了后面路径很容易错。怎么想:先按“html、css、less、js、assets、iconfont”分文件夹;怎么做:HTML 里先引入图标样式、页面样式和 flexible.js,less 里用 @import 引入公共基础样式。转写稿里特别强调:@import 后写路径和分号,路径是 less 文件时可省略 .less 后缀;导出路径写在 less 第一行 // out: ../css/,公共基础文件若不想导出 CSS,可写 // out: false。易错点:@import 不是 @important,末尾要有分号;如果没设置默认导出路径,就要自己在文件第一行写 // out: ../css/。

html
<link rel="stylesheet" href="./iconfont/iconfont.css">
<link rel="stylesheet" href="./css/index.css">
<body>
......
<script src="./js/flexible.js"></script>
</body>less
// out: ../css/
@import "./base";头部布局
为什么先做头部?它是页面最上面的固定结构,包含返回、标题、问诊记录三块,适合先练“大盒子 + flex 横排”。怎么想:把头部当成一个 header 大盒子,左右用 space-between 分开,垂直方向用 line-height 与高度一致做居中。怎么做:高度按设计稿 44px 换算成 rem,左右内边距 15px,也统一除以 @rootSize。转写稿里调试时先加粉色背景看盒子范围,确认高度、左右间距没问题后再删掉背景色。易错点:高度写成固定 44px 就不会适配;padding: 0 (15 / @rootSize) 要记得括号;line-height 与 height 一致才能让文字垂直居中。
html
<!-- 头部 -->
<header>1</header>less
// 头部
header {
display: flex;
justify-content: space-between;
padding: 0 (15 / @rootSize);
height: (44 / @rootSize);
background-color: pink;
line-height: (44 / @rootSize);
}头部内容
为什么要把返回、标题、记录分成三个元素?因为它们在 flex 主轴上有左中右关系,单独控制字体大小和颜色更方便。怎么想:左边用 a.back 包字体图标,中间用 h3,右边用 a.note;字体图标大小 22,标题 17,记录文字 15 且用绿色 #2CB5A5。怎么做:结构写好后,分别给 .icon-left、h3、.note 设置字号和颜色。转写稿里调试发现 .icon-left 的字号被 .iconfont 的默认样式覆盖,原因是同类选择器后写或权重相同;解决时可写 header .icon-left 或 .iconfont.icon-left 提高权重。易错点:不要写成 header .icon-left h3 这类错误层级;.note 的颜色要写在 a 上;图标大小不要漏写。
html
<a href="#" class="back"><span class="iconfont icon-left"></span></a>
<h3>极速问诊</h3>
<a href="#" class="note">问诊记录</a>less
.icon-left {
font-size: (22 / @rootSize);
}
h3 {
font-size: (17 / @rootSize);
}
.note {
font-size: (15 / @rootSize);
color: #2CB5A5;
}banner 区域
为什么 banner 要单独成块?它由入口图和一句提示文字组成,和头部、列表的间距不同。怎么想:外层 .banner 控制上下外边距和文字居中;图片固定宽高;文字里的“20s”用 span 单独变绿。怎么做:margin-top: 30、margin-bottom: 34,图片 240×206、下边距 18,p 字号 16,span 颜色 #16C2A3。转写稿里调试时先给盒子加背景看间距,再通过 text-align: center 让图片和文字整体居中。易错点:图片宽高不要只写宽度;span 要写在 p 内部并用 p span 选中;上下 margin 合并时看起来间距不对,要检查相邻盒子。
html
<!-- banner -->
<div class="banner">
<img src="./assets/entry.png" alt="">
<p><span>20s</span> 快速匹配专业医生</p>
</div>less
// banner
.banner {
margin-top: (30 / @rootSize);
margin-bottom: (34 / @rootSize);
text-align: center;
img {
margin-bottom: (18 / @rootSize);
width: (240 / @rootSize);
height: (206 / @rootSize);
}
p {
font-size: (16 / @rootSize);
span {
color: #16C2A3;
}
}
}问诊类型布局
为什么列表外层要加 .type?因为列表整体左右有 15px 内边距,每个 li 之间还有 15px 下边距。怎么想:ul 里放多个 li,每个 li 是带边框的卡片;卡片内部用 a 做 flex 横排,让图片、文字、右箭头一行排列。怎么做:li 设高度 78、边框 1px、圆角 4;a 也设高度 78 并 align-items: center,实现内容垂直居中。转写稿里提到 1px 边框不要再除以 @rootSize,因为最小线条通常就是 1px。易错点:li 和 a 的高度要配合;padding 写在 li 上时注意边框是否被撑开;margin-bottom 不要漏。
html
<!-- 问诊类型 -->
<div class="type">
<ul>
<li>
<a href="#">
<div class="pic">1</div>
<div class="txt">2</div>
<span class="iconfont icon-right"></span>
</a>
</li>
<li>2</li>
</ul>
</div>less
// 问诊类型
.type {
padding: 0 (15 / @rootSize);
li {
margin-bottom: (15 / @rootSize);
padding: 0 (15 / @rootSize);
height: (78 / @rootSize);
border: 1px solid #EDEDED;
border-radius: (4 / @rootSize);
a {
display: flex;
align-items: center;
// 内容在78里面垂直居中
height: (78 / @rootSize);
}
}
}问诊类型内容
为什么文字区要加 flex: 1?因为一行里图片固定 40×40,右侧图标固定大小,中间文字要自动占满剩余空间。怎么想:图片给 margin-right: 14,.txt 用 flex: 1,标题 16、行高 24,描述 13 且灰色 #848484,右箭头 16。怎么做:结构上按“图片、文字、箭头”三块写,样式上分别控制。转写稿里调试时发现标题和描述挤在一起,就给 h4 加行高;箭头不靠右时,检查 .txt 是否真的 flex: 1。易错点:.txt 不写 flex: 1 时箭头不会贴右;h4 默认外边距可能影响布局,可在 base 里清除;图标选择器不要误写成标签选择器。
html
<div class="pic">
<img src="./assets/type01.png" alt="">
</div>
<div class="txt">
<h4>三甲图文问诊</h4>
<p>三甲主治及以上级别医生</p>
</div>
<span class="iconfont icon-right"></span>less
img {
margin-right: (14 / @rootSize);
width: (40 / @rootSize);
height: (40 / @rootSize);
}
.txt {
flex:1;
h4 {
font-size: (16 / @rootSize);
color: #3C3E42;
line-height: (24 / @rootSize);
}
p {
font-size: (13 / @rootSize);
color: #848484;
}
}
.iconfont {
font-size: (16 / @rootSize);
}课件图示

代码示例
- HTML 结构
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>极速问诊</title>
<link rel="stylesheet" href="./iconfont/iconfont.css">
<link rel="stylesheet" href="./css/index.css">
</head>
<body>
<!-- 头部 -->
<header>
<a href="#" class="back"><span class="iconfont icon-left"></span></a>
<h3>极速问诊</h3>
<a href="#" class="note">问诊记录</a>
</header>
<!-- banner -->
<div class="banner">
<img src="./assets/entry.png" alt="">
<p><span>20s</span> 快速匹配专业医生</p>
</div>
<!-- 问诊类型 -->
<div class="type">
<ul>
<li>
<a href="#">
<div class="pic">
<img src="./assets/type01.png" alt="">
</div>
<div class="txt">
<h4>三甲图文问诊</h4>
<p>三甲主治及以上级别医生</p>
</div>
<span class="iconfont icon-right"></span>
</a>
</li>
</ul>
</div>
<script src="./js/flexible.js"></script>
</body>
</html>要点:头部使用 header 包住左、中、右三块内容;iconfont 引入后使用 icon-left、icon-right 字体图标;banner 中 span 单独包住 20s 方便单独设色;问诊类型按“ul > li > a”组织,pic、txt、iconfont 对应左中右三块。易错点:iconfont.css、css/index.css、flexible.js 和图片资源路径要与项目目录一致;第二项问诊类型可复制第一项结构后替换图片和文字。
- LESS 样式
less
// out: ../css/
@import "./base";
@rootSize: 37.5rem;
// 头部
header {
display: flex;
justify-content: space-between;
padding: 0 (15 / @rootSize);
height: (44 / @rootSize);
background-color: pink;
line-height: (44 / @rootSize);
.icon-left {
font-size: (22 / @rootSize);
}
h3 {
font-size: (17 / @rootSize);
}
.note {
font-size: (15 / @rootSize);
color: #2CB5A5;
}
}
// banner
.banner {
margin-top: (30 / @rootSize);
margin-bottom: (34 / @rootSize);
text-align: center;
img {
margin-bottom: (18 / @rootSize);
width: (240 / @rootSize);
height: (206 / @rootSize);
}
p {
font-size: (16 / @rootSize);
span {
color: #16C2A3;
}
}
}
// 问诊类型
.type {
padding: 0 (15 / @rootSize);
li {
margin-bottom: (15 / @rootSize);
padding: 0 (15 / @rootSize);
height: (78 / @rootSize);
border: 1px solid #EDEDED;
border-radius: (4 / @rootSize);
a {
display: flex;
align-items: center;
height: (78 / @rootSize);
img {
margin-right: (14 / @rootSize);
width: (40 / @rootSize);
height: (40 / @rootSize);
}
.txt {
flex: 1;
h4 {
font-size: (16 / @rootSize);
color: #3C3E42;
line-height: (24 / @rootSize);
}
p {
font-size: (13 / @rootSize);
color: #848484;
}
}
.iconfont {
font-size: (16 / @rootSize);
}
}
}
}要点:@rootSize: 37.5rem; 用于 375 设计稿换算,所有需要适配的尺寸写成 (数值 / @rootSize);头部用 display:flex; justify-content:space-between; 实现左中右分布;问诊类型卡片中 a 设为 flex 并用 align-items:center; 让内容在 78 高度内垂直居中;.txt { flex:1; } 让中间文字区域占满剩余宽度。易错点:LESS 除法要加括号;1px 边框通常不参与 rem 换算;h3 要写在 header 下,不要误写成图标内部的 h3。
- LESS 导入与导出
less
// out: ../css/
@import "./base";
@rootSize: 37.5rem;要点:第一行 // out: ../css/ 控制该 LESS 编译后导出到上一级 css 文件夹;@import "./base"; 用于把基础公共样式导入当前 LESS,避免重复写清除默认样式等代码;@rootSize: 37.5rem; 定义换算基准,后续尺寸统一除它。易错点:@import 后面要有引号和分号;导出注释一般放第一行;如果 base.less 只是被导入、不需要单独导出 CSS,可按转写稿思路使用禁止导出配置。
常见错误
- 现象:修改 less 后页面样式不变,css 目录也没有新文件 → 原因:
// out:注释不在第一行、路径写错,或文件未保存 → 修法:检查首行// out: ../css/,保存 less,确认对应 css 已生成到目标目录。 - 现象:页面基础样式全部丢失 → 原因:
index.less未导入base.less,或@import路径/分号写错 → 修法:补@import "./base";,保存后检查生成的 css 是否包含基础样式。 - 现象:字体图标显示为方块或不显示 → 原因:HTML 未引入
iconfont.css,或类名写成icon-left却漏了iconfont→ 修法:确认link引入正确,使用class="iconfont icon-left"这类完整类名。 - 现象:头部左中右三块没有分开,或左右贴边 → 原因:
header未设display:flex,或justify-content:space-between、左右 padding 写错 → 修法:header 设 flex 与 space-between,左右 padding 用(15 / @rootSize)。 - 现象:尺寸明显过大/过小,换设备后不协调 → 原因:把设计稿 px 直接写成 rem,或漏引
flexible.js,或未统一除以根字号 → 修法:确认flexible.js已引入,尺寸统一用(设计稿px / @rootSize),并抽成变量替换。 - 现象:问诊类型右侧箭头紧贴文字,文字区没有撑开 → 原因:
.txt未设置flex:1,或a未设 flex/高度 → 修法:给.txt{flex:1},给a{display:flex;align-items:center;height:(78 / @rootSize)}。 - 现象:给标题设置字号不生效 → 原因:标签选择器权重低于
.iconfont等类选择器,被覆盖 → 修法:用父级限定提高权重,如header h3或.type .txt h4。 - 现象:移动端边框被算成 0.x px 后几乎看不见 → 原因:把 1px 边框也按根字号换算 → 修法:边框保留
1px solid #EDEDED,不要参与 rem 细算。
练习
- 新建
less/index.less,完成base.less导入与导出到../css/的配置,保存后检查 css 文件生成位置和内容。 - 完成头部三栏布局:返回图标、标题“极速问诊”、问诊记录;要求高度
44/37.5rem,左右内边距15/37.5rem,三块两端对齐。 - 完成 banner 区域:图片宽
240/37.5rem、高206/37.5rem,图文整体居中,“20s”单独高亮。 - 完成问诊类型列表:每个
li高78/37.5rem、边框1px、圆角4/37.5rem;a垂直居中,.txt占满剩余空间,右侧箭头靠右。 - 将
37.5抽成 less 变量并替换头部、banner、问诊类型中的换算;分别用 iPhone 6/7/8 与 iPad 宽度检查字号、间距、图片是否稳定。
原视频对照
| # | 视频 | 时长 |
|---|---|---|
| 1 | less导入 | 08:05 |
| 2 | less导出 | 13:41 |
| 3 | 项目准备 | 07:30 |
| 4 | 项目(头部) | 14:47 |
| 5 | 变量 | 01:15 |
| 6 | 项目(banner) | 07:24 |
| 7 | 项目(完成) | 15:33 |
小结
- 本案例的核心是移动端适配与页面拆分,不是新的布局体系。
- less 工程化要先保证导入、导出链路正确,再进入页面样式编写。
- 尺寸换算应统一走根字号变量,避免页面中散落魔法数。
- 头部、banner、问诊类型都适合“大盒包小块”,再逐块调间距、字号、颜色。
- 1px 边框按设计稿保留,不参与 rem 细算。
- 综合案例中选择器权重问题比单个属性问题更常见,父级限定是低成本修法。
- 验收适配时要同时看不同设备宽度下的字号、间距、图片和文字稳定性。
- 先结构后样式、先大盒后内容,能明显减少返工。