搜尋

文字書寫方向 ( 垂直、水平 )

通常在瀏覽網頁時,都是採用「水平」的文字書寫方向,然而文字的方向不僅會影響閱讀,還會影響到對齊的方式,這篇教學會透過 CSS 的 writing-mode、text-orientation、direction 和 unicode-bidi 等屬性,讓文字內容呈現「垂直」的書寫方向。

快速導覽:

CSS 教學 - 文字書寫方向 ( 垂直、水平 )

writing-mode 書寫模式

writing-mode 樣式屬性可以設定文字的「書寫模式」,具有繼承特性,相關屬性值如下:

屬性值 行內方向 區塊方向
horizontal-tb 左到右 ( 預設值 ) 上到下 ( 預設值 )
vertical-rl 上到下 右到左
vertical-lr 下到上 左到右

writing-mode 不只會影響文字書寫的水平方向,也會影響其他元素排列方向,下方範例展示三種不同語系的書寫方向,英文語系轉換方向後,字母的方向也會跟著旋轉 90 度 ( 包含半形數字和標點 ),而中日韓文語系會保持原來的方向 ( 包含全形數字和標點 ),而雖然方向改變不是「旋轉」,因此原本區塊的樣式還是會保持一至 ( 上邊框不會變成左右邊框 )。

注意,如果區塊元素沒有設定寬度或高度,則水平時預設撐開到最大,垂直時則由元素內容決定大小。

線上展示:https://codepen.io/oxxo/pen/NWVyxdJ

<!-- HTML 程式碼 --> 
<h2>horizontal-tb</h2>
<div class="a">
  <div>Good morning! oxxo!</div>  
  <div>早安圈叉叉圈!</div> 
  <div>おはようございます。</div>
  <div>좋은 아침이에요 잘 지내요?</div>
  <div>0123456789!?</div>
  <div>0123456789!?</div>
</div>
<h2>vertical-rl</h2>
<div class="b">
  <div>Good morning! oxxo!</div>  
  <div>早安!圈叉叉圈!</div> 
  <div>おはようございます。</div>
  <div>좋은 아침이에요 잘 지내요?</div>
  <div>0123456789!?</div>
  <div>0123456789!?</div>
</div>
<h2>vertical-lr</h2>
<div class="c">
  <div>Good morning! oxxo!</div>  
  <div>早安!圈叉叉圈!</div> 
  <div>おはようございます。</div>
  <div>좋은 아침이에요 잘 지내요?</div>
  <div>0123456789!?</div>
  <div>0123456789!?</div>
</div>

<!-- CSS 程式碼 -->
<style>
  h2 {
    color: #f00;
    margin: 15px 5px 5px;
  }
  div div {
    border: 1px solid #000;
    border-top-width: 5px;   /* 上邊框加粗 */
    margin: 5px;
    padding: 5px;
  }
  .a {writing-mode: horizontal-tb;}
  .b {writing-mode: vertical-rl;}
  .c {writing-mode: vertical-lr;}
</style>

CSS 教學 - 文字書寫方向 ( 垂直、水平 ) - writing-mode 書寫模式

如果使用表格,可以更清楚的看見原本 3x2 的表格,在改變書寫模式後,變成了 2x3 的表格,而書寫方式同時也影響了文字換行還有垂直對齊的方向。

注意,垂直對齊在變更書寫模式後,方向會從從垂直變成水平

線上展示:https://codepen.io/oxxo/pen/BaeYjmM

<!-- HTML 程式碼 --> 
<h2>horizontal-tb</h2>
<table class="a">
  <tr>
    <td>Good morning! oxxo!</td>
    <td>早安圈叉叉圈!</td>
    <td>0123456789!?</td>
  </tr>
  <tr>
    <td>おはようございます。</td>
    <td>좋은 아침이에요 잘 지내요?</td>
    <td>0123456789!?</td>
  </tr>
</table>
<h2>vertical-rl</h2>
<table class="b">
  <tr>
    <td>Good morning! oxxo!</td>
    <td>早安圈叉叉圈!</td>
    <td>0123456789!?</td>
  </tr>
  <tr>
    <td>おはようございます。</td>
    <td>좋은 아침이에요 잘 지내요?</td>
    <td>0123456789!?</td>
  </tr>
</table>
<h2>vertical-lr</h2>
<table class="c">
  <tr>
    <td>Good morning! oxxo!</td>
    <td>早安圈叉叉圈!</td>
    <td>0123456789!?</td>
  </tr>
  <tr>
    <td>おはようございます。</td>
    <td>좋은 아침이에요 잘 지내요?</td>
    <td>0123456789!?</td>
  </tr>
</table>

<!-- CSS 程式碼 -->
<style>
  h2 {
    color: #f00;
    margin: 15px 5px 5px;
  }
  td {
    border: 1px solid #000;
    width: 120px;
    height: 120px;
    text-align: left;
    vertical-align: top;
  }
  .a {writing-mode: horizontal-tb;}
  .b {writing-mode: vertical-rl;}
  .c {writing-mode: vertical-lr;}
</style>

CSS 教學 - 文字書寫方向 ( 垂直、水平 ) - writing-mode 書寫模式

text-orientation 字元方向

text-orientation 樣式屬性可以設定「字元方向」,具有繼承特性,需要搭配 writing-mode: vertical-rl; 一起使用,相關屬性值如下:

屬性值 說明
mixed 所有非中日韓的字元順時針旋轉 90 度。
upright 所有非中日韓的字元,使用「中日韓文字」的呈現方式。
sideways 整行旋轉 90 度。

下方範例呈現不同的 text-orientation 屬性樣式,可以觀察到就算使用 upright 的方式旋轉字元,該字元仍然保有「非中日韓」文字的特性,當過長的單詞超過範圍後,如果使用預設值就會超出邊界

線上展示:https://codepen.io/oxxo/pen/rNgJJrd

<!-- HTML 程式碼 --> 
<h2>horizontal-tb</h2>
<div class="a">
  <div>Good morning! oxxo!</div>  
  <div>早安圈叉叉圈!</div> 
  <div>おはようございます。</div>
  <div>좋은 아침이에요 잘 지내요?</div>
  <div>0123456789!?</div>
  <div>0123456789!?</div>
</div>
<h2>vertical-rl</h2>
<div class="b">
  <div>Good morning! oxxo!</div>  
  <div>早安!圈叉叉圈!</div> 
  <div>おはようございます。</div>
  <div>좋은 아침이에요 잘 지내요?</div>
  <div>0123456789!?</div>
  <div>0123456789!?</div>
</div>
<h2>vertical-lr</h2>
<div class="c">
  <div>Good morning! oxxo!</div>  
  <div>早安!圈叉叉圈!</div> 
  <div>おはようございます。</div>
  <div>좋은 아침이에요 잘 지내요?</div>
  <div>0123456789!?</div>
  <div>0123456789!?</div>
</div>

<!-- CSS 程式碼 -->
<style>
  h2 {
    color: #f00;
    margin: 0;
    padding: 15px 5px 5px;
    clear: both;
  }
  div div {
    height:150px;
    border: 1px solid #000;
    margin: 5px;
    padding: 5px;
    float: left;
    writing-mode: vertical-lr;  /* 需要使用這個樣式屬性 */
  }
  .a {text-orientation: mixed;}
  .b {text-orientation: upright;}
  .c {text-orientation: sideways; }
</style>

CSS 教學 - 文字書寫方向 ( 垂直、水平 ) - text-orientation 字元方向

direction、unicode-bidi 宣告方向

direction 樣式屬性可以進行「宣告方向」,會影響元素的排列顯示方向,具有繼承特性,相關屬性值如下:

屬性值 說明
ltr 左到右 ( 預設值 )
rtl 右到左

使用時需要注意「最後方的標點符號」,只要是位在文字最後方的標點符號 ( 文字「軟換行」產生的最後一行 ),在轉換方向後,會發生位置錯誤的狀況,下方的例子呈現轉換方向後的模樣,特別注意每一段落最後的標點符號,不只位置不如預期,有些方向甚至會相反。

注意,W3C 建議不要使用 directionunicode-bidi 屬性,使用 HTML 元素的 dir 屬性進行設定 ( 參考「HTML 元素屬性」 ),避免使用者停用 CSS 樣式時,造成無法順利修改文字方向的狀況。

線上展示:https://codepen.io/oxxo/pen/gOJvemg

<!-- HTML 程式碼 --> 
<div class="a">
  <div>Good morning!{{([  oxxo!{{([ </div>  
  <div>早安!?『「{{([ 最後一行後面的標點符號是相反的!?『「{{([</div> 
  <div>早安!?『「{{([ <br/>使用 br 產生硬換行!?『「{{([</div>
</div>
<h2>預設右到左的文字,改成 direction: ltr;</h2>
<div class="b">
  <div>صباح الخير!?{{([ علامات الترقيم بعد السطر الأخير معكوسة!?{{([</div>  
  <div>בוקר טוב!?{{([ סימני הפיסוק אחרי השורה האחרונה הפוכים!?{{([</div> 
</div>

<!-- CSS 程式碼 -->
<style>
  h2 {
    color: #f00;
    margin: 15px 0 0 5px;
    font-size: 18px;
  }
  div div {
    border: 1px solid #000;
    margin: 5px;
    padding: 5px;
  }
  .a div {direction: rtl;}
  .b div {direction: ltr;}
</style>

CSS 教學 - 文字書寫方向 ( 垂直、水平 ) - direction 宣告方向

除了單純使用 direction 宣告方向,有時還會額外搭配 unicode-bidi 來輔助設定字元方向,unicode-bidi 具有繼承特性,並有下列幾個屬性值:

屬性值 說明
normal 自動排列元素,會根據系統方向決定內容顯示方向 ( 預設值 )。
embed 自動排列元素時,替元素的前後加上特定字元,效果通常與 normal 相同。
bidi-override 自動排列元素時,所有字元都會按照指定方向排列。

下方的範例將左到右顯示的文字,改用 direction: rtl; 顯示為右到左,並修改 unicode-bidi 屬性值來凸顯差異 ( 標點符號會顛倒 )。

線上展示:https://codepen.io/oxxo/pen/xxNYWWx

<!-- HTML 程式碼 --> 
<h2>unicode-bidi: embed;</h2>
<div class="a">
  <div>Good morning!{{([  oxxo!{{([ </div>  
  <div>早安!?『「{{([ 最後一行後面的標點符號是相反的!?『「{{([</div> 
  <div>早安!?『「{{([ <br/>使用 br 產生硬換行!?『「{{([</div>
</div>
<h2>unicode-bidi: normal;</h2>
<div class="b">
  <div>Good morning!{{([  oxxo!{{([ </div>  
  <div>早安!?『「{{([ 最後一行後面的標點符號是相反的!?『「{{([</div> 
  <div>早安!?『「{{([ <br/>使用 br 產生硬換行!?『「{{([</div>
</div>
<h2>unicode-bidi: bidi-override;</h2>
<div class="c">
  <div>Good morning!{{([  oxxo!{{([ </div>  
  <div>早安!?『「{{([ 最後一行後面的標點符號是相反的!?『「{{([</div> 
  <div>早安!?『「{{([ <br/>使用 br 產生硬換行!?『「{{([</div>
</div>

<!-- CSS 程式碼 -->
<style>
  h2 {
    color: #f00;
    margin: 15px 0 0 5px;
    font-size: 18px;
  }
  div div {
    border: 1px solid #000;
    margin: 5px;
    padding: 5px;
    direction: rtl;
  }
  .a div {unicode-bidi: embed;}
  .b div {unicode-bidi: normal;}
  .c div {unicode-bidi: bidi-override;}
</style>

CSS 教學 - 文字書寫方向 ( 垂直、水平 ) - unicode-bidi 來輔助設定字元方向

小結

其實大多數的情況,是不需要修改文字方向的,但如果對於網頁有特殊需求,特別是一些中日韓文字的垂直排版,或要提供右向左書寫系統的使用者閱讀,就需要使用這些相關樣式囉。

意見回饋

如果有任何建議或問題,可傳送「意見表單」給我,謝謝~

CSS 教學

基本介紹

認識 CSS 開始使用 CSS CSS 語法規則 CSS 命名原則

CSS 選擇器

認識 CSS 選擇器 優先順序 ( 權重 ) 樣式繼承與聯集 元素選擇器 ID 和 Class 選擇器 屬性選擇器 文件結構選擇器 虛擬類別選擇器 ( 結構 ) 虛擬類別選擇器 ( 類型 ) 虛擬類別選擇器 ( 輸入 ) 虛擬類別選擇器 ( 行為 ) 虛擬類別選擇器 ( 超連結 ) 虛擬類別選擇器 ( 邏輯 ) 虛擬類別選擇器 ( 其他 ) 虛擬元素選擇器 群組與組合選擇器

數值與單位

關鍵字與文字數值 長度與角度單位 顏色單位 位置名稱與時間單位

變數與內容函式

變數 數學計算 文字與清單計數 生成內容與引號

顏色與濾鏡

色彩模型 漸層色 影像濾鏡

文字樣式

使用通用字型 使用外部字型 @font-face 定義字型 文字尺寸 常用文字樣式 文字換行 文字空白與 Tab 大小 文字行高與縮排 文字水平與垂直對齊 文字書寫方向 特殊文字樣式

元素容器

容器顯示類型 ( display ) 元素 display 對照表 盒子模型 ( Box Model ) 寬度與高度 內邊距 ( padding ) 外邊界 ( margin ) 邊框 ( border ) 邊框圓角 影像邊框 輪廓 ( outline ) 可見性與透明度 內容溢出與裁切

背景與陰影

背景顏色 背景圖 ( 定位、尺寸 ) 背景圖 ( 固定、重複 ) 背景圖 ( 多重背景、混合 ) 背景縮寫 ( background ) 容器陰影 ( box-shadow )

清單與表格

清單樣式 清單計數器 定義計數規則 表格基本樣式 表格邊框樣式 表格內容寬度與對齊

基本排版與定位

元素排版方式 浮動 ( float ) 浮動形狀 定位 ( position )

Flexbox 彈性排版

Flexbox 彈性盒子 Flexbox 對齊方式 Flexbox 彈性伸縮

Grid 網格排版

Grid 網格容器與格線 Grid 網格空間與命名 Grid 網格流向與間距 Grid 排列網格項目 Grid 項目對齊與順序

轉場與動畫

轉場 ( transition ) 轉場觸發事件 動畫 ( animation ) 動畫觸發事件 多重動畫的權重與順序

變形、裁切與遮罩

裁切路徑 ( clip-path ) 影像遮罩 ( mask )