Bootstrap 5 Tutorial

v5.3.0

Bootstrap 5 Tutorial

Customizing Bootstrap 5

Customization: Learn how to customize Bootstrap 5 with Sass variables, CSS custom properties, and build tools to create unique designs that match your brand.

Why Customize Bootstrap?

While Bootstrap provides excellent defaults, customization allows you to create unique designs that match your brand identity while maintaining all the benefits of the framework.

Default Bootstrap
Default alert

Standard Bootstrap appearance

Light Customization
Custom alert

Modified colors and styles

Heavy Customization
Fully custom alert

Complete design overhaul

Customization Methods

Four Approaches to Customization
1. CSS Overrides

Override Bootstrap styles with custom CSS.

/* Override in custom CSS */
            .btn-primary {
            background-color: #8a2be2;
            border-color: #8a2be2;
            }
EasyLimited
2. CSS Variables

Use Bootstrap's CSS custom properties.

/* Override CSS variables */
            :root {
            --bs-primary: #8a2be2;
            --bs-primary-rgb: 138, 43, 226;
            }
EasyDynamic
3. Sass Variables

Customize Bootstrap at build time with Sass.

// Customize Sass variables
            $primary: #8a2be2;
            $enable-rounded: false;

            @import "bootstrap";
MediumPowerful
4. Build Tools

Use Bootstrap's official build tools.

# Clone Bootstrap repo
            git clone https://github.com/twbs/bootstrap.git

            # Customize and build
            npm run css
HardComplete
Recommendation:

For most projects, use Sass variables for build-time customization and CSS variables for runtime theming (like dark mode). CSS overrides are good for quick fixes, and build tools are for advanced use cases.

Customizing with Sass Variables

Sass-Based Customization

Bootstrap 5 is built with Sass, allowing you to customize virtually every aspect before compilation.

Basic Sass Customization
// custom.scss

            // 1. Override default variables
            $primary: #8a2be2;        // Custom purple
            $secondary: #20b2aa;      // Custom teal
            $success: #00ab66;        // Custom green
            $info: #17a2b8;           // Keep default
            $warning: #ffc107;        // Keep default
            $danger: #dc3545;         // Keep default
            $light: #f8f9fa;          // Keep default
            $dark: #212529;           // Keep default

            // 2. Customize components
            $border-radius: 0.5rem;   // Larger border radius
            $border-radius-lg: 0.75rem;
            $border-radius-sm: 0.25rem;

            // 3. Customize typography
            $font-family-sans-serif: 'Inter', system-ui, -apple-system, sans-serif;
            $font-size-base: 1.1rem;  // Slightly larger base font
            $headings-font-weight: 700;

            // 4. Disable features you don't need
            $enable-rounded: true;    // Keep rounded corners
            $enable-shadows: true;    // Enable shadows
            $enable-gradients: false; // Disable gradients
            $enable-transitions: true;

            // 5. Import Bootstrap
            @import "bootstrap/scss/bootstrap";
Advanced Sass Customization
// advanced-custom.scss

            // Custom color palette
            $custom-colors: (
            "indigo": #6610f2,
            "purple": #6f42c1,
            "pink": #d63384,
            "orange": #fd7e14,
            "teal": #20c997,
            "cyan": #0dcaf0
            );

            // Add to theme colors map
            $theme-colors: map-merge($theme-colors, $custom-colors);

            // Custom spacing scale
            $spacer: 1rem;
            $spacers: (
            0: 0,
            1: $spacer * .25,   // 0.25rem
            2: $spacer * .5,    // 0.5rem
            3: $spacer,         // 1rem
            4: $spacer * 1.5,   // 1.5rem
            5: $spacer * 3,     // 3rem
            6: $spacer * 4.5,   // 4.5rem
            7: $spacer * 6      // 6rem
            );

            // Custom breakpoints
            $grid-breakpoints: (
            xs: 0,
            sm: 576px,
            md: 768px,
            lg: 992px,
            xl: 1200px,
            xxl: 1400px,
            xxxl: 1600px  // Custom breakpoint
            );

            // Custom container sizes
            $container-max-widths: (
            sm: 540px,
            md: 720px,
            lg: 960px,
            xl: 1140px,
            xxl: 1320px,
            xxxl: 1500px  // Custom container size
            );

            // Import Bootstrap
            @import "bootstrap/scss/bootstrap";
Build Process with Sass:
# Using npm scripts in package.json
            {
            "scripts": {
                "build-css": "sass scss/custom.scss:dist/css/bootstrap.css",
                "watch-css": "sass --watch scss/custom.scss:dist/css/bootstrap.css"
            }
            }

            # Run build
            npm run build-css

            # Watch for changes
            npm run watch-css
# Using command line directly
            sass scss/custom.scss css/custom.css

            # With compression
            sass scss/custom.scss css/custom.min.css --style=compressed

            # With source maps
            sass scss/custom.scss css/custom.css --source-map

            # Watch mode for development
            sass --watch scss/custom.scss:css/custom.css
Important Sass Tips:
  • Variable order matters: Override variables before importing Bootstrap
  • Use map-merge for maps: Don't override entire maps, merge your changes
  • Check available variables: See node_modules/bootstrap/scss/_variables.scss
  • Test changes: Small changes can have wide-ranging effects
  • Keep backups: Version control your custom Sass files

CSS Custom Properties (Variables)

Runtime Customization with CSS Variables

Bootstrap 5 includes CSS custom properties for many values, allowing runtime customization without recompilation.

Basic CSS Variable Overrides
/* Override in your CSS file */
            :root {
            /* Theme colors */
            --bs-primary: #8a2be2;
            --bs-primary-rgb: 138, 43, 226;
            --bs-secondary: #20b2aa;
            --bs-secondary-rgb: 32, 178, 170;
            
            /* Typography */
            --bs-font-sans-serif: 'Inter', system-ui, -apple-system, sans-serif;
            --bs-body-font-size: 1.1rem;
            --bs-body-color: #212529;
            
            /* Spacing */
            --bs-border-radius: 0.5rem;
            --bs-border-radius-lg: 0.75rem;
            --bs-border-radius-sm: 0.25rem;
            
            /* Shadows */
            --bs-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
            --bs-box-shadow-sm: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
            }

            /* For dark mode */
            [data-bs-theme="dark"] {
            --bs-body-bg: #212529;
            --bs-body-color: #adb5bd;
            --bs-primary: #6610f2;
            }
Dynamic CSS Variable Changes
/* CSS: Define themes */
            :root {
            --theme-primary: #0d6efd;
            --theme-border-radius: 0.375rem;
            }

            .theme-rounded {
            --theme-border-radius: 1rem;
            }

            .theme-flat {
            --theme-border-radius: 0;
            }

            /* Apply to Bootstrap components */
            .btn-primary {
            background-color: var(--theme-primary);
            border-radius: var(--theme-border-radius);
            }

            /* JavaScript: Change themes dynamically */
            // Change primary color
            document.documentElement.style.setProperty(
            '--theme-primary', 
            '#8a2be2'
            );

            // Toggle theme class
            document.documentElement.classList.toggle('theme-rounded');

            // Load theme from localStorage
            const savedTheme = localStorage.getItem('theme');
            if (savedTheme) {
            document.documentElement.setAttribute('data-bs-theme', savedTheme);
            }

            // Save theme preference
            function setTheme(theme) {
            document.documentElement.setAttribute('data-bs-theme', theme);
            localStorage.setItem('theme', theme);
            }
When to Use CSS Variables vs Sass:
Use CSS Variables ForUse Sass Variables For
Runtime theming (light/dark mode)Build-time configuration
User-customizable interfacesBrand colors and typography
Dynamic color schemesStructural changes (grid, breakpoints)
JavaScript-controlled stylesPerformance-critical optimizations
Progressive enhancementRemoving unused components

Component-Specific Customization

Customizing Individual Components
Buttons
// Sass variables
            $btn-padding-y: 0.75rem;
            $btn-padding-x: 1.5rem;
            $btn-border-radius: 50px;
            $btn-font-weight: 600;

            // CSS overrides
            .btn {
            text-transform: uppercase;
            letter-spacing: 0.5px;
            }

            .btn-primary {
            box-shadow: 0 4px 6px rgba(13, 110, 253, 0.2);
            }
Cards
// Sass variables
            $card-border-radius: 1rem;
            $card-border-width: 0;
            $card-box-shadow: 0 10px 20px rgba(0,0,0,0.1);

            // CSS overrides
            .card {
            transition: transform 0.3s ease;
            }

            .card:hover {
            transform: translateY(-5px);
            }

Custom card with hover effect

Forms
// Sass variables
            $input-border-radius: 0.5rem;
            $input-border-width: 2px;
            $input-focus-border-color: $primary;

            // CSS overrides
            .form-control {
            padding: 0.75rem 1rem;
            }

            .form-control:focus {
            box-shadow: 0 0 0 0.25rem rgba(138, 43, 226, 0.25);
            }
Creating Custom Components:
// custom-components.scss

            // Custom alert variant
            .alert-gradient {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            border: none;
            border-radius: $border-radius-lg;
            
            .alert-link {
                color: rgba(255, 255, 255, 0.9);
                text-decoration: underline;
            }
            }

            // Custom button variant
            .btn-glass {
            background: rgba(255, 255, 255, 0.1);
            backdrop-filter: blur(10px);
            border: 1px solid rgba(255, 255, 255, 0.2);
            color: white;
            
            &:hover {
                background: rgba(255, 255, 255, 0.2);
                border-color: rgba(255, 255, 255, 0.3);
            }
            }

            // Custom card variant
            .card-hover {
            overflow: hidden;
            position: relative;
            
            &::before {
                content: '';
                position: absolute;
                top: 0;
                left: 0;
                width: 100%;
                height: 5px;
                background: linear-gradient(90deg, $primary, $success);
            }
            
            &:hover {
                box-shadow: $box-shadow-lg;
            }
            }
Gradient Alert! This is a custom alert component.

Card with top gradient border

Build Tools & Optimization

Optimizing Your Custom Build
Removing Unused Components
// minimal-custom.scss

            // 1. Import Bootstrap functions first
            @import "bootstrap/scss/functions";
            @import "bootstrap/scss/variables";
            @import "bootstrap/scss/mixins";

            // 2. Override variables
            $primary: #8a2be2;
            $font-family-base: 'Inter', sans-serif;

            // 3. Import only what you need

            // Layout & components
            @import "bootstrap/scss/root";
            @import "bootstrap/scss/reboot";
            @import "bootstrap/scss/type";
            @import "bootstrap/scss/images";
            @import "bootstrap/scss/containers";
            @import "bootstrap/scss/grid";

            // Utilities
            @import "bootstrap/scss/utilities";
            @import "bootstrap/scss/utilities/api";

            // Custom components (only what you use)
            @import "bootstrap/scss/buttons";
            @import "bootstrap/scss/forms";
            @import "bootstrap/scss/card";
            @import "bootstrap/scss/alert";

            // Don't import components you don't use:
            // @import "bootstrap/scss/carousel";
            // @import "bootstrap/scss/modal";
            // @import "bootstrap/scss/dropdown";
Using PurgeCSS

Remove unused CSS from your final bundle.

// postcss.config.js
            module.exports = {
            plugins: [
                require('@fullhuman/postcss-purgecss')({
                content: [
                    './src/**/*.html',
                    './src/**/*.vue',
                    './src/**/*.jsx',
                    './src/**/*.js'
                ],
                defaultExtractor: content => 
                    content.match(/[A-Za-z0-9-_:/]+/g) || [],
                safelist: [
                    /^bg-/,
                    /^text-/,
                    /^border-/,
                    /:hover$/,
                    /:focus$/,
                    /^btn-/,
                    /^alert-/
                ]
                })
            ]
            }
PurgeCSS Tips:
  • Use safelist for dynamically added classes
  • Test thoroughly after purging
  • Monitor bundle size reductions
  • Consider critical CSS extraction
Build Size Comparison:
Build TypeCSS SizeReductionBest For
Full Bootstrap~200KB (unminified)0%Prototyping, simple sites
Minified~160KB20%Production (default)
Custom (selective import)50-100KB50-75%Custom applications
Custom + PurgeCSS20-50KB75-90%Performance-critical apps

Theme Creation Tools

Bootstrap.build

Online theme builder with visual customization

Visit
Bootswatch

Free themes for Bootstrap with easy integration

Visit
ThemeWagon

Premium Bootstrap templates and themes

Visit
BootThemes

Open source Bootstrap themes

Visit
StartBootstrap

Free and premium Bootstrap templates

Visit
Custom Build

Create your own with Sass and build tools

Best Practices & Common Mistakes

Customization Pitfalls to Avoid
❌ Common Mistakes:
  • Overriding with !important: Creates specificity wars
  • Modifying core files: Updates become impossible
  • Not testing updates: Customizations can break
  • Ignoring accessibility: Color contrast, focus states
  • Over-customizing: Loses Bootstrap's benefits
  • No version control: Can't track or revert changes
  • Forgetting responsive design: Break customizations on mobile
✅ Best Practices:
  • Use Sass variables: For systematic changes
  • Create custom files: Don't modify Bootstrap source
  • Test across breakpoints: Ensure responsiveness
  • Maintain accessibility: Check contrast, keyboard nav
  • Document customizations: For team and future you
  • Use version control: Track all custom changes
  • Optimize selectively: Only include what you need
  • Keep it maintainable: Simple, consistent customizations
Customization Checklist:
Customization Strategy Recommendations
  • Start with Sass variables: For brand colors, typography, and spacing
  • Use CSS variables for theming: Light/dark mode, user preferences
  • Create custom component variants: Extend rather than override
  • Optimize for production: Remove unused components, use PurgeCSS
  • Test systematically: Each customization can have unintended effects
  • Maintain upgrade path: Keep customizations separate from Bootstrap source
  • Consider performance: More customizations = larger CSS = slower load times
  • Balance uniqueness and consistency: Don't sacrifice usability for creativity
Quick Reference
  • $primary: #8a2be2; - Sass variable override
  • --bs-primary: #8a2be2; - CSS variable override
  • @import "bootstrap"; - Import after variables
  • npm run build - Compile Sass
  • data-bs-theme="dark" - Theme attribute
  • map-merge() - Sass map merging