Skip to main content Skip to docs navigation

从右到左

了解如何在 Bootstrap 的布局、组件和工具中启用对从右到左文本的支持。

熟悉

🌐 Get familiar

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

🌐 We recommend getting familiar with Bootstrap first by reading through our Getting Started Introduction page. Once you’ve run through it, continue reading here for how to enable RTL.

你可能还想了解一下 RTLCSS 项目,因为它是我们 RTL 方法的基础。

🌐 You may also want to read up on the RTLCSS project, as it powers our approach to RTL.

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

必需的 HTML

🌐 Required HTML

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

🌐 There are two strict requirements for enabling RTL in Bootstrap-powered pages.

  1. <html> 元素上设置 dir="rtl"
  2. <html> 元素上添加一个适当的 lang 属性,例如 lang="ar"

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

🌐 From there, you’ll need to include an RTL version of our CSS. For example, here’s the stylesheet for our compiled and minified CSS with RTL enabled:

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

入门模板

🌐 Starter template

你可以看到上述要求反映在这个修改后的 RTL 入门模板中。

🌐 You can see the above requirements reflected in this modified RTL starter template.

<!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">

    <!-- Bootstrap 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">

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

    <!-- Optional JavaScript; choose one of the two! -->

    <!-- Option 1: Bootstrap Bundle with Popper -->
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/js/bootstrap.bundle.min.js" integrity="sha384-FKyoEForCGlyvwx9Hj09JcYn3nv7wiPVlz7YYwJrWVcXK/BmnVDxM+D2scQbITxI" crossorigin="anonymous"></script>

    <!-- Option 2: Separate Popper and Bootstrap JS -->
    <!--
    <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"></script>
    <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"></script>
    -->
  </body>
</html>

RTL 示例

🌐 RTL examples

从我们的几个 RTL 示例 中开始。

🌐 Get started with one of our several RTL examples.

方法

🌐 Approach

我们在 Bootstrap 中构建 RTL 支持的方法有两个重要的决定,它们会影响我们编写和使用 CSS 的方式:

🌐 Our approach to building RTL support into Bootstrap comes with two important decisions that impact how we write and use our CSS:

  1. 首先,我们决定使用 RTLCSS 项目来构建它。 这为我们在从 LTR 转向 RTL 时管理更改和覆盖提供了一些强大的功能。它还允许我们从一个代码库构建两个版本的 Bootstrap。
  2. 其次,我们重命名了少量方向类以采用逻辑属性方法。 你们中的大多数人已经通过我们的 flex 工具使用过逻辑属性——它们用 startend 替代了像 leftright 这样的方向属性。这样一来,类名和数值在 LTR 和 RTL 中都适用,无需额外开销。

例如,不要使用 margin-left.ml-3,而是使用 .ms-3

不过,通过我们的源 Sass 或编译后的 CSS 使用 RTL 应该与我们默认的 LTR 不会有太大区别。

🌐 Working with RTL, through our source Sass or compiled CSS, shouldn’t be much different from our default LTR though.

从源头定制

🌐 Customize from source

在涉及自定义时,首选的方法是使用变量、映射和混入。这种方法对RTL同样适用,即使它是从编译后的文件进行后处理的,这都要归功于RTLCSS的工作方式

🌐 When it comes to customization, the preferred way is to take advantage of variables, maps, and mixins. This approach works the same for RTL, even if it’s post-processed from the compiled files, thanks to how RTLCSS works.

自定义 RTL 值

🌐 Custom RTL values

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

🌐 Using RTLCSS value directives, you can make a variable output a different value for RTL. For example, to decrease the weight for $font-weight-bold throughout the codebase, you may use the /*rtl: {value}*/ syntax:

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

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

🌐 Which would output to the following for our default CSS and RTL CSS:

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

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

替代字体堆栈

🌐 Alternative font stack

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

🌐 In the case you’re using a custom font, be aware that not all fonts support the non-Latin alphabet. To switch from Pan-European to Arabic family, you may need to use /*rtl:insert: {value}*/ in your font stack to modify the names of font families.

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

🌐 For example, to switch from Helvetica Neue font for LTR to Helvetica Neue Arabic for RTL, your Sass code could look like this:

$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 and RTL at the same time

在同一页面上需要同时支持从左到右(LTR)和从右到左(RTL)吗?多亏了 RTLCSS 字符串映射,这相当简单。用一个类封装你的 @import,并为 RTLCSS 设置自定义重命名规则:

🌐 Need both LTR and RTL on the same page? Thanks to RTLCSS String Maps, this is pretty straightforward. Wrap your @imports with a class, and set a custom rename rule for 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 来选择使用某个方向。

🌐 After running Sass then RTLCSS, each selector in your CSS files will be prepended by .ltr, and .rtl for RTL files. Now you’re able to use both files on the same page, and simply use .ltr or .rtl on your components wrappers to use one or the other direction.

在处理左右混合(LTR 和 RTL)实现时需要考虑的边缘情况和已知限制

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

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

🌐 Do you want to automate this process and address several edge cases involving both directions within a single stylesheet? Then, consider using PostCSS RTLCSS as a PostCSS plugin to process your source files. PostCSS RTLCSS uses RTLCSS behind the scenes to manage the direction flipping process, but it separates the flipped declarations into rules with a different prefix for LTR and RTL, something that allows you to have both directions within the same stylesheet file. By doing this, you can switch between LTR and RTL orientations by simply changing the dir of the page (or even by modifying a specific class if you configure the plugin accordingly).

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

  1. 建议你将 dir 属性添加到 html 元素中。这样,当你更改方向时,整个页面都会受影响。此外,请确保相应地添加 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 对应项(与 RTLCSS 中的 remove 指令效果相同)。

面包屑案例

🌐 The breadcrumb case

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

🌐 The breadcrumb separator is the only case requiring its own brand-new variable— namely $breadcrumb-divider-flipped —defaulting to $breadcrumb-divider.

其他资源

🌐 Additional resources