说起CSS里的文本垂直排列,很多开发者第一反应可能是旋转或者用一些奇技淫巧。但今天咱们得聊聊那个最根本、最语义化的原生方案——writing-mode属性。它可不是简单地把字“立”起来,而是真正改变了文本流的根本方向。

没错,writing-mode是目前最可靠、语义最清晰的原生CSS方案,它能实现真正的文本流方向切换,而不是靠旋转或Hack手段模拟出来的“假竖排”。
vertical-rl 是中文竖排的默认选择,但别直接套用
writing-mode: vertical-rl确实是中文、日文等传统竖排书写的标准值。不过,这里有个关键点容易被忽略:它不只是改变文字方向,而是会连带翻转整个布局的坐标系。
这意味着:
- 原本控制宽度的
width属性,在视觉上变成了控制高度。 - 原本控制高度的
height属性,在视觉上变成了控制宽度。 - 像
margin-left这样的外边距会出现在元素顶部,而padding-bottom则会出现在右侧。
一个常见的错误就是只给元素加上writing-mode: vertical-rl,却忘了同步调整相关的尺寸和内边距,结果导致容器“缩成一条线”或者文字显示不全。
那正确的做法是什么?
- 显式设置尺寸:明确设定
width和height,并在心里转换它们在新坐标系下的含义。 - 保持汉字直立:使用
text-orientation: upright来确保汉字不会旋转(否则像“一”这样的字就会横着躺下)。 - 理解行高的变化:此时
line-height控制的不再是“行间距”,而是变成了“列间距”。
.poem {
writing-mode: vertical-rl;
text-orientation: upright;
width: 2em; /* 视觉上代表“高度”,即每列有多高 */
height: 20em; /* 视觉上代表“宽度”,即总共有几列 */
line-height: 1.8; /* 此时控制的是列与列之间的间距 */
}
vertical-lr 和 sideways-* 的使用场景很窄,慎用
先说vertical-lr,它实现的是从左向右的竖排。这种排版方式基本上只适用于蒙古文等极少数语言。在普通的中文项目里强行使用,反而会让阅读顺序变得反直觉,不建议尝试。
再看sideways-rl和sideways-lr,这两个值就更特殊了。它们不仅让文本流垂直排列,还会让每一个字符都旋转90度。想象一下,“你好”两个字会变成两个横躺着的字。
这种效果或许在标签、侧边栏标题等装饰性场景中有一席之地,但存在几个硬伤:
- 兼容性差:Firefox 浏览器一直不支持
sideways-*系列值。 - 可读性低:字号稍小一点,识别起来就非常困难。
- 无障碍问题:屏幕阅读器很可能无法正确解析旋转后的字符顺序。
所以,除非设计稿明确要求这种“字横躺、列竖排”的特定效果,否则建议直接绕开这两个属性值。
writing-mode 影响 flex / grid 布局,必须重审容器逻辑
一旦父容器设置了writing-mode: vertical-rl,它内部的所有现代布局模型都会跟着“转向”。
具体来说:
flex-direction: row的含义会变成“从上到下”(也就是视觉上的垂直方向)。grid-template-columns: 1fr 2fr实际控制的变成了“行高的分配”,而不是列宽。justify-content对齐的是水平轴,但在竖排上下文中,这个“水平轴”对应的是页面的垂直方向。
这里最容易踩的坑就是:你想用display: flex让几个竖排的文字块横向并排,结果它们却堆叠成了一列。原因就在于,Flex布局的主轴已经随着writing-mode旋转了90度。
怎么应对呢?
- 如果只是想实现多个竖排段落的并排,使用
display: inline-block或者float: right反而更简单可控。 - 如果非要使用Flex布局,可能需要显式地写上
flex-direction: column(注意,在竖排上下文里,column才对应传统意义上的“横向”)。 - 调试时,可以打开浏览器的开发者工具,勾选“Layout”面板下的“Show flexbox overlays”选项,直观地查看主轴方向。
移动端和打印样式中,writing-mode 的行为更敏感
在移动端环境,比如iOS Safari或Android Chrome里,当writing-mode遇上font-size: small或者页面缩放(zoom)时,可能会出现字符错位、基线偏移,甚至整列文字消失的怪现象。这通常不是CSS的bug,而是不同平台的字体渲染引擎对垂直排版基线的支持存在差异。
几个关键注意事项:
- 慎用相对单位:尽量避免使用
em或rem作为竖排容器的尺寸基准,改用px或ch会更稳妥(是的,在竖排中ch单位依然表示一个汉字的宽度)。 - 打印需谨慎:在打印样式表里,最好默认禁用
writing-mode,除非你非常确定目标打印机驱动支持这种排版方式(事实上多数并不支持)。 - PDF导出有坑:如果需要把内容导出为PDF,像Puppeteer、wkhtmltopdf这类工具对
writing-mode的支持可能不稳定。一个兜底方案是考虑在服务端用Canvas来渲染竖排文字。
说到底,实现竖排真正的难点,不在于加上那行CSS代码,而在于意识到:竖排不是简单地“把字立起来”,它意味着一整套布局体系的重构。从字体、尺寸、盒模型到可访问性,都需要我们重新审视和校准。
