用 white-space: pre-wrap 和 word-break: break-word 解决长文本换行,配合 css 计数器与 display: table 实现序号对齐,动态插入需包裹 span,嵌套列表须分层重置计数器和 white-space。

直接用 white-space: pre-wrap 解决换行问题
列表项内容过长时最常见现象是:文字不折行、横向撑破容器、挤压复选框或按钮。这不是因为文本“太长”,而是浏览器默认把所有空白符(包括换行)当空格处理,且white-space: normal会丢掉原始换行,white-space: pre又拒绝折行。
唯一兼顾保留用户换行符和自动折行的方案是:
.custom-ol li {
white-space: pre-wrap;
word-break: break-word;
}
-
pre-wrap原样保留\n、\t和空格,同时允许在右边界自动断行 -
word-break: break-word(等价于overflow-wrap: break-word)确保连续无空格字符串(如长 URL、base64 片段)也能折行 - 必须配合固定宽度约束,比如
max-width: 400px或父容器设width,否则浏览器不知道在哪折 - 别和
text-overflow: ellipsis混用——pre-wrap不支持省略号,加了也无效
避免序号与文本错位:用 CSS 计数器 + display: table
如果移除了 <ol></ol> 默认的 padding-inline-start,常出现两个问题:序号被裁切、多行文本首行缩进不齐。这是因为原生序号是“装饰性”的,不参与文档流,无法对齐换行后的第二行。
可靠解法是关闭原生序号,用 CSS 计数器生成,并借助表格布局让序号单元格自适应宽度:
.custom-ol {
padding-inline-start: 0;
list-style: none;
counter-reset: custom-counter;
}
.custom-ol li {
display: table-row;
counter-increment: custom-counter;
}
.custom-ol li::before {
content: counter(custom-counter) '.';
display: table-cell;
text-align: end;
padding-inline-end: 4px;
width: 1px; /* 关键:触发最小内容宽度,100000 项也不挤 */
}
- 无需改 HTML 结构,仍用语义化
<ol></ol>和<li>,屏幕阅读器能正确播报序号 -
width: 1px是核心技巧,它让浏览器按实际内容撑开列宽,超长序号(如start="99999")不会挤压文本 - 不要用
flex或grid模拟序号列——它们需要预设宽度,无法响应式适配任意长度编号
动态插入长文本时,别用 textContent 直接塞
JavaScript 动态创建列表项时,如果直接用 li.textContent = longString,生成的是纯文本节点,无法被 white-space 或 overflow 控制——CSS 只作用于元素,不作用于文本节点本身。
正确做法是把文本包裹进一个内联或块级元素:
const li = document.createElement('li');
const span = document.createElement('span');
span.textContent = longString;
span.className = 'list-item-text'; // 对应 .list-item-text { white-space: pre-wrap; }
li.appendChild(span);
- 包裹后才能施加
white-space、max-width、overflow等样式 - 若需单行截断加省略号,必须用
display: inline-block+white-space: nowrap+text-overflow: ellipsis+ 明确max-width - 避免用
innerHTML插入未转义内容,防止 XSS;优先用textContent赋值给子元素
嵌套有序列表里长文本更难搞,得逐层控制
嵌套 <ol></ol> 中,子列表项的缩进、序号格式、文本换行会叠加影响。比如 type="a" 的子项 + 长文本,容易出现序号和文字不对齐、换行后悬挂缩进过大等问题。
关键点在于分层重置样式:
ol ol {
counter-reset: inner-counter;
}
ol ol li {
counter-increment: inner-counter;
}
ol ol li::before {
content: counter(outer-counter) '.' counter(inner-counter) '.';
/* 注意:外层计数器需在上一级定义并递增 */
}
- 每层都用独立计数器,避免
value属性硬编码导致嵌套错乱 - 嵌套项的
white-space必须显式继承或重设,不能依赖父级 cascade,某些浏览器对嵌套pre-wrap支持不一致 - 如果子列表项有图标或复选框,建议统一用
display: table方案,否则flex嵌套易因align-items导致基线偏移
最易被忽略的是:嵌套层级越深,序号宽度增长越快,但 table-cell 的 width: 1px 依然有效——这点比任何 padding-left 手动计算都可靠。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











