CSS國際化

語言: CN / TW / HK

本人翻譯者系奇舞團前端工程師

原文標題:CSS for internationalization

原文作者:Chen Hui jing

原文地址:https://chenhuijing.com/blog/css-for-i18n

我遇到過一些人,他們根本不認為CSS與國際化有關,但如果你仔細想想,國際化不僅僅是將你網站上的內容翻譯成多種語言,然後一勞永逸。這些內容的呈現方式存在各種細微差別,影響母語人士使用您網站的體驗。

國際化沒有單一的規範定義,但W3C提供了以下指導:

"國際化是一種產品、應用程式或文件的設計和開發,可以方便地為不同文化、地區或語言的目標受眾進行本地化。"

從Unicode和字元編碼的使用,到為翻譯內容提供服務的技術實現,以及所述內容的呈現,這是一個需要覆蓋的領域。今天,我將只討論多語言支援的CSS相關方面。

CSS通過告訴瀏覽器頁面上的元素應該如何設定樣式和佈局來描述網頁的顯示。在使用CSS的多語言頁面上,我們可以使用幾種方法將不同的樣式應用於不同的語言。

除此之外,CSS屬性還為指令碼和書寫系統提供了佈局和排版功能,而不僅僅是基於拉丁語的自上而下的水平排版功能,這種功能如今主要出現在WEB上。

所以,請做好準備,因為這可能會是一篇相當長的文章。¯(ツ)

與語言相關的樣式

你有沒有想過Chrome怎麼會問你是否想翻譯網頁的內容?額...不好吧,也許只有我一個人關注過這類問題?這是因為HTML元素上的lang屬性。

lang屬性是一個非常重要的屬性,因為它識別WEB上文字內容的語言,並且該資訊在許多地方都被使用。前面提到的Chrome內建翻譯,針對特定語言內容的搜尋引擎,以及螢幕閱讀器。

啊哈,也許你沒有想到螢幕閱讀器,但如果你不是一個螢幕閱讀器使用者或認識這樣的人,它可能不會放在心上。螢幕閱讀器利用語言資訊,以適當的口音和正確的發音讀出內容。

與語言相關的樣式化的關鍵在於在頁面標記中適當使用lang屬性。lang屬性將ISO 639[1]語言程式碼識別為值。

更新:Tobias Bengfort[2]指出lang屬性使用了一個名為BCP 47的IETF規範[3],該規範很大程度上基於ISO 639標準。

在大多數情況下,您將使用像zh這樣的兩個字母的程式碼來表示中文,但是中文(包括阿拉伯語等其他語言)被認為是一種巨集語言,它由許多具有更具體的主語言子標記的語言組成。

有關如何構造語言標記的深入解釋,請參閱HTML和XML中的語言標記[4]。

一般的指導是html元素必須總是有一個lang屬性集,然後由所有其他元素繼承。

<html lang="zh">

在同一頁上看到不同語言的內容並不少見。在本例中,您將使用span或div包裝該內容,並將正確的lang屬性應用於包裝元素。

```

The fourth animal in the Chinese Zodiac is Rabbit (兔子).

```

既然我們已經對其進行了分類,下面的技術將假設lang屬性已經得到了負責任的實現。

:lang()偽類選擇器

事實證明:lang()偽類選擇器並不是那麼有名。

但是這個偽類選擇器非常酷,因為它可以識別內容的語言,即使該語言是在元素之外宣告的。

例如,一行包含兩種語言的標記,如下所示:

```

  We use italics to emphasise words in English, 但是中文則是用著重號.

```

可採用以下樣式:

em:lang(zh) {   font-style: normal;   text-emphasis: dot; }

如果您的瀏覽器支援text-emphasis的CSS屬性,您應該能夠看到在em中的每個漢字中新增的強調標記(傳統上用於強調一系列東亞文字的排版符號)。Chrome需要-webkit-字首(此處噓聲一片)。

我們用斜體字強調英語中的單詞,但是中文則是用著重號.

但關鍵是,lang屬性不是應用於em元素,而是應用於其父元素。偽類仍然有效。如果我們使用更常見的屬性選擇器,例如[lang=“zh],則該屬性必須位於em元素上才能生效。

使用屬性選擇器

這就引出了我們的下一項技術,使用屬性選擇器。這些允許我們選擇具有特定屬性或具有特定值的屬性的元素。(外掛時間,要了解更多關於屬性選擇器的資訊,請嘗試您自己編寫的Codrops CSS參考條目[5])

有七種方法可以匹配屬性選擇器,但我只討論那些我認為與匹配lang屬性更相關的方法。我所有的例子都使用中文作為目標語言,所以zh及其變體。

更新:Amelia Bellamy Royds[6]指出,我的示例使屬性選擇器似乎是進行部分語言標記匹配所必需的,但:lang()偽類已經涵蓋了該用例。

首先,我們可以使用以下語法精確匹配lang屬性值:

[lang="zh"] /* will match only zh */

我之前提到過,漢語被認為是一種巨集語言,這意味著它的語言標籤可以由額外的細節組成,例如指令碼子標籤Hans或Hant(W3C說,如果需要區分,只使用指令碼子標籤,否則不使用)、區域子標籤HK或TW等等。

重點是,語言標籤可以比兩個字母長。但最一般化的類別總是排在第一位,所以要針對以特定字串開頭的屬性值,我們使用以下涉及^的語法:

[lang^="zh"] /*將匹配zh,zh HK,zh Hans,zhong,zh123… *基本上是以zh作為前兩個字元的任何內容*/

還有另一種涉及|的語法,它將匹配選擇器中的確切值,或者匹配一個以值開頭,緊接著是-的值。這似乎只是為了語言子程式碼匹配,不是嗎?

[lang|="zh"] /* 將匹配 zh, zh-HK, zh-Hans, zh-amazing, zh-123 */

請記住,對於屬性選擇器,屬性必須位於您想要設定樣式的元素上,如果它位於父級或祖先級,則它將不起作用。請注意,我提出的部分語言標記匹配示例已經可以通過:lang()偽類完成。

換句話說,除了lang=“en”之外,:lang(en)還將匹配lang=“en US”、lang=“en GB”等等。當我能想出更好的例子時,我會更新這些例子。同時,使用:lang()偽類。

普通類或ID如何?

是的。可以使用普通類或ID。儘管你不會再利用你元素上已有的便利。(再一次,我的假設是lang屬性被正確且負責任地應用)但當然,請繼續,併為應用特定語言相關樣式的元素提供類名。如果你真的想,沒有人會阻止你。

CSS屬性

好的,選擇器被覆蓋了。讓我們來談談我們希望應用於與這些選擇器匹配的元素的樣式。

Writing mode

writing-mode的預設值為horizontal-tb。完全合乎邏輯,因為網路誕生於歐洲核子研究中心,那裡的官方語言是英語和法語。此外,我認為大多數網路技術都是在說英語的國家首創的。

但人類的神奇給了我們3000多種文字,文字和書寫方向遠不止從上到下的水平方向這一種方式。

傳統的蒙古語從左到右垂直書寫,而日語、漢語和韓語等東亞語言在垂直書寫時從右到左。允許您這樣做的寫入模式屬性分別是垂直lr和垂直rl。

還有sideways-lr和sideways-rl的值,它們將符號側向旋轉。每個Unicode字元都有一個垂直方向屬性,告知呈現引擎在預設情況下字形應該如何定向。

我們可以通過text-orientation屬性來改變字元的朝向。當您使用垂直排版的東亞文字,並點綴以拉丁語為基礎的單詞或字元時,這通常會發揮作用。對於縮寫,您可以選擇使用text-combination-vertical將字母壓縮到一個字元空間中。

有些人可能想知道從右到左的語言,如阿拉伯語、希伯來語或波斯語(僅舉幾例),以及CSS是否也適用於這些指令碼。簡而言之,CSS不應該用於雙向樣式。W3C的指導如下:

因為方向性是文件結構的組成部分,所以應該使用標記來設定文件或資訊塊的方向性,或者標識文字中僅使用Unicode雙向演算法不足以實現所需方向性的位置。

這是因為通過CSS應用的樣式有可能被關閉,被覆蓋,無法識別,或者在不同的上下文中被更改/替換。相反,建議使用dir屬性來設定顯示文字的基本方向。

我強烈建議參考HTML中的結構化標記和從右到左的文字[7],CSS vs.標記的bidi支援[8],內聯標記和HTML中的雙向文字[9],以獲得更詳細的解釋和實現細節。

邏輯屬性

網頁上的所有東西都是一個盒子,CSS總是使用頂部、底部、左側和右側的物理方向來指示我們的目標盒子的哪一邊。但是,當writing-mode不是預設的從上到下的水平方向時,這些值往往會令人困惑。

因為規範仍然處於草案狀態,所以語法可能會繼續更改。即使現在,當前的瀏覽器實現與規範中的不同,所以一定要用MDN: CSS邏輯屬性和值[10]對最新的語法進行雙重檢查。

更新:David Baron指出,我使用的是規範的前一個版本中的舊語法,而在瀏覽器中實現的語法實際上是編輯草案中的語法。表已相應更新。

用於定位的盒子的物理邊和邏輯邊的書寫方向及其對應值的矩陣如下(該表從寫作時的規範中移除):

容器的邏輯頂部使用inset-block-start,而容器的邏輯底部使用inset-block-end。容器的邏輯左側使用inset-inline-start,而容器的邏輯右側使用inset-inline-end。

也有相應的邊界、邊距和填充的對映,它們是:

  • top to block-start
  • right to inline-end
  • bottom to block-end
  • left to inline-start

```

A comparison of physical and logical directions for borders

  Given the requirement is to have a box with a run of text within it with the   following characteristics:

      
  1.     The border colour at the top edge of the run of text should     be red.   
  2.   
  3.     The border colour at the right edge     of the run of text should be green.   
  4.   
  5.     The border colour at the bottom edge     of the run of text should be blue.   
  6.   
  7.     The border colour at the left edge     of the run of text should be yellow.   

  Using physical directions requires a modification every time the writing   direction changes, whereas using logical properties allows the same properties   and values for all six use cases.

  

Physical directions

       
               

This is a sentence.

      
      
border-top-color: tomato;
border-right-color: limegreen;
border-bottom-color: dodgerblue;
border-left-color: gold;
         
               

This is a sentence.

             
border-top-color: tomato;
border-left-color: limegreen;
border-bottom-color: dodgerblue;
border-right-color: gold;
    
    
               

This is a sentence.

             
border-left-color: tomato;
border-bottom-color: limegreen;
border-right-color: dodgerblue;
border-top-color: gold;
    
    
               

This is a sentence.

             
border-left-color: tomato;
border-top-color: limegreen;
border-right-color: dodgerblue;
border-bottom-color: gold;
    
    
               

This is a sentence.

             
border-right-color: tomato;
border-bottom-color: limegreen;
border-left-color: dodgerblue;
border-top-color: gold;
    
    
               

This is a sentence.

             
border-right-color: tomato;
border-top-color: limegreen;
border-left-color: dodgerblue;
border-bottom-color: gold;
    
  

  

Logical directions

              

This is a sentence.

                

This is a sentence.

                

This is a sentence.

                

This is a sentence.

                

This is a sentence.

                

This is a sentence.

          
border-block-start-color: tomato;
border-inline-end-color: limegreen;
border-block-end-color: dodgerblue;
border-inline-start-color: gold;

```

``` [class$="boxes"] {   display: flex;   flex-wrap: wrap;   justify-content: space-around;   gap: 1em; }

article {   margin-bottom: 1em; }

article > div, [class$="box"] {   width: 200px;   height: 200px;   border: 1em solid;   position: relative;   margin: 1em; }

.phy-box1 {   border-top-color: tomato;   border-right-color: limegreen;   border-bottom-color: dodgerblue;   border-left-color: gold; }

.phy-box2 {   border-top-color: tomato;   border-left-color: limegreen;   border-bottom-color: dodgerblue;   border-right-color: gold; }

.phy-box3 {   border-left-color: tomato;   border-bottom-color: limegreen;   border-right-color: dodgerblue;   border-top-color: gold; }

.phy-box4 {   border-left-color: tomato;   border-top-color: limegreen;   border-right-color: dodgerblue;   border-bottom-color: gold; }

.phy-box5 {   border-right-color: tomato;   border-bottom-color: limegreen;   border-left-color: dodgerblue;   border-top-color: gold; }

.phy-box6 {   border-right-color: tomato;   border-top-color: limegreen;   border-left-color: dodgerblue;   border-bottom-color: gold; }

.log-box {   border-block-start-color: tomato;   border-inline-end-color: limegreen;   border-block-end-color: dodgerblue;   border-inline-start-color: gold; }

.vlr {   writing-mode: vertical-lr; }

.vrl {   writing-mode: vertical-rl; }

pre {   background: #2d2d2d;   padding: 1em;  margin: .5em 0;  overflow: auto;   color: #ccc;   border-radius: 4px;   width: max-content;   margin: auto; } ```

邊框的物理和邏輯方向的比較

給定的要求是有一個框內的文字執行與以下特徵:

  • 文字執行的頂部邊緣的邊框顏色應為紅色。
  • 文字右邊緣的邊框顏色應為綠色。
  • 文字執行的底部邊緣的邊框顏色應為藍色。
  • 文字的左邊緣的邊框顏色應為黃色。
  • 使用物理方向需要在每次寫入方向改變時進行修改,而使用邏輯屬性則允許所有六個用例具有相同的屬性和值。

物理方向

邏輯方向

大小的對映如下:寬度到inline-size,高度到block-size。

列表和計數器

數字系統是用來表示數字的書寫系統,即使最常用的數字系統是印度-阿拉伯數字系統(0,1,2,3等等),CSS也允許我們用其他數字系統顯示有序列表。

預定義的計數器樣式可以與list-style-type屬性一起使用,該屬性涵蓋了從阿法爾語到烏爾都語的174個數字系統。你可以在MDN[11]上檢視完整的列表。

如果你對CSS計數器感興趣,我在去年的某個時候寫了一篇關於它們的文章[12],在文中我探索了在傳統中文環境中使用的“天干”和“地支”數字系統(以及CSS中一個非常流行的實現,為什麼不呢?)

text-decoration

如前所述,東亞語言沒有斜體的概念。相反,我們有強調點。它們可以放在字元的上方或下方,以強調文字,加強語氣或避免歧義。

漢字橫寫時,這些點放在漢字的下方,豎寫時,這些點放在漢字的右側。

另一方面,日語在水平書寫模式下,在字元上方放置強調點。為了使CSS屬性更加通用,在CSS text-decoration 模組第3級[13]中引入了text-emphasis-style、text-emphasis-position和text-emphasis-color。

除了點之外,你可以使用不同的符號,比如圓、三角形,甚至是單個字元作為字串。位置和顏色也可以根據各自的屬性進行調整。

線條裝飾也包含在同一規範中,為開發者提供了對下劃線和上劃線的更精細的控制(在規範的第4級)。但是,這對於那些經常溢位基線的升序或降序指令碼尤其有用。

CSS text-decoration 模組第4級[14]涵蓋了text-decoration-skip,該模組控制當覆蓋線和下劃線跨越字形時如何繪製覆蓋線和下劃線。同樣,對於像英語這樣的語言來說,這種情況發生的頻率較低,但對像緬甸語這樣的指令碼的美學影響很大。

字型變化

訪問OpenType特性有兩類CSS屬性,高階屬性和低階屬性。本規範建議儘可能使用高階屬性。這主要取決於瀏覽器支援。

例如,東亞字型變體允許控制具有變體的字元的字形形式,例如簡體中文字形和繁體中文字形。這是同一個字元,但它們可以寫得不同。

還有字型變體連字,它為連字和上下文形式提供了許多預定義的選項,如任意連字、歷史連字或上下文連字。

低階屬性是通過字型功能設定訪問的,您可以使用4個字母的OpenType標記來切換所需的功能(這取決於您的字型是否有這些功能,但假設有)。

共有141個功能標籤,從可選分數到對正替換,從Ruby符號形式到斜線零。這些CSS屬性與字型檔案本身的功能密切相關,因此外部依賴性取決於字型的選擇。

結束

這篇文章太長了,所以我將在第二部分更詳細地介紹我們如何使用之前提到的選擇器來構建佈局,以確保即使語言發生變化,我們的佈局也能保持健壯。像Flexbox和Grid這樣的現代佈局屬性非常適合這樣的用例。

關於CSS,我發現最有趣的事情之一是,我們如何以不同的方式將它們組合起來,以實現無數的結果,並且有超過500個CSS屬性存在,這是很多可能性。我並不是說什麼都可以,因為通常情況下,有很多方法可以達到相同的結果,有些方法比其他方法更合適。

然而,我們需要通過理解每種技術背後的機制,其優缺點,並意識到為什麼我們會選擇某種方式去做事情,從而做出最適合自己的決定。

我仍然相信,30多年過去了,網路仍然是一個資訊媒介,內容是關鍵。因此,無論使用何種語言或指令碼,都應該優化內容的呈現。我很高興CSS的不斷髮展為開發人員提供了實現這一目標的方法。

總之,敬請期待第二部分。

參考資料

[1]

ISO 639-1 codes: https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes

[2]

Tobias Bengfort : http://tobib.spline.de/xi/

[3]

BCP 47: https://www.w3.org/International/questions/qa-html-language-declarations

[4]

Language tags in HTML and XML: https://www.w3.org/International/articles/language-tags/

[5]

Codrops CSS reference entry: https://tympanus.net/codrops/css_reference/attribute-selectors/

[6]

Amelia Bellamy Royds: https://twitter.com/AmeliasBrain/status/1253053272585146368

[7]

HTML中的結構化標記和從右到左的文字: https://www.w3.org/International/questions/qa-html-dir

[8]

CSS vs.標記的bidi支援: https://www.w3.org/International/questions/qa-bidi-css-markup

[9]

Inline markup and bidirectional text in HTML: https://www.w3.org/International/articles/inline-bidi-markup/

[10]

MDN: CSS Logical Properties and Values: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Logical_Properties

[11]

list-style-type: https://developer.mozilla.org/en-US/docs/Web/CSS/list-style-type

[12]

CSS計數器的奇妙世界: https://chenhuijing.com/blog/the-wondrous-world-of-css-counters

[13]

CSS Text Decoration Module Level 3: https://drafts.csswg.org/css-text-decor-3/#emphasis-marks

[14]

CSS Text Decoration Module Level 4: https://drafts.csswg.org/css-text-decor-4/#text-decoration-skipping