Skip to main content Skip to docs navigation

RTL

了解如何在 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’s RTL feature is still experimental and will evolve based on user feedback. Spotted something or have an improvement to suggest? Open an issue, we’d love to get your insights.

必需的 HTML

¥Required HTML

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

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

  1. <html> 元素上设置 dir="rtl"

    ¥Set dir="rtl" on the <html> element.

  2. <html> 元素上添加适当的 lang 属性,例如 lang="ar"

    ¥Add an appropriate lang attribute, like lang="ar", on the <html> element.

从那里,你需要添加 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.3/dist/css/bootstrap.rtl.min.css" integrity="sha384-dpuaG1suU0eT09tx5plTaGMLBsfDLzUCCUXOY2j/LSvXYuG6Bqs43ALlhIqAJVRb" 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.3/dist/css/bootstrap.rtl.min.css" integrity="sha384-dpuaG1suU0eT09tx5plTaGMLBsfDLzUCCUXOY2j/LSvXYuG6Bqs43ALlhIqAJVRb" 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.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" 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.3/dist/js/bootstrap.min.js" integrity="sha384-0pUGZvbkm6XF6gxjEnlmuGrJXVbNuzT9qBBavbLwCsOGabYfZo0T0to5eqruptLy" 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。

    ¥First, we decided to build it with the RTLCSS project. This gives us some powerful features for managing changes and overrides when moving from LTR to RTL. It also allows us to build two versions of Bootstrap from one codebase.

  2. 其次,我们重命名了一些方向类以采用逻辑属性方法。感谢我们的 Flex 工具,你们中的大多数人已经与逻辑属性进行了交互 - 它们替换了 leftright 等方向属性,而有利于 startend。这使得类名和值适合 LTR 和 RTL,而无需任何开销。

    ¥Second, we’ve renamed a handful of directional classes to adopt a logical properties approach. Most of you have already interacted with logical properties thanks to our flex utilities—they replace direction properties like left and right in favor start and end. That makes the class names and values appropriate for LTR and RTL without any overhead.

例如,使用 .ms-3 代替 margin-left.ml-3

¥For example, instead of .ml-3 for margin-left, use .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.

Edge cases and known limitations to consider when working with a combined LTR and RTL implementation:

  1. When switching .ltr and .rtl, make sure you add dir and lang attributes accordingly.
  2. Loading both files can be a real performance bottleneck: consider some optimization, and maybe try to load one of those files asynchronously.
  3. Nesting styles this way will prevent our form-validation-state() mixin from working as intended, thus require you tweak it a bit by yourself. See #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).

Important things to take into account when using PostCSS RTLCSS to build a combined LTR and RTL implementation:

  1. It is recommended that you add the dir attribute to the html element. This way, the entire page will be affected when you change the direction. Also, make sure you add the lang attribute accordingly.
  2. Having a single bundle with both directions will increase the size of the final stylesheet (on average, by 20%-30%): consider some optimization.
  3. Take into account that PostCSS RTLCSS is not compatible with /* rtl:remove */ directives because it doesn’t remove any CSS rule. You should replace your /* rtl:remove */, /* rtl:begin:remove */ and /* rtl:end:remove */ directives with /* rtl:ignore */, /* rtl:begin:ignore */ and /* rtl:end:ignore */ directives respectively. These directives will ignore the rule and will not create an RTL counterpart (same result as the remove ones in RTLCSS).

面包屑案例

¥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