CSS 逻辑视口单位:`vi` (inline) 与 `vb` (block) 在不同书写模式下的动态变化

CSS 逻辑视口单位:vi (inline) 与 vb (block) 在不同书写模式下的动态变化

大家好,今天我们来深入探讨 CSS 逻辑视口单位 vivb,以及它们在不同书写模式 (writing modes) 下的动态变化。理解这两个单位对于创建响应式且能适应各种国际化布局的网页至关重要。

1. 视口单位的引入与传统视口单位的局限性

在响应式 Web 设计中,视口单位 (Viewport Units) 扮演着关键角色。vw (viewport width) 和 vh (viewport height) 允许我们根据视口的宽度和高度来定义元素的大小,从而实现相对视口大小的布局。例如,width: 50vw 会使元素的宽度占据视口宽度的 50%。

然而,vwvh 存在一个局限性:它们始终与视口的物理宽度和高度相关,而忽略了文本的书写方向和布局方向。在传统的水平书写模式(例如,从左到右)下,这通常不是问题。但是,当涉及到垂直书写模式(例如,日语的某些形式、蒙古语)或从右到左的书写模式(例如,阿拉伯语、希伯来语)时,vwvh 的行为可能不符合预期。

2. 逻辑视口单位:vivb 的诞生

为了解决上述局限性,CSS 引入了逻辑视口单位 vivb。这两个单位分别代表:

  • vi (inline viewport unit): 代表视口内联轴 (inline axis) 的大小。内联轴是文本在行内排列的方向。
  • vb (block viewport unit): 代表视口块轴 (block axis) 的大小。块轴是新文本块排列的方向。

关键区别在于,vivb 的含义会随着书写模式 (writing-mode) 和文本方向 (direction) 的改变而动态变化。这意味着,无论文本的书写方向如何,使用 vivb 都能确保元素的大小与视口的逻辑方向保持一致。

3. writing-modedirection 属性回顾

在深入了解 vivb 之前,我们需要回顾一下 writing-modedirection 这两个 CSS 属性,因为它们直接影响 vivb 的行为。

  • writing-mode: 定义了文本在块容器中是水平流动还是垂直流动。常见的值包括:

    • horizontal-tb (默认值): 水平方向从上到下流动。
    • vertical-rl: 垂直方向从右到左流动。
    • vertical-lr: 垂直方向从左到右流动。
  • direction: 定义了文本和其它内联内容的书写方向。常见的值包括:

    • ltr (默认值): 从左到右。
    • rtl: 从右到左。

4. vivb 在不同书写模式下的行为详解

现在,我们来看几个例子,说明 vivb 在不同书写模式下的行为。

4.1 水平书写模式 (writing-mode: horizontal-tb)

这是默认的书写模式,文本从左到右(或从右到左,取决于 direction 属性)水平排列,然后从上到下垂直排列。

  • 如果 direction: ltr (从左到右):

    • vi 相当于 vw (视口宽度)
    • vb 相当于 vh (视口高度)
  • 如果 direction: rtl (从右到左):

    • vi 仍然相当于 vw (视口宽度)
    • vb 仍然相当于 vh (视口高度)

在这个模式下,direction 属性不会影响 vivb 的行为,因为内联轴仍然是水平的,块轴仍然是垂直的。

<!DOCTYPE html>
<html>
<head>
<title>vi/vb - Horizontal Writing Mode</title>
<style>
body {
  margin: 0;
  height: 100vh; /* 确保视口高度完整 */
}

.container {
  width: 50vi;
  height: 50vb;
  background-color: lightblue;
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 20px;
}

/* 示例:direction: rtl */
.rtl {
  direction: rtl;
  background-color: lightcoral;
  margin-top: 20px;
}
</style>
</head>
<body>

<div class="container">
  vi/vb (ltr) - 宽度: 50vi, 高度: 50vb
</div>

<div class="container rtl">
  vi/vb (rtl) - 宽度: 50vi, 高度: 50vb
</div>

</body>
</html>

在这个例子中,两个 div 元素的宽度都是视口宽度的 50%,高度都是视口高度的 50%。direction: rtl 对元素的尺寸没有影响。

4.2 垂直书写模式 (writing-mode: vertical-rlwriting-mode: vertical-lr)

在这个模式下,文本垂直排列,然后从右到左 (vertical-rl) 或从左到右 (vertical-lr) 水平排列。

  • writing-mode: vertical-rl:

    • vi 相当于 vh (视口高度)
    • vb 相当于 vw (视口宽度)
  • writing-mode: vertical-lr:

    • vi 相当于 vh (视口高度)
    • vb 相当于 vw (视口宽度)

无论 direction 属性的值如何,vivb 的行为都是相同的。这是因为在垂直书写模式下,内联轴是垂直的,块轴是水平的。

<!DOCTYPE html>
<html>
<head>
<title>vi/vb - Vertical Writing Mode</title>
<style>
body {
  margin: 0;
  height: 100vh; /* 确保视口高度完整 */
}

.container {
  width: 50vb;
  height: 50vi;
  background-color: lightgreen;
  writing-mode: vertical-rl; /* 或 vertical-lr */
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 20px;
}

.lr {
    writing-mode: vertical-lr;
    background-color: lightgoldenrodyellow;
    margin-top: 20px;
}
</style>
</head>
<body>

<div class="container">
  vi/vb (vertical-rl) - 宽度: 50vb, 高度: 50vi
</div>

<div class="container lr">
    vi/vb (vertical-lr) - 宽度: 50vb, 高度: 50vi
  </div>

</body>
</html>

在这个例子中,writing-mode 设置为 vertical-rldiv 元素的宽度是视口宽度的 50%,高度是视口高度的 50%。 切换成vertical-lr后,vivb依然会动态的调整。

5. 逻辑视口单位的应用场景

vivb 在以下场景中特别有用:

  • 创建适应不同书写模式的布局: 无论文本的书写方向如何,都能确保元素的大小与视口的逻辑方向保持一致。
  • 实现国际化 (i18n) 支持: 轻松适应不同的语言和文化,而无需修改大量的 CSS 代码。
  • 构建复杂的布局: 结合其他 CSS 属性,例如 flexboxgrid,可以创建更灵活和响应式的布局。

6. 与其他视口单位的比较

单位 描述 行为
vw 视口宽度 (viewport width) 的百分比 始终与视口的物理宽度相关,不受 writing-modedirection 影响。
vh 视口高度 (viewport height) 的百分比 始终与视口的物理高度相关,不受 writing-modedirection 影响。
vi 视口内联轴 (inline axis) 的百分比 根据 writing-modedirection 动态变化。在水平书写模式下相当于 vw,在垂直书写模式下相当于 vh
vb 视口块轴 (block axis) 的百分比 根据 writing-modedirection 动态变化。在水平书写模式下相当于 vh,在垂直书写模式下相当于 vw
vmin vwvh 中较小的值的百分比 始终与 vwvh 相关,不受 writing-modedirection 影响。
vmax vwvh 中较大的值的百分比 始终与 vwvh 相关,不受 writing-modedirection 影响。
svwsvhsvisvblvwlvhlvilvbdvwdvhdvidvb Small/Large/Dynamic Viewport Units 考虑了浏览器地址栏等UI元素,并且在不同状态下会动态调整视口的大小。

7. 浏览器兼容性

vivb 的浏览器兼容性良好,主流浏览器都支持这些单位。但是,为了确保最佳的兼容性,建议使用 Polyfill 或 PostCSS 插件来支持旧版本的浏览器。可以通过 caniuse.com 查看最新的兼容性信息。

8. 使用注意事项

  • 理解 writing-modedirection: 在使用 vivb 之前,务必理解这两个属性如何影响布局。
  • 测试不同书写模式: 在不同的书写模式下测试你的布局,以确保它能够正常工作。
  • 避免过度使用: 虽然 vivb 非常强大,但不要过度使用它们。在某些情况下,使用传统的视口单位可能更简单和更有效。
  • 考虑动态视口单位: 比如在移动设备上,地址栏的显示与隐藏会改变视口的高度,如果需要更精确的控制,可以考虑使用 svh, lvhdvh 等动态视口单位。

9. 示例:创建自适应书写模式的卡片布局

下面是一个示例,展示如何使用 vivb 创建一个自适应书写模式的卡片布局。

<!DOCTYPE html>
<html>
<head>
<title>Adaptive Card Layout</title>
<style>
body {
  margin: 0;
  height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
}

.card {
  width: 80vi; /* 宽度为视口内联轴的 80% */
  height: 60vb; /* 高度为视口块轴的 60% */
  background-color: #f0f0f0;
  border-radius: 8px;
  padding: 20px;
  box-sizing: border-box;
  text-align: center;
}

.card h2 {
  font-size: 2vi; /* 字体大小为视口内联轴的 2% */
  margin-bottom: 10px;
}

.card p {
  font-size: 1.5vi; /* 字体大小为视口内联轴的 1.5% */
  line-height: 1.4;
}

/* 垂直书写模式 */
.vertical {
  writing-mode: vertical-rl;
}
</style>
</head>
<body>

<div class="card">
  <h2>卡片标题 (Horizontal)</h2>
  <p>这是一个使用 vi 和 vb 创建的自适应卡片布局示例。无论书写模式如何变化,卡片的尺寸和字体大小都会相应调整。</p>
</div>

<div class="card vertical">
    <h2>卡片标题 (Vertical)</h2>
    <p>这是一个使用 vi 和 vb 创建的自适应卡片布局示例。无论书写模式如何变化,卡片的尺寸和字体大小都会相应调整。</p>
  </div>

</body>
</html>

在这个例子中,卡片的宽度和高度分别基于 vivb,字体大小也基于 vi。当应用 vertical 类时,卡片的书写模式变为垂直方向,vivb 会自动调整,从而保持卡片布局的比例和可读性。

10. 更多代码示例

/* 设置根元素的字体大小,使其与视口内联轴的宽度成比例 */
:root {
  font-size: 1vi; /* 1vi = 1% of the viewport's inline size */
}

/* 确保图像在容器中完全显示,并保持其纵横比 */
.image-container {
  width: 50vi;
  height: 50vb;
}

.image-container img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain; /*  重要:保持纵横比,并在容器中完整显示图像 */
}

/* 创建一个占据视口全屏的覆盖层 */
.overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vi;
  height: 100vb;
  background-color: rgba(0, 0, 0, 0.5); /* 半透明黑色 */
  z-index: 1000; /* 确保覆盖层位于其他内容之上 */
}

11. 表格总结

特性 vi vb
内联轴 (inline axis) 块轴 (block axis)
水平书写模式 相当于 vw 相当于 vh
垂直书写模式 相当于 vh 相当于 vw
direction 影响 否 (在水平或垂直书写模式下,direction 属性对 vivb 没有直接影响,因为其定义了文本流的方向,而不是轴的方向。) 否 (同上)
主要用途 创建适应不同书写模式的内联尺寸 创建适应不同书写模式的块尺寸

灵活运用,适应不同场景

今天我们一起学习了 CSS 逻辑视口单位 vivb 的概念、行为和应用。希望通过今天的讲解,大家能够更好地理解和运用这两个单位,创建更加灵活和国际化的 Web 布局。谢谢大家!

更多IT精英技术系列讲座,到智猿学院

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注