文字書寫方向 ( 垂直、水平 )
通常在瀏覽網頁時,都是採用「水平」的文字書寫方向,然而文字的方向不僅會影響閱讀,還會影響到對齊的方式,這篇教學會透過 CSS 的 writing-mode、text-orientation、direction 和 unicode-bidi 等屬性,讓文字內容呈現「垂直」的書寫方向。
快速導覽:
writing-mode 書寫模式
writing-mode
樣式屬性可以設定文字的「書寫模式」,具有繼承特性,相關屬性值如下:
屬性值 | 行內方向 | 區塊方向 |
---|---|---|
horizontal-tb | 左到右 ( 預設值 ) | 上到下 ( 預設值 ) |
vertical-rl | 上到下 | 右到左 |
vertical-lr | 下到上 | 左到右 |
writing-mode
不只會影響文字書寫的水平方向,也會影響其他元素排列方向,下方範例展示三種不同語系的書寫方向,英文語系轉換方向後,字母的方向也會跟著旋轉 90 度 ( 包含半形數字和標點 ),而中日韓文語系會保持原來的方向 ( 包含全形數字和標點 ),而雖然方向改變不是「旋轉」,因此原本區塊的樣式還是會保持一至 ( 上邊框不會變成左右邊框 )。
注意,如果區塊元素沒有設定寬度或高度,則水平時預設撐開到最大,垂直時則由元素內容決定大小。
<!-- 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>
如果使用表格,可以更清楚的看見原本 3x2 的表格,在改變書寫模式後,變成了 2x3 的表格,而書寫方式同時也影響了文字換行還有垂直對齊的方向。
注意,垂直對齊在變更書寫模式後,方向會從從垂直變成水平。
<!-- 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>
text-orientation 字元方向
text-orientation
樣式屬性可以設定「字元方向」,具有繼承特性,需要搭配 writing-mode: vertical-rl;
一起使用,相關屬性值如下:
屬性值 | 說明 |
---|---|
mixed | 所有非中日韓的字元順時針旋轉 90 度。 |
upright | 所有非中日韓的字元,使用「中日韓文字」的呈現方式。 |
sideways | 整行旋轉 90 度。 |
下方範例呈現不同的 text-orientation
屬性樣式,可以觀察到就算使用 upright
的方式旋轉字元,該字元仍然保有「非中日韓」文字的特性,當過長的單詞超過範圍後,如果使用預設值就會超出邊界。
<!-- 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>
direction、unicode-bidi 宣告方向
direction
樣式屬性可以進行「宣告方向」,會影響元素的排列顯示方向,具有繼承特性,相關屬性值如下:
屬性值 | 說明 |
---|---|
ltr | 左到右 ( 預設值 ) |
rtl | 右到左 |
使用時需要注意「最後方的標點符號」,只要是位在文字最後方的標點符號 ( 文字「軟換行」產生的最後一行 ),在轉換方向後,會發生位置錯誤的狀況,下方的例子呈現轉換方向後的模樣,特別注意每一段落最後的標點符號,不只位置不如預期,有些方向甚至會相反。
注意,W3C 建議不要使用
direction
和unicode-bidi
屬性,使用 HTML 元素的 dir 屬性進行設定 ( 參考「HTML 元素屬性」 ),避免使用者停用 CSS 樣式時,造成無法順利修改文字方向的狀況。
<!-- 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>
除了單純使用 direction
宣告方向,有時還會額外搭配 unicode-bidi
來輔助設定字元方向,unicode-bidi
具有繼承特性,並有下列幾個屬性值:
屬性值 | 說明 |
---|---|
normal | 自動排列元素,會根據系統方向決定內容顯示方向 ( 預設值 )。 |
embed | 自動排列元素時,替元素的前後加上特定字元,效果通常與 normal 相同。 |
bidi-override | 自動排列元素時,所有字元都會按照指定方向排列。 |
下方的範例將左到右顯示的文字,改用 direction: rtl;
顯示為右到左,並修改 unicode-bidi
屬性值來凸顯差異 ( 標點符號會顛倒 )。
<!-- 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>
小結
其實大多數的情況,是不需要修改文字方向的,但如果對於網頁有特殊需求,特別是一些中日韓文字的垂直排版,或要提供右向左書寫系統的使用者閱讀,就需要使用這些相關樣式囉。
意見回饋
如果有任何建議或問題,可傳送「意見表單」給我,謝謝~