中文排版二三事

中文排版二三事

前段时间一直在折腾中文排版相关的事情,自认为结果还算不错。故开源之,即是Entry.css。这是一个可配置的、更适合阅读的中文文章样式库,可以用来快速搭建中文博客主题或是用于项目文档的样式。在这篇博文中会介绍下在做这个库过程中学到的一些中文排版知识,以及它的特色。

垂直的韵律

Typography大师Robert Bringhurst (The Elements of Typographic Style一书的作者)曾经说:

“Space in typography is like time in music. It is infinitely divisible, but a few proportional intervals can be much more useful than a limitless choice of arbitrary quantities.” 排版中的空间就想音乐中的时间一样。他是无限整除的,但是按比例的间隔比起毫无限制的使用任意大小要有用很多。

在做web开发和设计中经常会用到网格。它即解决了统一性,也避免了我们在排版时纠结那一两个像素的位置摆放。可惜网格只能解决水平方向的排版布局,在垂直方向上一直没有这样的技术,全仰仗设计师大大的美感了。不过最近出现了baselinecss这样的css库,它类似于960 grid,提供了一个css库以及一些psd磨版。它是基于“vertical rhythm”原则设计的库,解决了垂直方向上的排版布局。

Vertical Rhythm可译成垂直的旋律。它的排版思路是垂直方向上各行文字的行高是一个基础数值的n倍,n是正整数。一般情况下,我们会把基础数值设置成基本文字的行高。但是有时这不一定能符合要求。这样的限制可以让文字的布局变的更美观,且易于阅读。特别是对于有很多文字的页面,减少视觉疲劳是很重要的。

上面那个样例采用了14px/28px和21px/28px这两种“字体大小/行高”样式。对于中文来说看起来挺合适。基线之道这篇文章中也提到了另外一种:16px/22px ,28px/33px,40px/44px。可以看到它的基础数值是11px,所以也并不需要拘泥于“基础数值是基本文字的行高”这条。实际上我们需要遵守的规则是:

按照一定比例的间隔,让阅读更加舒适。

这看起来这是一件挺简单的事情,但是实际操作起来还是会有很多问题的。于是涌现了很多相关工具,辅助你开发这样的拥有美妙旋律的网站。例如:

  1. baseliner.js是一个js库帮助你在页面上绘制固定间隔的横线
  2. basehold.it 是一个类似hold.it的服务,可以提供用于绘制横线的css或背景图片
  3. baseline.js是一个js库用于确保外部资源,例如图片的高度是基础数值的n倍。不过这个库还有不少bug

开发时你还会用到些复杂情况:

边距与边框(em与px)

当我们需要设置上下各一像素边框时,就会导致有两像素多余。旋律就会被打破。同样上下padding与margin都会有这个问题。我们可以设置上下padding/margin/border之和为基础数值的正整数倍。

对于基于px单位的情况,这样处理还算比较容易,只是加减法而已。如果你是用em这样的相对单位呢?你的border如果实际上只需要1px,字体大小为14px。那么你需要设置border为1/14em。如果你不想支持旧浏览器,那么你还可以用伪元素after/before来伪装上下border。less代码如下:

.fake-border-top-bottom (@color: #CCC, @width: 1px) {
    position: relative;
    &:before,
    &:after {
        position: absolute;
        z-index: 1;
        content: '';
        width: 100%;
        height: @width;
        background-color: @color;
    }
    &:before {
        top: 0;
        left: 0;
    }
    &:after {
        bottom: 0;
        left: 0;
    }
}

可惜这种方法对img这样没有after/before伪元素的标签不起作用,对于pre、table这样的标签也有些小bug。当然对于固定高度的元素还可以用box-sizing限制死高度。

最后你还会遇到浏览器对于em单位计算不精确导致1像素的偏差。我本来也打算基于em来写entry.css,结果总是遇到chrome浏览器在处理计算时的bug。后来干脆换成了px,当然也损失了对于缩放情况的优化。

外部资源

更多会遭遇的麻烦是外部资源的高度问题。比如你的文章中可以引入图片,恰巧你又不知道高度的确定值,那么很可能图片会打破旋律。对此没有什么特别好的办法,使用js是我能想到的唯一方法。于是基于baseline.js库来设置外部资源的高度,如下:

baseline.init('.entry img, .entry iframe', 28); // 这是standalone版本的baseline.js

其实在我写这篇文章的时候这个库有不少bug,用之前先看下github上别人的pull request。

缩放因子

最后还有个问题,真的仅仅凭借p {line-height: 28px;}一句就可以确保p的行高是28px吗?看这个例子:

p标签中有一个small标签,这时p标签的整体高度是57px,不是行高56px(28px*2)的。这是因为small继承得到行高为28px,然后small与匿名文本一起按照baseline摆放。行高最终是通过一行之上的最高边界与最低边界确定的。而small的文字比匿名文本小,于是计算就可以知道行高就会有可能超过28px。理论上可以计算:(28-14)/2 + 14 + (28-10)/2 = 30,但在safari上实际得到的结果确是29px。对此还没搞明白为什么。后来找到的解决方案是使用“缩放因子”而不是绝对数值,即line-height:2

当然如果有行内元素的行内块高度超过基础数值也会打破旋律。对于这种情况我还没有比较好的解决方案。

样式的优化

Entry.css也考虑到了针对中文阅读做些特殊优化,比如下划线样式。众所周知,下划线有个很严重的问题是:使用某些字体时,下划线会和文字粘在一起。例如中文的“十”字和下划线粘连的时候就会造成“十”和“士”两字难以区分。Entry.css使用了border-bottom来模拟下划线样式。除此之外,对于相邻的两个下划线样式还会设置一些间隔,避免下划线粘连。

如果文字和下划线的颜色一样,人的视觉误差会造成错觉:让人感觉下划线的颜色更深一些。于是Entry.css使用了less css中的lighten方法,降低了下划线的颜色。

对于中文缩近,并没有采用text-indent来实现,因为其默认继承的特性并不是我所期望的。所以采用了如下方法:

.start-with2word () {
    // text-indent: 2em; 避免继承,故不用
    &:before {
        content: '  ';
        display: inline;
    }
}

使用了伪元素before实现了两个中文字的缩近。

Entry.css还提供了“书名号、缩写、着重符、旁注、上下标等等”这样的特殊样式。可以参考下Entry.css的文档

大小与适应性

以前我在写样式的时候觉得一行之上显示的文字应该尽量多,后来发现一行之上的文字太多反而会影响到自己阅读的耐心,让自己的眼睛变的很累。于是我开始思考一行放多少字才算合适。后来我通过纸质书籍找到了一个合适的数值:40。大概统计了身边十本书籍之后,发现一行之上的中文大概都在40字左右。

在写Entry.css之前就已经设计好了它要支持小屏幕,于是在限制宽度的时候都使用了max-width,而不是width。最大宽度设置成了@font-size * 42,在左右各留一个字大小的空间。

对于基础文字大小,我设置成了14px。主要是综合了各种默认字体在各个系统中的样子,觉得14px还算比较均衡的一个数值,再大的话可能会导致在使用特殊字体时变得特别难看。当然你也可以使用typekit、justfont、Typesquare这样的服务,使用在线字体。

自定义

对于这点不做过多说明了。因为Entry.css是基于less写的,所以使用了less提供的变量功能实现了自定义配置功能。Entry.css提供了基础的左、中、右三种布局方式。又因为对于配色这块不太了解,所以移除了最初默认提供的标题背景配色。期待大家可以提供很棒的配色~

最后如果你有什么喜欢的样式,或是觉得需要的功能,更或是发现了bug,请提交issue给我。Feel free to use it~

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏编程

采用DIV+CSS布局对SEO优化有何好处?

DIV+CSS布局,页面代码精简,这一点对XHTML有所了解的都知道。代码精简所带来SEO优化直接好处有两点:一是提高spider爬行效率,能在最短的时间内爬完...

20460
来自专栏DeveWork

WebFont 三宗罪之二:吹毛求疵的WebFont 渲染差异

话说上次发了篇危言耸听的“WebFont 三宗罪”系列之一,今日来讲三宗罪之二:吹毛求疵的WebFont 渲染差异。为什么用上“吹毛求疵”这个修饰词呢?因为Je...

23750
来自专栏星回的实验室

CSS居中方法集锦

这阵一直忙各路笔试面试,心越来越浮躁,也好久没有写些东西。不过也正是这些虐我千百遍的笔试面试题让我愈发地觉得确有必要整理一下知识点,让网上书上看的杂乱无章的东西...

11210
来自专栏葡萄城控件技术团队

基于Html5的Canvas实现的Clocks (钟表)

Canvas是Html5中非常重要的Feature 之一,究竟Canvas的未来会怎么样? 各大巨头有着不同的想法,微软的IE9会全面支持Canvas, Saf...

20860
来自专栏菜鸟前端工程师

html+css学习笔记019-H5响应式布局0自适应布局

40620
来自专栏我分享我快乐

分享-类似谷歌浏览器图标的绘制方法

前言:学生们在学习ps软件的过程中非常的认真与努力,所以对于软件的使用可以说已经很熟练了,可是为什么当我们给学生安排一些原创设计需求的时候,学生却有种无从下手的...

337120
来自专栏九彩拼盘的叨叨叨

第三届 CSS 开发者大会笔记

这次大会于 2016 年 12 月 17 日在广州的天虹酒店举办。演讲嘉宾有大漠,勾三股四等一些业界大牛们。特邀嘉宾有 Andrey Sitnik(PostCS...

13820
来自专栏GIS讲堂

lzugis——Arcgis Server for JavaScript API之自定义InfoWindow(续)

同样的标题后面加了一个括弧,不是为了增减博文数量,而确实是上个功能的完善,标注为续,意思是继续上次的内容,来说说如何自定义InfoWindow。

16930
来自专栏IT大咖说

从UI到AI——移动端H5生成技术漫谈

15150
来自专栏九彩拼盘的叨叨叨

《写给大家看的设计书》摘要与总结

该书适合完全没有设计背景,或在设计方面没有经过正规培训的人。 该书的描述浅显易懂,并且配有很多插图来做描述的说明。阅读起来觉得很轻松。

8130

扫码关注云+社区

领取腾讯云代金券