列表 - 学习 Web 开发
无序列表
无序列表用于标记列表项目顺序无关紧要的列表——让我们以购物清单为例。
豆浆
油条
豆汁
焦圈
每份无序的清单从
- 元素开始,需要包裹清单上所有被列出的项目:
- (list item,列表项)元素把每个列出的项目单独包裹起来:
html
- 豆浆
- 油条
- 豆汁
- 焦圈
主动学习:标记无序列表
尝试编辑下面的运行实例来创建一个 HTML 无序列表。
实时输出
可编辑代码
按 ESC 退出编辑区域,按 Tab 可插入制表符
'\t'豆浆
油条
豆汁
焦圈
html {
font-family: sans-serif;
}
h2 {
font-size: 16px;
}
.a11y-label {
margin: 0;
text-align: right;
font-size: 0.7rem;
width: 98%;
}
body {
margin: 10px;
background: #f5f9fa;
}
const textarea = document.getElementById("code");
const reset = document.getElementById("reset");
const solution = document.getElementById("solution");
const output = document.querySelector(".output");
const code = textarea.value;
let userEntry = textarea.value;
function updateCode() {
output.innerHTML = textarea.value;
}
const htmlSolution =
"
- \n
- 豆浆 \n
- 油条 \n
- 豆汁 \n
- 焦圈 \n
let solutionEntry = htmlSolution;
reset.addEventListener("click", () => {
textarea.value = code;
userEntry = textarea.value;
solutionEntry = htmlSolution;
solution.value = "显示答案";
updateCode();
});
solution.addEventListener("click", () => {
if (solution.value === "显示答案") {
textarea.value = solutionEntry;
solution.value = "隐藏答案";
} else {
textarea.value = userEntry;
solution.value = "显示答案";
}
updateCode();
});
textarea.addEventListener("input", updateCode);
window.addEventListener("load", updateCode);
// 阻止制表键跳出文本区域
// 而是在光标位置输出制表符
textarea.onkeydown = (e) => {
if (e.code === "Tab") {
e.preventDefault();
insertAtCaret("\t");
}
if (e.code === "Escape") {
textarea.blur();
}
};
function insertAtCaret(text) {
const scrollPos = textarea.scrollTop;
let caretPos = textarea.selectionStart;
const front = textarea.value.substring(0, caretPos);
const back = textarea.value.substring(
textarea.selectionEnd,
textarea.value.length,
);
textarea.value = front + text + back;
caretPos += text.length;
textarea.selectionStart = caretPos;
textarea.selectionEnd = caretPos;
textarea.focus();
textarea.scrollTop = scrollPos;
}
// 每次用户更新文本区域代码时,更新已保存的 userCode
textarea.onkeyup = () => {
// 我们只想在显示用户代码时保存状态,
// 而不是保存解答,因此解答不会保存在用户代码上
if (solution.value === "显示答案") {
userEntry = textarea.value;
} else {
solutionEntry = textarea.value;
}
updateCode();
};
有序列表
有序列表需要按照项目的顺序列出来——让我们以一组方向指示为例:
沿这条路走到头
右转
直行穿过第一个十字路口
在第三个十字路口处左转
继续走 300 米,学校就在你的右手边
这个标记的结构和无序列表一样,除了需要用
- 元素而不是
- 沿这条路走到头
- 右转
- 直行穿过第一个十字路口
- 在第三个十字路口处左转
- 继续走 300 米,学校就在你的右手边
- 沿这条路走到头
- 右转
- 直行穿过第一个十字路口
- 在第三个十字路口处左转
- 继续走 300 米,学校就在你的右手边
- 去骨鸡胸肉:一斤八两
- 干红辣椒:八钱
- 炸花生米:一两五钱
- 花椒粒:两大匙
- 葱:两根(切段)
- 蛋白:一个
- 淀粉:三大匙
- 酱油:两大匙
- 蒜末:半茶匙
- 糖:半茶匙
- 白醋:一茶匙
- 色拉油:适量
- 盐:两茶匙
- 先用蛋白一个、盐半茶匙及淀粉两大匙搅拌均匀,调成“腌料”,鸡胸肉切成约一厘米见方的碎丁并用“腌料”搅拌均匀,腌渍半小时。
- 用酱油一大匙、淀粉水一大匙、糖半茶匙、盐四分之一茶匙、白醋一茶匙、蒜末半茶匙调拌均匀,调成“综合调味料”。
- 鸡丁腌好以后,色拉油下锅烧热,先将鸡丁倒入锅内,用大火快炸半分钟,炸到变色之后,捞出来沥干油汁备用。
- 在锅里留下约两大匙油,烧热后将切好的干辣椒下锅,用小火炒香后,再放入花椒粒和葱段一起爆香。随后鸡丁重新下锅,用大火快炒片刻后,再倒入“综合调味料”继续快炒。
- 如果你采用正宗川菜做法,最后只需加入花生米,炒拌几下就可以起锅了。
- 如果你在北方,可加入黄瓜丁、胡萝卜丁和花生米,翻炒后起锅。
-
先用蛋白一个、盐半茶匙及淀粉两大匙搅拌均匀,调成“腌料”,鸡胸肉切成约一厘米见方的碎丁并用“腌料”搅拌均匀,腌渍半小时。
-
用酱油一大匙、淀粉水一大匙、糖半茶匙、盐四分之一茶匙、白醋一茶匙、蒜末半茶匙调拌均匀,调成“综合调味料”。
-
鸡丁腌好以后,色拉油下锅烧热,先将鸡丁倒入锅内,用大火快炸半分钟,炸到变色之后,捞出来沥干油汁备用。
-
在锅里留下约两大匙油,烧热后将切好的干辣椒下锅,用小火炒香后,再放入花椒粒和葱段一起爆香。随后鸡丁重新下锅,用大火快炒片刻后,再倒入“综合调味料”继续快炒。
- 如果你采用正宗川菜做法,最后只需加入花生米,炒拌几下就可以起锅了。
- 如果你在北方,可加入黄瓜丁、胡萝卜丁和花生米,翻炒后起锅。
-
先用蛋白一个、盐半茶匙及淀粉两大匙搅拌均匀,调成“腌料”,鸡胸肉切成约一厘米见方的碎丁并用“腌料”搅拌均匀,腌渍半小时。
-
用酱油一大匙、淀粉水一大匙、糖半茶匙、盐四分之一茶匙、白醋一茶匙、蒜末半茶匙调拌均匀,调成“综合调味料”。
-
鸡丁腌好以后,色拉油下锅烧热,先将鸡丁倒入锅内,用大火快炸半分钟,炸到变色之后,捞出来沥干油汁备用。
-
在锅里留下约两大匙油,烧热后将切好的干辣椒下锅,用小火炒香后,再放入花椒粒和葱段一起爆香。随后鸡丁重新下锅,用大火快炒片刻后,再倒入“综合调味料”继续快炒。
-
如果你采用正宗川菜做法,最后只需加入花生米,炒拌几下就可以起锅了。
- 如果你在北方,可加入黄瓜丁、胡萝卜丁和花生米,翻炒后起锅。
-
- (description term,描述术语)元素包裹。每个描述都用
- (description definition,描述定义)元素包裹。
描述列表示例
让我们来完成下面的标记例子:
html
- 内心独白
-
戏剧中,某个角色对自己的内心活动或感受进行念白表演,这些台词只面向观众,而其他角色不会听到。
- 语言独白
-
戏剧中,某个角色把自己的想法直接进行念白表演,观众和其他角色都可以听到。
- 旁白
-
戏剧中,为渲染幽默或戏剧性效果而进行的场景之外的补充注释念白,只面向观众,内容一般都是角色的感受、想法、以及一些背景信息等。
浏览器的默认样式会在描述列表的术语及其定义之间产生缩进。
单个术语的多个描述
请注意,一个术语可以同时有多个描述,例如:
html
- 旁白
-
戏剧中,为渲染幽默或戏剧性效果而进行的场景之外的补充注释念白,只面向观众,内容一般都是角色的感受、想法、以及一些背景信息等。
-
写作中,指与当前主题相关的一段内容,通常不适于直接置于内容主线中,因此置于附近的其他位置(通常位于主线内容旁边一个文本框内)。
主动学习:标记一组定义
现在是时候尝试一下描述列表了。在输入区域的原始文本里添加相应的元素,使得它在输出区域是以描述列表的形式出现。如果你喜欢,你也可以使用你自己的描述术语和描述。
如果你做错了,你可以随时点击重置按钮。如果实在进行不下去,可以点击显示答案。
实时输出
可编辑代码
按 ESC 退出编辑区域,按 Tab 可插入制表符
'\t'培根
整个世界的粘合剂。
鸡蛋
一块蛋糕的粘合剂。
咖啡
一种浅棕色的饮料。
可以在清晨带来活力。
html {
font-family: sans-serif;
}
h2 {
font-size: 16px;
}
.a11y-label {
margin: 0;
text-align: right;
font-size: 0.7rem;
width: 98%;
}
body {
margin: 10px;
background: #f5f9fa;
}
const textarea = document.getElementById("code");
const reset = document.getElementById("reset");
const solution = document.getElementById("solution");
const output = document.querySelector(".output");
const code = textarea.value;
let userEntry = textarea.value;
function updateCode() {
output.innerHTML = textarea.value;
}
const htmlSolution =
"
- \n
- 培根 \n
- 整个世界的粘合剂。 \n
- 鸡蛋 \n
- 一块蛋糕的粘合剂。 \n
- 咖啡 \n
- 一种浅棕色的饮料。 \n
- 可以在清晨带来活力。 \n
let solutionEntry = htmlSolution;
reset.addEventListener("click", () => {
textarea.value = code;
userEntry = textarea.value;
solutionEntry = htmlSolution;
solution.value = "显示答案";
updateCode();
});
solution.addEventListener("click", () => {
if (solution.value === "显示答案") {
textarea.value = solutionEntry;
solution.value = "隐藏答案";
} else {
textarea.value = userEntry;
solution.value = "显示答案";
}
updateCode();
});
textarea.addEventListener("input", updateCode);
window.addEventListener("load", updateCode);
// 阻止制表键跳出文本区域
// 而是在光标位置输出制表符
textarea.onkeydown = (e) => {
if (e.code === "Tab") {
e.preventDefault();
insertAtCaret("\t");
}
if (e.code === "Escape") {
textarea.blur();
}
};
function insertAtCaret(text) {
const scrollPos = textarea.scrollTop;
let caretPos = textarea.selectionStart;
const front = textarea.value.substring(0, caretPos);
const back = textarea.value.substring(
textarea.selectionEnd,
textarea.value.length,
);
textarea.value = front + text + back;
caretPos += text.length;
textarea.selectionStart = caretPos;
textarea.selectionEnd = caretPos;
textarea.focus();
textarea.scrollTop = scrollPos;
}
// 每次用户更新文本区域代码时,更新已保存的 userCode
textarea.onkeyup = () => {
// 我们只想在显示用户代码时保存状态,
// 而不是保存解答,因此解答不会保存在用户代码上
if (solution.value === "显示答案") {
userEntry = textarea.value;
} else {
solutionEntry = textarea.value;
}
updateCode();
};
技能测试!
关于 HTML 基本语义元素的三篇文章已经读完,但你还记得最重要的信息吗?你可以找到一些进一步的测试,以验证你在继续前进之前已经保留了这些信息——参见技能测试:HTML 文本基础知识。
总结
列表就到此为止。接下来我们将进行更高层次的讨论。我们已经展示了如何实现一些单个页面的功能,但如何构建整个 HTML 页面呢?接下来将讨论文档结构。
上一页 概述:使用 HTML 构建 Web 下一页
Help improve MDN
Was this page helpful to you?
Yes
No
Learn how to contribute
This page was last modified on 2025年4月30日 by MDN contributors.
View this page on GitHub • Report a problem with this content
- 元素将所有项目包裹:
html
主动学习:标记有序列表
尝试编辑下面的示例来创建一个 HTML 有序列表:
实时输出
可编辑代码
按 ESC 退出编辑区域,按 Tab 可插入制表符
'\t'沿这条路走到头
右转
直行穿过第一个十字路口
在第三个十字路口处左转
继续走 300 米,学校就在你的右手边
html {
font-family: sans-serif;
}
h2 {
font-size: 16px;
}
.a11y-label {
margin: 0;
text-align: right;
font-size: 0.7rem;
width: 98%;
}
body {
margin: 10px;
background: #f5f9fa;
}
const textarea = document.getElementById("code");
const reset = document.getElementById("reset");
const solution = document.getElementById("solution");
const output = document.querySelector(".output");
const code = textarea.value;
let userEntry = textarea.value;
function updateCode() {
output.innerHTML = textarea.value;
}
const htmlSolution = `
let solutionEntry = htmlSolution;
reset.addEventListener("click", () => {
textarea.value = code;
userEntry = textarea.value;
solutionEntry = htmlSolution;
solution.value = "显示答案";
updateCode();
});
solution.addEventListener("click", () => {
if (solution.value === "显示答案") {
textarea.value = solutionEntry;
solution.value = "隐藏答案";
} else {
textarea.value = userEntry;
solution.value = "显示答案";
}
updateCode();
});
textarea.addEventListener("input", updateCode);
window.addEventListener("load", updateCode);
// 阻止制表键跳出文本区域
// 而是在光标位置输出制表符
textarea.onkeydown = (e) => {
if (e.code === "Tab") {
e.preventDefault();
insertAtCaret("\t");
}
if (e.code === "Escape") {
textarea.blur();
}
};
function insertAtCaret(text) {
const scrollPos = textarea.scrollTop;
let caretPos = textarea.selectionStart;
const front = textarea.value.substring(0, caretPos);
const back = textarea.value.substring(
textarea.selectionEnd,
textarea.value.length,
);
textarea.value = front + text + back;
caretPos += text.length;
textarea.selectionStart = caretPos;
textarea.selectionEnd = caretPos;
textarea.focus();
textarea.scrollTop = scrollPos;
}
// 每次用户更新文本区域代码时,更新已保存的 userCode
textarea.onkeyup = () => {
// 我们只想在显示用户代码时保存状态,
// 而不是保存解答,因此解答不会保存在用户代码上
if (solution.value === "显示答案") {
userEntry = textarea.value;
} else {
solutionEntry = textarea.value;
}
updateCode();
};
主动学习:标记我们的食谱
到了这里,你拥有了所有你需要的信息来标记我们的食谱样例。你可以选择创建一份 text-start.html 起始文件的本地拷贝并在本地完成它,或者在下面的可编辑示例中进行。在本地做可能会更好,因为这样你就可以保存你正在做的工作,而如果你把它填到可编辑的例子中,在你下次打开页面时,它就会丢失。各有利弊吧。
实时输出
可编辑代码
按 ESC 退出编辑区域,按 Tab 可插入制表符
'\t'宫保鸡丁的做法
宫保鸡丁,川菜系中的传统名菜,由鸡丁、干辣椒、花生米等炒制而成。由于其入口鲜辣,鸡肉的鲜嫩配合花生的香脆,广受大众欢迎。
相传宫保鸡丁是清朝光绪年间的署理四川总督丁宝桢所发明,是他招待客人时叫家厨煮的菜肴。由于丁宝桢后来被封为东宫少保(太子少保),所以被称为“丁宫保”,而这道菜亦被称为“宫保鸡丁”
原料
去骨鸡胸肉:一斤八两
干红辣椒:八钱
炸花生米:一两五钱
花椒粒:两大匙
葱:两根(切段)
蛋白:一个
淀粉:三大匙
酱油:两大匙
蒜末:半茶匙
糖:半茶匙
白醋:一茶匙
色拉油:适量
盐:两茶匙
做法
先用蛋白一个、盐半茶匙及淀粉两大匙搅拌均匀,调成“腌料”,鸡胸肉切成约一厘米见方的碎丁并用“腌料”搅拌均匀,腌渍半小时。
用酱油一大匙、淀粉水一大匙、糖半茶匙、盐四分之一茶匙、白醋一茶匙、蒜末半茶匙调拌均匀,调成“综合调味料”。
鸡丁腌好以后,色拉油下锅烧热,先将鸡丁倒入锅内,用大火快炸半分钟,炸到变色之后,捞出来沥干油汁备用。
在锅里留下约两大匙油,烧热后将切好的干辣椒下锅,用小火炒香后,再放入花椒粒和葱段一起爆香。随后鸡丁重新下锅,用大火快炒片刻后,再倒入“综合调味料”继续快炒。
如果你采用正宗川菜做法,最后只需加入花生米,炒拌几下就可以起锅了。
如果你在北方,可加入黄瓜丁、胡萝卜丁和花生米,翻炒后起锅。
大千鸡
张大千居加拿大期间,曾按自己喜好改变宫保鸡丁的做法,并传授当地厨师,厨师将之命名为“大千鸡”,以兹纪念。大千鸡与宫保鸡丁不同之处,是使用经细工去皮、出骨、剔膜的鸡腿肉,以干辣椒、豆瓣酱为味,而且不用花生。
>
html {
font-family: sans-serif;
}
h2 {
font-size: 16px;
}
.a11y-label {
margin: 0;
text-align: right;
font-size: 0.7rem;
width: 98%;
}
body {
margin: 10px;
background: #f5f9fa;
}
const textarea = document.getElementById("code");
const reset = document.getElementById("reset");
const solution = document.getElementById("solution");
const output = document.querySelector(".output");
const code = textarea.value;
let userEntry = textarea.value;
function updateCode() {
output.innerHTML = textarea.value;
}
const htmlSolution = `
宫保鸡丁的做法
宫保鸡丁,川菜系中的传统名菜,由鸡丁、干辣椒、花生米等炒制而成。由于其入口鲜辣,鸡肉的鲜嫩配合花生的香脆,广受大众欢迎。
相传宫保鸡丁是清朝光绪年间的署理四川总督丁宝桢所发明,是他招待客人时叫家厨煮的菜肴。由于丁宝桢后来被封为东宫少保(太子少保),所以被称为“丁宫保”,而这道菜亦被称为“宫保鸡丁”
原料
做法
大千鸡
张大千居加拿大期间,曾按自己喜好改变宫保鸡丁的做法,并传授当地厨师,厨师将之命名为“大千鸡”,以兹纪念。大千鸡与宫保鸡丁不同之处,是使用经细工去皮、出骨、剔膜的鸡腿肉,以干辣椒、豆瓣酱为味,而且不用花生。
`;let solutionEntry = htmlSolution;
reset.addEventListener("click", () => {
textarea.value = code;
userEntry = textarea.value;
solutionEntry = htmlSolution;
solution.value = "显示答案";
updateCode();
});
solution.addEventListener("click", () => {
if (solution.value === "显示答案") {
textarea.value = solutionEntry;
solution.value = "隐藏答案";
} else {
textarea.value = userEntry;
solution.value = "显示答案";
}
updateCode();
});
textarea.addEventListener("input", updateCode);
window.addEventListener("load", updateCode);
// 阻止制表键跳出文本区域
// 而是在光标位置输出制表符
textarea.onkeydown = (e) => {
if (e.code === "Tab") {
e.preventDefault();
insertAtCaret("\t");
}
if (e.code === "Escape") {
textarea.blur();
}
};
function insertAtCaret(text) {
const scrollPos = textarea.scrollTop;
let caretPos = textarea.selectionStart;
const front = textarea.value.substring(0, caretPos);
const back = textarea.value.substring(
textarea.selectionEnd,
textarea.value.length,
);
textarea.value = front + text + back;
caretPos += text.length;
textarea.selectionStart = caretPos;
textarea.selectionEnd = caretPos;
textarea.focus();
textarea.scrollTop = scrollPos;
}
// 每次用户更新文本区域代码时,更新已保存的 userCode
textarea.onkeyup = () => {
// 我们只想在显示用户代码时保存状态,
// 而不是保存解答,因此解答不会保存在用户代码上
if (solution.value === "显示答案") {
userEntry = textarea.value;
} else {
solutionEntry = textarea.value;
}
updateCode();
};
如果你感到棘手,你可以随时按下显示答案按钮,或者在我们的 GitHub 仓库上检查 text-complete.html 样例。
嵌套列表
将一个列表嵌入到另一个列表是完全可以的。你可能想让一些子项目列在一级项目之下。让我们从食谱示例中获取第二个列表:
html
由于最后两项与它们的前一项非常密切相关(它们看起来更像该项的子项或选项),将它们编辑成无序列表,并嵌套在该项的子项中可能更合理。就像下面这样:
html
尝试回到上一个实践操作的例子中,并更新第二个列表。
描述列表
描述列表的目的是标记一组项目及其相关描述,如术语和定义或问题和答案。让我们来看一组术语和定义的示例:
内心独白
戏剧中,某个角色对自己的内心活动或感受进行念白表演,这些台词只面向观众,而其他角色不会听到。
语言独白
戏剧中,某个角色把自己的想法直接进行念白表演,观众和其他角色都可以听到。
旁白
戏剧中,为渲染幽默或戏剧性效果而进行的场景之外的补充注释念白,只面向观众,内容一般都是角色的感受、想法、以及一些背景信息等。
描述列表使用与其他列表类型不同的包裹标签——
- ;此外,每一项都用
html
豆浆
油条
豆汁
焦圈
然后就是用