Cheatsheet Bootstrap
Framework CSS para desenvolvimento responsivo
Bootstrap
Installation and Setup
Via CDN
<!-- CSS in the <head> --> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet"> <!-- JS bundle before </body> --> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
The CSS goes in the <head>; the bundle.min.js (which includes Popper.js) goes before </body>. The bundle is needed for dropdowns, modals and tooltips to work.
Bootstrap Icons
<!-- CDN --> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css"> <!-- Usage --> <i class="bi bi-heart"></i> <i class="bi bi-gear-fill"></i> <i class="bi bi-arrow-right fs-4 text-primary"></i>
The Bootstrap Icons package has 2000+ SVG icons the a font. Use bi bi-name for outline and bi bi-name-fill for filled. Combine with utilities like fs-4 and text-primary to style them.
Base template
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, initial-scale=1">
<title>App</title>
<link href="bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">...</div>
<script src="bootstrap.bundle.min.js"></script>
</body>
</html>The meta viewport is essential for responsiveness — without it, the site does not scale on mobile. The lang="en" helps accessibility and SEO. Always include the UTF-8 charset.
Dark mode
<!-- Enable global dark mode -->
<html data-bs-theme="dark">
<!-- Or per component -->
<div class="card" data-bs-theme="dark">
<div class="card-body">Dark theme</div>
</div>
<!-- Toggle via JS -->
document.documentElement
.setAttribute('data-bs-theme', 'dark');Bootstrap 5.3+ natively supports data-bs-theme="dark". Apply it on <html> for global or on an element for local. Colors adapt automatically (backgrounds, texts, borders). Combine with prefers-color-scheme via JS.
Via npm
npm install bootstrap
// CSS (in your main file):
import 'bootstrap/dist/css/bootstrap.min.css';
// JS:
import 'bootstrap';
// Or just specific components:
import { Modal, Dropdown } from 'bootstrap';Via npm you have full control of the build. Import the full CSS or use Sass to customize. The JS import registers all plugins; you can import only as ones you need to reduce the bundle.
Sass (customization)
// custom.scss — override BEFORE importing $primary: #6f42c1; $font-family-base: 'Inter', sans-serif; $border-radius: 0.5rem; $enable-shadows: true; @import "bootstrap/scss/bootstrap";
Customize Bootstrap via Sass: define variables ($primary, $font-family-base) before the @import. You can import just parts: bootstrap/scss/functions, variables, mixins, and the components you need.
Containers
<div class="container">Fixed width per breakpoint</div> <div class="container-fluid">100% always</div> <div class="container-md">100% until md, fixed after</div> <div class="container-lg">100% until lg, fixed after</div> <div class="container-xxl">100% until xxl, fixed after</div>
container has a max width that changes per breakpoint. container-fluid is always 100%. container-{breakpoint} is 100% until the given breakpoint and fixed after — useful for layouts that only need a limit on large screens.
Import only parts
// Import only what is needed (smaller CSS) @import "bootstrap/scss/functions"; @import "bootstrap/scss/variables"; @import "bootstrap/scss/mixins"; @import "bootstrap/scss/root"; @import "bootstrap/scss/reboot"; @import "bootstrap/scss/containers"; @import "bootstrap/scss/grid"; @import "bootstrap/scss/utilities";
To reduce the final CSS, import only as needed modules. Order matters: functions → variables → mixins first. Then the components (grid, buttons, forms). Useful for projects with an optimized build.
Grid e Layout
Grid structure
<div class="container">
<div class="row">
<div class="col">Column 1</div>
<div class="col">Column 2</div>
<div class="col">Column 3</div>
</div>
</div>The hierarchy is container → row → col. The grid has 12 columns. The row is a flex container with negative margins to align with the container's padding. Never put content directly in the row.
col-{breakpoint}-{n} — responsive
<div class="col-12 col-md-6 col-lg-4"> <!-- 100% on mobile --> <!-- 50% from md (768px) --> <!-- 33% from lg (992px) --> </div> <div class="col-12 col-sm-6 col-xl-3"> <!-- 100% → 50% on sm → 25% on xl --> </div>
The breakpoint prefix defines from which width the rule applies. Below the breakpoint, the column stacks (100%). Mobile-first pattern: start with col-12 and add larger widths progressively.
Column order
<div class="row"> <div class="col order-3">Visually 3rd</div> <div class="col order-1">Visually 1st</div> <div class="col order-2">Visually 2nd</div> </div> <div class="col order-first">First</div> <div class="col order-last">Last</div>
order-0 to order-5, order-first and order-last visually reorder without changing the HTML. Useful for responsive: order-1 order-md-2 changes the order only on desktop. The default is order-0.
Columns with equal heights
<div class="row row-cols-1 row-cols-md-3 g-4">
<div class="col">
<div class="card h-100">
<div class="card-body">Variable content...</div>
</div>
</div>
<div class="col">
<div class="card h-100">
<div class="card-body">More text here...</div>
</div>
</div>
</div>Use h-100 on the card inside each col to ensure equal heights in the same row. The grid columns already have the same height (flex stretch), but the inner content needs h-100 to fill it.
col — equal width
<div class="row"> <div class="col">1/3</div> <div class="col">1/3</div> <div class="col">1/3</div> </div> <div class="row"> <div class="col">1/4</div> <div class="col">1/4</div> <div class="col">1/4</div> <div class="col">1/4</div> </div>
col without a number divides the space into equal parts automatically. Bootstrap calculates the width based on the number of sibling columns. It works on all breakpoints (it stacks on mobile by default with a plain col).
row-cols-{n} — columns per row
<div class="row row-cols-2 row-cols-md-4 g-3"> <div class="col"><div class="card">A</div></div> <div class="col"><div class="card">B</div></div> <div class="col"><div class="card">C</div></div> <div class="col"><div class="card">D</div></div> </div>
row-cols-{n} defines how many columns fit per row, without needing classes on each col. Ideal for card grids: row-cols-1 row-cols-md-3 = 1 column on mobile, 3 on tablet. All columns get equal width.
Vertical alignment
<div class="row align-items-start" style="height:200px"> <div class="col">Top</div> </div> <div class="row align-items-center" style="height:200px"> <div class="col">Center</div> </div> <div class="row align-items-end" style="height:200px"> <div class="col">Bottom</div> </div>
align-items-start/center/end aligns all columns vertically inside the row. The row needs a defined height for the effect to be visible. To align a single column, use align-self-* on that column.
Forced line break
<div class="row"> <div class="col-6">Column 1</div> <div class="col-6">Column 2</div> <!-- Forced break --> <div class="w-100"></div> <div class="col-6">Column 3</div> <div class="col-6">Column 4</div> </div>
An empty <div class="w-100"> forces a line break in the grid (it takes up 100% of the width). Useful when you want to control where the columns break without creating multiple rows. It can be responsive: d-none d-md-block.
col-auto — fits the content
<div class="row"> <div class="col-auto">Short text</div> <div class="col">Takes the rest</div> </div> <div class="row justify-content-center"> <div class="col-auto">Centered to the content</div> </div>
col-auto makes the column only the wide the its content (like width: auto). Combine it with col to have one fixed column and another that fills the rest. Useful for labels + inputs side by side.
Gutters (spacing)
<div class="row g-3">General gap (x+y)</div> <div class="row gx-2">Horizontal only</div> <div class="row gy-4">Vertical only</div> <div class="row g-0">No spacing</div> <!-- Responsive --> <div class="row g-2 g-md-4">More space on desktop</div>
g-0 to g-5 controls the space between columns (gutters). gx = horizontal, gy = vertical. g-0 removes it entirely (useful for flush layouts). It accepts responsive prefixes: g-md-4.
Horizontal alignment
<div class="row justify-content-start"> <div class="col-4">Left</div> </div> <div class="row justify-content-center"> <div class="col-4">Center</div> </div> <div class="row justify-content-between"> <div class="col-4">Left</div> <div class="col-4">Right</div> </div>
justify-content-* distributes the columns horizontally in the row. Options: start, center, end, between, around, evenly. It works because the row is a flex container.
col-{n} — fixed width
<div class="row"> <div class="col-6">50%</div> <div class="col-6">50%</div> </div> <div class="row"> <div class="col-8">Main (66%)</div> <div class="col-4">Sidebar (33%)</div> </div> <div class="col-12">100% (full row)</div>
The number indicates columns out of 12: col-6 = 50%, col-4 = 33%, col-3 = 25%. The sum should be 12 (or less). If it exceeds 12, the extra columns move to the next line (automatic wrap).
Offset (shift)
<div class="row">
<div class="col-md-6 offset-md-3">
Centered (3 + 6 + 3 = 12)
</div>
</div>
<div class="row">
<div class="col-md-4 offset-md-4">
Shifted to the center
</div>
</div>offset-{bp}-{n} pushes the column N positions to the right (left margin). To center a col-6: offset-md-3 (3+6+3=12). On mobile, use offset-0 to reset. Alternative: mx-auto with a fixed col.
Nesting rows
<div class="row">
<div class="col-8">
<div class="row">
<div class="col-6">Sub-col A</div>
<div class="col-6">Sub-col B</div>
</div>
</div>
<div class="col-4">Sidebar</div>
</div>Put a row inside a col to create sub-grids. The sub-row's 12 columns are relative to the parent column (not the container). Gutters nest correctly. You do not need an extra container.
Flexbox
Enable flex
<div class="d-flex">Flex container</div> <div class="d-inline-flex">Inline flex</div> <!-- Responsive --> <div class="d-flex d-md-none">Flex only on mobile</div> <div class="d-none d-lg-flex">Flex only on lg+</div>
d-flex turns the element into a flex container; the children become flex items. d-inline-flex is the inline version. It accepts responsive prefixes: d-md-flex enables flex only from md up. The grid row is already flex by default.
align-self (one item)
<div class="d-flex align-items-start" style="height:200px"> <div>Top</div> <div class="align-self-center">Center</div> <div class="align-self-end">Bottom</div> <div class="align-self-stretch">Stretched</div> </div>
align-self-* overrides align-items on a single item. Same values: start, center, end, baseline, stretch. Useful when one item needs a different alignment than its siblings.
align-content (multiple lines)
/* Requires flex-wrap to take effect */ align-content-start align-content-end align-content-center align-content-between align-content-around align-content-stretch /* default */ <div class="d-flex flex-wrap align-content-center" style="height:300px">
align-content-* aligns the lines when there is flex-wrap and multiple lines. Without wrap, it has no effect. stretch (default) distributes the lines over the space. Useful to center a group of items that break into several lines.
Direction (main axis)
flex-row /* row → (default) */ flex-row-reverse /* row ← */ flex-column /* column ↓ */ flex-column-reverse /* column ↑ */ <!-- Responsive --> flex-column flex-md-row /* column on mobile, row on md+ */
flex-row (default) places items in a row; flex-column in a column. -reverse inverts the order. The mobile-first pattern is flex-column flex-md-row — stacks on mobile, side by side on desktop.
flex-wrap (line break)
flex-wrap /* allows wrapping to the next line */ flex-nowrap /* does not wrap (default) */ flex-wrap-reverse /* reversed wrap */ <div class="d-flex flex-wrap gap-2"> <div class="p-2 bg-light">Item 1</div> <div class="p-2 bg-light">Item 2</div> <div class="p-2 bg-light">Item 3</div> </div>
flex-wrap lets items move to the next line when they do not fit. flex-nowrap (default) forces everything on one line (may cause overflow). Essential for lists of tags, chips or card grids with flex.
Perfect centering
<div class="d-flex justify-content-center
align-items-center" style="height:100vh">
<div class="text-center">
Centered on both axes
</div>
</div>The combination d-flex + justify-content-center + align-items-center centers any content horizontally and vertically. The container needs a height (e.g.: 100vh, h-100). The modern centering pattern.
justify-content (main axis)
justify-content-start /* start (default) */ justify-content-end /* end */ justify-content-center /* center */ justify-content-between /* space between */ justify-content-around /* space around */ justify-content-evenly /* equal space */
justify-content-* distributes items along the main axis (horizontal in flex-row). between = first at the start, last at the end, equal space between. evenly = equal space everywhere. The most used are center and between.
gap (space between items)
<div class="d-flex gap-3"> <div>Item</div> <div>Item</div> </div> gap-0, gap-1, gap-2, gap-3, gap-4, gap-5 row-gap-2 /* space between rows */ column-gap-4 /* space between columns */ <!-- Responsive --> <div class="d-flex gap-2 gap-md-4">
gap-0 to gap-5 defines the spacing between flex items (replaces margins). row-gap = between rows, column-gap = between columns. Cleaner than using me-*/mb-* on each item. It accepts responsive prefixes.
Bar with space between
<div class="d-flex justify-content-between
align-items-center p-3 bg-light">
<span class="fw-bold">Logo</span>
<nav class="d-flex gap-3">
<a href="#">Home</a>
<a href="#">About</a>
<a href="#">Contact</a>
</nav>
</div>Classic pattern: justify-content-between + align-items-center places the logo on the left and the menu on the right, both centered vertically. gap-3 spaces the nav links without individual margins.
align-items (cross axis)
align-items-start /* top */ align-items-end /* bottom */ align-items-center /* vertical center */ align-items-baseline /* text baseline */ align-items-stretch /* stretch (default) */
align-items-* aligns items perpendicular to the main axis (vertical in flex-row). stretch (default) makes the items the same height. center centers vertically. The container needs a height for the effect to be visible.
flex-fill and grow/shrink
<div class="d-flex"> <div class="flex-fill">Takes everything</div> <div>Fixed</div> </div> flex-grow-0 /* does not grow (default) */ flex-grow-1 /* grows to fill */ flex-shrink-0 /* does not shrink */ flex-shrink-1 /* shrinks (default) */
flex-fill makes the item grow to take all available space (like flex: 1 1 auto). flex-grow-1 = grows; flex-shrink-0 = does not shrink (useful for buttons/labels that should not compress).
Responsive flex
<!-- Column on mobile, row on md+ --> <div class="d-flex flex-column flex-md-row gap-3"> <div>Sidebar</div> <div class="flex-fill">Content</div> </div> <!-- Responsive gap --> <div class="d-flex gap-2 gap-lg-4"> <!-- Wrap only on mobile --> <div class="d-flex flex-wrap flex-md-nowrap">
All flex classes accept breakpoint prefixes: flex-md-row, gap-lg-4, justify-content-md-between. The mobile-first pattern applies: define mobile first and override at larger breakpoints.
Components
Accordion
<div class="accordion" id="acc">
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button"
data-bs-toggle="collapse"
data-bs-target="#c1">Title</button>
</h2>
<div id="c1" class="accordion-collapse collapse show"
data-bs-parent="#acc">
<div class="accordion-body">Content</div>
</div>
</div>
</div>The Accordion shows expandable panels. data-bs-toggle="collapse" + data-bs-target controls the opening. data-bs-parent="#acc" makes only one panel open at a time. show = open by default.
Collapse
<button class="btn btn-primary" data-bs-toggle="collapse"
data-bs-target="#content">Show/Hide</button>
<div class="collapse" id="content">
<div class="card card-body">
Content collapsible
</div>
</div>
<!-- Horizontal -->
<div class="collapse collapse-horizontal" id="h">collapse hides/shows content. data-bs-toggle="collapse" + data-bs-target controls it. Add show to start open. collapse-horizontal animates the width instead of the height. The basis of the Accordion and the mobile Navbar.
Tooltip and Popover
<!-- Tooltip (requires JS init) -->
<button data-bs-toggle="tooltip" data-bs-placement="top"
title="Dica useful">Passa o mouse</button>
<!-- Popover -->
<button data-bs-toggle="popover" title="Title"
data-bs-content="Content do popover">Click</button>
// JS (required):
document.querySelectorAll('[data-bs-toggle="tooltip"]')
.forEach(el => new bootstrap.Tooltip(el));Tooltip shows a hint on hover; Popover shows content on click. Both require manual JS initialization. data-bs-placement: top, bottom, left, right. data-bs-html="true" allows HTML in the content.
Carousel
<div id="car" class="carousel slide" data-bs-ride="carousel">
<div class="carousel-inner">
<div class="carousel-item active">
<img src="1.jpg" class="d-block w-100" alt="Slide 1">
</div>
<div class="carousel-item">
<img src="2.jpg" class="d-block w-100" alt="Slide 2">
</div>
</div>
<button class="carousel-control-prev" data-bs-target="#car"
data-bs-slide="prev">
<span class="carousel-control-prev-icon"></span>
</button>
</div>The Carousel is an image slider. data-bs-ride="carousel" starts it automatically. d-block w-100 on the image ensures full width. Controls: data-bs-slide="prev/next". Add carousel-indicators for dots.
Offcanvas
<button class="btn btn-primary" data-bs-toggle="offcanvas"
data-bs-target="#menu">Open menu</button>
<div class="offcanvas offcanvas-start" id="menu">
<div class="offcanvas-header">
<h5>Menu</h5>
<button class="btn-close" data-bs-dismiss="offcanvas"></button>
</div>
<div class="offcanvas-body">
Links de navigation...
</div>
</div>Offcanvas is a sliding side panel. Positions: offcanvas-start (left), offcanvas-end (right), offcanvas-top, offcanvas-bottom. data-bs-dismiss="offcanvas" closes it. Ideal for mobile menus and carts.
Pagination
<nav>
<ul class="pagination pagination-lg">
<li class="page-item disabled">
<a class="page-link" href="#">Previous</a>
</li>
<li class="page-item active">
<a class="page-link" href="#">1</a>
</li>
<li class="page-item">
<a class="page-link" href="#">2</a>
</li>
</ul>
</nav>pagination creates paginated navigation. page-item active = current page; disabled = not clickable. Sizes: pagination-sm, pagination-lg. Center it with justify-content-center on the ul.
Dropdown
<div class="dropdown">
<button class="btn btn-primary dropdown-toggle"
data-bs-toggle="dropdown">Menu</button>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="#">Action 1</a></li>
<li><a class="dropdown-item" href="#">Action 2</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item text-danger" href="#">Exit</a></li>
</ul>
</div>The Dropdown shows a drop-down menu on click. data-bs-toggle="dropdown" activates it. dropdown-divider separates groups. Positions: dropup, dropend, dropstart on the parent div. Alignment: dropdown-menu-end.
Spinner
<div class="spinner-border text-primary" role="status"> <span class="visually-hidden">A load...</span> </div> <div class="spinner-grow text-success" role="status"></div> <!-- In a button --> <button class="btn btn-primary" disabled> <span class="spinner-border spinner-border-sm"></span> A process... </button>
spinner-border = spinning ring; spinner-grow = a growing dot. spinner-border-sm = small version (for buttons). Use text-* for color. Always include visually-hidden with text for accessibility.
Scrollspy
<body data-bs-spy="scroll" data-bs-target="#nav" data-bs-offset="100" tabindex="0"> <nav id="nav" class="navbar navbar-light bg-light"> <a class="nav-link" href="#sec1">Section 1</a> <a class="nav-link" href="#sec2">Section 2</a> </nav> <div id="sec1" style="height:500px">...</div> <div id="sec2" style="height:500px">...</div>
Scrollspy automatically highlights the active link the you scroll. data-bs-spy="scroll" on the body + data-bs-target points to the nav. The links must point to the sections' IDs. data-bs-offset adjusts the activation point.
Tabs
<ul class="nav nav-tabs" role="tablist">
<li class="nav-item">
<button class="nav-link active" data-bs-toggle="tab"
data-bs-target="#tab1">Tab 1</button>
</li>
<li class="nav-item">
<button class="nav-link" data-bs-toggle="tab"
data-bs-target="#tab2">Tab 2</button>
</li>
</ul>
<div class="tab-content">
<div class="tab-pane fade show active" id="tab1">...</div>
<div class="tab-pane fade" id="tab2">...</div>
</div>nav-tabs creates tabs with a line. data-bs-toggle="tab" + data-bs-target links to the panel. tab-pane fade show active on the content. Use nav-pills for the pill version. fade adds a transition.
Progress bar
<div class="progress" style="height: 20px">
<div class="progress-bar bg-success" style="width: 75%">
75%
</div>
</div>
<!-- Striped and animated -->
<div class="progress">
<div class="progress-bar progress-bar-striped
progress-bar-animated" style="width: 50%"></div>
</div>progress is the outer bar; progress-bar is the fill (width via style or JS). progress-bar-striped adds stripes; progress-bar-animated animates them. bg-* changes the color. Multiple bars = segmented progress.
Placeholder (skeleton)
<div class="card">
<div class="card-body">
<h5 class="card-title placeholder-glow">
<span class="placeholder col-6"></span>
</h5>
<p class="card-text placeholder-glow">
<span class="placeholder col-7"></span>
<span class="placeholder col-4"></span>
<span class="placeholder col-10"></span>
</p>
</div>
</div>placeholder creates skeleton loading (a loading skeleton). col-6 defines the bar's width. placeholder-glow animates with a glow; placeholder-wave animates with a wave. Replace it with the real content when the data loads.
Buttons and Badges
Basic button
<button class="btn btn-primary">Click</button> <a href="#" class="btn btn-success">Link the button</a> <input type="submit" class="btn btn-danger" value="Send">
btn is the base class; the second class defines the color. It works on <button>, <a> and <input>. Use <button> for JS actions and <a> for navigation (accessibility).
Block button (full width)
<div class="d-grid gap-2">
<button class="btn btn-primary btn-lg">
Width total
</button>
<button class="btn btn-outline-secondary">
Secondary
</button>
</div>
<!-- Responsive: block only on mobile -->
<div class="d-grid d-md-inline-block">d-grid on the container makes the buttons take up 100% of the width. gap-2 spaces stacked buttons. In Bootstrap 5 there is no btn-block — use d-grid. For responsive: d-grid d-md-inline-block.
Button group
<div class="btn-group" role="group"> <button class="btn btn-outline-primary">Esq</button> <button class="btn btn-outline-primary">Middle</button> <button class="btn btn-outline-primary">Dir</button> </div> <!-- Vertical --> <div class="btn-group-vertical"> <!-- Toolbar --> <div class="btn-toolbar" role="toolbar"> <div class="btn-group me-2">...</div> <div class="btn-group">...</div> </div>
btn-group groups buttons side by side (merged borders). btn-group-vertical stacks them. btn-toolbar combines multiple groups. Add role="group" for accessibility. Sizes: btn-group-sm, btn-group-lg.
Button colors
btn-primary /* blue (main action) */ btn-secondary /* gray */ btn-success /* green (confirmation) */ btn-danger /* red (danger/delete) */ btn-warning /* yellow (warning) */ btn-info /* cyan (information) */ btn-light /* light */ btn-dark /* dark */ btn-link /* looks like a link */
The colors are semantic: primary for the main action, danger for destructive actions, success for confirmation. btn-link removes the background and border (looks like a link but keeps the button's padding). Customize via $theme-colors in Sass.
Disabled and loading button
<button class="btn btn-primary" disabled>Desativado</button> <!-- Loading state --> <button class="btn btn-primary" disabled> <span class="spinner-border spinner-border-sm"></span> A process... </button> <a class="btn btn-primary disabled" aria-disabled="true"> Link desativado </a>
disabled removes interaction and applies opacity. On <a>, use the disabled class + aria-disabled="true" (there is no disabled attribute on links). Combine it with spinner-border-sm for a loading state.
Close button
<button class="btn-close" aria-label="Close"></button> <!-- White version (for dark backgrounds) --> <button class="btn-close btn-close-white" aria-label="Close"></button> <!-- Disabled --> <button class="btn-close" disabled></button>
btn-close is the standard X button (uses an SVG background). btn-close-white inverts it to white (dark backgrounds). Always include aria-label="Close" because the button has no visible text. Used in modals, alerts and offcanvas.
Outline button
<button class="btn btn-outline-primary">Primary</button> <button class="btn btn-outline-danger">Danger</button> <button class="btn btn-outline-dark">Escuro</button> <!-- On hover, fills with the color -->
btn-outline-* creates buttons with only an outline and a transparent background. On hover/focus, it fills with the color. Ideal for secondary actions that should not visually compete with the btn-primary. All colors are available.
Badge
<span class="badge bg-primary">New</span> <span class="badge bg-danger">5</span> <span class="badge rounded-pill bg-success">12</span> <span class="badge text-bg-warning">Attention</span> <!-- In a heading --> <h2>Notifications <span class="badge bg-secondary">4</span></h2>
badge is a small label. bg-* defines the background color. rounded-pill fully rounds it. text-bg-* (BS 5.3+) sets background + text color with automatic contrast. Position it with position-absolute for corners.
Button size
<button class="btn btn-primary btn-lg">Big</button> <button class="btn btn-primary">Normal</button> <button class="btn btn-primary btn-sm">Small</button>
btn-lg = large (more padding and font); btn-sm = small. The normal size does not need an extra class. Use btn-lg for main CTAs and btn-sm for actions in tables or toolbars.
Badge on a button
<button class="btn btn-primary position-relative">
Notifications
<span class="position-absolute top-0 start-100
translate-middle badge rounded-pill bg-danger">
99+
<span class="visually-hidden">not lidas</span>
</span>
</button>Position the badge in the button's corner with position-absolute + top-0 start-100 translate-middle. rounded-pill gives the circular shape. visually-hidden adds context for screen readers (accessibility).
Forms
Text field
<div class="mb-3">
<label for="name" class="form-label">Name</label>
<input type="text" class="form-control" id="name"
placeholder="Your name">
<div class="form-text">Name complete.</div>
</div>form-control styles inputs and textareas. form-label formats the label. form-text shows help text below. mb-3 spaces the fields. Always use for on the label linked to the input's id (accessibility).
Range and file input
<label class="form-label">Volume</label> <input type="range" class="form-range" min="0" max="100" step="5" id="vol"> <!-- File input --> <div class="mb-3"> <label class="form-label">File</label> <input class="form-control" type="file" id="file"> </div> <!-- Multiple files --> <input class="form-control" type="file" multiple>
form-range styles the native slider. min, max, step control the values. For files, use type="file" with form-control. multiple allows several files. The style adapts to the browser.
Inline form (grid)
<form class="row g-3 align-items-end">
<div class="col-auto">
<label class="form-label">Name</label>
<input class="form-control">
</div>
<div class="col-auto">
<label class="form-label">Email</label>
<input class="form-control">
</div>
<div class="col-auto">
<button class="btn btn-primary">Send</button>
</div>
</form>Use the grid (row g-3) for inline forms. col-auto fits the content. align-items-end aligns the fields by the bottom (useful when there are labels). Responsive: add col-12 col-md-auto to stack on mobile.
Select
<select class="form-select" aria-label="Choose"> <option selected>Choose an option...</option> <option value="1">Option 1</option> <option value="2">Option 2</option> </select> <!-- Multiple --> <select class="form-select" multiple size="3"> <!-- Size --> <select class="form-select form-select-sm">
form-select styles the native dropdown. multiple + size allows multiple selection. form-select-sm/form-select-lg adjust the size. aria-label describes the field without a visible label.
Floating labels
<div class="form-floating mb-3">
<input type="email" class="form-control" id="email"
placeholder="name@example.com">
<label for="email">Email</label>
</div>
<div class="form-floating">
<textarea class="form-control" id="msg"
placeholder="Message" style="height:100px"></textarea>
<label for="msg">Message</label>
</div>form-floating makes the label float above the field when filled. The placeholder is required (even if empty) for the effect to work. The label comes AFTER the input in the HTML. It works with textarea (set the height).
Disabled form
<fieldset disabled>
<div class="mb-3">
<label class="form-label">Name</label>
<input class="form-control" value="Anna">
</div>
<div class="mb-3">
<label class="form-label">Email</label>
<input class="form-control" value="ana@mail.com">
</div>
<button class="btn btn-primary">Send</button>
</fieldset><fieldset disabled> disables all fields and buttons inside it at once. More convenient than disabled on each element. The style is applied automatically (opacity, cursor). Ideal for read-only forms.
Checkbox and Radio
<div class="form-check">
<input class="form-check-input" type="checkbox"
id="chk1" checked>
<label class="form-check-label" for="chk1">Aceito</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio"
name="option" id="r1">
<label class="form-check-label" for="r1">Option A</label>
</div>
<!-- Inline -->
<div class="form-check form-check-inline">form-check wraps each checkbox/radio. form-check-input styles the control; form-check-label the text. form-check-inline places them side by side. checked checks it by default. Radios in the same group share the name.
Validation
<div class="mb-3"> <label class="form-label">Email</label> <input class="form-control is-valid" value="a@b.com"> <div class="valid-feedback">Looks good!</div> </div> <div class="mb-3"> <label class="form-label">Password</label> <input class="form-control is-invalid"> <div class="invalid-feedback">Minimum 8 characters.</div> </div>
is-valid shows a green border + icon; is-invalid shows a red border. valid-feedback/invalid-feedback show the message (only visible with the matching state). Combine it with the browser's JS validation (novalidate + JS).
Switch (toggle)
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox"
role="switch" id="sw1">
<label class="form-check-label" for="sw1">
Activate notifications
</label>
</div>
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox"
role="switch" id="sw2" checked disabled>
<label class="form-check-label" for="sw2">Always active</label>
</div>form-switch turns the checkbox into a switch (toggle). role="switch" improves the semantics for screen readers. It works with checked and disabled. A modern look with no extra JS.
Input group
<div class="input-group mb-3"> <span class="input-group-text">@</span> <input class="form-control" placeholder="Username"> </div> <div class="input-group"> <input class="form-control" placeholder="Search..."> <button class="btn btn-primary">Ir</button> </div> <div class="input-group"> <span class="input-group-text">€</span> <input type="number" class="form-control"> <span class="input-group-text">.00</span> </div>
input-group attaches text, icons or buttons to the input. input-group-text is the addon (prefix/suffix). You can have addons on both sides. Useful for @, €, units or action buttons stuck to the field.
Navbar and Navigation
Basic navbar
<nav class="navbar navbar-expand-lg bg-body-tertiary">
<div class="container">
<a class="navbar-brand" href="#">Logo</a>
<button class="navbar-toggler" data-bs-toggle="collapse"
data-bs-target="#nav">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="nav">
<ul class="navbar-nav ms-auto">
<li class="nav-item">
<a class="nav-link active" href="#">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">About</a>
</li>
</ul>
</div>
</div>
</nav>navbar-expand-lg defines when the menu collapses (below lg). navbar-toggler is the hamburger button. navbar-collapse wraps the links. ms-auto pushes the menu to the right. bg-body-tertiary gives it a background.
Form in the navbar
<div class="collapse navbar-collapse" id="nav">
<ul class="navbar-nav me-auto">...</ul>
<form class="d-flex" role="search">
<input class="form-control me-2" type="search"
placeholder="Search...">
<button class="btn btn-outline-success">Fetch</button>
</form>
</div>Use d-flex on the form to align input + button. me-auto on the navbar-nav pushes the form to the right. me-2 spaces the input from the button. type="search" provides semantics and a native clear icon.
Navbar colors
<!-- Light (BS 5.3 default) --> <nav class="navbar bg-body-tertiary"> <!-- Dark --> <nav class="navbar bg-dark" data-bs-theme="dark"> <!-- Custom color --> <nav class="navbar" style="background-color: #6f42c1" data-bs-theme="dark"> <!-- Transparent --> <nav class="navbar bg-transparent">
In BS 5.3+, use data-bs-theme="dark" for light text on dark backgrounds. bg-body-tertiary is the default light background. bg-dark + data-bs-theme="dark" = dark navbar. You can use any color with inline style.
Offcanvas the a mobile navbar
<nav class="navbar bg-body-tertiary">
<div class="container">
<a class="navbar-brand">Logo</a>
<button class="navbar-toggler" data-bs-toggle="offcanvas"
data-bs-target="#menu">
<span class="navbar-toggler-icon"></span>
</button>
<div class="offcanvas offcanvas-end" id="menu">
<div class="offcanvas-header">
<h5>Menu</h5>
<button class="btn-close"
data-bs-dismiss="offcanvas"></button>
</div>
<div class="offcanvas-body">
<ul class="navbar-nav">...</ul>
</div>
</div>
</div>
</nav>Alternative to collapse: use offcanvas for a side menu on mobile. data-bs-toggle="offcanvas" on the toggler. offcanvas-end slides in from the right. More space and flexibility than the traditional collapse. Popular in mobile-first apps.
Fixed and sticky navbar
<!-- Always visible at the top --> <nav class="navbar fixed-top"> <!-- Sticks to the top on scroll --> <nav class="navbar sticky-top"> <!-- Fixed at the bottom --> <nav class="navbar fixed-bottom"> <!-- With offset for content --> <body style="padding-top: 70px">
fixed-top = always visible (removed from the flow; add padding-top to the body). sticky-top = sticks to the top when the scroll reaches it (stays in the flow). fixed-bottom = bar fixed at the bottom. Prefer sticky-top when possible.
Breadcrumb
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item">
<a href="#">Home</a>
</li>
<li class="breadcrumb-item">
<a href="#">Products</a>
</li>
<li class="breadcrumb-item active" aria-current="page">
Detalhes
</li>
</ol>
</nav>breadcrumb shows the navigation trail. The last item has active + aria-current="page" (current page, no link). The separator (/) comes via CSS (--bs-breadcrumb-divider). Always use <nav aria-label="breadcrumb"> for accessibility.
Dropdown in the navbar
<ul class="navbar-nav">
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#"
data-bs-toggle="dropdown">Services</a>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="#">Web</a></li>
<li><a class="dropdown-item" href="#">Mobile</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item" href="#">All</a></li>
</ul>
</li>
</ul>Add dropdown to the nav-item and dropdown-toggle + data-bs-toggle="dropdown" to the link. The dropdown-menu holds the items. On mobile (collapsed), the dropdown opens the an accordion. dropdown-divider separates groups.
Nav pills and underline
<!-- Pills -->
<ul class="nav nav-pills">
<li class="nav-item">
<a class="nav-link active" href="#">Active</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Other</a>
</li>
</ul>
<!-- Underline (BS 5.3+) -->
<ul class="nav nav-underline">
<li class="nav-item">
<a class="nav-link active" href="#">Active</a>
</li>
</ul>nav-pills = rounded background on the active item. nav-underline (BS 5.3+) = underline on the active one. nav-tabs = tabs with a border. All accept nav-fill (equal width) and nav-justified (full width).
Cards and Lists
Basic card
<div class="card" style="width: 18rem">
<div class="card-body">
<h5 class="card-title">Title</h5>
<h6 class="card-subtitle mb-2 text-body-secondary">
Subtitle</h6>
<p class="card-text">Description of the content.</p>
<a href="#" class="btn btn-primary">See more</a>
</div>
</div>card is the flexible container. card-body adds padding. card-title, card-subtitle, card-text format the content. text-body-secondary gives the subtitle a subtle color. Width via style or the grid.
Horizontal card
<div class="card mb-3" style="max-width: 540px">
<div class="row g-0">
<div class="col-md-4">
<img src="photo.jpg" class="img-fluid rounded-start"
alt="Photo">
</div>
<div class="col-md-8">
<div class="card-body">
<h5 class="card-title">Title</h5>
<p class="card-text">Description lateral.</p>
</div>
</div>
</div>
</div>Use the grid inside the card for a horizontal layout: image in one column, text in another. g-0 removes gutters. rounded-start rounds only the left of the image. img-fluid makes it responsive. It stacks on mobile automatically.
Responsive table
<div class="table-responsive">
<table class="table">
<thead>...</thead>
<tbody>...</tbody>
</table>
</div>
<!-- Responsive up to a breakpoint -->
<div class="table-responsive-md">
<table class="table">...</table>
</div>table-responsive wraps the table and adds horizontal scroll on small screens. table-responsive-{bp} only adds scroll below the breakpoint (e.g. -md = scroll only on mobile). Essential for tables with many columns.
Card with image
<div class="card">
<img src="photo.jpg" class="card-img-top" alt="Photo">
<div class="card-body">
<h5 class="card-title">Title</h5>
<p class="card-text">Text descritivo.</p>
</div>
</div>
<!-- Image at the bottom -->
<div class="card">
<div class="card-body">Text</div>
<img src="photo.jpg" class="card-img-bottom" alt="Photo">
</div>card-img-top places the image at the top (with rounded corners). card-img-bottom at the bottom. The image should have a descriptive alt. Combine with object-fit-cover + a fixed height for images of different sizes.
List group
<ul class="list-group"> <li class="list-group-item active">Active</li> <li class="list-group-item">Item 2</li> <li class="list-group-item disabled">Desativado</li> <li class="list-group-item">Item 4</li> </ul> <!-- Without outer borders --> <ul class="list-group list-group-flush"> <!-- Numbered --> <ol class="list-group list-group-numbered">
list-group creates styled lists. active highlights; disabled disables. list-group-flush removes side borders (for use inside cards). list-group-numbered numbers automatically. Items can be links (list-group-item-action).
Card group and Masonry
<!-- Card group (merged borders) -->
<div class="card-group">
<div class="card">...</div>
<div class="card">...</div>
<div class="card">...</div>
</div>
<!-- Masonry (requires Masonry JS) -->
<div class="row" data-masonry='{"percentPosition": true}'>
<div class="col-sm-6 col-lg-4 mb-4">
<div class="card">Height variable</div>
</div>
</div>card-group merges the cards' borders (no gap). Masonry (via an external lib) creates a Pinterest-style layout with variable heights. The normal grid aligns by rows; masonry fills vertical gaps. Requires the masonry.pkgd.min.js library.
Header, footer and overlay
<div class="card">
<div class="card-header">Highlight</div>
<div class="card-body">Main content</div>
<div class="card-footer text-body-secondary">
2 days ago
</div>
</div>
<!-- Overlay over an image -->
<div class="card bg-dark text-white">
<img src="bg.jpg" class="card-img" alt="Background">
<div class="card-img-overlay">
<h5 class="card-title">Title about image</h5>
</div>
</div>card-header/card-footer are sections with a subtle background. card-img-overlay positions content over the image (absolute position). Use bg-dark text-white for legibility over photos. Ideal for hero cards.
List group with badges and checkboxes
<ul class="list-group">
<li class="list-group-item d-flex
justify-content-between align-items-center">
Messages
<span class="badge bg-primary rounded-pill">14</span>
</li>
<li class="list-group-item">
<input class="form-check-input me-1" type="checkbox">
Task completed
</li>
</ul>Combine d-flex justify-content-between for a badge on the right. rounded-pill gives the counter a circular shape. Checkboxes inside list-group-item create task lists. me-1 spaces the checkbox from the text.
Card grid
<div class="row row-cols-1 row-cols-md-3 g-4">
<div class="col">
<div class="card h-100">
<img src="1.jpg" class="card-img-top" alt="">
<div class="card-body">
<h5 class="card-title">Card 1</h5>
<p class="card-text">Text variable...</p>
</div>
</div>
</div>
<div class="col">
<div class="card h-100">...</div>
</div>
</div>row-cols-1 row-cols-md-3 = 1 column on mobile, 3 on md+. g-4 spaces the cards. h-100 ensures equal heights on the same row. The most-used pattern for listings of products, articles and teams.
Table
<table class="table table-striped table-hover">
<thead>
<tr>
<th>#</th>
<th>Name</th>
<th class="text-end">Value</th>
</tr>
</thead>
<tbody>
<tr class="table-warning">
<td>1</td>
<td>Anna</td>
<td class="text-end">€120</td>
</tr>
</tbody>
</table>table styles the table. table-striped = alternating rows; table-hover = highlight on hover. table-bordered, table-sm (compact), table-responsive (horizontal scroll). Per-row colors: table-warning, table-danger.
Modal, Alerts and Toasts
Basic modal
<button class="btn btn-primary" data-bs-toggle="modal"
data-bs-target="#myModal">Open</button>
<div class="modal fade" id="myModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Title</h5>
<button class="btn-close"
data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">Content here.</div>
<div class="modal-footer">
<button class="btn btn-secondary"
data-bs-dismiss="modal">Close</button>
<button class="btn btn-primary">Save</button>
</div>
</div>
</div>
</div>data-bs-toggle="modal" + data-bs-target="#id" opens the modal. fade adds a transition. data-bs-dismiss="modal" closes it. Structure: modal → modal-dialog → modal-content → header/body/footer.
Dismissible alert
<div class="alert alert-warning alert-dismissible fade show"
role="alert">
<strong>Attention!</strong> Space almost full.
<button class="btn-close" data-bs-dismiss="alert"
aria-label="Close"></button>
</div>alert-dismissible + btn-close with data-bs-dismiss="alert" makes the alert closable. fade show adds a closing animation. The X button is positioned automatically on the right. After closing, the element is removed from the DOM.
Backdrop and static
<!-- Does not close on outside click -->
<div class="modal" data-bs-backdrop="static"
data-bs-keyboard="false">
<!-- No backdrop (transparent background) -->
<div class="modal" data-bs-backdrop="false">
<!-- Via JS -->
new bootstrap.Modal(el, {
backdrop: 'static',
keyboard: false
});data-bs-backdrop="static" prevents closing on outside click. data-bs-keyboard="false" disables Escape. data-bs-backdrop="false" removes the dark overlay. Useful for important forms where losing data would be a problem.
Modal sizes
<div class="modal-dialog modal-sm">Small</div> <div class="modal-dialog modal-lg">Big</div> <div class="modal-dialog modal-xl">Extra big</div> <div class="modal-dialog modal-fullscreen">Screen integer</div> <!-- Fullscreen only on mobile --> <div class="modal-dialog modal-fullscreen-md-down"> <!-- Vertically centered --> <div class="modal-dialog modal-dialog-centered"> <!-- With scroll in the body --> <div class="modal-dialog modal-dialog-scrollable">
Sizes: modal-sm, modal-lg, modal-xl, modal-fullscreen. modal-fullscreen-md-down = fullscreen only below md. modal-dialog-centered centers vertically. modal-dialog-scrollable scrolls only the body.
Toast
<div class="toast-container position-fixed bottom-0 end-0 p-3">
<div class="toast" role="alert" data-bs-delay="5000">
<div class="toast-header">
<strong class="me-auto">Notification</strong>
<small>now</small>
<button class="btn-close" data-bs-dismiss="toast"></button>
</div>
<div class="toast-body">
File shipped com success!
</div>
</div>
</div>
// JS to show it:
new bootstrap.Toast(document.querySelector('.toast')).show();Toast = a small, temporary notification. toast-container positions it (use position-fixed bottom-0 end-0). data-bs-delay="5000" = auto-closes in 5s. Requires .show() via JS. Stack multiple toasts in the container.
Modal via JavaScript
// Open
const modal = new bootstrap.Modal(
document.getElementById('myModal')
);
modal.show();
// Close
modal.hide();
// Toggle
modal.toggle();
// Events
document.getElementById('myModal')
.addEventListener('hidden.bs.modal', () => {
console.log('Modal closed');
});The JS API: new bootstrap.Modal(el) creates the instance; .show(), .hide(), .toggle() control it. Events: show.bs.modal, shown.bs.modal, hide.bs.modal, hidden.bs.modal. Useful for opening after validation or a fetch.
Popover (detailed)
<button class="btn btn-lg btn-danger" data-bs-toggle="popover"
data-bs-title="Title" data-bs-content="Content detailed
do popover com more information."
data-bs-placement="right">Click to see</button>
// JS (required):
const popover = new bootstrap.Popover(el, {
trigger: 'focus', // closes on click outside
html: true // allows HTML in the content
});Popover shows rich content on click. data-bs-title + data-bs-content define the content. data-bs-placement: top/bottom/left/right. Requires JS init. trigger: 'focus' closes on click outside. html: true allows HTML.
Alerts
<div class="alert alert-success" role="alert"> Operation completed com success! </div> <div class="alert alert-danger" role="alert"> Error ao process o order. </div> <div class="alert alert-warning" role="alert"> <strong>Attention!</strong> Check the fields. </div> <div class="alert alert-info" role="alert"> New version available. </div>
alert alert-* shows feedback messages. Colors: success, danger, warning, info, primary, secondary, light, dark. Always use role="alert" for accessibility. Links inside: alert-link.
Modal with a form
<div class="modal fade" id="formModal">
<div class="modal-dialog">
<div class="modal-content">
<form>
<div class="modal-header">
<h5 class="modal-title">New record</h5>
<button class="btn-close"
data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<div class="mb-3">
<label class="form-label">Name</label>
<input class="form-control" required>
</div>
</div>
<div class="modal-footer">
<button class="btn btn-secondary"
data-bs-dismiss="modal">Cancel</button>
<button class="btn btn-primary"
type="submit">Save</button>
</div>
</form>
</div>
</div>
</div>Place the <form> inside modal-content (wrapping header/body/footer). The type="submit" on the button submits the form. Use the hidden.bs.modal event to reset the form after closing. Validate before closing.
Utilities
Margin (outer spacing)
m-0, m-1, m-2, m-3, m-4, m-5 /* all sides */ mt-3 /* margin-top */ mb-2 /* margin-bottom */ ms-1 /* margin-start (left in LTR) */ me-4 /* margin-end (right in LTR) */ mx-auto /* centers horizontally */ my-3 /* margin-top + bottom */
m = margin. Suffixes: t (top), b (bottom), s (start/left), e (end/right), x (horizontal), y (vertical). Scale: 0 to 5 (0, 0.25rem, 0.5rem, 1rem, 1.5rem, 3rem). mx-auto centers blocks.
Background colors
bg-primary, bg-success, bg-danger bg-warning, bg-info, bg-dark bg-light, bg-white, bg-transparent <!-- Subtle (BS 5.3+) --> bg-primary-subtle bg-danger-subtle <!-- Gradient --> bg-primary bg-gradient
bg-* sets the background color. bg-*-subtle (BS 5.3+) gives pastel tones (ideal for custom alerts). bg-gradient adds a subtle gradient. Combine with text-white or text-dark for legible contrast.
Shadows
shadow-none /* no shadow */ shadow-sm /* subtle */ shadow /* default */ shadow-lg /* pronounced */ <div class="card shadow"> <div class="btn shadow-sm">
shadow adds a box-shadow. Levels: shadow-sm (subtle), shadow (default), shadow-lg (pronounced). shadow-none removes it (useful to override the card/button default). For a hover elevation effect: combine with custom CSS.
Overflow and scroll
overflow-auto /* scroll only if needed */ overflow-hidden /* cuts the excess */ overflow-visible /* shows (default) */ overflow-scroll /* always scroll */ <!-- Separate axes --> overflow-x-auto /* horizontal scroll */ overflow-y-hidden /* cuts vertical */
overflow-* controls content that exceeds the box. overflow-auto = scroll only when needed. overflow-hidden = cuts (useful with text-truncate). overflow-x-auto for tables or horizontal lists. overflow-y-hidden prevents vertical scroll.
Visually hidden (accessibility)
<span class="visually-hidden"> Text to leitores de screen </span> <!-- Visible on focus (skip links) --> <a class="visually-hidden-focusable" href="#content"> Skip to content </a> <label class="visually-hidden" for="search">Search</label> <input id="search" class="form-control">
visually-hidden hides visually but keeps it accessible to screen readers (unlike d-none). visually-hidden-focusable appears when it receives focus (skip links). Essential for labels of fields with a placeholder and icons without text.
Padding (inner spacing)
p-0, p-1, p-2, p-3, p-4, p-5 /* all sides */ pt-3 /* padding-top */ pb-2 /* padding-bottom */ px-4 /* padding-left + right */ py-2 /* padding-top + bottom */ ps-3 /* padding-start */ pe-1 /* padding-end */
p = padding, same logic the margin. px = horizontal, py = vertical. The scale is identical: 0 to 5. Use p-3 for consistent padding in custom cards, py-5 for sections with lots of vertical space.
Display
d-none /* hidden */ d-block /* block */ d-inline /* inline */ d-inline-block /* inline-block */ d-flex /* flexbox */ d-grid /* grid */ d-inline-flex /* inline flex */ <!-- Responsive --> d-none d-md-block /* hidden on mobile, visible on md+ */ d-md-none /* visible only on mobile */
d-* controls the display type. d-none hides completely. d-flex enables flexbox. The most-used responsive pattern: d-none d-md-block (hides on mobile, shows on md+). d-md-none = shows only on mobile.
Width and height
w-25, w-50, w-75, w-100 /* width % */ w-auto /* automatic width */ h-25, h-50, h-75, h-100 /* height % */ h-auto /* automatic height */ mw-100 /* max-width: 100% */ mh-100 /* max-height: 100% */ vw-100 /* 100% viewport width */ vh-100 /* 100% viewport height */ min-vh-100 /* min-height: 100vh */
w-* = width the a percentage; h-* = height. vw-100/vh-100 = viewport. min-vh-100 = full-screen minimum height (hero sections). mw-100 prevents image overflow. w-auto resets to automatic.
Object-fit (images/videos)
<img src="photo.jpg" class="object-fit-cover" style="height:200px; width:100%"> object-fit-contain /* fits everything (may show bars) */ object-fit-cover /* fills (crops) */ object-fit-fill /* stretches (distorts) */ object-fit-scale-down /* smaller of contain/none */ object-fit-none /* original size */ <!-- Responsive --> object-fit-md-cover
object-fit-* controls how images/videos fit the box. cover = fills by cropping (the most used for thumbnails). contain = shows everything (may show bars). Combine with a fixed height + w-100 for uniform image grids.
Vertical align and float
/* Vertical align (inline/table-cell) */ align-baseline, align-top align-middle, align-bottom align-text-top, align-text-bottom /* Float (legacy — prefer flex) */ float-start /* left */ float-end /* right */ float-none clearfix /* clears floats on the parent */
align-* aligns inline or table-cell elements vertically. float-* is legacy — today prefer d-flex. clearfix on the parent clears floats (avoids height collapse). Kept for compatibility with old code.
Responsive spacing
p-2 p-md-4 /* more padding on desktop */ mt-3 mt-lg-5 /* more margin on lg+ */ d-none d-md-block /* hidden on mobile */ gap-2 gap-lg-4 /* larger gap on big screens */ text-center text-md-start /* align left on md+ */
All utility classes accept breakpoint prefixes: p-md-4, mt-lg-5, d-none d-md-block. The pattern is mobile-first: the class without a prefix applies to all; with a prefix, it overrides from that breakpoint up.
Text and typography
text-center, text-start, text-end /* alignment */ fw-bold, fw-semibold, fw-normal /* weight */ fst-italic /* italic */ text-uppercase, text-lowercase /* transform */ text-decoration-none /* no underline */ text-truncate /* cuts with ... */ fs-1, fs-2, fs-3, fs-4, fs-5, fs-6 /* font size */ lh-1, lh-sm, lh-base, lh-lg /* line-height */
text-* aligns; fw-* controls the weight; fs-1 to fs-6 set the font size (1=largest). text-truncate cuts long text with an ellipsis (requires display: block or inline-block). lh-* adjusts line spacing.
Position
position-static position-relative position-absolute position-fixed position-sticky <!-- Coordinates --> top-0, top-50, top-100 bottom-0, start-0, end-0, start-50 translate-middle /* centers on the point */ translate-middle-x /* centers only horizontally */
position-* sets the positioning type. Coordinates: top-0, start-50, etc. (0%, 50%, 100%). translate-middle shifts -50% on both axes (perfect centering). Use position-relative on the parent for absolute on the child.
Opacity and interaction
opacity-0, opacity-25, opacity-50, opacity-75, opacity-100 pe-none /* pointer-events: none (not clickable) */ pe-auto /* pointer-events: auto */ user-select-none /* not selectable */ user-select-all /* selects everything on click */ visible /* visibility: visible */ invisible /* visibility: hidden (takes up space) */
opacity-* sets transparency. pe-none disables clicks (overlays, loading). user-select-none prevents text selection (buttons, labels). invisible hides but keeps the space (unlike d-none which removes it from the flow).
Z-index
z-0, z-1, z-2, z-3 /* low values */ z-n1 /* z-index: -1 */ /* Bootstrap uses internally: */ /* dropdown: 1000, sticky: 1020 */ /* fixed: 1030, modal-backdrop: 1040 */ /* modal: 1050, popover: 1070, tooltip: 1080 */ <div class="position-relative z-1">Overlapped</div>
z-0 to z-3 and z-n1 for simple stacking. Bootstrap reserves high values for components (modal: 1050, tooltip: 1080). To layer content above a modal, you need a z-index > 1050. Use position-relative for z-index to work.
Text colors
text-primary /* blue */ text-success /* green */ text-danger /* red */ text-warning /* yellow */ text-info /* cyan */ text-dark /* dark */ text-muted /* subtle gray (BS 5.3: text-body-secondary) */ text-white /* white */ text-body-secondary /* gray (new in BS 5.3) */
text-* sets the text color. In BS 5.3+, text-body-secondary replaces text-muted (adapts to dark mode). Combine with bg-* for contrast. Use semantic colors: danger for errors, success for success.
Borders and rounding
border, border-0 /* all / none */ border-top, border-end /* specific sides */ border-primary, border-danger /* color */ border-1, border-2, border-3 /* thickness */ rounded, rounded-0, rounded-1, rounded-2, rounded-3 rounded-circle /* circle (square images) */ rounded-pill /* pill (buttons/badges) */ rounded-top, rounded-start /* specific sides */
border adds a border; border-0 removes it. border-{color} changes the color; border-{1-5} the thickness. rounded rounds corners (0 to 5). rounded-circle for avatars; rounded-pill for badges/buttons.
Centering with position
<!-- Center absolutely -->
<div class="position-relative" style="height:300px">
<div class="position-absolute top-50 start-50
translate-middle">
Centered!
</div>
</div>
<!-- Badge in the corner -->
<div class="position-relative">
<span class="position-absolute top-0 start-100
translate-middle badge bg-danger">5</span>
</div>Centering pattern: parent position-relative + child position-absolute top-50 start-50 translate-middle. For corner badges: top-0 start-100 translate-middle. Modern alternative: d-flex + justify-content-center + align-items-center.
Ratio (aspect ratio)
<div class="ratio ratio-16x9">
<iframe src="https://youtube.com/embed/..."
title="Video"></iframe>
</div>
ratio-1x1 /* square */
ratio-4x3 /* old TV */
ratio-16x9 /* widescreen */
ratio-21x9 /* ultrawide */
<!-- Custom via CSS variable -->
<div class="ratio" style="--bs-aspect-ratio: 66.67%">ratio + ratio-16x9 keeps a responsive aspect ratio for videos/iframes. The content stretches to fill. ratio-1x1 for square avatars. Custom: --bs-aspect-ratio: 66.67% (2:3). Replaces the old padding-bottom hack.
Responsive
Breakpoints
xs < 576px (phone — no prefix) sm ≥ 576px (phone landscape) md ≥ 768px (tablet) lg ≥ 992px (small desktop) xl ≥ 1200px (desktop) xxl ≥ 1400px (large screen)
Breakpoints are mobile-first: classes without a prefix apply to all; with a prefix, they override from that width up. xs has no prefix (col-6 = col-xs-6). The values are in em in the Sass (576px = 36em).
Responsive typography
<h1 class="display-1">Title enorme</h1> <h1 class="display-4">Title big</h1> <!-- Responsive font size --> <p class="fs-6 fs-md-4 fs-lg-3">Text that cresce</p> <!-- Responsive alignment --> <p class="text-center text-md-start"> Centered no mobile, left no desktop </p>
display-1 to display-6 are extra-large headings. fs-1 to fs-6 set sizes (they accept prefixes: fs-md-4). Responsive alignment: text-center text-md-start. Bootstrap already uses clamp() on headings by default.
Hide/show by breakpoint
d-none d-sm-block /* hidden on xs, visible on sm+ */ d-sm-none /* visible ONLY on xs */ d-none d-md-block /* hidden up to md */ d-md-none /* visible only on xs and sm */ d-none d-lg-block d-xl-none /* visible only on lg */ <!-- Practical example --> <span class="d-none d-md-inline">Menu complete</span> <button class="d-md-none">☰</button>
Combine d-none + d-{bp}-block to show from a breakpoint up. d-{bp}-none hides from that breakpoint up. Classic pattern: full menu on desktop (d-none d-md-inline) + hamburger on mobile (d-md-none).
Responsive containers
<!-- Max width per breakpoint --> .container /* fixed at each bp */ .container-sm /* 100% up to sm, fixed after */ .container-md /* 100% up to md, fixed after */ .container-lg /* 100% up to lg, fixed after */ .container-xl /* 100% up to xl, fixed after */ .container-xxl /* 100% up to xxl, fixed after */ .container-fluid /* always 100% */
container-{bp} is 100% up to the breakpoint and a fixed width after. E.g.: container-lg = 100% on mobile/tablet, fixed (960px) on lg+. Useful when you want full-width on mobile but limited on desktop. container-fluid = always 100%.
Responsive image
<img src="photo.jpg" class="img-fluid" alt="Responsiva"> <img src="photo.jpg" class="img-thumbnail" alt="Miniatura"> <!-- Picture with sources --> <picture> <source srcset="big.webp" media="(min-width:768px)"> <img src="pequena.webp" class="img-fluid" alt="Photo"> </picture>
img-fluid = max-width: 100%; height: auto (never exceeds the parent). img-thumbnail adds a border + padding + rounding. Use <picture> + srcset to serve different images per breakpoint (performance).
Spacing per breakpoint
<!-- Progressive padding --> <section class="py-3 py-md-5"> <div class="container px-3 px-lg-5"> <!-- Responsive margin --> <div class="mb-3 mb-lg-5"> <!-- Responsive gap --> <div class="d-flex gap-2 gap-md-4"> <!-- Full-height hero section only on desktop --> <section class="min-vh-100 d-none d-md-flex">
Adjust spacing per screen: py-3 py-md-5 (less padding on mobile). gap-2 gap-md-4 (more space on desktop). min-vh-100 for hero sections. Mobile needs less space; desktop can be more generous.
Responsive grid (patterns)
<!-- 1 col mobile → 2 tablet → 4 desktop --> <div class="row row-cols-1 row-cols-md-2 row-cols-xl-4 g-4"> <!-- Sidebar + content --> <div class="row"> <div class="col-12 col-md-4 col-lg-3">Sidebar</div> <div class="col-12 col-md-8 col-lg-9">Content</div> </div> <!-- Stack on mobile --> <div class="d-flex flex-column flex-md-row gap-3">
Common patterns: row-cols-1 row-cols-md-2 row-cols-xl-4 for progressive grids. Sidebar: col-md-4 col-lg-3 + content col-md-8 col-lg-9. Always mobile-first: start with 1 column and add widths at larger breakpoints.
Media queries in Sass
// Bootstrap mixins
@include media-breakpoint-up(md) {
.sidebar { width: 250px; }
}
@include media-breakpoint-down(md) {
.sidebar { display: none; }
}
@include media-breakpoint-between(sm, lg) {
.card { flex-direction: column; }
}
@include media-breakpoint-only(md) {
.title { font-size: 1.5rem; }
}The media-breakpoint-up/down/between/only mixins generate media queries with Bootstrap's breakpoints. up(md) = @media (min-width: 768px). down(md) = @media (max-width: 767.98px). Use them in custom Sass for consistency.
Tips and Good Practices
Bundle includes Popper
<!-- bootstrap.bundle.min.js = Bootstrap + Popper.js --> <script src="bootstrap.bundle.min.js"></script> <!-- bootstrap.min.js = Bootstrap only (no Popper) --> <script src="bootstrap.min.js"></script> // Popper is required for: // - Dropdowns // - Tooltips // - Popovers
The bundle includes Popper.js (positioning of dropdowns, tooltips, popovers). If you use bootstrap.min.js (no bundle), you need to load Popper separately. When in doubt, always use the bundle — it's the simplet.
Accessibility (ARIA)
<button aria-label="Close" class="btn-close"></button> <nav aria-label="breadcrumb"> <div class="alert" role="alert"> <div class="modal" aria-labelledby="title" aria-hidden="true"> <input aria-describedby="ajuda"> <span id="ajuda" class="form-text">Text de ajuda</span>
Always use ARIA attributes: aria-label on buttons without text, role="alert" on alerts, aria-labelledby on modals, aria-describedby for help. aria-hidden="true" on decorative elements. Bootstrap already includes some, but check.
data-bs-* attributes
data-bs-toggle="modal" /* opens a modal */ data-bs-toggle="collapse" /* collapses */ data-bs-toggle="dropdown" /* dropdown */ data-bs-toggle="tooltip" /* tooltip */ data-bs-toggle="offcanvas" /* offcanvas */ data-bs-target="#id" /* target */ data-bs-dismiss="modal" /* closes */ data-bs-ride="carousel" /* auto-play */
In Bootstrap 5, all attributes use the data-bs- prefix (it used to be data-). toggle defines as behavior; target the target element; dismiss closes. No jQuery needed — everything works with HTML attributes.
CSS variables (BS 5.3)
/* Bootstrap exposes CSS variables: */
:root {
--bs-primary: #0d6efd;
--bs-body-font-size: 1rem;
--bs-border-radius: 0.375rem;
}
/* Use them directly: */
.card {
border-radius: var(--bs-border-radius);
color: var(--bs-primary);
}
/* Override per component: */
.btn-custom { --bs-btn-bg: #6f42c1; }Bootstrap 5.3 exposes CSS variables (--bs-*) that you can use and override without Sass. --bs-primary, --bs-border-radius, --bs-body-font-size. Components use --bs-btn-*, --bs-card-*. Ideal for runtime theming (dark mode toggle).
No jQuery (BS 5)
// Bootstrap 5 does NOT need jQuery // Native JavaScript API: const modal = new bootstrap.Modal(el); const dropdown = new bootstrap.Dropdown(el); const tooltip = new bootstrap.Tooltip(el); const collapse = new bootstrap.Collapse(el); const offcanvas = new bootstrap.Offcanvas(el); // Get an existing instance: const m = bootstrap.Modal.getInstance(el);
Bootstrap 5 removed the jQuery dependency. Use the native API: new bootstrap.Modal(el), .getInstance(el). Each component has .show(), .hide(), .toggle(), .dispose(). Events: el.addEventListener('shown.bs.modal', fn).
Combined utilities (patterns)
<!-- Hero section -->
<section class="bg-dark text-white py-5 min-vh-100
d-flex align-items-center">
<div class="container text-center">
<h1 class="display-3 fw-bold">Title</h1>
<p class="lead text-body-secondary">Subtitle</p>
<a class="btn btn-primary btn-lg mt-3">CTA</a>
</div>
</section>
<!-- Profile card -->
<div class="card text-center shadow-sm">
<img class="rounded-circle mx-auto mt-3" width="80">
<div class="card-body">
<h5 class="fw-semibold">Name</h5>
<p class="text-body-secondary small">Role</p>
</div>
</div>Combine utilities for common patterns: hero = bg-dark text-white py-5 min-vh-100 d-flex align-items-center. Profile card = text-center shadow-sm + rounded-circle mx-auto. Composing utilities avoids custom CSS in most cases.
Reboot (global reset)
/* Bootstrap's Reboot normalizes: */ - box-sizing: border-box (all elements) - margin: 0 on the body - base font-family and line-height - links with the primary color - buttons with cursor: pointer - tables with border-collapse - images with vertical-align: middle
Reboot is Bootstrap's global reset (based on Normalize). It applies box-sizing: border-box to everything, removes body margins, sets base typography. It's imported automatically. If you don't want it, you can import only specific components via Sass.
Documentation and resources
# Official documentation https://getbootstrap.com/docs/5.3/ # Icons (2000+) https://icons.getbootstrap.com/ # Examples and templates https://getbootstrap.com/docs/5.3/examples/ # CDN (jsDelivr) https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/ # Source (GitHub) https://github.com/twbs/bootstrap
The official documentation (getbootstrap.com/docs) has interactive examples of all components. icons.getbootstrap.com lists the 2000+ icons. The Examples section has complete templates (album, dashboard, sign-in). The CDN via jsDelivr is the fastest.