css揭秘 – 字体排印(二)

这是我参与更文挑战的第10天,活动详情查看: 更文挑战

华丽的&符号

难题

在文学作品的字体排印中,会发现简写的 & 符号备受推崇,但是可以显示出优美 & 字符的字体往往并不适用于页面中的其他文本。毕竟对于标题来说,真正美丽而优雅的效果正是来源于清爽的无衬线字体与华丽的衬线 & 符号之间的对比。

在写代码的过程中,通常会通过脚本或者手动的使用 <span> 标签把每个 & 符号包起来:

 HTML <span class="amp">&amp;</span> CSS
复制代码

然后给 .amp 这个类指定想要的样式:

.amp {
    font-family: Baskerville, "Goudy Old Style",
        Garamond, Palatino, serif;
    font-style: italic;
}
复制代码

可以看到如下效果:

image.png

这个方法可以实现,但是这个方法相当麻烦,而且有时候完全行不通,在某些情况下无法轻易修改 HTML 结构。是否可以让 CSS 去单独的美化某个字符呢?

解决方案

通常会在 font-family 中同时声明多个字体,这样即使指定的最优先字体不可用,也可以回退到其他符合整体风格设计的字体。这个机制对单个字符也是有效的。如果某款字体可用,但只包括某几个字符,那它就会用来显示这几个字符,这个规则对本地字体和 @font-face 引入的嵌入字体都是有效的。

@font-face {
    font-family: Ampersand;
    src: url("fonts/ampersand.woff");
}
h1 {
    font-family: Ampersand, Helvetica, sans-serif;
}
复制代码

上述方法比较灵活,但是对于只想使用系统本地字体的人来说就不够理想了。我们知道, @font-face 规则中的 src 描述符还可以接受 local() 函数用来指定本地字体的名称。

@font-face {
    font-family: Ampersand;
    src: local('Baskerville'),
        local('Goudy Old Style'),
        local('Garamond'),
        local('Palatino');
}
复制代码

但是这些字形又覆盖了所有的字体,并不能起到美化单独字符的作用,还需要一个描述来声明想用这几款本地字体来显示哪些字符。这个描述叫做 unicode-range

unicode-range 描述符只在 @font-face 规则内部生效,可以把字体作用的字符范围限制在一个子集内,这个语法是基于“Unicode码位”的,可使用如下命令在浏览器控制台查看所需要的字符的十六进制码位。

"&".charCodeAt(0).toString(16); // 返回26
复制代码

得到了字符的十六进制码位,然后需要在码位前面加上 U+ 作为前缀。可以这样来声明:

unicode-range: U+26;
复制代码

如果你想指定一个字符区间,还是要加上 U+ 前缀,比如 U+400-4FF 。实际上对于这个区间来说,你还可以使用通配符,以这样的方式来写:U+4?? 。同时指定多个字符或多个区间也允许的,把它们用逗号隔开即可,比如 U+26, U+4??, U+2665-2670

@font-face {
    font-family: Ampersand;
    src: local('Baskerville'),
        local('Goudy Old Style'),
        local('Palatino'),
        local('Book Antiqua');
        unicode-range: U+26,U+21; /*&和!*/
}
h1 {
    font-family: Ampersand, Helvetica, sans-serif;
}
复制代码

最终的呈现效果

image.png

用不同的字体来美化数字、符号、标点等。各种创意完全停不下来!小编使用这种方式解决了需要给有音调的a展示不同的字体的问题!欢迎大家体验~~

自定义下划线

难题

文本的下划线中,后来的 css 给了一种解决方案:

text-decoration: underline;
复制代码

但是,满足不了我们的需要,因此我们将主意打到了下边框上,用边框来模拟下划线。尽管用 border-bottom 模拟出来的文本下划线给予了我们对颜色、线宽、线型的控制能力,但它并不完美。这些“下划线”跟文本之间的空隙很大,位置甚至比字形的降部(descender)还要低!我们可以试着修复这个问题,将这个链接的 display 属性设置为inline-block ,再指定一个稍小的 line-height ,例如说:

display: inline-block;
border-bottom: 1px solid gray;
line-height: .9;
复制代码

这个方法确实可以让下划线向文本贴近,但同时会阻止正常的文本换行行为。我们还可以尝试运用一层内嵌的 box-shadow 来模拟下划线的效果:

box-shadow: 0 -1px gray inset;
复制代码

它跟 border-bottom 存在的问题一样,只不过它显示出来的下划线离文本稍近一些。那么有没有其他办法可以产生即美观又灵活,而且可以定制各种样式的下划线呢?

解决方案

最佳方案来自于 background-image 及其相关属性。背景可以完美地跟随换行的文本,而且可以通过 CSS 渐变来凭空生成所需的图像:

background: linear-gradient(gray, gray) no-repeat;
background-size: 100% 1px;
background-position: 0 1.15em;
复制代码

image.png
但是,下划线会穿过某些字母(比如 p 和 y)的降部。如果下划线在遇到字母时会自动断开避让,因此作如下修改:

background: linear-gradient(gray, gray) no-repeat;
background-size: 100% 1px;
background-position: 0 1.15em;
text-shadow: .05em 0 white, -.05em 0 white;
复制代码

image.png
修改后,下划线遇到有降部的字母后会断开避让

background: linear-gradient(90deg,
                gray 66%, transparent 0) repeat-x;
background-size: .2em 1px;
background-position: 0 1.2em;
复制代码

image.png
虚线下划线

现在 css3 中有对应样式可以实现上述的效果:

  • text-decoration-color 用于自定义下划线或其他装饰效果的颜色。
  • text-decoration-style 用于定义装饰效果的风格(比如实线、虚线、波浪线等)。
  • text-decoration-line 用于线条的样子,删除线下划线等等。
  • text-underline-position 用于微调下划线的具体摆放位置。

现实中的文字效果

难题

在网页中,对文字进行艺术加工已经变得非常普遍了,比如凸版印刷效果,当鼠标悬停时的模糊效果,浮雕(伪 3D)效果,等等。要达成这些效果,会用到一系列精心排列的文本投影,并且需要明白我们的眼睛是如何工作的,因为这些手段往往建立在视错觉的基础上。

解决方案

凸版印刷效果

background: hsl(210, 13%, 40%);
color: hsl(210, 13%, 75%);
text-shadow: 0 -1px 1px black;
复制代码

image.png
空心字效果

<style>
    h1 {
        font: 300%/1 Rockwell, serif;
        background: pink;
        color: white;
    }

    h1 text {
        fill: currentColor;
    }

    h1 svg {
        overflow: visible
    }

    h1 use {
        stroke: green;
        stroke-width: 6;
        stroke-linejoin: round;
    }
</style>
<h1><svg width="2em" height="1.2em">
    <use xlink:href="#css" />
    <text id="css" y="1em">空心字效果</text>
</svg></h1>
复制代码

image.png
文字外发光效果

<style>
    a {
        background: #203;
        color: white;
        transition: 1s;
        text-shadow: 0 0 .1em, 0 0 .3em;
    }
    a:hover {
        filter: blur(.1em);
    }
</style>
<a href="#">文字外发光效果</a>
复制代码

image.png
文字凸起效果

background: #58a;
color: white;
text-shadow: 0 1px hsl(0,0%,85%),
             0 2px hsl(0,0%,80%),
             0 3px hsl(0,0%,75%),
             0 4px hsl(0,0%,70%),
             0 5px hsl(0,0%,65%),
             0 5px 10px black;
复制代码

image.png
SCSS 中的 mixin 写法如下:

@mixin text-3d($color: white, $depth: 5) {
    $shadows: ();
    $shadow-color: $color;

    @for $i from 1 through $depth {
        $shadow-color: darken($shadow-color, 10%);
        $shadows: append($shadows,
            0 ($i * 1px) $shadow-color, comma);
    }

    color: $color;
    text-shadow: append($shadows,
    0 ($depth * 1px) 10px black, comma);
}
复制代码

把所有的投影都设成黑色,并且去掉最底层的投影,就可以模拟出一种在复古标志牌中常见的文字效果。

color: white;
background: hsl(0,50%,45%);
text-shadow: 1px 1px black, 2px 2px black,
             3px 3px black, 4px 4px black,
             5px 5px black, 6px 6px black,
             7px 7px black, 8px 8px black;
复制代码

image.png

@function text-retro($color: black, $depth: 8) {
    $shadows: (1px 1px $color, );

    @for $i from 2 through $depth {
        $shadows: append($shadows,
            ($i*1px) ($i*1px) $color, comma);
    }

    @return $shadows;
}
h1 {
    color: white;
    background: hsl(0, 50%, 45%);
    text-shadow: text-retro();
}
复制代码

最后说一句

如果这篇文章对您有所帮助,或者有所启发的话,帮忙关注一下,您的支持是我坚持写作最大的动力,多谢支持。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享