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);
});
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章