网页排版老翻车?试试用“字行长度”这根线,把布局串起来才舒服

2,376字
10–15 分钟
in

看了一堆设计书,里头老提“字行长度”这词儿,听着玄乎,其实就是一行文字有多长。但别小看它,这玩意儿搁以前那是真家伙事儿。早年间排铅字,工人手里拿个排字尺,那尺子多宽,这行字就得排多长,页面上的边栏、留白、分栏,全得围着这根尺子转。现在虽然不用铅字了,但道理没变,让内容自己去决定布局,比我们对着屏幕瞎猜尺寸要靠谱得多。

目录

摸透字行长度

这概念说白了,就是一行字从脑袋到尾巴跑完的距离。用ch这个CSS单位来量它最合适,因为1ch就等于当前字体下“0”这个数字的宽度,跟文字本身的特性绑得死死的。一般公认,一行字大概60到70个字符读起来最不费劲,所以60ch就成了个万能起点。但得记住,这只是个参考线,换套字体,这线就得跟着挪。比如那种大写字母特别高的字体,看着就显大,60ch就显得老长;字挤一块儿的字体,60ch又显得憋屈。这玩意儿就得靠眼睛收货,边看边调。

实际操作流程

定下全局基准

把根儿上的基准定好,后头所有东西都围着它转,布局就不容易乱套。

  1. 打开样式表,找到:root这个根元素选择器。
  2. 在里面塞进一个自定义属性--measure,值先给个60ch
  3. 别急着完事,找个有长段落文字的页面瞅瞅。如果一行字看着太长,让人脖子都想跟着左右晃,就把--measure往小了改,比如55ch。要是觉得一行字太短,读着感觉句子被剁碎了,就往大了调,比如65ch

锁死文本块宽度

正文区域最怕的就是在大屏幕上一路狂奔,变成一根没完没了的面条。得用这个基准值给它上个枷锁。

  1. 找到负责文章正文的容器,比如article标签。
  2. 给它加上max-inline-size: var(--measure);。这里不用max-width,用max-inline-size更符合逻辑流向,意思是限制它的“行内尺寸”,也就是横向的最大宽度。
  3. 再加个margin-inline: auto;,让这块内容在父容器里自动居中,两边留白就匀称了。

在这个过程中,可能会发现有些地方没被这条规则管到。比如图片说明或者引用块,它们有自己的宽度设置。那就得单独给这些元素也套上这个逻辑,让所有文本块都守规矩。

多栏布局自动分

想让长文自动分成多栏,又不想写死几栏,这里有个偷懒又聪明的法子。

  1. 给容器(比如article)加上column-width: var(--measure);
  2. 浏览器自己就动起来了。当容器够宽,能塞进两个--measure宽的栏,它就自动给你分成两栏。宽到能塞进三个,就分成三栏。要是宽度不够放两栏,它就乖乖变回单栏,压根不用写一堆@media断点。

试的时候会发现,栏和栏之间的间距可能不太对,显得挤。可以顺手加个column-gap属性,给栏之间定个舒服的间隔,比如2rem

网格布局“抱大腿”

做那种一宽一窄的布局时,让宽的那栏内容直接抱住--measure这条大腿,阅读体验就稳了。

  1. 定义一个网格容器,比如<div class="layout">
  2. display: grid; 先把它变成网格。
  3. grid-template-columns: minmax(0, var(--measure)) 1fr; 这句是核心。意思是网格有两列,第一列的最小宽度是0,最大宽度就是--measure,永远不会超过这个舒服的阅读宽度。第二列1fr就是“行,剩下的空间都归我”,自动填满剩余区域。

这里要留意的是minmax(0, var(--measure))里的这个“0”。如果写成minmax(auto, var(--measure)),当旁边那列内容太少时,第一列的内容可能会因为自身的auto宽度而撑开,导致宽度失控。写成0就彻底把控制权交给了--measure

容器查询自动折叠

设备屏幕千奇百怪,与其盯着屏幕宽度瞎猜,不如让组件自己感知自己的“生存环境”来决定怎么摆。

  1. 给一个布局组件,比如<div data-layout="yogi">,设置display: grid; grid-template-columns: 3fr 1fr;,一个主内容区,一个侧边栏。
  2. 想让它窄了就自动变单列,用容器查询盯着它。首先得声明它是个容器:container-type: inline-size;
  3. 然后写查询规则:
    css @container (max-width: var(--measure)) { [data-layout="yogi"] { grid-template-columns: 1fr; } }
    这句话意思是,当这个组件的宽度小于等于--measure(也就是那个舒服的阅读宽度)时,它就把两列的布局改成单列,侧边栏乖乖滚到主内容下面。

用容器查询得确保被查询的元素确实是个容器,别忘了加container-type属性。另外,--measure这个基准值在查询里同样好使,确保了组件何时折叠完全是看内容自己的脸色,不是设备。

多个方案来备用

有时候光一套基准不够用,得准备几套不同尺码的“字行长度”,应付各种场面。

  1. :root里把基准扩展一下:
    css :root { --measure: 60ch; --measure-s: 55ch; --measure-l: 80ch; }
  2. 方案一:给不同角色。正文段落就用--measure。图片下面的小说明,字本来就小,一行太长也难受,可以给它的容器单独设置max-inline-size: var(--measure-s);。开头的导语或者大标题,想让它气派点,可以设置max-inline-size: var(--measure-l);
  3. 方案二:做精细控制。假设有个侧边栏,里面有些简介文字,想把它的宽度控制在短一点的范围。可以直接给侧边栏元素设置max-inline-size: var(--measure-s);。这么一来,页面里每个文本块都有自己的“紧箍咒”,但源头都来自那几套--measure的变体,整个页面的节奏感就统一了。