创建垂直表单控件

本指南介绍如何使用 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 会将最小值设置为滑块的顶部,将最大值设置为滑块的底部。

以下各节将展示如何创建不同类型的垂直表单控件,以及每个控件的示例。请参阅每个链接的参考页面上的浏览器兼容性信息,以了解每种类型的准确支持信息。

范围滑块、仪表和进度条

让我们看看如何创建垂直范围滑块、测量器和进度条。

基本示例

一组典型的视觉 <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。这会导致滑块、测量器和进度条从上到下绘制,如上所示。

您可以通过设置 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" 属性可以添加到 <input type="range"> 元素本身中,用于旧版 Firefox。

此示例的 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> 元素。

选择基本示例

以下 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 将文本方向设置为从下到上,而不是默认的从上到下。

还值得注意的是,在上面的示例中,选择选项的内联方向是从右到左,因为我们使用了 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> 类型为 <input type="text"> 的元素,但其他文本 <input> 类型的行为也是相同的:passwordnumberurl 等。

基本文本输入和文本区域示例

以下 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;
}

结果如下所示

另请参阅