Day 16 | 用 ul、ol、li 一个标签,把散资料收成有序的技能清单页

Day 16 | 用 ul、ol、li 一个标签,把散资料收成有序的技能清单页

本文是《100天精通HTML基础入门》专栏第 16 篇,订阅专栏不迷路。
摘要 :本文基于 HTML5 现行规范,用演化式讲清一件事------技能清单别再一行一行用 <p> 硬敲。我们从一堆散乱的 <p> 出发,逐版演进到 <ul> 无序列表、<ol> 有序列表带嵌套子清单、最后用 <dl> 把"技能名 + 熟练度"这种成对信息语义收口。四版运行结果都在 Chrome 128 下验证过。适合刚做完名片页、正往阶段二走的读者,读完你能交出一个结构正确的技能清单页,并说清 li 外面裸写字、嵌套漏一层 ul 这两个坑为什么会崩。列表的默认记号与缩进是 CSS 早期就定下的机制,长期适用。

本文目录

  • 技能清单先长这样:一堆 p 标签硬堆

  • v2:一个 ul 把同级内容收成一挂

  • v3:该排序的用 ol,往里再嵌一层子清单

  • 漏掉这一层 ul,子清单和父级挤成一坨

  • 把字写在 li 外面,浏览器当场不收

  • v4:一组词配解释用 dl,语义才对得上

  • 为什么列表天生带记号和缩进

  • 今天小结:清单成了,那个点却碍眼

技能清单先长这样:一堆 p 标签硬堆

阶段一的电子名片里,"我会什么"那块多半是你一行一行敲出来的 <p>。它不难看,但难维护:想加一项得自己挪序号,想调顺序得重敲,读屏软件也数不出"这里有 3 条技能"。先把这版还原出来------运行结果在 Chrome 128 下看过,它长得像清单,骨子里是一堆各过各的段落。

Plaintext 复制代码
<!-- 《100天精通HTML基础入门》Day 16 · 平头哥 · 技术改变世界,勤奋改变人生 -->
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>技能清单 v1 · 一堆 p 硬堆</title>
  <style>
    /* v1 的问题:每条技能是独立段落,彼此没有"同属一组"的关系 */
    /* 序号靠手打,一旦加项或调序,下面的数字全得重敲 */
    * { box-sizing: border-box; }
    body { font-family: "Microsoft YaHei", sans-serif; background: #f7f5ef;
      color: #24292f; margin: 0; line-height: 1.7; }
    .wrap { max-width: 560px; margin: 24px auto; background: #fff;
      border: 1px solid #d8d3c8; border-radius: 14px; padding: 24px 28px; }
    h1 { font-size: 22px; margin: 0 0 14px; }
    p { margin: 0 0 8px; font-size: 15px; }
  </style>
</head>
<body>
  <div class="wrap">
    <h1>我的技能</h1>
    <p>1. HTML 结构与语义标签</p>
    <p>2. 页面排版与移动端适配</p>
    <p>3. 把列表和链接组合成导航</p>
  </div>
</body>
</html>

三个手打的序号就是三颗定时炸弹。更麻烦的是语义:HTML 根本不知道这三行是"一组",对它而言就是三个不相干的 <p>。这就是我们要演化的起点。

v2:一个 ul 把同级内容收成一挂

先说最要紧的改动:同级、无序、彼此并列的内容,交给一个 <ul> 包着,每条放进一个 <li>。你不用再管序号和缩进,浏览器会自动给每条前面点一个实心圆点,并留出整齐的左缩进。为什么用 ul 而不是继续 <p>?因为这组技能之间没有先后,"结构"不比"排版"更靠前,是无序关系。

样式代码不用细看,理解为给网页化妆即可,CSS 专栏里会展开。

Plaintext 复制代码
<!-- 《100天精通HTML基础入门》Day 16 · 平头哥 · 技术改变世界,勤奋改变人生 -->
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>技能清单 v2 · 一个 ul 收成一挂</title>
  <style>
    /* ul 负责"这是一组",li 负责"组里的每一条" */
    /* 圆点和左缩进是浏览器默认样式,这一版我们不覆盖它 */
    * { box-sizing: border-box; }
    body { font-family: "Microsoft YaHei", sans-serif; background: #f7f5ef;
      color: #24292f; margin: 0; line-height: 1.7; }
    .wrap { max-width: 560px; margin: 24px auto; background: #fff;
      border: 1px solid #d8d3c8; border-radius: 14px; padding: 24px 28px; }
    h1 { font-size: 22px; margin: 0 0 12px; }
    ul { margin: 0; padding-left: 22px; }
    li { font-size: 15px; margin-bottom: 6px; }
  </style>
</head>
<body>
  <div class="wrap">
    <h1>我的技能</h1>
    <ul>
      <li>HTML 结构与语义标签</li>
      <li>页面排版与移动端适配</li>
      <li>把列表和链接组合成导航</li>
    </ul>
  </div>
</body>
</html>

运行结果对比 v1:页面长得几乎一样,但源码从"三个各过各的段落"变成了"一条列表挂三个项"。加一项只需多写一行 <li>,序号、圆点、缩进浏览器全包。这就是清单式的正确底座。

v3:该排序的用 ol,往里再嵌一层子清单

清单不只有并列。学习路径、操作步骤这种有先后 的,要用 <ol>,让浏览器替你编号。另外还有个有意思的事:清单能套清单------在某个 <li> 里面再放一个完整的 <ul>,就长出第二层。注意这条铁律:每一层子清单,都得自带一个 <ul> (或 <ol>)外壳 ,不能光秃秃地再写几个 <li>

样式代码不用细看,理解为给网页化妆即可,CSS 专栏里会展开。

Plaintext 复制代码
<!-- 《100天精通HTML基础入门》Day 16 · 平头哥 · 技术改变世界,勤奋改变人生 -->
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>技能清单 v3 · ol 排序 + 嵌套子清单</title>
  <style>
    /* ol 有先后:浏览器给 1 2 3,步骤顺序错了就得重排 */
    /* 嵌套只在父 li 内部再开一个 ul,缩进由浏览器自动处理 */
    * { box-sizing: border-box; }
    body { font-family: "Microsoft YaHei", sans-serif; background: #f7f5ef;
      color: #24292f; margin: 0; line-height: 1.7; }
    .wrap { max-width: 560px; margin: 24px auto; background: #fff;
      border: 1px solid #d8d3c8; border-radius: 14px; padding: 24px 28px; }
    h1 { font-size: 22px; margin: 0 0 12px; }
    ol { margin: 0; padding-left: 22px; }
    ol > li { font-size: 15px; margin-bottom: 8px; }
    ol ul { margin-top: 6px; padding-left: 22px; }
    ol ul li { font-size: 14px; color: #4a5560; margin-bottom: 3px; }
  </style>
</head>
<body>
  <div class="wrap">
    <h1>我的技能</h1>
    <ol>
      <li>前端基础
        <ul>
          <li>HTML 结构与语义标签</li>
          <li>页面排版与移动端适配</li>
        </ul>
      </li>
      <li>进阶技能
        <ul>
          <li>把列表和链接组合成导航</li>
          <li>表单与页面结构</li>
        </ul>
      </li>
      <li>正在学
        <ul>
          <li>CSS 盒模型</li>
        </ul>
      </li>
    </ol>
  </div>
</body>
</html>

现象验证:编号 1 2 3 是 ol 给的,子项前面的短横是嵌套 ul 给的,两层缩进整齐。把某条技能提到第一层,只要在 <li> 之间移动整块,浏览器会重算编号------这正是清单比手打序号值钱的地方。

漏掉这一层 ul,子清单和父级挤成一坨

新手坑里最阴的一个:你以为缩进敲到位,层级就对了。可 HTML 不认空格,只认标签。想再开一层,必须有那个 <ul> 外壳。少了它,子项的 <li> 会被当成父级的兄弟,和"前端基础""进阶技能"平起平坐,整页层级当场塌平。下面是漏掉第二层 ul 的翻车现场。

Plaintext 复制代码
<!-- 《100天精通HTML基础入门》Day 16 · 平头哥 · 技术改变世界,勤奋改变人生 -->
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>翻车 · 嵌套漏了一层 ul</title>
  <style>
    /* 每个 li 描一条浅边框,让"本该是父子却被拉平"的关系肉眼可见 */
    /* 现象:子项和父项同级排,少了一格缩进 */
    * { box-sizing: border-box; }
    body { font-family: "Microsoft YaHei", sans-serif; background: #f7f5ef;
      color: #24292f; margin: 0; line-height: 1.7; }
    .wrap { max-width: 560px; margin: 24px auto; background: #fff;
      border: 1px solid #d8d3c8; padding: 24px 28px; }
    ol { padding-left: 22px; }
    li { border: 1px dashed #b0342a; margin: 6px 0; padding: 2px 6px; }
  </style>
</head>
<body>
  <div class="wrap">
    <ol>
      <li>前端基础</li>
      <li>HTML 结构与语义标签</li>
      <li>页面排版与移动端适配</li>
      <li>进阶技能</li>
      <li>把列表和链接组合成导航</li>
    </ol>
  </div>
</body>
</html>

对照上面 v3 的效果图:那本来该缩进一格、属于"前端基础"之下的两条,现在被拍平成了和"前端基础"同级的 2、3、5 号。修复只有一步------把这几条 <li> 用一个新的 <ul> 包起来,塞回父 <li> 里面。

把字写在 li 外面,浏览器当场不收

另一个高频手误:写着写着,把某句话打在了 <li> 结束标签之后、</ul> 之前。这行裸字不属于任何列表项,浏览器会把它当成列表外的一段普通文本,常常挤在最奇怪的位置。规则很简单:列表里的每一条文字,必须在 <li> 的开闭标签中间

下面这份就是把一句话落在了列表结构里的正确写法:凡是补充说明,要么进 <li> 里,要么整段移到 </ul> 之后当普通 <p>,绝不能悬在 <ul> 内、<li> 外。

Plaintext 复制代码
<!-- 《100天精通HTML基础入门》Day 16 · 平头哥 · 技术改变世界,勤奋改变人生 -->
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>技能清单 · li 内容收口对照</title>
  <style>
    /* 每条技能连同它的说明,整体留在同一个 li 里 */
    /* 全局说明移出列表,用 p 独立成段,不污染清单结构 */
    * { box-sizing: border-box; }
    body { font-family: "Microsoft YaHei", sans-serif; background: #f7f5ef;
      color: #24292f; margin: 0; line-height: 1.7; }
    .wrap { max-width: 560px; margin: 24px auto; background: #fff;
      border: 1px solid #d8d3c8; border-radius: 14px; padding: 24px 28px; }
    h1 { font-size: 22px; margin: 0 0 12px; }
    ul { margin: 0; padding-left: 22px; }
    li { font-size: 15px; margin-bottom: 8px; }
    .note { font-size: 13px; color: #6b7280; display: block; }
    .out { margin: 14px 0 0; font-size: 13px; color: #6b7280; }
  </style>
</head>
<body>
  <div class="wrap">
    <h1>我的技能</h1>
    <ul>
      <li>HTML 结构与语义标签<span class="note">含列表、链接的组合</span></li>
      <li>页面排版与移动端适配</li>
      <li>把列表和链接组合成导航</li>
    </ul>
    <p class="out">以上按熟练度排序,持续更新中。</p>
  </div>
</body>
</html>

v4:一组词配解释用 dl,语义才对得上

到这一步清单已经很稳了。但"技能名 + 熟练度"这种一个词配一段解释 的成对信息,用 ul 其实略勉强------它不是并列同类,而是"术语---描述"关系。HTML 给了专门的 <dl>:定义列表。<dt> 是被解释的词,<dd> 是解释。把它当语义收口,读屏器和搜索引擎能准确理解你的结构。

样式代码不用细看,理解为给网页化妆即可,CSS 专栏里会展开。

Plaintext 复制代码
<!-- 《100天精通HTML基础入门》Day 16 · 平头哥 · 技术改变世界,勤奋改变人生 -->
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>技能清单 v4 · dl 语义收口</title>
  <style>
    /* dl 里 dt 是技能名,dd 是熟练度说明,一一对应 */
    /* 一个 dt 后面可跟多个 dd,读屏器会把它俩关联起来 */
    * { box-sizing: border-box; }
    body { font-family: "Microsoft YaHei", sans-serif; background: #f7f5ef;
      color: #24292f; margin: 0; line-height: 1.7; }
    .wrap { max-width: 560px; margin: 24px auto; background: #fff;
      border: 1px solid #d8d3c8; border-radius: 14px; padding: 24px 28px; }
    h1 { font-size: 22px; margin: 0 0 12px; }
    dt { font-size: 16px; font-weight: 700; color: #1b4055; margin-top: 10px; }
    dd { margin: 2px 0 0 0; font-size: 14px; color: #4a5560;
      padding-left: 14px; border-left: 3px solid #ffd166; }
  </style>
</head>
<body>
  <div class="wrap">
    <h1>技能清单</h1>
    <dl>
      <dt>HTML 结构与语义</dt>
      <dd>熟练:标签闭合、嵌套、列表与链接</dd>
      <dt>页面排版</dt>
      <dd>熟练:间距、对齐、留白</dd>
      <dd>在学:移动优先与媒体查询</dd>
    </dl>
  </div>
</body>
</html>

到这里技能清单页做完了:v1 散装段落 → v2 一个 ul → v3 ol 带嵌套 → v4 dl 收口。四个版本每一版都比上一版更接近数据的真实关系,这正是演化式的价值------你不是背四个标签,是学会按"关系"选标签。

为什么列表天生带记号和缩进

停一下讲原理,因为这直接决定你以后敢不敢改它。浏览器对 HTML 有一套内置的默认样式(叫 UA 样式),ulol 一出现,它就自动套上 list-style 记号和一个约 40px 的左内边距。之所以给缩进,是为了让"这是一组"这件事在视觉上立刻成立,不依赖任何 CSS。你写 ul { padding-left: 20px } 那行,是在覆盖浏览器已经帮你做好的事,而不是从零造。

这条机制从 CSS 早期规范起就没变过,不依赖具体版本,长期适用。风险点在于:很多人嫌圆点丑,顺手写一句 ul { list-style: none } 想全页去掉------结果把这一页所有列表的点一起抹了。这一条怎么优雅地控制,是明天 Day 17 的正题。

顺带给一个更新说明:HTML 早期还有 <menu><dir> 两个专门用来做列表的老标签,如今已被 ul 替代、当作过时写法基本不再使用,新代码没必要去碰它;同样地,早年有人用嵌套 <table> 硬凑出列表的缩进和记号,那套做法的语义替代方案就是今天这组 ul/ol/dl。之所以强调"替代",是因为它们都能跑、不报错,和 Day 15 复盘里那批"能跑但不对"的旧习惯是同一类陷阱------正确性要靠语义,不靠肉眼看着像。

还有一个容易被忽略的边界:嵌套列表能套多深没有硬性上限,但每多一层,可读性和缩进都会指数级变差,超过两到三层就该换成小标题分节,而不是继续往里塞 ul。这一点属于经验约束,不是规范强制,适用时留意。

今天小结:清单成了,那个点却碍眼

这一页我们做了什么

  • v1:一堆 <p> 手打序号,长得像清单但不是清单;

  • v2:同级无序 → 一个 <ul> 收成一挂,序号缩进交给浏览器;

  • v3:有先后 → <ol>,子清单往里嵌套但每层自带一个 ****ul;

  • v4:词配解释 → <dl>,语义收口。

两个坑各配一个动作:漏一层 ul 会让子项被拉平,补外壳即可;字写在 li 外面会脱离列表,收进 li 或移出 </ul>。下面这张表把四版各自的适用场景一次看全,你对着选就不会错。

版本 标签 内容关系 什么时候用它
v1 <p> 手打 只是过渡,别在正式页里这么写
v2 <ul>+<li> 并列无序 技能、要点、标签云这类同级项
v3 <ol>+<li> 有先后 步骤、排名、学习路径,可再嵌 ul
v4 <dl>+<dt>+<dd> 词配解释 术语表、技能名对熟练度说明

明天 Day 17 我们接着清单往下走:列表前面那个圆点太丑怎么办?用一行 list-style 让它消失,再把无点列表改造成导航的雏形------顺便讲清楚为什么随手一句 ul { list-style: none } 会让全页列表一起遭殃。

参考资料


我是平头哥,技术改变世界,勤奋改变人生。

《100天精通HTML基础入门》每天 20:00 更新,订阅专栏不迷路。

相关推荐
代码青铜z1 小时前
不会写代码做小程序,模板开发和AI 编程靠谱吗?创业前先看这 5 件事
前端
统计学小王子1 小时前
数学建模国赛倒计时 2 天 ——《统计模型精讲(广义线性模型 R 语言实例 + 分析)》
开发语言·数学建模·r语言
小傅哥1 小时前
Java + DDD,1:1 复刻 Deepseek Harness 项目
前端·后端·ai编程
此冬歌咏1 小时前
自动化服务器运维监控系统(python+shell)
linux·运维·服务器·开发语言·python·自动化
积硅步致千里1 小时前
Word 里的 .wmf 其实是 EMF:一次 metafile 转 PNG 排障
前端·后端
mayaairi1 小时前
Vue2 组件通讯(二):ref、自定义事件与provide/inject实战
前端·javascript·vue.js
Cx330❀2 小时前
【Linux网络】深入TCP协议:从滑动窗口到拥塞控制与性能优化全景解析
linux·开发语言·网络·tcp/ip·ai·性能优化·ai编程
开开心心就好2 小时前
PDF图片去水印软件,支持批量处理页面
前端·javascript·人工智能·智能手机·pdf·语音识别
爱敲代码的小杨.2 小时前
【Spring】Spring Web MVC
前端·spring·mvc