pre 预格式文本
<pre> 标签用于定义预格式化文本(Preformatted Text)。被 <pre> 包裹的内容会保留源代码中的空格、换行符和制表符等空白字符,按照原始格式进行显示。<pre> 最常见的用途是与 <code> 标签配合,展示代码片段。
前置知识
阅读本节前,建议先了解:blockquote 引用块
基础概念
<pre> 是 "preformatted" 的缩写。在普通的 HTML 文本中,浏览器会将连续的空白字符压缩为单个空格。而 <pre> 元素打破了这一规则——它会忠实地保留文本中的所有空白字符(包括空格、换行和制表符),使文本按照源代码中书写的方式显示。
这使得 <pre> 成为展示需要保持格式的内容的理想选择,例如:
- 计算机代码
- ASCII 艺术
- 纯文本文件内容
- 诗歌(需要保持特定排版)
语法
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>pre 预格式文本示例</title>
</head>
<body>
<h1>pre 标签示例</h1>
<!-- 普通 p 标签:空白被压缩 -->
<p>普通段落中 多个空格会被压缩。</p>
<!-- pre 标签:保留空白字符 -->
<pre>pre 标签中 多个空格会被保留。
第二行
缩进的第三行</pre>
</body>
</html>详细说明
pre 的默认样式
浏览器为 <pre> 提供了以下默认样式:
| 属性 | 默认值(Chrome) | 说明 |
|---|---|---|
| display | block | 块级元素 |
| font-family | monospace | 等宽字体 |
| margin | 1em 0 | 上下外边距 |
| white-space | pre | 保留空白字符 |
| overflow | visible | 默认不裁剪溢出内容 |
monospace 字体
<pre> 默认使用等宽字体(monospace),即每个字符占用相同的宽度。这确保了代码的对齐效果。常见的等宽字体有:Courier New、Consolas、Monaco、Menlo。
pre 与 code 配合使用
<pre> 本身只负责保留格式,不表达"这是代码"的语义。因此,在展示代码片段时,推荐将 <code> 放在 <pre> 内部,形成语义+格式的组合:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>pre 与 code 配合</title>
<style>
pre {
background: #f5f5f5;
padding: 1rem;
border-radius: 4px;
overflow-x: auto;
}
code {
font-family: "Consolas", "Monaco", monospace;
font-size: 0.9rem;
}
</style>
</head>
<body>
<h1>代码展示</h1>
<!-- 推荐:pre 包裹 code,语义和格式都有 -->
<pre><code>function greet(name) {
console.log("你好, " + name + "!");
}
greet("世界");</code></pre>
<!-- 注意:<pre> 内的 <code> 不应有换行 -->
<pre><code>
function greet(name) {
return "Hello, " + name;
}
</code></pre>
</body>
</html>pre 与 code 的换行问题
<pre> 标签内紧邻标签的换行符会被保留。为避免代码块前面出现多余的空行,<pre> 和 <code> 之间不应有换行:
<!-- 不推荐:<pre> 和 <code> 之间有换行,会导致代码块顶部有空行 -->
<pre>
<code>let x = 10;</code>
</pre>
<!-- 推荐:<pre> 和 <code> 紧邻,没有多余换行 -->
<pre><code>let x = 10;</code></pre>pre 中可以包含的内容
<pre> 内部可以包含文本和行内元素,如 <code>、<em>、<strong>、<a>、<span> 等,但不能包含块级元素:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>pre 内的行内元素</title>
<style>
pre { background: #f5f5f5; padding: 1rem; }
</style>
</head>
<body>
<!-- pre 中可以使用行内元素做语法高亮 -->
<pre><code><span style="color: blue;">function</span> <span style="color: #d73a49;">add</span>(a, b) {
<span style="color: #6f42c1;">return</span> a + b;
}</code></pre>
<!-- pre 中也可以包含链接 -->
<pre>更多文档请访问:<a href="https://developer.mozilla.org">MDN Web Docs</a></pre>
</body>
</html><!-- 错误:pre 中不能包含块级元素 -->
<pre>
<p>这是一段文字</p> <!-- 浏览器会提前关闭 pre -->
</pre>overflow 处理
<pre> 中的长文本或代码行可能会超出容器宽度,导致页面出现水平滚动条或内容被截断。这是使用 <pre> 时最常见的问题。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>pre overflow 处理</title>
<style>
body { max-width: 680px; margin: 0 auto; padding: 2rem 1rem; }
/* 方案一:水平滚动(推荐,不截断代码) */
.scroll-pre {
background: #f5f5f5;
padding: 1rem;
border-radius: 4px;
overflow-x: auto; /* 允许水平滚动 */
white-space: pre; /* 保持原始格式 */
}
/* 方案二:自动换行(代码可读性可能降低) */
.wrap-pre {
background: #f5f5f5;
padding: 1rem;
border-radius: 4px;
overflow-x: hidden;
white-space: pre-wrap; /* 在必要时换行 */
word-break: break-all;
}
/* 方案三:保留空白但允许换行 */
.pre-wrap {
background: #f5f5f5;
padding: 1rem;
border-radius: 4px;
white-space: pre-wrap; /* 保留空白,但允许自然换行 */
overflow-x: hidden;
}
</style>
</head>
<body>
<h1>处理 pre 中的长文本</h1>
<h2>方案一:水平滚动</h2>
<pre class="scroll-pre"><code>const result = someVeryLongFunctionName(someVeryLongArgumentName1, someVeryLongArgumentName2, someVeryLongArgumentName3);</code></pre>
<h2>方案二:自动换行</h2>
<pre class="wrap-pre"><code>const result = someVeryLongFunctionName(someVeryLongArgumentName1, someVeryLongArgumentName2, someVeryLongArgumentName3);</code></pre>
<h2>方案三:保留空白但允许换行</h2>
<pre class="pre-wrap"><code>const result = someVeryLongFunctionName(
someVeryLongArgumentName1,
someVeryLongArgumentName2,
someVeryLongArgumentName3
);</code></pre>
</body>
</html>white-space 属性对比
| 值 | 空格 | 换行符 | 自动换行 | 适用场景 |
|---|---|---|---|---|
pre | 保留 | 保留 | 否 | 代码展示(默认值) |
pre-wrap | 保留 | 保留 | 是 | 长文本 + 保持缩进 |
pre-line | 压缩 | 保留 | 是 | 保留换行的普通文本 |
normal | 压缩 | 压缩 | 是 | 普通文本(非 pre) |
nowrap | 压缩 | 压缩 | 否 | 单行显示 |
实战示例
代码展示页面
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>代码展示</title>
<style>
body {
font-family: -apple-system, BlinkMacSystemFont, sans-serif;
max-width: 760px;
margin: 0 auto;
padding: 2rem 1rem;
line-height: 1.6;
}
pre {
background: #282c34;
color: #abb2bf;
padding: 1.25rem;
border-radius: 8px;
overflow-x: auto;
font-size: 0.875rem;
line-height: 1.5;
}
pre code {
font-family: "Fira Code", "Consolas", "Monaco", monospace;
}
/* 语法高亮类 */
.keyword { color: #c678dd; }
.string { color: #98c379; }
.comment { color: #5c6370; font-style: italic; }
.function { color: #61afef; }
.number { color: #d19a66; }
</style>
</head>
<body>
<h1>JavaScript 示例代码</h1>
<p>以下是一个使用 <code>Array.reduce()</code> 方法计算数组总和的示例:</p>
<pre><code><span class="keyword">const</span> numbers = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>];
<span class="comment">// 使用 reduce 计算总和</span>
<span class="keyword">const</span> sum = numbers.<span class="function">reduce</span>((acc, cur) => {
<span class="keyword">return</span> acc + cur;
}, <span class="number">0</span>);
console.<span class="function">log</span>(<span class="string">`总和为:${sum}`</span>); <span class="comment">// 总和为:15</span></code></pre>
<p>这段代码首先定义了一个包含五个数字的数组,然后使用 <code>reduce()</code> 方法对数组进行累加,初始值为 0。</p>
</body>
</html>ASCII 艺术展示
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>ASCII 艺术</title>
<style>
body { max-width: 680px; margin: 0 auto; padding: 2rem 1rem; }
pre.ascii-art {
background: #1a1a2e;
color: #00ff88;
padding: 1.5rem;
border-radius: 8px;
font-size: 0.75rem;
line-height: 1.2;
overflow-x: auto;
}
</style>
</head>
<body>
<h1>ASCII 艺术展示</h1>
<pre class="ascii-art">
___ _ _
/ _ \ _ __ ___ _ __ __ _ __| || |
| |_| | '_ ` _ \| '__/ _` / _` || |_
| _ | | | | | | | | (_| | (_| | _|
|_| |_|_| |_| |_|_| \__,_|\__, |_||
|___/
</pre>
<pre class="ascii-art">
/\_/\
( o.o )
> ^ <
/| |\
(_| |_)
</pre>
</body>
</html>诗歌排版
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>诗歌排版</title>
<style>
body { max-width: 680px; margin: 0 auto; padding: 2rem 1rem; font-family: serif; }
pre.poem {
text-align: center;
font-size: 1.25rem;
line-height: 2;
background: #fafafa;
padding: 2rem;
border-radius: 8px;
}
</style>
</head>
<body>
<h1>静夜思</h1>
<p>作者:李白</p>
<pre class="poem"> 床前明月光,
疑是地上霜。
举头望明月,
低头思故乡。</pre>
</body>
</html>注意事项
HTML 实体转义
在 <pre> 中展示 HTML 标签时,需要对 < 和 > 进行转义,否则浏览器会将它们解析为真正的 HTML 标签:
<!-- 错误:<div> 会被解析为 HTML 元素 -->
<pre><code><div class="box">Hello</div></code></pre>
<!-- 正确:使用 HTML 实体转义 -->
<pre><code><div class="box">Hello</div></code></pre>| 字符 | HTML 实体 | 说明 |
|---|---|---|
< | < | 小于号 |
> | > | 大于号 |
& | & | 和号 |
pre 与 tab 的处理
<pre> 会保留制表符(Tab),但不同编辑器对 Tab 宽度的设置不同,可能导致显示不一致。建议使用空格替代制表符,或通过 CSS 设置 Tab 的显示宽度:
pre {
tab-size: 4; /* 设置 Tab 宽度为 4 个空格 */
tab-width: 4; /* Firefox 兼容 */
-moz-tab-size: 4; /* Firefox 旧版 */
}最佳实践
- 与 code 配合使用:展示代码时,使用
<pre><code>...</code></pre>的组合 - 注意标签换行:
<pre>和<code>之间不要有换行,避免顶部出现空行 - 处理溢出:使用
overflow-x: auto允许水平滚动,避免截断代码 - 转义 HTML 实体:在
<pre>中展示 HTML 代码时,记得转义<、>、& - 选择合适的 white-space:根据内容类型选择
pre、pre-wrap或pre-line - 设置等宽字体:使用可靠的等宽字体栈,确保代码对齐
下一节
继续学习:strong 与 b