Bootstrap 5 Tutorial
v5.3.0Bootstrap 5 Tutorial
RTL Support in Bootstrap 5
RTL Support: Learn how to implement Right-to-Left language support in Bootstrap 5 for Arabic, Hebrew, Persian, and other RTL languages.
RTL Demo
Toggle between LTR (Left-to-Right) and RTL (Right-to-Left) modes.
LTR
Left-to-Right (English)
Understanding RTL Languages
Right-to-Left (RTL) languages require mirroring the layout, including text direction, alignment, and component positioning. Bootstrap 5 provides comprehensive RTL support.
LTR (Left-to-Right)
Text flows from left to right. Margins and padding are applied to the left/right accordingly.
- English
- Spanish
- French
- German
RTL (Right-to-Left)
يتدفق النص من اليمين إلى اليسار. يتم تطبيق الهوامش والحشو على اليمين / اليسار وفقًا لذلك.
- العربية (Arabic)
- עברית (Hebrew)
- فارسی (Persian)
- اردو (Urdu)
Implementing RTL in Bootstrap 5
RTL Setup Methods
Method 1: Using RTL CSS File
The simplest method - include Bootstrap's RTL CSS file.
<!-- For LTR (default) -->
<link href="bootstrap.min.css" rel="stylesheet">
<!-- For RTL -->
<link href="bootstrap.rtl.min.css" rel="stylesheet">
<!-- Or from CDN -->
<!-- LTR -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<!-- RTL -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.rtl.min.css" rel="stylesheet">
<!-- Remember to set dir attribute -->
<html dir="rtl" lang="ar">
<!-- RTL content -->
</html>Method 2: Building RTL with Sass
Generate RTL CSS from Sass source files.
// rtl.scss
// Import Bootstrap functions/variables
@import "bootstrap/scss/functions";
@import "bootstrap/scss/variables";
// Enable RTL
$enable-rtl: true;
// Import Bootstrap
@import "bootstrap/scss/bootstrap";
// Or build specific RTL components
$enable-rtl: true;
@import "bootstrap/scss/root";
@import "bootstrap/scss/reboot";
@import "bootstrap/scss/type";
// ... other components
// Build command with RTL flag
sass --style=compressed scss/rtl.scss css/bootstrap.rtl.min.css
// Using npm scripts
{
"scripts": {
"build-rtl": "sass --style=compressed scss/rtl.scss:dist/css/bootstrap.rtl.min.css"
}
}Important Notes:
- Bootstrap 5.1+ has built-in RTL support
- Use
dir="rtl"attribute on HTML element - Set appropriate
langattribute (e.g.,lang="ar") - Test with actual RTL content, not just mirrored LTR
- Consider mixing LTR and RTL content (bi-directional text)
RTL Utilities and Classes
Direction-Aware Utilities
Bootstrap 5 introduces direction-aware utility classes that automatically adjust for RTL contexts.
Margin and Padding Utilities
| LTR Class | RTL Equivalent | Description |
|---|---|---|
.ms-* | .me-* (in RTL) | Margin start → Margin end |
.me-* | .ms-* (in RTL) | Margin end → Margin start |
.ps-* | .pe-* (in RTL) | Padding start → Padding end |
.pe-* | .ps-* (in RTL) | Padding end → Padding start |
Text Alignment
<!-- These classes work in both LTR and RTL -->
<p class="text-start">Text aligned to start</p>
<p class="text-end">Text aligned to end</p>
<p class="text-center">Centered text</p>
<!-- Legacy classes (still work) -->
<p class="text-left">Left aligned (LTR only)</p>
<p class="text-right">Right aligned (LTR only)</p>
<!-- Float utilities -->
<div class="float-start">Float start</div>
<div class="float-end">Float end</div>
<!-- In RTL mode:
- .text-start becomes right-aligned
- .text-end becomes left-aligned
- .float-start floats right
- .float-end floats left
-->Border Utilities
<!-- Border side utilities -->
<div class="border-start">Border start</div>
<div class="border-end">Border end</div>
<div class="border-top">Border top</div>
<div class="border-bottom">Border bottom</div>
<!-- In RTL:
- .border-start becomes right border
- .border-end becomes left border
-->
<!-- Border radius utilities -->
<div class="rounded-start">Rounded start</div>
<div class="rounded-end">Rounded end</div>
<div class="rounded-top">Rounded top</div>
<div class="rounded-bottom">Rounded bottom</div>
<!-- In RTL:
- .rounded-start rounds right side
- .rounded-end rounds left side
-->
<!-- Example with multiple utilities -->
<div class="border border-primary border-start-0 border-end-3 p-3">
Custom border styling that works in both LTR and RTL
</div>Visual Demonstration
Border End
Border Start
Text aligned to start (left in LTR)
Component Behavior in RTL
RTL Component Examples
Navigation
Breadcrumb
Form Elements
Pagination
Grid System in RTL
RTL Grid Layout
The grid system automatically adapts to RTL direction, maintaining proper column ordering.
First
Second
Third
Column Ordering in RTL
Order 2
Order 3
Order 1
Order 4
<!-- Grid columns automatically reorder in RTL -->
<div class="row" dir="rtl">
<div class="col-4">Column 1 (appears on right)</div>
<div class="col-4">Column 2 (appears in middle)</div>
<div class="col-4">Column 3 (appears on left)</div>
</div>
<!-- Order classes work consistently -->
<div class="row" dir="rtl">
<div class="col-3 order-2">Second in DOM, first visually</div>
<div class="col-3 order-1">First in DOM, second visually</div>
<div class="col-3 order-4">Fourth in DOM, third visually</div>
<div class="col-3 order-3">Third in DOM, fourth visually</div>
</div>
<!-- Offset classes also adapt -->
<div class="row" dir="rtl">
<div class="col-4 offset-4">
<!-- In RTL, offset-4 adds margin right -->
</div>
</div>
<!-- Responsive ordering -->
<div class="row" dir="rtl">
<div class="col-md-4 order-md-2 order-1">
<!-- Different order on mobile vs desktop -->
</div>
</div>JavaScript Components in RTL
RTL JavaScript Behavior
Dropdown Positioning
Tooltip and Popover
Carousel Direction
JavaScript Configuration for RTL
// Detecting RTL direction
const isRTL = document.documentElement.dir === 'rtl' ||
document.documentElement.getAttribute('dir') === 'rtl';
// Configuring components for RTL
// Tooltip/Popover placement
const tooltip = new bootstrap.Tooltip(element, {
placement: isRTL ? 'left' : 'right'
});
// Carousel direction
const carousel = new bootstrap.Carousel(element, {
// Carousel automatically handles RTL
});
// Dropdown positioning
// Dropdowns automatically adjust in RTL
// Modal positioning
// Modals automatically center correctly in RTL
// Toast positioning
const toast = new bootstrap.Toast(element, {
// Toasts can be positioned relative to RTL
});
// Checking if Bootstrap is in RTL mode
if (typeof bootstrap !== 'undefined') {
// Some components have RTL detection built-in
}
// Manually setting component direction
function initializeComponents() {
const direction = isRTL ? 'rtl' : 'ltr';
// Set direction on dynamically created elements
document.querySelectorAll('.dynamic-component').forEach(el => {
el.dir = direction;
});
}
// Listening for direction changes
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (mutation.attributeName === 'dir') {
const newDirection = document.documentElement.dir;
// Reinitialize components with new direction
initializeComponents();
}
});
});
observer.observe(document.documentElement, {
attributes: true,
attributeFilter: ['dir']
});Custom RTL Styling
Creating Custom RTL Styles
CSS Custom Properties for RTL
/* Using CSS logical properties */
.custom-component {
/* Use logical properties for RTL support */
margin-inline-start: 1rem; /* ms-* equivalent */
margin-inline-end: 1rem; /* me-* equivalent */
padding-inline-start: 1rem; /* ps-* equivalent */
padding-inline-end: 1rem; /* pe-* equivalent */
border-inline-start: 2px solid #000; /* border-start equivalent */
text-align: start; /* text-start equivalent */
}
/* Using :dir() pseudo-class */
.custom-component:dir(ltr) {
/* LTR specific styles */
background-position: left center;
}
.custom-component:dir(rtl) {
/* RTL specific styles */
background-position: right center;
}
/* Using attribute selectors */
[dir="ltr"] .custom-component {
/* LTR styles */
}
[dir="rtl"] .custom-component {
/* RTL styles */
transform: scaleX(-1); /* Mirror if needed */
}
/* Custom properties with direction */
:root {
--custom-spacing-start: 1rem;
--custom-spacing-end: 2rem;
}
[dir="rtl"] {
--custom-spacing-start: 2rem;
--custom-spacing-end: 1rem;
}
.custom-component {
margin-left: var(--custom-spacing-start);
margin-right: var(--custom-spacing-end);
}Sass Mixins for RTL
// RTL mixin for property flipping
@mixin rtl($property, $ltr-value, $rtl-value) {
#{$property}: $ltr-value;
[dir="rtl"] & {
#{$property}: $rtl-value;
}
}
// Usage
.custom-element {
@include rtl(margin-left, 1rem, 0);
@include rtl(margin-right, 0, 1rem);
@include rtl(text-align, left, right);
}
// Logical property mixin
@mixin logical($property, $value) {
@if $property == margin or $property == padding {
#{$property}-inline-start: $value;
} @else if $property == border {
border-inline-start: $value;
} @else if $property == float {
float: inline-start;
}
}
// Direction-aware spacing mixin
@mixin spacing($property, $values...) {
@if $enable-rtl {
@if $property == margin or $property == padding {
@if length($values) == 4 {
// margin: top right bottom left
#{$property}: nth($values, 1) nth($values, 4) nth($values, 3) nth($values, 2);
} @else if length($values) == 2 {
// margin: top-bottom left-right
#{$property}: nth($values, 1) nth($values, 2) nth($values, 1) nth($values, 2);
}
}
} @else {
#{$property}: $values;
}
}
// Bi-directional text mixin
@mixin bidi-text($ltr-content, $rtl-content) {
content: $ltr-content;
[dir="rtl"] & {
content: $rtl-content;
}
}
.custom-icon::before {
@include bidi-text("←", "→");
}Testing and Debugging RTL
RTL Testing Strategies
Testing Checklist
- HTML structure: Verify
dir="rtl"andlangattributes - Text direction: Ensure text flows right-to-left
- Alignment: Check text alignment (right-aligned in RTL)
- Margins and padding: Verify logical spacing
- Component positioning: Dropdowns, tooltips, modals
- Navigation: Menus, breadcrumbs, pagination
- Forms: Labels, inputs, validation messages
- Typography: Font family, line height, letter spacing
- Icons: Directional icons (arrows, chevrons)
- Images: Flipping if necessary
Common RTL Issues
- Mixed direction content: LTR text within RTL layout
- Hardcoded directions: Using
left/rightinstead of logical properties - Icon direction: Arrows pointing wrong way
- Background positions: Not mirrored for RTL
- Third-party components: May not support RTL
- CSS transforms: May need adjustment
- JavaScript calculations: Position calculations may be off
- Print styles: May not account for RTL
Debugging Tools
- Browser DevTools: Toggle direction attribute
- RTL testing extensions: Force RTL mode
- Screen readers: Test with Arabic/Hebrew screen readers
- Visual testing tools: Compare LTR/RTL screenshots
- Validator tools: Check for direction issues
Best Practices for RTL Implementation
RTL Implementation Best Practices
- Start with RTL in mind: Design for both directions from the beginning
- Use logical properties: Prefer
start/endoverleft/right - Test with real content: Use actual Arabic/Hebrew text, not just mirrored LTR
- Consider bidirectional text: Handle mixed LTR/RTL content properly
- Customize icons: Flip or replace directional icons for RTL
- Set proper language attributes: Use correct
langvalues - Test all components: Ensure every Bootstrap component works in RTL
- Performance considerations: RTL CSS may increase bundle size slightly
- Document RTL customizations: Team should understand RTL implementation
- User testing: Get feedback from native RTL language speakers
Quick Reference
dir="rtl"- HTML direction attributebootstrap.rtl.min.css- RTL CSS file.ms-* / .me-*- Margin start/end.text-start / .text-end- Text alignment.border-start / .border-end- Border sidesmargin-inline-start- CSS logical property$enable-rtl: true- Sass variable