Bootstrap 5 Tutorial

v5.3.0

Bootstrap 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 lang attribute (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 ClassRTL EquivalentDescription
.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
We'll never share your email with anyone else.
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" and lang attributes
  • 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/right instead 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/end over left/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 lang values
  • 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 attribute
  • bootstrap.rtl.min.css - RTL CSS file
  • .ms-* / .me-* - Margin start/end
  • .text-start / .text-end - Text alignment
  • .border-start / .border-end - Border sides
  • margin-inline-start - CSS logical property
  • $enable-rtl: true - Sass variable
Implementation Checklist