连字符断行
hyphens
难题
设计师迷恋文本的两端对齐效果。不过在网页中,两端对齐却极少使用。因为在对文本进行两端
对齐处理时,需要调整单词的间距,此时会出现“单词孤岛”现象。这个结果不仅看起来很糟糕,而且损伤了可读性。
以前,有一些在网页上实现连字符断行的方法,但这类方法完全是“伤敌八百,自损一千” 。常见的方法包括服务器端预处理、JavaScript后期处理、用在线生成器单独处理,甚至还有开发者耐着性子在单词中纯手工插入软连字符(­
)。
解决方案
CSS 文本(第三版)引入了一个新的属性hyphens
。它接受三个值:none、manual 和 auto。
manual 是它的初始值,需要人工插入软连字符(­
);
none 会禁用这种行为;
auto会自动断行
1 | huphens: auto; |
如果需要更细粒度地控制连字符的行为(比如在简短的引文中),你仍然可以通过一些软连字符(­
)来辅助浏览器进行断词。hyphens
属性会优先处理它们,然后再去计算其他可以断词的地方。
插入换行
伪元素、white-space
难题
通过CSS来插入换行的需求通常与定义列表有关,但有时也涉及其他场景。在通常情况下,采用定义列表是标签语义化。
举例来说,考虑下面这段结构代码:
1 | //HTML |
不过,由于这些<dt>
和<dd>
都是块级元素,我们最终得到的往往是下图,所有的名和值均独占一行
解决方案
基本上,我们需要做的只是在每个<dd>
后面添加一个换行。如果不在乎使用表现型的结构标记,可以请出老套的<br>
元素,比如这样:
1 | <!-- 如果你这样写,天崩地裂万劫不复 --> |
这种方法不仅在可维护性方面是一种糟糕的实践,而且污染了结构层的代码。
只要能使用生成性内容来添加换行,并以此取代<br>
元素,那么问题就可以解决了!
实际上,有一个Unicode字符是专门代表换行符的:0x000A。在CSS中,这个字符可以写作”\000A”,或简化为”\A”。我们可以用它来作为::after伪元素的内容,并将其添加到每个<dd>
元素的尾部
1 | dd::after { |
这样做还是不行,默认情况下(块级元素前后自带换行符),这些换行符会与相邻的其他空白符进行合并。
我们希望保留源代码中的这些空白符和换行,会用到white-space: pre
。
1 | dt, dd { display: inline; } |
文本行的斑马条纹
CSS 渐变,background-size,“条纹背景”,“灵活的背景定位”
难题
我们最常用:nth-child()/:nth-of-type()
来解决的一个需求就是表格的“斑马条纹”。
当我们想把表格行的这种效果应用到文本行时,仍然有些力不从心。
解决方案
我们可以在CSS 中用渐变直接生成背景图像,而且可以用em单位来设定背景尺寸,这样背景就可以自动适应font-size 的变化了。
1 | padding:.5em; |
这里有一个严肃的小问题不可忽视:代码行和条纹是错位的,破坏了整体效果。这是怎么回事?
第一条条纹是从容器的最顶部开始的,这是背景图像最平常的表现。不过,我们的代码并不是
从那里开始的,因为那样排版会显得很局促。如你所见,我们对容器应用了.5em 的内边距,这个距离正是这些条纹与理想位置之间的偏差。
background-origin
这个属性正是我们所需要的:它可以告诉浏览器在解析background-position
时以content box
的外沿作为基准,而不是默认的padding box
外沿。
1 | padding: .5em; |
调整Tab的宽度
tab-size
难题
包含大量代码的网页(比如文档或教程)在样式上面对着无法回避的挑战。我们通常使用<pre>
和<code>
元素来显示代码,人们在网页中却常常有意避开tab。这是因为浏览器会把其宽度显示为 8 个字符!
解决方案
在CSS3中,一个新的CSS属性tab-size
可以控制这个情况。这个属性接受一个数字(表示字符数)或者一个长度值(这个不那么实用)。我们通常希望把它设置为4(表示 4 个字符的宽度)或
2。
1 | pre{ |
连字
暂时看不出对中文语境的影响
华丽的&符号
麻烦而用处不大
自定义下划线
CSS渐变、background-sizetext-shadow、“条纹背景”
难题
尽管默认样式text-decoration
很实用,但往往太过扎眼,更不要提在不同浏览器下的渲染效果大相径庭。
尽管用border-bottom
模拟出来的文本下划线给予了我们对颜色、线宽、线型的控制能力,但它并不完美,这些“下划线”跟文本之间的空隙很大,位置甚至比字形的降部(descender)还
要低,并且也会阻止正常的文本换行行为。box-shadow
和其有一样的缺点。
解决方案
最佳方案来自于background-image
及其相关属性。
1 | background:linear-gradient(gray,gray) no-repeat; |
请注意下划线会穿过某些字母(比如p和y)的降部。如果下划线在遇到字母时会自动断开避让,那效果看起来岂不是更好?
假如背景是一片实色,就可以设置两层与背景色相同的text-shadow
来模拟这种效果。
1 | background:linear-gradient(gray,gray) no-repeat; |
使用渐变来实现下划线的高明之处在于,这些线条极为灵活。举例来说,如果要生成一条虚线下划线
1 | background:linear-gradient(90deg,gray 66%,transparent 0) repeat-x; |
下面是我自己的曲线版
1 | background:linear-gradient(45deg,transparent 45%,gray 0,gray 55%,transparent 0) repeat-x, |
下面的官方版:
1 | background: linear-gradient(-45deg, transparent 40%, red 0, red 60%, transparent 0) 0 1em, |
现实中的文字效果
基本的text-shadow
难题
在网页中,对文字进行艺术加工已经变得非常普遍了,比如凸版印刷效果,当鼠标悬停时的模糊效果,浮雕(伪3D)效果
凸版印刷效果
这种效果尤其适用于中等亮度背景配上深色文字的场景;但它也可用于深色底、浅色字的场景,只要文字不是黑色并且背景不是纯黑或纯白就行。
浅底深字
当我们在浅色背景上使用深色文字时,在底部加上浅色投影通常效果最佳。到底要多浅,取决于你用的是什么颜色,以及你期望最终效果有多明显,因此需要反复尝试其透明度以达到满意效果。我们最终敲定为 80% 不透明度的白色
1 | background: hsl(210, 13%, 60%); |
深底浅字
给文字顶部加深色投影是最佳方案
1 | background: hsl(210, 13%, 40%); |
空心字效果
流传最广的方法就是使用多个text-shadow
,分别为这些投影加上不同方向的少量偏移,就像这样
1 | background:deepink; |
文字外发光效果
在某些类型的网站中,文字外发光效果常用于凸显标题,或给链接添加鼠标悬停效果。
这种方法有一个最简单的版本:
你只需要准备几层重叠的text-shadow
即可,不需要考虑偏移量,颜色也只需跟文字保持一致。
1 | a{ |
这个效果还可以做得更炫。如果你在:hover状态下把文字本身隐藏掉,那它看起来真的就像在慢慢变模糊。
1 | a{ |
不过你要牢记一点,依赖text-shadow
来实现文字显示的做法无法实现平稳退化:如果浏览器不支持text-shadow
,那就什么字也看不见了。
1 | a{ |
文字凸起效果
text-shadow
难题
另一种在拟物化风格的网站中流行的效果是文字凸起(伪3D)效果。
这其中的主要思路就是:
使用一长串累加的投影,不设模糊并以1px 的跨度逐渐错开,使颜色逐渐变暗,然后在底部加一层强
烈模糊的暗投影,从而模拟完整的立体效果。
1 | background: #58a; |
这种繁琐冗长的代码正是 CSS 预处理器的 mixin 功能所要解决的问题。我们在SCSS 中可以这样来做:
1 | @mixin text-3d($color: white, $depth: 5) { |
这种效果还有很多变种。比如把所有的投影都设成黑色,并且去掉最底层的投影,就可以模拟出一种在复古标志牌中常见的文字效果:
1 | color: white; |
环形文字
基本的SVG