- 前端
【免费下载链接】heti
赫蹏(hètí)是专为中文内容展示设计的排版样式增强。它基于通行的中文排版规范而来,可以为网站的读者带来更好的文章阅读体验。
赫蹏(hètí)是一个专为中文内容展示设计的排版样式增强方案,基于《中文排版需求》(CLREQ)等通行中文排版规范实现,可为网站读者带来更符合阅读习惯的文章体验。本文以项目 README.md 为主线,结合仓库源码(lib/与js/目录)与构建配置,完整讲解从"三步接入"到网格排版原理、版式修饰器、黑暗模式以及中西文混排自动美化的全链路实践,读完即可直接在你的站点上落地一套高质量的中文排版。
项目概览:为什么需要一套"中文排版增强"
西文排版有成熟的 CSS 生态,而中文内容在默认浏览器样式下往往存在标点悬挂缺失、中西文间距失衡、行宽失当、列表序号不符合中文习惯等问题。赫蹏正是为此而生:它不是 CSS 框架,也不是组件库,而是以class="heti"为根的排版样式增强层,在页面既有语义结构上叠加一套贴合中文排版规范的美化样式。
仓库入口文件 lib/heti.scss 中,所有样式都被封装进#{$root-selector}(默认.heti)作用域内,并按三个层次组织:
- 基础模块:
hetiBase、hetiHeading、hetiList、hetiTable、hetiInline; - 版式修饰器:
hetiFontModifier、hetiColumnModifier、hetiWritingModeModifier、hetiAncientModifier、hetiAnnotationModifier; - 工具类样式:
hetiBlockHelperClasses、hetiInlineHelperClasses、hetiAddOns。
这样的分层意味着:引入赫蹏不会污染全局样式,只作用于你显式标记的容器及其内部元素。
核心特性一览
- 贴合网格的排版:以"标准行高 + 标准字号"为网格单位推导所有垂直/水平间距;
- 全标签样式美化:
h1~h6、p、ul/ol/dl、table、blockquote、pre、a、em、mark等均有规范样式; - 预置古文、诗词样式:
heti--ancient、heti--poetry修饰器; - 预置多种排版样式:行间注(
heti--annotation)、多栏(heti--columns-*)、竖排(heti--vertical)等; - 多种预设字体族(仅限桌面端):黑体、宋体、楷体及混排的 "classic" 方案;
- 简/繁体中文支持:内置大陆、台湾两套标点规范可切换;
- 自适应黑暗模式:跟随系统
prefers-color-scheme或手动指定; - 中西文混排美化:基于 JavaScript 自动在 CJK 与 ANS 字符间插入间距,不再手敲空格;
- 全角标点挤压:基于 JavaScript 自动调整标点相邻间距;
- 兼容normalize.css、CSS Reset等常见样式重置;
- 移动端支持。
快速上手:三步接入赫蹏
第一步:引入样式文件
在页面<head>中引入heti.css(CDN 方式):
<link rel="stylesheet" href="//unpkg.com/heti/umd/heti.min.css">如果希望自托管,可以直接使用本仓库的构建产物。仓库 package.json 的build:style脚本用 Sass 将 lib/heti.scss 压缩编译为umd/heti.min.css(当前版本为0.9.6),_site/目录中也提供了对应的未压缩版 heti.css 可直接参考或部署。
第二步:给容器加上.heti类
在要作用的容器元素上增加class="heti":
<article class="entry heti"> <h1>我的世界观</h1> <p>有钱人的生活就是这么朴实无华,且枯燥</p> …… </article>从 lib/heti.scss 可以看到,.heti根容器会获得:max-width: 42em的行宽限制、16px 默认字号、1.5 倍行高、针对中英文混排的overflow-wrap/hyphens处理,以及后续引入的全部模块样式。也就是说,仅仅加一个类名,段落、标题、列表、表格等常见文章元素就已具备规范的中文排版效果。
第三步(可选):引入增强脚本
中西文自动混排与全角标点挤压依赖 JavaScript 增强:
<script src="//unpkg.com/heti/umd/heti-addon.min.js"></script> <script> const heti = new Heti('.heti'); heti.autoSpacing(); // 自动进行中西文混排美化和标点挤压 </script>Heti类定义在 js/heti-addon.js 中,默认的rootSelector同样是.heti,因此上述代码会扫描页面中所有.heti容器。增强脚本的具体原理见下文专章。
贴合网格的排版:一套"标准单位"推导全部间距
赫蹏排版效果的基石是 lib/_variables.scss 中定义的两套网格单位:
// 垂直方向标准单位 = 标准行高 $std-block-unit: $line-height-size-normal !default; // 16px * 1.5 = 24px // 水平方向标准单位 = 标准字号 $std-inline-unit: $font-size-normal !default; // 16px其中默认$font-size-normal: 16px、$line-height-normal: 1.5、$line-length: 42em(注释明确说明:中文每行展示文字 CPL 建议在 30~50 之间,默认取 42)。
所有模块的边距都由这两个单位推导,而不是散落的魔法数字。以 lib/_base.scss 为例:
blockquote的margin-block-start为$std-block-unit * 0.5(半行),margin-block-end为$std-block-unit(一行),水平缩进为$std-inline-unit * 2;p的margin-block-start: $std-block-unit * 0.5、margin-block-end: $std-block-unit,且中文段落text-align: justify两端对齐,非中文(通过:not(:lang(zh))判定)则回到start对齐;hr的上下外边距同样由$std-block-unit * 2推导;- 容器内首尾元素的外边距会被清零,避免破坏网格节奏。
标题模块 lib/_heading.scss 遵循同样的节奏:标题顶部间距一行、底部半行(margin-block-end: $std-block-unit * 0.5),h1字号 32px / 行高 48px,h224px / 36px,以此类推;相邻标题(如h1 + h2)之间压缩为半行间距,体现信息亲密性。h1~h3中文标题额外增加letter-spacing: 0.05em的微小字距,非中文自动归零。
正是这种"以网格单位推导间距"的做法,让段落、标题、列表、表格之间呈现整齐的行节奏,即 README 中所说的"贴合网格的排版"。
全标签样式美化:中文排版规范在元素级的具体落地
行内元素细节
lib/_inline.scss 是行内样式的主力,许多处理直接映射到中文排版规范:
- 中文引号:
q元素默认使用台湾规范(「」『』),注释说明"默认无论简繁都采用台湾规范,修改只需重新定义变量$chinese-quote-set即可";非中文内容回退到浏览器原生引号; - 中文不斜体:
address、cite、dfn、em等元素默认font-style: normal(中文语境下斜体并非恰当强调手段),仅非中文时显示斜体;em改用加粗强调; small的完美字号:通过font-size: 0.875em实现 12px→11px、14px→12px、16px→14px 的整数化缩放;- 上下标:
sub/sup基于baseline定位并带 0.25em 外边距,避免与相邻汉字粘连; - 带划线元素(
abbr[title]、del、ins、s、u)统一增加 1px 外边距,防止视觉上混为一个元素; mark使用淡黄背景(深色模式自动切换为深色版本),rt注音 0.875em 字号。
列表与表格
lib/_list.scss 处理列表间距与序号样式,并专门兼容 CSS Reset 的污染:当$_css-reset-scheme: "reset"时,会重置被ul, li { list-style: none; }抹掉的 disc/decimal/circle/square 序号;若搭配 normalize.css 则不存在该问题。
lib/_table.scss 为表格设置了table-layout: fixed、居中、1px 边框(深色模式自动调整边框色)、单元格内边距由网格单位推导,caption默认放在表格底部。
与常见样式重置的兼容性
这正是 README 中"兼容normalize.css、CSS Reset"的实现基础:一方面通过 lib/_variables.scss 的$_css-reset-scheme变量预设两套重置方案;另一方面所有样式都作用在.heti作用域内,不会与全局重置规则发生级联冲突,主题自带样式也使用!important在容器首尾元素上清边距,保证任何环境下的可预期表现。
版式修饰器:一行类名切换多种排版
修饰器需要与.heti组合使用(如.heti heti--vertical h1),这是 lib/heti.scss 注释明确的使用约定。
字体族修饰器:黑体 / 宋体 / 楷体 / 传统混排
lib/modifiers/font-stack.scss 提供heti--sans(默认黑体)、heti--serif(宋体)、heti--hei、heti--song、heti--kai以及heti--classic:
--classic是"传统字体"方案:标题用楷体 800 字重、正文用宋体、blockquote/cite/q引用用楷体、表头与说明文字(figcaption、caption、th)用黑体;- 源码注释特别提醒:由于渲染机制等原因,应尽量避免衬线、非衬线字体混排,否则会引起行高不一致的问题。
字体族的背后是 lib/fonts/ 下的_hei.scss、_song.scss、_kai.scss三组@font-face声明,它们不加载任何网络字体,而是通过local()依次回退到各平台的中文字体(如 PingFang、Heiti SC、Microsoft YaHei、Source Han Sans、Noto Sans CJK、SimSun、楷体等),并按 200/400/600/800 字重分别映射系统字体。这也解释了"多种预设字体族(仅限桌面端)"——移动端 WebView 字体资源有限,字体回退主要服务桌面浏览器。
竖排版式:heti--vertical
lib/modifiers/writing-mode.scss 实现竖排:
&--vertical { max-width: none; max-height: $line-length; writing-mode: vertical-rl; letter-spacing: 0.125em; ... }竖排时writing-mode: vertical-rl(从右到左),行宽约束从宽度转移为max-height,标题左对齐,q引号自动切换为竖排引号集(默认台湾规范『』「」)。变量定义在 lib/_variables.scss:$chinese-quote-presets内置cn(GB/T 15834-2011《标点符号用法》)、tw(《重訂標點符號手冊》)、common(部分中文社区如知乎采用的规范)三套引号预设,每套又区分 horizontal/vertical 两套字符;$chinese-quote-set默认取"common",可通过覆写该变量切换简繁引号规范。
多栏版式:heti--columns-*
lib/modifiers/column.scss 支持两种分栏方式,分别由 lib/_variables.scss 中的$column-count-list: (1, 2, 3, 4)与$column-width-list: (16em ... 48em)生成:
- 按列数:
heti--columns-2、heti--columns-3、heti--columns-4(column-count); - 按列宽:
heti--columns-16em、heti--columns-20em直至heti--columns-48em(column-width)。
多栏时取消总行宽限制、column-gap: 2em,段落间距减半并增加首行缩进。
古文与诗词版式:heti--ancient/heti--poetry
lib/modifiers/ancient.scss 提供:
- 两种修饰器共用:正文切换宋体,标题切换楷体 800 字重并居中;标题内的元信息(
heti-meta)在桌面端(min-width: 640px)采取"悬挂"处理,不占据空间、不影响居中; --ancient(古文、文言文、词):段落首行缩进2em;--poetry(诗):段落无缩进、居中显示。
行间注版式:heti--annotation
lib/modifiers/annotation.scss 实现古籍常见的"行间注":
- 段落去掉段间距、首行缩进,行高加大到
$line-height-expanded-ultra: 2.25,为注音与着重号留出空间; em使用text-emphasis: filled circle着重号并置于文字下方(text-emphasis-position: under right),非中文自动取消;- 源码注释记录了实测结论:"着重号不应影响行间距,经测试最小可用行高为 1.7",可见行高取值来自真实排版实验。
工具类样式
除修饰器外,lib/helpers/_block.scss 与 lib/helpers/_inline.scss 还提供仅在.heti内部使用的工具类:
heti-meta:元信息(无缩进,块级);heti-verse:诗节(无缩进、居中);heti-large/heti-x-large/heti-small/heti-x-small:扩展字号(18/20/14/12px);heti-list-latin:拉丁序号有序列表(上层upper-latin,逐层lower-roman→lower-latin);heti-list-han:中文序号列表(cjk-ideographic,逐层decimal→decimal-leading-zero);heti-fn:页脚注样式,含目标高亮;heti-hang:标点悬挂;heti-em:强烈着重号(text-emphasis: filled circle);heti-ruby heti-ruby--inline:内联 Ruby 注音(display: inline-flex; flex-direction: column-reverse),按字拆分使用,不额外占据行高。
自适应黑暗模式
黑暗模式由 lib/_variables.scss 的darkmode-stylemixin 统一驱动,$darkmode变量支持三种取值:
| 取值 | 行为 |
|---|---|
true | 默认:通过@media (prefers-color-scheme: dark)跟随系统自动切换 |
false | 完全禁用黑暗模式样式 |
'manual' | 手动模式:需要配合[data-darkmode="dark"]与[data-darkmode="auto"]选择器(见$manualmode-dark-selector/$manualmode-auto-selector变量) |
主题内所有需要适配深色的颜色(blockquote、hr、table边框、mark、u[title]、sup:target高亮等)都通过@include darkmode-style { ... }包裹。站点演示页 _site/scss/heti.scss 就是手动模式的范例:将$darkmode覆写为'manual'后,页面提供强制深色([data-darkmode="dark"])与跟随系统([data-darkmode="auto"])两条路径,具体实现可对照 _site/scss/index.scss。
中西文混排美化与全角标点挤压:JS 增强原理
autoSpacing()是本项目 JavaScript 增强的核心方法,实现在 js/heti-addon.js 中,基于 DOM 文本遍历库heti-findandreplacedomtext(见 package.json 依赖声明)。它分两个阶段工作。
阶段一:中西文间距(spacing)
对文本节点执行三组正则匹配,命中处用heti-spacing元素包裹并依靠 lib/helpers/_add-on.scss 的样式完成间距:
- 全角字符(CJK)两侧夹 ANS(ASCII 字母/数字/符号)时:包裹
heti-spacing-start heti-spacing-end,前加 0.25em、后加 0.25em; - 行首/行尾与 CJK 相邻的 ANS 片段:分别只加
heti-spacing-start(margin-inline-end: 0.25em)或heti-spacing-end(margin-inline-start: 0.25em)。
正则中的 CJK 与 ANS 字符集覆盖了\u3400-\u9fff等 CJK 统一表意文字、全角标点以及 ASCII 字母数字符号,足以应对常见中西混排场景。
阶段二:全角标点挤压(adjacent)
通过三组"相邻标点"正则,将特定组合用heti-adjacent元素包裹,再配合负边距实现挤压:
- 半角挤压(
heti-adjacent-half,margin-inline-end: -0.5em):停顿号接起始标点(如。后接「)、开引号接开引号、闭引号接停顿/开引号等组合,例如 "他说:「你好。」" 中:与「的组合; - 四分之一挤压(
heti-adjacent-quarter,margin-inline-end: -0.25em):间隔号(·・‧)接开引号、闭引号接间隔号,以及"停顿号接弯引号"(如。“」)与"弯引号接全角开引号"(如“《」)的场景; heti-adjacent基础样式设置了text-spacing-trim: space-all与unicode-bidi: isolate——后者注释说明是为了解决苹方等字体下标点过度挤压的问题。
浏览器兼容与跳过机制
- lookbehind 检测:构造函数会先探测浏览器是否支持正则
(?<=...)后行断言,不支持时自动切换到"无 lookbehind"的正则变体并调整offset(见 js/heti-addon.js); - 跳过元素:
pre、code、sup、sub以及heti-spacing/heti-close元素不参与处理(源码中的HETI_SKIPPED_ELEMENTS); - 手动跳过:给元素添加
heti-skip类即可跳过处理(HETI_SKIPPED_CLASS); - 断行元素:
ins、del、s、a被视为非连续文本上下文(HETI_NON_CONTIGUOUS_ELEMENTS),避免跨元素错误匹配。
rollup.config.js 将其打包为 UMD 产物:umd/heti-addon.min.js(压缩版,移除调试信息)与_site/heti-addon.js(演示站用),全局暴露Heti类,因此使用方式就是new Heti('.heti').autoSpacing()。
构建与定制:从 npm scripts 到 SCSS 变量覆写
构建命令
package.json 的scripts提供完整开发链路:
| 命令 | 作用 |
|---|---|
npm start | Sass 监听模式编译演示站样式 |
npm run compile | Rollup 监听模式编译 JS 增强 |
npm run build:style | 将 lib/heti.scss 压缩编译为umd/heti.min.css |
npm run build:site | 编译演示站样式 |
npm run build:script | Rollup 编译js/heti-addon.js为 UMD 产物 |
npm run build | 依次执行以上三个构建 |
npm test | 通过 stylelint 对lib/**/*.scss做样式规范检查 |
常用自定义变量
由于核心样式全部基于!default变量(见 lib/_variables.scss),你可以覆写它们生成自己的定制版本:
$root-selector:根选择器名(默认.heti);$darkmode:黑暗模式开关(true/false/'manual');$chinese-quote-set:引号规范(cn/tw/common);$line-length:行宽(默认42em);$font-size-normal/$line-height-normal:基础字号与行高;$column-count-list/$column-width-list:分栏修饰器的可选值;$font-family-hei/$font-family-song/$font-family-kai:三大字体族。
覆写方式与演示站一致——先定义变量,再@import "../../lib/heti";(参考 _site/scss/heti.scss)。
结语
赫蹏覆盖了中文长文阅读场景的大部分刚需:网格化排版、全标签美化、诗词/古文/行间注/竖排/多栏等预置版式、简繁引号规范切换、黑暗模式,以及基于 JavaScript 的中西文混排与标点挤压。项目自身的 WIP 清单(见 README.md)也确认了这些能力的完成状态。接入成本仅一行 CSS 加一个类名,增强脚本可选——即便不做任何 JS 处理,仅 CSS 部分也能带来明显的中文阅读体验提升。若你的站点以中文长文为主,赫蹏是一套开箱即用、且可深度定制的排版增强方案。
- 前端
【免费下载链接】heti
赫蹏(hètí)是专为中文内容展示设计的排版样式增强。它基于通行的中文排版规范而来,可以为网站的读者带来更好的文章阅读体验。
相关推荐
赫蹏最佳实践总结:从入门到精通的中文排版增强全攻略
赫蹏最佳实践总结:从入门到精通的中文排版增强全攻略 赫蹏(hètí)是专为中文内容展示设计的排版样式增强工具,基于通行的中文排版规范,可以为网站读者带来更好的文
前端赫蹏JavaScript增强脚本终极解析:自动化中西文混排的实现原理与实战指南
赫蹏JavaScript增强脚本终极解析:自动化中西文混排的实现原理与实战指南 赫蹏(hètí)是专为中文内容展示设计的排版样式增强工具,基于通行的中文排版规范
前端DeBERTa-v3-large奖励模型与其他主流奖励模型的终极对比评测指南
DeBERTa v3 large奖励模型与其他主流奖励模型的终极对比评测指南 在人工智能快速发展的今天, DeBERTa v3 large奖励模型 作为先进的自
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考