]> git.ipfire.org Git - thirdparty/bootstrap.git/commitdiff
Remove RTLCSS dependency, update docs and CSS to use native RTL (#41858)
authorMark Otto <markd.otto@gmail.com>
Sat, 15 Nov 2025 03:08:01 +0000 (19:08 -0800)
committerGitHub <noreply@github.com>
Sat, 15 Nov 2025 03:08:01 +0000 (19:08 -0800)
* Remove RTLCSS dependency, update docs and CSS to use native RTL

* Rewrite more RTL stuff, was too verbose

25 files changed:
README.md
build/generate-sri.mjs
build/generate-utilities-json.mjs
build/postcss.config.mjs
config.yml
package.json
scss/_breadcrumb.scss
scss/_carousel.scss
scss/_popover.scss
scss/_spinners.scss
scss/_tooltip.scss
scss/content/_reboot.scss
site/src/assets/examples/blog-rtl/index.astro
site/src/assets/examples/blog/blog.css
site/src/assets/examples/blog/blog.rtl.css [deleted file]
site/src/assets/examples/carousel-rtl/index.astro
site/src/assets/examples/carousel/carousel.rtl.css [deleted file]
site/src/assets/examples/cheatsheet-rtl/index.astro
site/src/assets/examples/cheatsheet/cheatsheet.rtl.css [deleted file]
site/src/assets/examples/dashboard-rtl/index.astro
site/src/assets/examples/dashboard/dashboard.rtl.css [deleted file]
site/src/content/docs/getting-started/contents.mdx
site/src/content/docs/getting-started/rtl.mdx
site/src/libs/bootstrap.ts
site/src/libs/config.ts

index e3618e643e5cc3c8b95c73adfe1ff282f93cc3c8..32e088f9e412a3ba1997ef0d4cc8708efa1bb2a4 100644 (file)
--- a/README.md
+++ b/README.md
@@ -87,34 +87,18 @@ Within the download you’ll find the following directories and files, logically
   │   ├── bootstrap-grid.css.map
   │   ├── bootstrap-grid.min.css
   │   ├── bootstrap-grid.min.css.map
-  │   ├── bootstrap-grid.rtl.css
-  │   ├── bootstrap-grid.rtl.css.map
-  │   ├── bootstrap-grid.rtl.min.css
-  │   ├── bootstrap-grid.rtl.min.css.map
   │   ├── bootstrap-reboot.css
   │   ├── bootstrap-reboot.css.map
   │   ├── bootstrap-reboot.min.css
   │   ├── bootstrap-reboot.min.css.map
-  │   ├── bootstrap-reboot.rtl.css
-  │   ├── bootstrap-reboot.rtl.css.map
-  │   ├── bootstrap-reboot.rtl.min.css
-  │   ├── bootstrap-reboot.rtl.min.css.map
   │   ├── bootstrap-utilities.css
   │   ├── bootstrap-utilities.css.map
   │   ├── bootstrap-utilities.min.css
   │   ├── bootstrap-utilities.min.css.map
-  │   ├── bootstrap-utilities.rtl.css
-  │   ├── bootstrap-utilities.rtl.css.map
-  │   ├── bootstrap-utilities.rtl.min.css
-  │   ├── bootstrap-utilities.rtl.min.css.map
   │   ├── bootstrap.css
   │   ├── bootstrap.css.map
   │   ├── bootstrap.min.css
-  │   ├── bootstrap.min.css.map
-  │   ├── bootstrap.rtl.css
-  │   ├── bootstrap.rtl.css.map
-  │   ├── bootstrap.rtl.min.css
-  │   └── bootstrap.rtl.min.css.map
+  │   └── bootstrap.min.css.map
   └── js/
       ├── bootstrap.bundle.js
       ├── bootstrap.bundle.js.map
@@ -131,7 +115,7 @@ Within the download you’ll find the following directories and files, logically
   ```
 </details>
 
-We provide compiled CSS and JS (`bootstrap.*`), as well as compiled and minified CSS and JS (`bootstrap.min.*`). [Source maps](https://web.dev/articles/source-maps) (`bootstrap.*.map`) are available for use with certain browsers’ developer tools. Bundled JS files (`bootstrap.bundle.js` and minified `bootstrap.bundle.min.js`) include [Popper](https://popper.js.org/docs/v2/).
+We provide compiled CSS and JS (`bootstrap.*`), as well as compiled and minified CSS and JS (`bootstrap.min.*`). [Source maps](https://web.dev/articles/source-maps) (`bootstrap.*.map`) are available for use with certain browsers' developer tools. Bundled JS files (`bootstrap.bundle.js` and minified `bootstrap.bundle.min.js`) include [Popper](https://popper.js.org/docs/v2/). All CSS files work for both LTR and RTL layouts thanks to logical properties—simply set `dir="rtl"` on your HTML element.
 
 
 ## Bugs and feature requests
index 5622843f347944c180c00c757507cc08c01650e4..1daa44c8c1678674d214508b7522962da941f1ba 100644 (file)
@@ -29,10 +29,6 @@ const files = [
     file: 'dist/css/bootstrap.min.css',
     configPropertyName: 'css_hash'
   },
-  {
-    file: 'dist/css/bootstrap.rtl.min.css',
-    configPropertyName: 'css_rtl_hash'
-  },
   {
     file: 'dist/js/bootstrap.min.js',
     configPropertyName: 'js_hash'
index bea11f991f1ab4b1d8a9250c8bf3e297c78d418d..3c5e93331a872d5990ed2691a6ee2c5d2cf4fd74 100644 (file)
@@ -58,24 +58,20 @@ try {
   writeFileSync(outputPath, JSON.stringify(parsed, null, 2))
   console.log(`✓ Wrote metadata to ${outputPath}`)
 
-  // Clean up temporary CSS files (including RTL variants that may have been generated)
+  // Clean up temporary CSS files
   try {
     unlinkSync(cssPath)
   } catch {
     // File may not exist
   }
 
-  // Also clean up any RTL variants that postcss may have created
-  const rtlFiles = [
-    'dist/css/utilities-metadata.tmp.rtl.css',
-    'dist/css/utilities-metadata.tmp.rtl.css.map',
-    'dist/css/utilities-metadata.tmp.rtl.min.css',
-    'dist/css/utilities-metadata.tmp.rtl.min.css.map',
+  // Also clean up any other temporary variants that may have been created
+  const tempFiles = [
     'dist/css/utilities-metadata.tmp.min.css',
     'dist/css/utilities-metadata.tmp.min.css.map'
   ]
 
-  for (const file of rtlFiles) {
+  for (const file of tempFiles) {
     try {
       unlinkSync(path.join(rootDir, file))
     } catch {
index 7717cfc3f1f6fb767cd5ab67ca4f0470c1e151cf..5085844e6e4c714fd9bdcb065dd5e022a5ccde28 100644 (file)
@@ -10,8 +10,7 @@ export default context => {
     plugins: {
       autoprefixer: {
         cascade: false
-      },
-      rtlcss: context.env === 'RTL'
+      }
     }
   }
 }
index 24d49eae5774582bc2cd4b1c1841cb5cbc035c99..de3b6767a7e71a3fbd7bf1ef44f508bc74ddda8c 100644 (file)
@@ -36,8 +36,6 @@ cdn:
   # See https://www.srihash.org for info on how to generate the hashes
   css:                  "https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css"
   css_hash:             "sha384-sRIl4kxILFvY47J16cr9ZwB07vP4J8+LH7qKQnuqkuIAvNWLzeN8tE5YBujZqJLB"
-  css_rtl:              "https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.rtl.min.css"
-  css_rtl_hash:         "sha384-CfCrinSRH2IR6a4e6fy2q6ioOX7O6Mtm1L9vRvFZ1trBncWmMePhzvafv7oIcWiW"
   js:                   "https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/js/bootstrap.min.js"
   js_hash:              "sha384-G/EV+4j2dNv+tEPo3++6LCgdCROaejBqfUeNjuKAiuXbjrxilcCdDz6ZAVfHWe1Y"
   js_bundle:            "https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/js/bootstrap.bundle.min.js"
index b72d26cf10050e6dfb9cb11c937f8fa5e8b5dedc..019aa97c41c3335f1c407e073d3d3bbfd5007418 100644 (file)
   "scripts": {
     "start": "npm-run-all --parallel watch docs-serve",
     "bundlewatch": "bundlewatch --config .bundlewatch.config.json",
-    "css": "npm-run-all css-compile css-prefix css-rtl css-minify css-docs",
+    "css": "npm-run-all css-compile css-prefix css-minify css-docs",
     "css-compile": "sass --style expanded --source-map --embed-sources --no-error-css scss/bootstrap.scss:dist/css/bootstrap.css scss/bootstrap-grid.scss:dist/css/bootstrap-grid.css scss/bootstrap-reboot.scss:dist/css/bootstrap-reboot.css scss/bootstrap-utilities.scss:dist/css/bootstrap-utilities.css",
     "css-docs": "node build/generate-utilities-json.mjs",
-    "css-rtl": "cross-env NODE_ENV=RTL postcss --config build/postcss.config.mjs --dir \"dist/css\" --ext \".rtl.css\" \"dist/css/*.css\" \"!dist/css/*.min.css\" \"!dist/css/*.rtl.css\" \"!dist/css/*.tmp.css\"",
     "css-lint": "npm-run-all --aggregate-output --continue-on-error --parallel css-lint-*",
     "css-lint-stylelint": "stylelint \"**/*.{css,scss}\" --cache --cache-location .cache/.stylelintcache",
     "css-lint-vars": "fusv scss/ site/src/scss/",
     "css-minify": "npm-run-all --aggregate-output --parallel css-minify-*",
-    "css-minify-main": "cleancss -O1 --format breakWith=lf --with-rebase --source-map --source-map-inline-sources --output dist/css/ --batch --batch-suffix \".min\" \"dist/css/*.css\" \"!dist/css/*.min.css\" \"!dist/css/*rtl*.css\" \"!dist/css/*.tmp.css\"",
-    "css-minify-rtl": "cleancss -O1 --format breakWith=lf --with-rebase --source-map --source-map-inline-sources --output dist/css/ --batch --batch-suffix \".min\" \"dist/css/*rtl.css\" \"!dist/css/*.min.css\"",
+    "css-minify-main": "cleancss -O1 --format breakWith=lf --with-rebase --source-map --source-map-inline-sources --output dist/css/ --batch --batch-suffix \".min\" \"dist/css/*.css\" \"!dist/css/*.min.css\" \"!dist/css/*.tmp.css\"",
     "css-prefix": "npm-run-all --aggregate-output --parallel css-prefix-*",
-    "css-prefix-main": "postcss --config build/postcss.config.mjs --replace \"dist/css/*.css\" \"!dist/css/*.rtl*.css\" \"!dist/css/*.min.css\" \"!dist/css/*.tmp.css\"",
+    "css-prefix-main": "postcss --config build/postcss.config.mjs --replace \"dist/css/*.css\" \"!dist/css/*.min.css\" \"!dist/css/*.tmp.css\"",
     "css-prefix-examples": "postcss --config build/postcss.config.mjs --replace \"site/src/assets/examples/**/*.css\"",
-    "css-prefix-examples-rtl": "cross-env-shell NODE_ENV=RTL postcss --config build/postcss.config.mjs --dir \"site/src/assets/examples/\" --ext \".rtl.css\" --base \"site/src/assets/examples/\" \"site/src/assets/examples/{blog,carousel,dashboard,cheatsheet}/*.css\" \"!site/src/assets/examples/{blog,carousel,dashboard,cheatsheet}/*.rtl.css\"",
     "css-test": "jasmine --config=scss/tests/jasmine.js",
     "js": "npm-run-all js-compile js-minify",
     "js-compile": "npm-run-all --aggregate-output --parallel js-compile-*",
@@ -96,7 +93,6 @@
     "netlify": "npm-run-all dist release-sri astro-build",
     "watch": "npm-run-all --parallel watch-*",
     "watch-css-main": "nodemon --watch scss/ --ext scss --exec \"npm-run-all css-lint css-compile css-prefix\"",
-    "watch-css-dist": "nodemon --watch dist/css/ --ext css --ignore \"dist/css/*.rtl.*\" --exec \"npm run css-rtl\"",
     "watch-css-docs": "nodemon --watch site/src/scss/ --ext scss --exec \"npm run css-lint\"",
     "watch-css-test": "nodemon --watch scss/ --ext scss,js --exec \"npm run css-test\"",
     "watch-js-main": "nodemon --watch js/src/ --ext js --exec \"npm-run-all js-lint js-compile\"",
     "remark-html": "^16.0.1",
     "rollup": "^4.53.2",
     "rollup-plugin-istanbul": "^5.0.0",
-    "rtlcss": "^4.3.0",
     "sass": "^1.90.0",
     "sass-true": "^9.0.0",
     "shelljs": "^0.10.0",
index f7d1929fba595cd49d3c21ee060d9ec5a4b5d6f0..a296e90f77a28387068485845df2102f48d0a0d2 100644 (file)
@@ -52,10 +52,14 @@ $breadcrumb-border-radius:          null !default;
         float: inline-start; // Suppress inline spacings and underlining of the separator
         padding-inline-end: var(--#{$prefix}breadcrumb-item-padding-x);
         color: var(--#{$prefix}breadcrumb-divider-color);
-        content: var(--#{$prefix}breadcrumb-divider, escape-svg($breadcrumb-divider)) #{"/* rtl:"} var(--#{$prefix}breadcrumb-divider, escape-svg($breadcrumb-divider-flipped)) #{"*/"};
+        content: var(--#{$prefix}breadcrumb-divider, escape-svg($breadcrumb-divider));
       }
     }
 
+    [dir="rtl"] &:not(:first-child)::before {
+      content: var(--#{$prefix}breadcrumb-divider, escape-svg($breadcrumb-divider-flipped));
+    }
+
     &.active {
       color: var(--#{$prefix}breadcrumb-item-active-color);
     }
index ebdbe820abb5ec40bfbd8dd4de8ba3f3f5acfebc..58897ba899b8784cecd446d347896ebb8a67868e 100644 (file)
@@ -179,10 +179,19 @@ $carousel-control-icon-filter-dark:   invert(1) grayscale(100) !default;
   }
 
   .carousel-control-prev-icon {
-    background-image: escape-svg($carousel-control-prev-icon-bg) #{"/*rtl:" + escape-svg($carousel-control-next-icon-bg) + "*/"};
+    background-image: escape-svg($carousel-control-prev-icon-bg);
   }
+
+  [dir="rtl"] .carousel-control-prev-icon {
+    background-image: escape-svg($carousel-control-next-icon-bg);
+  }
+
   .carousel-control-next-icon {
-    background-image: escape-svg($carousel-control-next-icon-bg) #{"/*rtl:" + escape-svg($carousel-control-prev-icon-bg) + "*/"};
+    background-image: escape-svg($carousel-control-next-icon-bg);
+  }
+
+  [dir="rtl"] .carousel-control-next-icon {
+    background-image: escape-svg($carousel-control-prev-icon-bg);
   }
 
   // Optional indicator pips/controls
index a0dbcb90363e498b21a2a3655f9deece4fae3f68..e53b4c6f9f14d10741ec81e36c2156a5ea5500f1 100644 (file)
@@ -107,7 +107,6 @@ $popover-arrow-height:              .5rem !default;
     }
   }
 
-  /* rtl:begin:ignore */
   .bs-popover-end {
     > .popover-arrow {
       left: calc(-1 * (var(--#{$prefix}popover-arrow-height)) - var(--#{$prefix}popover-border-width));
@@ -131,8 +130,6 @@ $popover-arrow-height:              .5rem !default;
     }
   }
 
-  /* rtl:end:ignore */
-
   .bs-popover-bottom {
     > .popover-arrow {
       top: calc(-1 * (var(--#{$prefix}popover-arrow-height)) - var(--#{$prefix}popover-border-width));
@@ -166,7 +163,6 @@ $popover-arrow-height:              .5rem !default;
     }
   }
 
-  /* rtl:begin:ignore */
   .bs-popover-start {
     > .popover-arrow {
       right: calc(-1 * (var(--#{$prefix}popover-arrow-height)) - var(--#{$prefix}popover-border-width));
@@ -190,8 +186,6 @@ $popover-arrow-height:              .5rem !default;
     }
   }
 
-  /* rtl:end:ignore */
-
   .bs-popover-auto {
     &[data-popper-placement^="top"] {
       @extend .bs-popover-top;
index b246e74788076de9ff66b343228686258dbb06b2..aa3b96db6f52b5832a230cbfe712aae7ce5d633a 100644 (file)
@@ -32,7 +32,7 @@ $spinner-border-width-sm: .2em !default;
 
   // scss-docs-start spinner-border-keyframes
   @keyframes spinner-border {
-    to { transform: rotate(360deg) #{"/* rtl:ignore */"}; }
+    to { transform: rotate(360deg); }
   }
   // scss-docs-end spinner-border-keyframes
 
index 2f8788f35ec627be6e0a86a464c93f4cbefc755d..d08e84dbba9eb1c000a414da5e50a0aaff0a4dae 100644 (file)
@@ -86,7 +86,6 @@ $form-feedback-tooltip-border-radius: $tooltip-border-radius !default;
     }
   }
 
-  /* rtl:begin:ignore */
   .bs-tooltip-end .tooltip-arrow {
     left: calc(-1 * var(--#{$prefix}tooltip-arrow-height));
     width: var(--#{$prefix}tooltip-arrow-height);
@@ -99,8 +98,6 @@ $form-feedback-tooltip-border-radius: $tooltip-border-radius !default;
     }
   }
 
-  /* rtl:end:ignore */
-
   .bs-tooltip-bottom .tooltip-arrow {
     top: calc(-1 * var(--#{$prefix}tooltip-arrow-height));
 
@@ -111,7 +108,6 @@ $form-feedback-tooltip-border-radius: $tooltip-border-radius !default;
     }
   }
 
-  /* rtl:begin:ignore */
   .bs-tooltip-start .tooltip-arrow {
     right: calc(-1 * var(--#{$prefix}tooltip-arrow-height));
     width: var(--#{$prefix}tooltip-arrow-height);
@@ -124,8 +120,6 @@ $form-feedback-tooltip-border-radius: $tooltip-border-radius !default;
     }
   }
 
-  /* rtl:end:ignore */
-
   .bs-tooltip-auto {
     &[data-popper-placement^="top"] {
       @extend .bs-tooltip-top;
index 14e9ecd2f8242ac393e5dfa5b2b6f3e234183ed3..e112e3b9e3c2ab6fd08d7057993ffced154a0bb9 100644 (file)
     }
   }
 
-  // 1. A few input types should stay LTR
+  // A few input types should stay LTR regardless of document direction
   // See https://rtlstyling.com/posts/rtl-styling#form-inputs
-  // 2. RTL only output
-  // See https://rtlcss.com/learn/usage-guide/control-directives/#raw
 
-  /* rtl:raw:
   [type="tel"],
   [type="url"],
   [type="email"],
   [type="number"] {
     direction: ltr;
   }
-  */
 
   // Remove the inner padding in Chrome and Safari on macOS.
 
index 69f1a9b99c8db397f0fcdf3bda76622bf1df9b28..8553c0f2c991d189f165c87cc5aaed6f2d05f333 100644 (file)
@@ -1,7 +1,7 @@
 ---
 export const title = 'قالب المدونة'
 export const direction = 'rtl'
-export const extra_css = ['https://fonts.googleapis.com/css?family=Amiri:wght@400;700&display=swap', '../blog/blog.rtl.css']
+export const extra_css = ['https://fonts.googleapis.com/css?family=Amiri:wght@400;700&display=swap', '../blog/blog.css']
 import Placeholder from "@shortcodes/Placeholder.astro"
 ---
 
index 86eedaf1de09d17e8ca784383ca5cf86d4de47de..e12f4e14bddcea4e75a363c94b37172be075b6ed 100644 (file)
@@ -1,16 +1,29 @@
 /* stylelint-disable @stylistic/selector-list-comma-newline-after */
 
 .blog-header-logo {
-  font-family: "Playfair Display", Georgia, "Times New Roman", serif/*rtl:Amiri, Georgia, "Times New Roman", serif*/;
+  font-family: "Playfair Display", Georgia, "Times New Roman", serif;
   font-size: 2.25rem;
 }
 
+[dir="rtl"] .blog-header-logo {
+  font-family: Amiri, Georgia, "Times New Roman", serif;
+}
+
 .blog-header-logo:hover {
   text-decoration: none;
 }
 
 h1, h2, h3, h4, h5, h6 {
-  font-family: "Playfair Display", Georgia, "Times New Roman", serif/*rtl:Amiri, Georgia, "Times New Roman", serif*/;
+  font-family: "Playfair Display", Georgia, "Times New Roman", serif;
+}
+
+[dir="rtl"] h1,
+[dir="rtl"] h2,
+[dir="rtl"] h3,
+[dir="rtl"] h4,
+[dir="rtl"] h5,
+[dir="rtl"] h6 {
+  font-family: Amiri, Georgia, "Times New Roman", serif;
 }
 
 .flex-auto {
diff --git a/site/src/assets/examples/blog/blog.rtl.css b/site/src/assets/examples/blog/blog.rtl.css
deleted file mode 100644 (file)
index bd0c9d1..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/* stylelint-disable @stylistic/selector-list-comma-newline-after */
-
-.blog-header-logo {
-  font-family: Amiri, Georgia, "Times New Roman", serif;
-  font-size: 2.25rem;
-}
-
-.blog-header-logo:hover {
-  text-decoration: none;
-}
-
-h1, h2, h3, h4, h5, h6 {
-  font-family: Amiri, Georgia, "Times New Roman", serif;
-}
-
-.flex-auto {
-  flex: 0 0 auto;
-}
-
-.h-250 { height: 250px; }
-@media (min-width: 768px) {
-  .h-md-250 { height: 250px; }
-}
-
-/* Pagination */
-.blog-pagination {
-  margin-bottom: 4rem;
-}
-
-/*
- * Blog posts
- */
-.blog-post {
-  margin-bottom: 4rem;
-}
-.blog-post-meta {
-  margin-bottom: 1.25rem;
-  color: #727272;
-}
index fced29dd01efa35bafc8eb08431c7a1e3a085ebe..6a981e49423c9fcf226fbe2ca0d837aff206ce42 100644 (file)
@@ -1,7 +1,7 @@
 ---
 export const title = 'قالب  شرائح العرض'
 export const direction = 'rtl'
-export const extra_css = ['../carousel/carousel.rtl.css']
+export const extra_css = ['../carousel/carousel.css']
 import Placeholder from "@shortcodes/Placeholder.astro"
 ---
 
diff --git a/site/src/assets/examples/carousel/carousel.rtl.css b/site/src/assets/examples/carousel/carousel.rtl.css
deleted file mode 100644 (file)
index 9ff275d..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/* GLOBAL STYLES
--------------------------------------------------- */
-/* Padding below the footer and lighter body text */
-
-body {
-  padding-top: 3rem;
-  padding-bottom: 3rem;
-  color: rgb(var(--bs-tertiary-color-rgb));
-}
-
-
-/* CUSTOMIZE THE CAROUSEL
--------------------------------------------------- */
-
-/* Carousel base class */
-.carousel {
-  margin-bottom: 4rem;
-}
-/* Since positioning the image, we need to help out the caption */
-.carousel-caption {
-  bottom: 3rem;
-  z-index: 10;
-}
-
-/* Declare heights because of positioning of img element */
-.carousel-item {
-  height: 32rem;
-}
-
-
-/* MARKETING CONTENT
--------------------------------------------------- */
-
-/* Center align the text within the three columns below the carousel */
-.marketing .col-lg-4 {
-  margin-bottom: 1.5rem;
-  text-align: center;
-}
-.marketing .col-lg-4 p {
-  margin-right: .75rem;
-  margin-left: .75rem;
-}
-
-
-/* Featurettes
-------------------------- */
-
-.featurette-divider {
-  margin: 5rem 0; /* Space out the Bootstrap <hr> more */
-}
-
-/* Thin out the marketing headings */
-
-/* RESPONSIVE CSS
--------------------------------------------------- */
-
-@media (min-width: 40em) {
-  /* Bump up size of carousel content */
-  .carousel-caption p {
-    margin-bottom: 1.25rem;
-    font-size: 1.25rem;
-    line-height: 1.4;
-  }
-
-  .featurette-heading {
-    font-size: 50px;
-  }
-}
-
-@media (min-width: 62em) {
-  .featurette-heading {
-    margin-top: 7rem;
-  }
-}
index ce954a0a66ace54302330c365436e0eb4a27d637..66a2ce8ef78ad09c2f64f0f98b00db16d48477ea 100644 (file)
@@ -4,7 +4,7 @@ import { getVersionedDocsPath } from '@libs/path'
 import Example from '@shortcodes/Example.astro'
 
 export const title = 'ورقة الغش'
-export const extra_css = ['../cheatsheet/cheatsheet.rtl.css']
+export const extra_css = ['../cheatsheet/cheatsheet.css']
 export const extra_js = [{src: '../cheatsheet/cheatsheet.js'}]
 export const body_class = 'bg-body-tertiary'
 export const direction = 'rtl'
diff --git a/site/src/assets/examples/cheatsheet/cheatsheet.rtl.css b/site/src/assets/examples/cheatsheet/cheatsheet.rtl.css
deleted file mode 100644 (file)
index 416e39f..0000000
+++ /dev/null
@@ -1,156 +0,0 @@
-body {
-  scroll-behavior: smooth;
-}
-
-/**
- * Bootstrap "Journal code" icon
- * @link https://icons.getbootstrap.com/icons/journal-code/
- */
-.bd-heading a::before {
-  display: inline-block;
-  width: 1em;
-  height: 1em;
-  margin-left: .25rem;
-  content: "";
-  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23999' viewBox='0 0 16 16'%3E%3Cpath d='M4 1h8a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2h1a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1V3a1 1 0 0 0-1-1H4a1 1 0 0 0-1 1H2a2 2 0 0 1 2-2z'/%3E%3Cpath d='M2 5v-.5a.5.5 0 0 1 1 0V5h.5a.5.5 0 0 1 0 1h-2a.5.5 0 0 1 0-1H2zm0 3v-.5a.5.5 0 0 1 1 0V8h.5a.5.5 0 0 1 0 1h-2a.5.5 0 0 1 0-1H2zm0 3v-.5a.5.5 0 0 1 1 0v.5h.5a.5.5 0 0 1 0 1h-2a.5.5 0 0 1 0-1H2z'/%3E%3Cpath fill-rule='evenodd' d='M8.646 5.646a.5.5 0 0 1 .708 0l2 2a.5.5 0 0 1 0 .708l-2 2a.5.5 0 0 1-.708-.708L10.293 8 8.646 6.354a.5.5 0 0 1 0-.708zm-1.292 0a.5.5 0 0 0-.708 0l-2 2a.5.5 0 0 0 0 .708l2 2a.5.5 0 0 0 .708-.708L5.707 8l1.647-1.646a.5.5 0 0 0 0-.708z'/%3E%3C/svg%3E");
-  background-size: 1em;
-}
-
-/* stylelint-disable-next-line selector-max-universal */
-.bd-heading + div > * + * {
-  margin-top: 3rem;
-}
-
-/* Table of contents */
-.bd-aside a {
-  padding: .1875rem .5rem;
-  margin-top: .125rem;
-  margin-right: .3125rem;
-  color: var(--bs-body-color);
-}
-
-.bd-aside a:hover,
-.bd-aside a:focus {
-  color: var(--bs-body-color);
-  background-color: rgba(121, 82, 179, .1);
-}
-
-.bd-aside .active {
-  font-weight: 600;
-  color: var(--bs-body-color);
-}
-
-.bd-aside .btn {
-  padding: .25rem .5rem;
-  font-weight: 600;
-  color: var(--bs-body-color);
-}
-
-.bd-aside .btn:hover,
-.bd-aside .btn:focus {
-  color: var(--bs-body-color);
-  background-color: rgba(121, 82, 179, .1);
-}
-
-.bd-aside .btn:focus {
-  box-shadow: 0 0 0 1px rgba(121, 82, 179, .7);
-}
-
-.bd-aside .btn::before {
-  width: 1.25em;
-  line-height: 0;
-  content: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23ccc' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M5 14l6-6-6-6'/%3e%3c/svg%3e");
-  transition: transform .35s ease;
-  transform: rotate(180deg) translateX(-2px);
-  transform-origin: .5em 50%;
-}
-
-.bd-aside .btn[aria-expanded="true"]::before {
-  transform: rotate(90deg);
-}
-
-
-/* Examples */
-.scrollspy-example {
-  height: 200px;
-}
-
-[id="modal"] .bd-example .btn,
-[id="buttons"] .bd-example .btn,
-[id="tooltips"] .bd-example .btn,
-[id="popovers"] .bd-example .btn,
-[id="dropdowns"] .bd-example .btn-group,
-[id="dropdowns"] .bd-example .dropdown,
-[id="dropdowns"] .bd-example .dropup,
-[id="dropdowns"] .bd-example .dropend,
-[id="dropdowns"] .bd-example .dropstart {
-  margin: 0 0 1rem 1rem;
-}
-
-/* Layout */
-@media (min-width: 1200px) {
-  body {
-    display: grid;
-    grid-template-rows: auto;
-    grid-template-columns: 1fr 4fr 1fr;
-    gap: 1rem;
-  }
-
-  .bd-header {
-    position: fixed;
-    top: 0;
-    right: 0;
-    left: 0;
-    z-index: 1030;
-    grid-column: 1 / span 3;
-  }
-
-  .bd-aside,
-  .bd-cheatsheet {
-    padding-top: 4rem;
-  }
-
-  /**
-   * 1. Too bad only Firefox supports subgrids ATM
-   */
-  .bd-cheatsheet,
-  .bd-cheatsheet section,
-  .bd-cheatsheet article {
-    display: inherit; /* 1 */
-    grid-template-rows: auto;
-    grid-template-columns: 1fr 4fr;
-    grid-column: 1 / span 2;
-    gap: inherit; /* 1 */
-  }
-
-  .bd-aside {
-    grid-area: 1 / 3;
-    scroll-margin-top: 4rem;
-  }
-
-  .bd-cheatsheet section,
-  .bd-cheatsheet section > h2 {
-    top: 2rem;
-    scroll-margin-top: 2rem;
-  }
-
-  .bd-cheatsheet section > h2::before {
-    position: absolute;
-    top: 0;
-    right: 0;
-    bottom: -2rem;
-    left: 0;
-    z-index: -1;
-    content: "";
-  }
-
-  .bd-cheatsheet article,
-  .bd-cheatsheet .bd-heading {
-    top: 8rem;
-    scroll-margin-top: 8rem;
-  }
-
-  .bd-cheatsheet .bd-heading {
-    z-index: 1;
-  }
-}
index c5758e95c3836206017da29fc10dc5fa9399580a..5557e7b4d7d09588fc102812f2cc2e2dd690c6a2 100644 (file)
@@ -1,7 +1,7 @@
 ---
 export const title = 'قالب لوحة القيادة'
 export const direction = 'rtl'
-export const extra_css = ['../dashboard/dashboard.rtl.css']
+export const extra_css = ['../dashboard/dashboard.css']
 export const extra_js = [
   { src: 'https://cdn.jsdelivr.net/npm/chart.js@4.3.2/dist/chart.umd.js', integrity: 'sha384-eI7PSr3L1XLISH8JdDII5YN/njoSsxfbrkCTnJrzXt+ENP5MOVBxD+l6sEG4zoLp'},
   { src: 'dashboard.js'}
diff --git a/site/src/assets/examples/dashboard/dashboard.rtl.css b/site/src/assets/examples/dashboard/dashboard.rtl.css
deleted file mode 100644 (file)
index 5c8a7e2..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-.bi {
-  display: inline-block;
-  width: 1rem;
-  height: 1rem;
-}
-
-/*
- * Sidebar
- */
-
-@media (min-width: 768px) {
-  .sidebar .offcanvas-lg {
-    position: -webkit-sticky;
-    position: sticky;
-    top: 48px;
-  }
-  .navbar-search {
-    display: block;
-  }
-}
-
-.sidebar .nav-link {
-  font-size: .875rem;
-  font-weight: 500;
-}
-
-.sidebar .nav-link.active {
-  color: #2470dc;
-}
-
-.sidebar-heading {
-  font-size: .75rem;
-}
-
-/*
- * Navbar
- */
-
-.navbar-brand {
-  padding-top: .75rem;
-  padding-bottom: .75rem;
-  background-color: rgba(0, 0, 0, .25);
-  box-shadow: inset 1px 0 0 rgba(0, 0, 0, .25);
-}
-
-.navbar .form-control {
-  padding: .75rem 1rem;
-}
index 6377d7af4747268b135b339da6ff795d76de4b94..1ad5555e1d28ce761218d0d32156081c95f983e5 100644 (file)
@@ -19,34 +19,18 @@ bootstrap/
 │   ├── bootstrap-grid.css.map
 │   ├── bootstrap-grid.min.css
 │   ├── bootstrap-grid.min.css.map
-│   ├── bootstrap-grid.rtl.css
-│   ├── bootstrap-grid.rtl.css.map
-│   ├── bootstrap-grid.rtl.min.css
-│   ├── bootstrap-grid.rtl.min.css.map
 │   ├── bootstrap-reboot.css
 │   ├── bootstrap-reboot.css.map
 │   ├── bootstrap-reboot.min.css
 │   ├── bootstrap-reboot.min.css.map
-│   ├── bootstrap-reboot.rtl.css
-│   ├── bootstrap-reboot.rtl.css.map
-│   ├── bootstrap-reboot.rtl.min.css
-│   ├── bootstrap-reboot.rtl.min.css.map
 │   ├── bootstrap-utilities.css
 │   ├── bootstrap-utilities.css.map
 │   ├── bootstrap-utilities.min.css
 │   ├── bootstrap-utilities.min.css.map
-│   ├── bootstrap-utilities.rtl.css
-│   ├── bootstrap-utilities.rtl.css.map
-│   ├── bootstrap-utilities.rtl.min.css
-│   ├── bootstrap-utilities.rtl.min.css.map
 │   ├── bootstrap.css
 │   ├── bootstrap.css.map
 │   ├── bootstrap.min.css
-│   ├── bootstrap.min.css.map
-│   ├── bootstrap.rtl.css
-│   ├── bootstrap.rtl.css.map
-│   ├── bootstrap.rtl.min.css
-│   └── bootstrap.rtl.min.css.map
+│   └── bootstrap.min.css.map
 └── js/
     ├── bootstrap.bundle.js
     ├── bootstrap.bundle.js.map
@@ -62,7 +46,7 @@ bootstrap/
     └── bootstrap.min.js.map
 ```
 
-This is the most basic form of Bootstrap: compiled files for quick drop-in usage in nearly any web project. We provide compiled CSS and JS (`bootstrap.*`), as well as compiled and minified CSS and JS (`bootstrap.min.*`). [Source maps](https://web.dev/articles/source-maps) (`bootstrap.*.map`) are available for use with certain browsers’ developer tools. Bundled JS files (`bootstrap.bundle.js` and minified `bootstrap.bundle.min.js`) include [Popper](https://popper.js.org/docs/v2/).
+This is the most basic form of Bootstrap: compiled files for quick drop-in usage in nearly any web project. We provide compiled CSS and JS (`bootstrap.*`), as well as compiled and minified CSS and JS (`bootstrap.min.*`). [Source maps](https://web.dev/articles/source-maps) (`bootstrap.*.map`) are available for use with certain browsers' developer tools. Bundled JS files (`bootstrap.bundle.js` and minified `bootstrap.bundle.min.js`) include [Popper](https://popper.js.org/docs/v2/). All CSS files work for both LTR and RTL layouts thanks to logical properties—simply set `dir="rtl"` on your HTML element.
 
 ### CSS files
 
@@ -71,10 +55,10 @@ Bootstrap includes a handful of options for including some or all of our compile
 <BsTable class="table">
 | CSS files | Layout | Content | Components | Utilities |
 | --- | --- | --- | --- | --- |
-| `bootstrap.css`<br/> `bootstrap.min.css`<br/> `bootstrap.rtl.css`<br/> `bootstrap.rtl.min.css` | Included | Included | Included | Included |
-| `bootstrap-grid.css`<br/> `bootstrap-grid.rtl.css`<br/> `bootstrap-grid.min.css`<br/> `bootstrap-grid.rtl.min.css` | [Only grid system]([[docsref:/layout/grid]]) | — | — | [Only flex utilities]([[docsref:/utilities/flex]]) |
-| `bootstrap-utilities.css`<br/> `bootstrap-utilities.rtl.css`<br/> `bootstrap-utilities.min.css`<br/> `bootstrap-utilities.rtl.min.css` | — | — | — | Included |
-| `bootstrap-reboot.css`<br/> `bootstrap-reboot.rtl.css`<br/> `bootstrap-reboot.min.css`<br/> `bootstrap-reboot.rtl.min.css` | — | [Only Reboot]([[docsref:/content/reboot]]) | — | — |
+| `bootstrap.css`<br/> `bootstrap.min.css` | Included | Included | Included | Included |
+| `bootstrap-grid.css`<br/> `bootstrap-grid.min.css` | [Only grid system]([[docsref:/layout/grid]]) | — | — | [Only flex utilities]([[docsref:/utilities/flex]]) |
+| `bootstrap-utilities.css`<br/> `bootstrap-utilities.min.css` | — | — | — | Included |
+| `bootstrap-reboot.css`<br/> `bootstrap-reboot.min.css` | — | [Only Reboot]([[docsref:/content/reboot]]) | — | — |
 </BsTable>
 
 ### JS files
index 8c3ce87453c2818fc1fa22de8873881c782a6992..5b72674def6946ebff10b6c191ec91e3de2d8266 100644 (file)
@@ -4,32 +4,72 @@ description: Learn how to enable support for right-to-left text in Bootstrap acr
 toc: true
 ---
 
-## Get familiar
+<Callout type="info">
+  **ProTip:** Get familiar with Bootstrap first with our [getting started guide]([[docsref:/getting-started/introduction]]) before working with RTL.
+</Callout>
 
-We recommend getting familiar with Bootstrap first by reading through our [Getting Started Introduction page]([[docsref:/getting-started/introduction]]). Once you’ve run through it, continue reading here for how to enable RTL.
+## How it works
 
-You may also want to read up on [the RTLCSS project](https://rtlcss.com/), as it powers our approach to RTL.
+Bootstrap uses **CSS logical properties** throughout the framework to make RTL support native and automatic. Set `dir="rtl"` and add a `lang` attribute, like `lang="ar"`, on your HTML element and the browser will handle the directional layout changes for you. No separate stylesheets are needed.
 
-<Callout type="warning">
-**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]([[config:repo]]/issues/new/choose), we’d love to get your insights.
-</Callout>
+Logical properties are CSS properties that adapt to the writing mode and direction of content. Instead of using physical directions like `left` and `right`, they use logical concepts like `start` and `end`:
 
-## Required HTML
+- `margin-left` → `margin-inline-start`
+- `margin-right` → `margin-inline-end`
+- `padding-left` → `padding-inline-start`
+- `border-right` → `border-inline-end`
 
-There are two strict requirements for enabling RTL in Bootstrap-powered pages.
+When you set `dir="rtl"`, these logical properties automatically flip to match the right-to-left layout without requiring any additional CSS transformations. Only HTML changes are required.
 
-1. Set `dir="rtl"` on the `<html>` element.
-2. Add an appropriate `lang` attribute, like `lang="ar"`, on the `<html>` element.
+### Required HTML
 
-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:
+One line of changes to your HTML is all it takes to enable RTL. Bootstrap will then automatically adapt to the RTL direction using logical properties.
 
-```html
-<link rel="stylesheet" href="[[config:cdn.css_rtl]]" integrity="[[config:cdn.css_rtl_hash]]" crossorigin="anonymous">
+```diff
+- <html lang="en">
++ <html lang="ar" dir="rtl">
 ```
 
+### Live demo
+
+Toggle between LTR and RTL on this page to see Bootstrap's logical properties in action:
+
+<div class="bd-example">
+  <b-checkgroup>
+    <div class="switch">
+      <input type="checkbox" value="" id="rtlSwitch" switch />
+    </div>
+    <label for="rtlSwitch">Enable RTL mode</label>
+  </b-checkgroup>
+</div>
+
+<script>
+{`
+(function() {
+  const rtlSwitch = document.getElementById('rtlSwitch');
+  const htmlElement = document.documentElement;
+
+  // Check current direction on load
+  if (htmlElement.getAttribute('dir') === 'rtl') {
+    rtlSwitch.checked = true;
+  }
+
+  rtlSwitch.addEventListener('change', function() {
+    if (this.checked) {
+      htmlElement.setAttribute('dir', 'rtl');
+      htmlElement.setAttribute('lang', 'ar');
+    } else {
+      htmlElement.setAttribute('dir', 'ltr');
+      htmlElement.setAttribute('lang', 'en');
+    }
+  });
+})();
+`}
+</script>
+
 ### Starter template
 
-You can see the above requirements reflected in this modified RTL starter template.
+Here's a modified RTL starter template:
 
 ```html
 <!doctype html>
@@ -40,7 +80,7 @@ You can see the above requirements reflected in this modified RTL starter templa
     <meta name="viewport" content="width=device-width, initial-scale=1">
 
     <!-- Bootstrap CSS -->
-    <link rel="stylesheet" href="[[config:cdn.css_rtl]]" integrity="[[config:cdn.css_rtl_hash]]" crossorigin="anonymous">
+    <link rel="stylesheet" href="[[config:cdn.css]]" integrity="[[config:cdn.css_hash]]" crossorigin="anonymous">
 
     <title>مرحبًا بالعالم!</title>
   </head>
@@ -65,122 +105,37 @@ You can see the above requirements reflected in this modified RTL starter templa
 
 Get started with one of our several [RTL examples]([[docsref:/examples/#rtl]]).
 
-## Approach
-
-Our approach to building RTL support into Bootstrap comes with two important decisions that impact how we write and use our CSS:
-
-1. **First, we decided to build it with the [RTLCSS](https://rtlcss.com/) 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. **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.
-
-  For example, instead of `.ml-3` for `margin-left`, use `.ms-3`.
-
-Working with RTL, through our source Sass or compiled CSS, shouldn’t be much different from our default LTR though.
-
-## Customize from source
+## Switching directions
 
-When it comes to [customization]([[docsref:/customize/sass]]), 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](https://rtlcss.com/learn/getting-started/why-rtlcss/).
-
-### Custom RTL values
-
-Using [RTLCSS value directives](https://rtlcss.com/learn/usage-guide/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:
-
-```scss
-$font-weight-bold: 700 #{/* rtl:600 */} !default;
-```
-
-Which would output to the following for our default CSS and RTL CSS:
-
-```css
-/* bootstrap.css */
-dt {
-  font-weight: 700 /* rtl:600 */;
-}
-
-/* bootstrap.rtl.css */
-dt {
-  font-weight: 600;
-}
-```
-
-### Alternative font stack
-
-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.
-
-For example, to switch from `Helvetica Neue` font for LTR to `Helvetica Neue Arabic` for RTL, your Sass code could look like this:
-
-```scss
-$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;
-```
+**Need both LTR and RTL on the same page?** Wrap your content in containers with different `dir` attributes:
 
-### LTR and RTL at the same time
-
-Need both LTR and RTL on the same page? Thanks to [RTLCSS String Maps](https://rtlcss.com/learn/usage-guide/string-map/), this is pretty straightforward. Wrap your `@import`s with a class, and set a custom rename rule for RTLCSS:
-
-```scss
-/* 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*/
+```html
+<!doctype html>
+<html lang="en">
+  <head>
+    <meta charset="utf-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1">
+    <link rel="stylesheet" href="[[config:cdn.css]]" integrity="[[config:cdn.css_hash]]" crossorigin="anonymous">
+    <title>LTR and RTL</title>
+  </head>
+  <body>
+    <!-- LTR content -->
+    <div dir="ltr" lang="en">
+      <h1>This is left-to-right text</h1>
+      <p>Content flows from left to right.</p>
+    </div>
+
+    <!-- RTL content -->
+    <div dir="rtl" lang="ar">
+      <h1>هذا نص من اليمين إلى اليسار</h1>
+      <p>المحتوى يتدفق من اليمين إلى اليسار.</p>
+    </div>
+  </body>
+</html>
 ```
 
-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.
-
-<Callout type="warning">
-**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]([[docsref:/customize/optimize]]), and maybe try to [load one of those files asynchronously](https://www.filamentgroup.com/lab/load-css-simpler/).
-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](https://github.com/twbs/bootstrap/issues/31223).
-</Callout>
-
-Do you want to automate this process and address several edge cases involving both directions within a single stylesheet? Then, consider using [PostCSS RTLCSS](https://github.com/elchininet/postcss-rtlcss) as a [PostCSS](https://github.com/postcss/postcss) plugin to process your source files. PostCSS RTLCSS uses [RTLCSS](https://rtlcss.com) 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).
-
-<Callout type="warning">
-**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]([[docsref:/customize/optimize]]).
-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:freeze */`, `/* rtl:begin:freeze */` and `/* rtl:end:freeze */` directives respectively. These directives will prefix the targeted rules or declarations with the current direction but will not create an RTL counterpart (same result as the `remove` ones in RTLCSS).
-</Callout>
-
-## The breadcrumb case
-
-The [breadcrumb separator]([[docsref:/components/breadcrumb]]#dividers) is the only case requiring its own brand-new variable— namely `$breadcrumb-divider-flipped` —defaulting to `$breadcrumb-divider`.
-
 ## Additional resources
 
-- [RTLCSS](https://rtlcss.com/)
+- [MDN: CSS Logical Properties and Values](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Logical_Properties)
+- [CSS Logical Properties - web.dev](https://web.dev/learn/css/logical-properties/)
 - [RTL Styling 101](https://rtlstyling.com/posts/rtl-styling)
index fb124637980e9cd5a3e48b2b587072dedaa269c3..39af96e756a108742fc15ac4457047d9429761ca 100644 (file)
@@ -5,10 +5,6 @@ import { getVersionedDocsPath } from '@libs/path'
 export function getVersionedBsCssProps(direction: 'rtl' | undefined) {
   let bsCssLinkHref = '/dist/css/bootstrap'
 
-  if (direction === 'rtl') {
-    bsCssLinkHref = `${bsCssLinkHref}.rtl`
-  }
-
   if (import.meta.env.PROD) {
     bsCssLinkHref = `${bsCssLinkHref}.min`
   }
@@ -21,7 +17,7 @@ export function getVersionedBsCssProps(direction: 'rtl' | undefined) {
   }
 
   if (import.meta.env.PROD) {
-    bsCssLinkProps.integrity = direction === 'rtl' ? getConfig().cdn.css_rtl_hash : getConfig().cdn.css_hash
+    bsCssLinkProps.integrity = getConfig().cdn.css_hash
   }
 
   return bsCssLinkProps
index be01d8550e61da7b912a47bd8c8a6f541738b700..d3fb83b759cf8ff5b6a9dff0e936803ff5e950a0 100644 (file)
@@ -22,9 +22,7 @@ const configSchema = z.object({
   blog: z.string().url(),
   cdn: z.object({
     css: z.string().url(),
-    css_rtl: z.string().url(),
     css_hash: z.string(),
-    css_rtl_hash: z.string(),
     js: z.string().url(),
     js_hash: z.string(),
     js_bundle: z.string().url(),