CSS Secret——Typography

连字符的使用

在排版良好的书和杂志中,文字都是两端对齐的。但是在CSS中我们很少这么用,因为书里有连字符来解决长单词会带来的一行中空白过多的情形,而CSS没有。
在CSS Text Level 3中,有这么一个新的值,叫hyphens,可选none,manual和auto。

#hyphens{
  width:200px;
  text-align: justify;
  -webkit-hyphens: auto;
  hyphens: auto;
}

这里要想这个属性正常工作,要记得将HTML的lang属性置为正确的值。
在设置为auto时,我们同样可以通过&shy来手动指定连字符,浏览器会优先考虑它们。
把词分开的算法大致有两种:贪婪算法和Knuth-Pass算法。前者一次考虑一行,尽可能放下多的单词(在可以使用连字符的情况下则是尽可能多的音节),然后考虑下一行。Knuth-Pass算法则是将所有文字一起考虑,产生最美观的效果,当然它比较慢。
在很多桌面应用中,使用Knuth-Pass,但浏览器大多是使用贪婪算法。
在CSS Text Level 4中加入了更多的属性来控制连字符:hyphenate-limit-lines、hyphenate-limit-chars、hyphenate-limit-zone、hyphenate-limit-last、hyphenate-character。

换行符

一般我们可以使用

<br />

来换行。
还有一种更优雅的办法。

dd + dt::before {
  content: '\A';
  white-space: pre;
}

在要换行的元素的前面加个内容为\A的伪元素,但这里要注意,white-space要设置为不忽略换行符。
使用+号这样的选择符可以优雅的控制第一个和最后一个元素与其它元素样式不同这样的情况。

文字行斑马纹

我们经常使用:nth-child()来区分表的奇偶行,以便对奇偶行应用不同的样式。
我们有时也想对一段文字做同样的处理。
很容易想到,使用之前的条纹背景,配上em这个单位,可以很完美的适配文字的行距。

#striped-text{
  width:200px;
  padding: .5em;
  line-height: 1.5;
  background: beige;
  background-size: auto 3em;
  background-origin: content-box;
  background-image: linear-gradient(rgba(0,0,0,.2) 50%,
          transparent 0);
}

调整tab长度

tab在代码中是很重要的,但是在浏览器中显示代码是却总是避免使用,因为在浏览器中tab被显示为8个字符的长度。
CSS Text Level 3中可以控制了。

code {
  display: block;
  margin: 1em 0;
  white-space: pre;
  font:normal 100%/1.5 "Monaco";
  tab-size: 4;
}

连字的处理

这个在中文中用的不多。
在英文的某些字体中,特别设计了某两个字符一起出现时的连字字体,但是浏览器默认并不使用这些,可以使用一个值来开启这些。

font-variant-ligatures: common-ligatures
                        discretionary-ligatures
                        historical-ligatures;

&符号

这里想说的不止是&符号,而是怎么针对某个特定字符设定字体。
假如我们有这么一个段文字:

HTML & CSS

我们只想针对&来设定字体,我们会这样做:

HTML <span class="amp">&amp;</span> CSS
.amp {
    font-family: Baskerville, "Goudy Old Style",
                 Garamond, Palatino, serif;
    font-style: italic;
}

那如果页面里有很多呢?如果这是从后台返回来的数据呢?我们是没办法把这些字符一个一个找出来加类的。
所以我们得找个新的办法来做这件事。
其实,我们是可以找到只给某些字符设置字体的办法的,这利用了我们平时看起来很平常的字体栈的机制,字体栈就是在font-family里声明多个字体,当排在字体在电脑内找不到时就往后找。这个机制同样适合另一种情况:当一种在字体栈前面的字体只对某几种字符有定义的时候,这些字符会使用这个字体,其他字符会使用字体栈后面的字体。

@font-face {
  font-family: Ampersand;
  src: local('Baskerville-Italic'),
  local('GoudyOldStyleT-Italic'),
  local('Palatino-Italic'),
  local('BookAntiqua-Italic');
  unicode-range: U+26;
}
#ampersands{
  font-family: Ampersand,"Monaco";
  font-size: 100px;
}

这里使用@font-face来定义了一个自己的字体,并通过字体作用的unicode范围规定这个字体只用于&。
这种方式还可以应用于文字中数字,罗马字母等应用不同字体。

定制的下划线

哈哈万能的线性渐变背景又来啦。

#underline {
  font:normal 150%/1.5 "Monaco";
  background-color: #fff;
  a{
    background: linear-gradient(gray, gray) no-repeat;
    background-size: 100% 1px;
    background-position: 0 1.15em;
    text-shadow: .1em 0 white, -.1em 0 white;
  }
}

这里使用一个1px高的背景作为下划线,并使用与背景同色的文字阴影来模拟下划线经过p,y这类字母时的间断。
想要虚线的下划线也很简单:

background: linear-gradient(90deg,
        gray 66%, transparent 0) repeat-x;
background-size: .4em 2px;
background-position: 0 1.1em;
text-shadow: .1em 0 white, -.1em 0 white;

波浪线:

a.error{
  background: linear-gradient(-45deg, transparent 40%, red 0, red 60%, transparent 0) 0 1.1em,
  linear-gradient(45deg, transparent 40%, red 0, red 60%, transparent 0) .2em 1.1em;
  background-repeat: repeat-x;
  background-size: .4em .2em;
  text-shadow: .05em 0 white, -.05em 0 white;
}

各种拟物化的字体效果

凸版印刷

就是凹进去的文字啦,利用文字阴影让字看起来是凹进去的。

font:normal 150%/1.5 "Monaco";
  background: hsl(210, 13%, 60%);
  color: hsl(210, 13%, 30%);
  text-shadow: 0 .05em .05em hsla(0,0%,100%,.8);

文字描边

使用多层文字阴影的办法:

#stroked{
  font:bold 300%/1.5 "Monaco";
  background: deeppink;
  color: white;
  text-shadow: 2px 2px black, -2px -2px black,
  2px -2px black, -2px 2px black;
}

这样效果并不好,最好的还是SVG。

<h1 class="strokedSVG">
    <svg width="2em" height="1.2em">
        <use xlink:href="#css" />
        <text id="css" y="1em">CSS</text>
    </svg>
</h1>
h1.strokedSVG {
  font: 500%/1 Rockwell, serif;
  background: deeppink;
  color: white;
}
h1.strokedSVG  text {
  fill: currentColor;
}
h1.strokedSVG  svg { overflow: visible }
h1.strokedSVG  use {
  stroke: black;
  stroke-width: 6;
  stroke-linejoin: round;
}

发光的文字

#glowing{
  background: #203;
  color: white;
  font:bold 300%/1.5 "Monaco";
  transition: 1s;
  &:hover {
    text-shadow: 0 0 .1em, 0 0 .3em;
  }
}

突出的文字

可以使用多重阴影层叠的办法来达到想要的3D效果。

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;

SCSS:

@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);
}
#extruded{
  font:bold 300%/1.5 "Monaco";
  background: #58a;
  @include text-3d(#eee, 4);
}

这个效果还有一些变体,比如使用同样颜色的阴影模仿长长的影子:

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;

SCSS:

@function text-retro($color: black, $depth: 8) {
  $shadows: ();
  @for $i from 1 through $depth {
    $shadows: append($shadows,
                    ($i*1px) ($i*1px) $color, comma);
  }
  @return $shadows;
}
#text-retro {
  font:bold 300%/1.5 "Monaco";
  color: white;
  background: hsl(0,50%,45%);
  text-shadow: text-retro();
}

圆形文字

这里得使用SVG了

<div class="circular">
    <svg viewBox="0 0 100 100">
        <path d="M 0,50 a 50,50 0 1,1 0,1 z"
              id="circle" />
        <text><textPath xlink:href="#circle">
            circular reasoning works because
        </textPath></text>
    </svg>
</div>
.circular{
  width:200px;
  margin: 3em auto 0;
  path {
    fill: none;
  }
  svg {
    display: block;
    overflow: visible;
  }
}

啊,如果你不想重复的在HTML中写这些SVG元素,你可以使用JS动态创建:

<div class="circularJS">
   circular reasoning works because
</div>
$$('.circularJS').forEach(function(el) {
    var NS = "http://www.w3.org/2000/svg";
    var xlinkNS = "http://www.w3.org/1999/xlink";
    var svg = document.createElementNS(NS, "svg");
    var circle = document.createElementNS(NS, "path");
    var text = document.createElementNS(NS, "text");
    var textPath = document.createElementNS(NS, "textPath");
    svg.setAttribute("viewBox", "0 0 100 100");
    circle.setAttribute("d", "M0,50 a50,50 0 1,1 0,1z");
    circle.setAttribute("id", "circle");
    textPath.textContent = el.textContent;
    textPath.setAttributeNS(xlinkNS, "xlink:href", "#circle");
    text.appendChild(textPath);
    svg.appendChild(circle);
    svg.appendChild(text);
    el.textContent = '';
    el.appendChild(svg);
});
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值