建立垂直表單控制元件

本指南介紹瞭如何使用 CSS 的 writing-modedirection 屬性來建立和配置垂直表單控制元件。這包括:

通用技術

在現代瀏覽器中,writing-mode 屬性可以設定為垂直值,以垂直顯示文字字元通常為水平的表單控制元件(例如拉丁語系),文字會以預設方向旋轉 90 度顯示。通常垂直書寫的文字字元(例如中文或日語)在這方面不受影響。

這在建立垂直語言表單時非常有用。

具體而言:

  • writing-mode: vertical-lr 將建立塊流向為從左到右的垂直表單控制元件,這意味著在具有換行或多行文字的控制元件中,後續行將出現在前一行的右側。
  • writing-mode: vertical-rl 將建立塊流向為從右到左的垂直表單控制元件,這意味著在具有換行或多行文字的控制元件中,後續行將出現在前一行的左側。

你也可以使用 transform 將控制元件旋轉 90 度,但這會將控制元件放置在其自身的圖層中,並可能導致意外的佈局副作用,例如覆蓋其他內容。使用 writing-mode 提供了一個更可靠的解決方案。

注意:雖然 writing-mode 屬性得到了很好的支援,但使用 writing-mode 建立垂直方向的表單控制元件直到 2024 年才獲得完整的瀏覽器支援。

注意:實驗性的 sideways-lrsideways-rl 值分別與 vertical-lrvertical-rl 有類似的效果,不同之處在於,通常垂直書寫的文字字元(例如中文或日語)會旋轉 90 度側向顯示,而水平書寫的文字字元(例如拉丁語系)不受這些值的影響。

此外,direction 屬性可用於控制控制元件內部內容的方向:

  • direction: ltr 將使內容從頂部開始流向底部。
  • direction: rtl 將使內容從底部開始流向頂部。

direction 屬性可用於設定內聯基本方向——即內容在一行中排列的主要方向,它定義了一行的“開始”和“結束”在哪一側。對於基於文字的表單控制元件,區別是顯而易見的——文字流從頂部或底部開始。在非基於文字的控制元件(如範圍滑塊)中,direction 設定了控制元件繪製的方向。例如,在垂直滑塊上設定 direction: ltr 會將最小值置於滑塊頂部,最大值置於滑塊底部。

以下各節將展示如何建立不同型別的垂直表單控制元件,並附有每個型別的示例。請查閱每個連結參考頁面上的瀏覽器相容性資訊,以瞭解每種型別的確切支援情況。

範圍滑塊、meter 和進度條

我們來看看如何建立垂直的範圍滑塊、meter 和進度條。

基本示例

一組典型的視覺化 <input type="range"> 滑塊、<progress><meter> 控制元件是這樣建立的:

html
<form>
  <input type="range" min="0" max="11" value="9" step="1" />
  <meter id="fuel" min="0" max="100" low="33" high="66" optimum="80" value="20">
    at 50/100
  </meter>
  <progress id="file" max="100" value="70">70%</progress>
</form>

注意:最佳實踐是為每個表單控制元件包含一個 <label> 元素,以便為每個欄位關聯有意義的文字描述,以實現可訪問性(更多資訊請參見使用有意義的文字標籤)。我們在此沒有這樣做,因為本文純粹關注表單控制元件的視覺渲染方面,但你應該確保在生產程式碼中這樣做。

要垂直顯示這些控制元件,我們可以使用如下的 CSS:

css
input[type="range"],
meter,
progress {
  margin-block-end: 20px;
  writing-mode: vertical-lr;
}

writing-mode: vertical-lr(和 vertical-rl)可在現代瀏覽器中使控制元件垂直顯示。

結果如下所示:

從下到上繪製控制元件

預設情況下,控制元件的 direction 值為 ltr。這會導致你的滑塊、meter 和進度條從上到下繪製,如上所示。

你可以透過設定 direction: rtl 來改變這一點——這會使它們從下到上繪製:

css
input[type="range"],
meter,
progress {
  margin-block-end: 20px;
  writing-mode: vertical-lr;
  direction: rtl;
}

結果如下所示:

在舊版瀏覽器中建立垂直範圍滑塊

在不支援使用 writing-modedirection 建立垂直表單控制元件的舊版瀏覽器中,可用的替代方案有限。以下方法僅適用於 <input type="range">,並使文字從下到上流動——它們對 <meter><progress> 元素沒有影響:

  • 非標準的 appearance: slider-vertical 屬性可以在舊版 Safari 和 Chrome 中使用。
  • 非標準的 orient="vertical" 屬性可以在舊版 Firefox 中新增到 <input type="range"> 元素本身。

此示例的 HTML 僅包含一個 <input type="range"> 滑塊,並添加了 orient="vertical" 以使其在舊版 Firefox 中垂直顯示:

html
<form>
  <input type="range" min="0" max="11" value="9" step="1" orient="vertical" />
</form>

為了使控制元件在舊版 Chrome 和 Safari 中也能垂直顯示,我們可以使用 appearance: slider-vertical

css
input[type="range"] {
  margin-block-end: 20px;
  appearance: slider-vertical;
}

結果如下所示:

select 元素

本節介紹如何處理垂直的 <select> 元素。

Select 基本示例

下面的 HTML 建立了兩個 <select> 元素,一個只能單選,另一個可以多選:

html
<form>
  <select multiple>
    <option>First</option>
    <option>Second</option>
    <option>Third</option>
    <option>Fourth</option>
    <option>Fifth</option>
  </select>
  <select>
    <option>First</option>
    <option>Second</option>
    <option>Third</option>
    <option>Fourth</option>
    <option>Fifth</option>
  </select>
</form>

要垂直顯示這些控制元件,我們可以使用如下的 CSS:

css
select {
  inline-size: 100px;
  margin-block-end: 20px;
  writing-mode: vertical-rl;
}

結果如下所示:

調整文字方向和選項順序

同樣,可以使用 direction 屬性值為 rtl 來將文字方向設定為從下到上,而不是預設的從上到下。

還值得注意的是,在上面的示例中,select 選項的內聯方向是從右到左,因為我們使用了 writing-mode: vertical-rl。如果我們改用 writing-mode: vertical-lr<option> 文字將從左到右顯示。

我們將使用三個列表框(multiple<select> 元素來探討這兩種用例,以便輕鬆地並排比較效果。

html
<form>
  <div>
    <h2>writing-mode: vertical-lr</h2>
    <select multiple>
      <option>First</option>
      <option>Second</option>
      <option>Third</option>
      <option>Fourth</option>
      <option>Fifth</option>
    </select>
  </div>
  <div class="direction">
    <h2>direction: rtl & writing-mode: vertical-lr</h2>
    <select multiple>
      <option>First</option>
      <option>Second</option>
      <option>Third</option>
      <option>Fourth</option>
      <option>Fifth</option>
    </select>
  </div>
  <div class="reverse-option-order">
    <h2>writing-mode: vertical-rl</h2>
    <select multiple>
      <option>First</option>
      <option>Second</option>
      <option>Third</option>
      <option>Fourth</option>
      <option>Fifth</option>
    </select>
  </div>
</form>

在此示例的 CSS 中,我們為這三個列表框設定了以下屬性:

  1. writing-mode: vertical-rl,顯示方式與前一個示例相同——文字從上到下流動,選項從右到左顯示。
  2. writing-mode: vertical-rldirection: rtl,選項從右到左,但文字流反轉為從下到上。
  3. writing-mode: vertical-lr,文字從上到下,但選項順序反轉為從左到右。
css
select {
  inline-size: 100px;
  margin-block-end: 20px;
  writing-mode: vertical-rl;
}

.direction select {
  direction: rtl;
}

.reverse-option-order select {
  writing-mode: vertical-lr;
}

結果如下所示:

按鈕

本節介紹如何處理垂直的 <button> 元素。請注意,雖然我們在下面的示例中只使用了 <button> 元素,但對於其他建立按鈕的元素,其行為是相同的,例如 <input>buttonresetsubmit 型別。

基本按鈕示例

下面的 HTML 建立了兩個 <button> 元素,一個帶有一行文字,另一個帶有三行:

html
<button>Press me</button> <button>Press me<br />Please?<br />Thanks</button>

要垂直顯示這些按鈕,我們可以使用如下的 CSS:

css
button {
  inline-size: 100px;
  margin-block-end: 20px;
  writing-mode: vertical-rl;
}

結果如下所示:

調整按鈕文字行順序

當你將 writing-mode 的值從 vertical-rl 切換到 vertical-lr 時,後續的文字行將出現在前一行的右側,而不是左側。

此示例使用了我們在前一個示例中看到的帶有三行文字的按鈕的兩個副本,這樣你就可以輕鬆看到更改書寫模式的效果:

html
<div>
  <h2>writing-mode: vertical-lr</h2>
  <button>Press me<br />Please?<br />Thanks</button>
</div>
<div class="reverse-line-order">
  <h2>writing-mode: vertical-rl</h2>
  <button>Press me<br />Please?<br />Thanks</button>
</div>

在 CSS 中,我們在第一個按鈕上設定 writing-mode: vertical-rl,使行順序從右到左排列。在第二個按鈕上,我們設定 writing-mode: vertical-lr 來反轉行順序——從左到右:

css
button {
  inline-size: 100px;
  margin-block-end: 20px;
  writing-mode: vertical-rl;
}

.reverse-line-order button {
  writing-mode: vertical-lr;
}

結果如下所示:

基於文字的表單控制元件

最後,我們來看看如何處理垂直的 <textarea> 和文字型別的 <input>。請注意,雖然我們在下面的示例中只包含了一個 <input type="text"> 元素,但對於其他文字型別的 <input>,其行為是相同的:passwordnumberurl 等。

基本文字輸入和 textarea 示例

下面的 HTML 建立了一個 <textarea> 和一個 <input type="text">

html
<form>
  <textarea>This is my textarea</textarea>
  <input type="text" value="Input text" />
</form>

要垂直顯示輸入框和文字區域,我們可以使用如下的 CSS:

css
textarea,
input[type="text"] {
  inline-size: 100px;
  margin-block-end: 20px;
  writing-mode: vertical-rl;
}

結果如下所示:

調整文字方向和行佈局順序

你可以使用 direction 屬性值為 rtl 來將文字方向從預設的從上到下更改為從下到上。你還可以將 writing-mode 設定為 vertical-lr 而不是 vertical-rl,以使 <textarea> 中的多行文字從左到右顯示,而不是預設的從右到左。

此示例使用了我們在前一個示例中看到的相同文字控制元件的三個副本,這樣你就可以輕鬆看到如上所述更改 directionwriting-mode 的效果:

html
<form>
  <div>
    <h2>writing-mode: vertical-lr</h2>
    <textarea>This is my textarea</textarea>
    <input type="text" value="Input text" />
  </div>
  <div class="direction">
    <h2>direction: rtl & writing-mode: vertical-lr</h2>
    <textarea>This is my textarea</textarea>
    <input type="text" value="Input text" />
  </div>
  <div class="reverse-line-order">
    <h2>writing-mode: vertical-rl</h2>
    <textarea>This is my textarea</textarea>
    <input type="text" value="Input text" />
  </div>
</form>

在 CSS 中,我們為這三組文字控制元件設定了以下屬性:

  1. writing-mode: vertical-rl 使其顯示方式與前一個示例相同——文字從上到下流動,行從右到左流動。
  2. writing-mode: vertical-rldirection: rtl 使行從右到左流動,但文字流反轉為從下到上。
  3. writing-mode: vertical-lr 使文字從上到下流動,但反轉了行的流動方向——從左到右。請注意,這對 <input type="text"> 元素沒有影響,因為它們始終是單行。
css
textarea,
input[type="text"] {
  inline-size: 100px;
  margin-block-end: 20px;
  writing-mode: vertical-rl;
}

.direction textarea,
.direction input[type="text"] {
  writing-mode: vertical-rl;
  direction: rtl;
}

.reverse-line-order textarea,
.reverse-line-order input[type="text"] {
  writing-mode: vertical-lr;
}

結果如下所示:

另見