跳到主要内容

RTL(从右到左)

学习如何在我们的布局、组件和工具中启用对 Bootstrap 右到左文本的支持。

熟悉

我们建议首先通过阅读我们的入门介绍页面来熟悉 Bootstrap。一旦你完成了阅读,请继续在这里了解如何启用 RTL。

你可能还想了解一下 RTLCSS 项目,因为它推动了我们对 RTL 的方法。

Bootstrap 的 RTL 功能仍处于实验阶段,将根据用户反馈不断发展。发现了问题或有改进建议吗?提交问题,我们很希望听到你的意见。

必需的 HTML

在使用 Bootstrap 的页面中启用 RTL 有两个严格的要求。

  1. 设置 dir="rtl" 在……上 <html> 元素。
  2. 添加适当的 lang 属性,像 lang="ar",在 <html> 元素。

从那里,你需要包含我们 CSS 的 RTL 版本。例如,这里是启用 RTL 的已编译和压缩 CSS 的样式表:

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.rtl.min.css" integrity="sha384-CfCrinSRH2IR6a4e6fy2q6ioOX7O6Mtm1L9vRvFZ1trBncWmMePhzvafv7oIcWiW" crossorigin="anonymous">

起始模板

你可以在这个修改过的 RTL 启动模板中看到上述要求的体现。

<!doctype html>
<html lang="ar" dir="rtl">
  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
<span class="token comment">&lt;!-- Bootstrap CSS --&gt;</span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>link</span> <span class="token attr-name">rel</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>stylesheet<span class="token punctuation">"</span></span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.rtl.min.css<span class="token punctuation">"</span></span> <span class="token attr-name">integrity</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>sha384-CfCrinSRH2IR6a4e6fy2q6ioOX7O6Mtm1L9vRvFZ1trBncWmMePhzvafv7oIcWiW<span class="token punctuation">"</span></span> <span class="token attr-name">crossorigin</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>anonymous<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>

<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>title</span><span class="token punctuation">&gt;</span></span>مرحبًا بالعالم!<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>title</span><span class="token punctuation">&gt;</span></span>

</head> <body> <h1>مرحبًا بالعالم!</h1>

<span class="token comment">&lt;!-- Optional JavaScript; choose one of the two! --&gt;</span>

<span class="token comment">&lt;!-- Option 1: Bootstrap Bundle with Popper --&gt;</span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span> <span class="token attr-name">src</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/js/bootstrap.bundle.min.js<span class="token punctuation">"</span></span> <span class="token attr-name">integrity</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>sha384-FKyoEForCGlyvwx9Hj09JcYn3nv7wiPVlz7YYwJrWVcXK/BmnVDxM+D2scQbITxI<span class="token punctuation">"</span></span> <span class="token attr-name">crossorigin</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>anonymous<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span><span class="token script"></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">&gt;</span></span>

<span class="token comment">&lt;!-- Option 2: Separate Popper and Bootstrap JS --&gt;</span>
<span class="token comment">&lt;!--
&lt;script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.8/dist/umd/popper.min.js" integrity="sha384-I7E8VVD/ismYTF4hNIPjVp/Zjvgyol6VFvRkX/vR+Vc4jQkC+hVqc2pM8ODewa9r" crossorigin="anonymous"&gt;&lt;/script&gt;
&lt;script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/js/bootstrap.min.js" integrity="sha384-G/EV+4j2dNv+tEPo3++6LCgdCROaejBqfUeNjuKAiuXbjrxilcCdDz6ZAVfHWe1Y" crossorigin="anonymous"&gt;&lt;/script&gt;
--&gt;</span>

</body> </html>

RTL 示例

从我们的一些 RTL 示例 中开始。

方法

我们在 Bootstrap 中构建 RTL 支持的方法涉及两个重要决定,这会影响我们如何编写和使用 CSS:

  1. 首先,我们决定用它来建造 RTLCSS 项目。 这为我们在从从左到右(LTR)切换到从右到左(RTL)时管理更改和覆盖提供了一些强大的功能。它还允许我们从一个代码库构建两个版本的 Bootstrap。

  2. 其次,我们已将少数几个方向类重命名,以采用逻辑属性的方法。 你们大多数人已经通过我们的 flex 工具使用过逻辑属性——它们替代了方向属性,例如 left 和 right 支持 start 和 end这使得类名和数值对于从左到右(LTR)和从右到左(RTL)都是合适的,而无需任何额外开销。

例如,不要使用 .ml-3 来表示 margin-left,而使用 .ms-3。

通过我们的源 Sass 或编译后的 CSS 处理 RTL,应该与默认的 LTR 并没有太大不同。

从源自定义

在涉及自定义时,首选的方法是利用变量、映射和mixin。由于RTLCSS 的工作原理,即使是在从编译文件后处理的情况下,这种方法对 RTL 也同样适用。

自定义 RTL 值

使用 RTLCSS 值指令,你可以让一个变量在 RTL 情况下输出不同的值。例如,要在整个代码库中减小 $font-weight-bold 的权重,你可以使用 /*rtl: {value}*/ 语法:

$font-weight-bold: 700 #{/* rtl:600 */} !default;

对于我们的默认 CSS 和 RTL CSS,将输出以下内容:

/* bootstrap.css */
dt {
  font-weight: 700 /* rtl:600 */;
}

/* bootstrap.rtl.css */ dt { font-weight: 600; }

替代字体堆栈

如果你正在使用自定义字体,请注意并非所有字体都支持非拉丁字母表。要从泛欧洲字体切换到阿拉伯字体系列,你可能需要在字体堆栈中使用/*rtl:insert: {value}*/来修改字体系列的名称。

例如,要将从Helvetica Neue字体用于从左到右切换到Helvetica Neue Arabic用于从右到左,你的Sass代码可以如下所示:

$font-family-sans-serif:
  Helvetica Neue #{"/* rtl:insert:Arabic */"},
  // Cross-platform generic font family (default user interface font)
  system-ui,
  // Safari for macOS and iOS (San Francisco)
  -apple-system,
  // Chrome < 56 for macOS (San Francisco)
  BlinkMacSystemFont,
  // Windows
  "Segoe UI",
  // Android
  Roboto,
  // Basic web fallback
  Arial,
  // Linux
  "Noto Sans",
  // Sans serif fallback
  sans-serif,
  // Emoji fonts
  "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji" !default;

从左到右(LTR)和从右到左(RTL)同时存在

需要在同一页面上同时使用LTR和RTL吗?多亏了RTLCSS字符串映射,这非常简单。用一个类包裹你的@import,然后为RTLCSS设置自定义重命名规则:

/* rtl:begin:options: {
  "autoRename": true,
  "stringMap":[ {
    "name": "ltr-rtl",
    "priority": 100,
    "search": ["ltr"],
    "replace": ["rtl"],
    "options": {
      "scope": "*",
      "ignoreCase": false
    }
  } ]
} */
.ltr {
  @import "../node_modules/bootstrap/scss/bootstrap";
}
/*rtl:end:options*/

在运行 Sass 然后运行 RTLCSS 之后,你的 CSS 文件中的每个选择器都会被添加 .ltr 前缀,RTL 文件则添加 .rtl 前缀。现在你可以在同一页面上使用这两个文件,只需在你的组件包装元素上使用 .ltr 或 .rtl 来使用其中一个方向。

在使用混合的LTR和RTL实现时需要考虑的边缘情况和已知限制:

  1. 在切换.ltr和.rtl时,确保相应地添加dir和lang属性。
  2. 同时加载两个文件可能会成为实际性能瓶颈:考虑进行一些优化,也可以尝试异步加载其中一个文件。
  3. 以这种方式嵌套样式会阻止我们的form-validation-state()mixin按预期工作,因此需要你自己稍作调整。见#31223。

你是否想自动化此过程,并在单个样式表中处理涉及双向的多个边缘情况?那么,可以考虑使用 PostCSS RTLCSS 作为 PostCSS 插件来处理你的源文件。PostCSS RTLCSS 在幕后使用 RTLCSS 来管理方向翻转过程,但它将翻转后的声明分离到带有不同前缀的规则中,用于 LTR 和 RTL,这样可以让你在同一个样式表文件中同时拥有两种方向。通过这样做,你可以通过简单地更改页面的dir(甚至通过根据插件配置修改特定类)来在 LTR 和 RTL 方向之间切换。

需要考虑的重要事项 在使用 PostCSS RTLCSS 构建组合的 LTR 和 RTL 实现时:

  1. 建议为 html 元素添加 dir 属性。这样更改方向时,整个页面都会随之变化。同时记得相应更新 lang 属性。
  2. 将两种方向都放在一个捆绑包中会增加最终样式表的大小(平均增加20%-30%):考虑一些 优化.
  3. 请考虑到 PostCSS RTLCSS 不兼容 /* rtl:remove */ 指令,因为它不会移除任何 CSS 规则。你应该替换你的 /* rtl:remove */, /* rtl:begin:remove */ 和 /* rtl:end:remove */ 带有指令的 /* rtl:freeze */, /* rtl:begin:freeze */ 和 /* rtl:end:freeze */ 各自的指令。这些指令会在目标规则或声明前加上当前方向,但不会创建 RTL 对应项(与 remove RTLCSS 中的那些).

面包屑案例

面包屑分隔符 是唯一需要自己全新变量的情况——即 $breadcrumb-divider-flipped——默认值为 $breadcrumb-divider。

附加资源