1. 程式人生 > >引號使用宋體其他使用微軟雅黑或蘋方字型 和 示例

引號使用宋體其他使用微軟雅黑或蘋方字型 和 示例

大部分內容來源於: http://www.zhangxinxu.com/wordpress/2016/11/css-unicode-range-character-font-face/

<!DOCTYPE html>

<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no">
    <meta name="description" content="CSS font-face微軟雅黑和蘋方字型自定義示意頁面" />

    <meta name="keywords" content="css, font-face, font, 字型, 微軟雅黑, 蘋方" />
    <meta name="author" content="" />
    <title>引號使用宋體其他使用微軟雅黑或蘋方字型</title>
    <style>
@font-face {
        font-family: BASE;
        src: local('PingFang SC'),
             local("Microsoft Yahei");
      }
      @font-face {
        font-family: quote;
        src: local('SimSun');


        /*使用本文的unicode-range,也就是我們使用unicode-range指定就引號使用宋體*/
        unicode-range: U+201c, U+201d;
      }
      h1 {
        font-weight: 400;
        font-family: BASE;
      }
      .quote {
        font-family: quote, BASE;
      }
    </style>
</head>
<body>
<h1>我是“微軟雅黑”或者是“蘋方字型”</h1>
  <h1 class="quote">我是“微軟雅黑”或者是“蘋方字型”,但是引號是宋體</h1>
</body>

</html>

上面做法能看出來,unicode-range是成本最低同時效果最好的實現方式。不知諸位是不是對unicode-range開始有了興趣呢?

unicode-range的值和語法:

    unicode-range的值正如名稱所示,是unicode值,就是U+以及後面可以表示各種字元和文字的幾個數字或字母,初始值為:U+0-10FFFF,也就是所有字符集。



    語法如下,參考自MDN:
    /* 支援的值 */
    unicode-range: U+26;               /* 單個字元編碼 */
    unicode-range: U+0-7F;
    unicode-range: U+0025-00FF;        /* 字元編碼區間 */
    unicode-range: U+4??;              /* 萬用字元區間 */
    unicode-range: U+0025-00FF, U+4??; /* 多個值 */


    其中,?可以理解為佔位符,表示0-F的值,因此,U+4??表示從U+400到U+4FF。
    unicode-range的語法 就是U+跟上對應字元的charCode值。


    於是,前端領域字元表示方式又多了一員:
    1. HTML中字元輸出使用&#x配上charCode值;
    2. 在JavaScript檔案中為防止亂碼轉義,則是\u配上charCode值;
    3. 而在CSS檔案中,如CSS偽元素的content屬性,直接使用\ 配上charCode值。
    4. unicode-range是U+配上charCode值。


    那有哪些常用的unicode值範圍呢?以及如何獲得任意字元的unicode值呢?


    unicode-range的常用unicode值及獲取 對於我們中文使用者,最常用的有下面這些:

  • 漢字:[0x4e00,0x9fa5](或十進位制[19968,40869])
  • 數字:[0x30,0x39](或十進位制[48, 57])
  • 小寫字母:[0x61,0x7a](或十進位制[97, 122])
  • 大寫字母:[0x41,0x5a](或十進位制[65, 90])
關於中文漢字更詳盡的編碼,我特意整理了一個頁面,以及可以預覽對應字元範圍的所有字元內容。您可以狠狠地點選這裡:中文漢字unicode編碼範圍整理demo


截圖效果如下:

中文漢字的unicode編碼整理

中文漢字的unicode編碼整理


左側的漢字都是可以點選的,然後,我又順便花時間做了個可以預覽unicode-range範圍字元內容的頁面,例如unicode-range對應字元顯示工具兼顯示基本漢字demo


地址後面的range=寫上對應的unicode-range範圍內容,就可以知道對應的都是那些字元了,例如,上面語法那裡出現過的U+0025-00FF,我們看看都是對應哪些內容,我們把url後面改成如下圖:

url後面地址變化示意

url後面地址變化示意


結果原來指的是這些字元:

對應的字元內容

對應的字元內容


某個具體的字元unicode值如何獲取?
這就需要我之前在“使用&#x3000;等空格實現最小成本中文對齊”一文中提到的小工具了,這裡:任意字元轉換成HTML識別格式工具頁面


例如:

任意字元轉換工具




上面的a9就是我們需要的charCode值,&#x是在HTML中顯示字元實體用的,這裡不用管,然後套永在unicode-range屬性值中就是U+9aU+a9,一開始的宋體引號例子,我就是使用這個工具獲取到U+201cU+201d的。


unicode-range適合使用的場景

我看到有部分前端小夥伴使用unicode-range的場景是這樣的,一段內容,英文數字等使用某個字型,中文使用另外一個字型,於是,使用unicode-range弄了一段自定義編碼,看上去很酷,畢竟使用了很多人都不知道的unicode-range,實際上,這並不是unicode-range真正適合的應用場景(雖然確實也實現了效果),為什麼呢?

比方說你希望數字英文是Helvetica字型,中文是蘋方或微軟雅黑,直接把英文字型放在前面就可以了!

.font {
    font-family: Helvetica, 'Pingfang SC', 'microsoft yahei';
}

因為,據我所知,這些英文字型是沒有中文字符集對映的,也就是,英文字型實際上對中文是沒有任何作用的。考慮到font-family的字型解析是從前往後依次的,所以,自然而然上面的程式碼數字英文是Helvetica字型,中文是蘋方或微軟雅黑,完全不需要使用unicode-range做吃力不討好的事情。

unicode-range適合使用的場景究竟是什麼呢?

在我看來,是對中文內容中的某部分中文字元做特殊字型處理,或者是英文字型中部分字元做特殊字型處理,這個才是適合的。比方說,上面使用宋體引號的案例,因為都是中文字型,因此,才有使用unicode-range的價值。

unicode-range的相容性

我擦,caniuse打不開。

相容性相關JSON資料參見這裡

MDN上顯示為:
MDN上unicode-range相容性

基本上,IE9+瀏覽器開始支援,Firefox 44開始支援不錯,至於Chrome和移動端,大家自然可以愉快地玩耍。總而言之,相容性還是很不錯的,至少在實際專案中使用我覺得很OK啦。IE8什麼的字型效果差點就差點,畢竟不是影響功能的CSS屬性。


結語

在處理unicode-range的時候,突然感嘆,要是@font-face規則中可以定義文字的預設顏色就好了,這樣,我們要在前端實現搜尋高亮效果,根本就不需要對HTML做任何事情,直接把對於的搜尋內容轉換成unicode編碼,使用unicode-range匹配,自動變得,那就厲害了,可惜不支援。畢竟僅僅是字型匹配似乎不是很明顯。

本人附加個小示例,功能是可以動態指定指定文字或符號 為特殊字型:

<style id="hCss">
      @font-face {
        font-family: BASE;
        src: local('PingFang SC'),
             local("Microsoft Yahei");
      }
      @font-face {
        font-family: quote;
        src: local('SimSun');

        /*使用本文的unicode-range,也就是我們使用unicode-range指定就引號使用宋體*/
        unicode-range: U+201c, U+201d;
      }
      h1 {
        font-weight: 400;
        font-family: BASE;
      }
      .quote {
        font-family: quote, BASE;
      }

</style>
    
<script>
      function toUnicode(str){
        if(typeof str=='undefined'||str==null||str==''){ return null; }
        var returnArr = [];

        for(var i=0,iLen=str.length; i<iLen; i++) {
          var char = str.charAt(i),// 獲取字元
              code = str.charCodeAt(i), // 數字編碼值
              str0 = String.fromCharCode(code),// 編碼互轉
              code16 = code.toString(16), // 轉為16進位制陣列 "4e2d"
              ustr = "U+"+code16;//"\\u"+code16; // 變成字面量表示法 "\u4e2d"
          returnArr.push(ustr);
        }
        return returnArr;
      }

      var arr = toUnicode("\“微軟雅黑\”");

      var hCss = document.querySelector('#hCss') || null;
      var fontFace = '@font-face{font-family: pa; src: local(\'SimSun\'); unicode-range:'+arr.join(',')+';} .payattention{font-family:pa, BASE;}';
      hCss.append(fontFace);
</script>