DevTools

Cheatsheet Bootstrap

Framework CSS para desenvolvimento responsivo

Volver a los lenguajes
Bootstrap
128 tarjetas encontradas
Categorías:
Versiones:

Instalación y configuración


8 cards
Vía CDN
<!-- CSS en el <head> -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">

<!-- Bundle JS antes de </body> -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>

El CSS va en el <head>; el bundle.min.js (que incluye Popper.js) va antes de </body>. El bundle es necesario para que dropdowns, modales y tooltips funcionen.

Bootstrap Icons
<!-- CDN -->
<link rel="stylesheet"
  href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">

<!-- Uso -->
<i class="bi bi-heart"></i>
<i class="bi bi-gear-fill"></i>
<i class="bi bi-arrow-right fs-4 text-primary"></i>

El paquete Bootstrap Icons tiene 2000+ iconos SVG como fuente. Usa bi bi-nombre para outline y bi bi-nombre-fill para relleno. Combínalos con utilidades como fs-4 y text-primary para darles estilo.

Plantilla base
<!DOCTYPE html>
<html lang="es">
<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>

El meta viewport es esencial para la responsividad — sin él, el sitio no escala en mobile. El lang="es" ayuda a la accesibilidad y al SEO. Incluir siempre el charset UTF-8.

Dark mode
<!-- Activar dark mode global -->
<html data-bs-theme="dark">

<!-- O por componente -->
<div class="card" data-bs-theme="dark">
  <div class="card-body">Tema oscuro</div>
</div>

<!-- Toggle vía JS -->
document.documentElement
  .setAttribute('data-bs-theme', 'dark');

Bootstrap 5.3+ soporta data-bs-theme="dark" de forma nativa. Aplícalo en <html> para global o en un elemento para local. Los colores se adaptan automáticamente (fondos, textos, bordes). Combínalo con prefers-color-scheme vía JS.

Vía npm
npm install bootstrap

// CSS (en tu archivo principal):
import 'bootstrap/dist/css/bootstrap.min.css';

// JS:
import 'bootstrap';

// O solo componentes específicos:
import { Modal, Dropdown } from 'bootstrap';

Vía npm tienes control total del build. Importa el CSS completo o usa Sass para personalizar. El import del JS registra todos los plugins; puedes importar solo los que necesites para reducir el bundle.

Sass (personalización)
// custom.scss — sobrescribir ANTES de importar
$primary: #6f42c1;
$font-family-base: 'Inter', sans-serif;
$border-radius: 0.5rem;
$enable-shadows: true;

@import "bootstrap/scss/bootstrap";

Personaliza Bootstrap vía Sass: define variables ($primary, $font-family-base) antes del @import. Puedes importar solo partes: bootstrap/scss/functions, variables, mixins, y los componentes que necesites.

Contenedores
<div class="container">Ancho fijo por breakpoint</div>
<div class="container-fluid">100% siempre</div>
<div class="container-md">100% hasta md, fijo después</div>
<div class="container-lg">100% hasta lg, fijo después</div>
<div class="container-xxl">100% hasta xxl, fijo después</div>

container tiene un ancho máximo que cambia por breakpoint. container-fluid es siempre 100%. container-{breakpoint} es 100% hasta el breakpoint indicado y fijo después — útil para layouts que solo necesitan un límite en pantallas grandes.

Importar solo partes
// Importar solo lo necesario (menos 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";

Para reducir el CSS final, importa solo los módulos necesarios. El orden importa: functionsvariablesmixins primero. Después los componentes (grid, buttons, forms). Útil para proyectos con un build optimizado.

Diseño de cuadrícula


14 cards
Estructura del grid
<div class="container">
  <div class="row">
    <div class="col">Columna 1</div>
    <div class="col">Columna 2</div>
    <div class="col">Columna 3</div>
  </div>
</div>

La jerarquía es containerrowcol. El grid tiene 12 columnas. La row es un flex container con márgenes negativos para alinear con el padding del container. Nunca pongas contenido directamente en la row.

col-{breakpoint}-{n} — responsiva
<div class="col-12 col-md-6 col-lg-4">
  <!-- 100% en mobile -->
  <!-- 50% a partir de md (768px) -->
  <!-- 33% a partir de lg (992px) -->
</div>

<div class="col-12 col-sm-6 col-xl-3">
  <!-- 100% → 50% en sm → 25% en xl -->
</div>

El prefijo del breakpoint define a partir de qué ancho se aplica la regla. Por debajo del breakpoint, la columna se apila (100%). Patrón mobile-first: empieza con col-12 y añade anchos mayores progresivamente.

Orden de las columnas
<div class="row">
  <div class="col order-3">Visualmente 3º</div>
  <div class="col order-1">Visualmente 1º</div>
  <div class="col order-2">Visualmente 2º</div>
</div>

<div class="col order-first">Primero</div>
<div class="col order-last">Último</div>

order-0 a order-5, order-first y order-last reordenan visualmente sin cambiar el HTML. Útil para responsivo: order-1 order-md-2 cambia el orden solo en desktop. El valor por defecto es order-0.

Columnas con alturas iguales
<div class="row row-cols-1 row-cols-md-3 g-4">
  <div class="col">
    <div class="card h-100">
      <div class="card-body">Contenido variable...</div>
    </div>
  </div>
  <div class="col">
    <div class="card h-100">
      <div class="card-body">Más texto aquí...</div>
    </div>
  </div>
</div>

Usa h-100 en el card dentro de cada col para garantizar alturas iguales en la misma fila. Las columnas del grid ya tienen la misma altura (flex stretch), pero el contenido interno necesita h-100 para rellenar.

col — ancho igual
<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 sin numero divide el espacio en partes iguales automáticamente. Bootstrap calcula el ancho según el numero de columnas hermanas. Funciona en todos los breakpoints (se apila en mobile por defecto con un col simple).

row-cols-{n} — columnas por fila
<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} define cuántas columnas caben por fila, sin necesitar clases en cada col. Ideal para grillas de cards: row-cols-1 row-cols-md-3 = 1 columna en mobile, 3 en tablet. Todas las columnas quedan con ancho igual.

Alineación vertical
<div class="row align-items-start" style="height:200px">
  <div class="col">Arriba</div>
</div>

<div class="row align-items-center" style="height:200px">
  <div class="col">Centro</div>
</div>

<div class="row align-items-end" style="height:200px">
  <div class="col">Abajo</div>
</div>

align-items-start/center/end alinea todas las columnas verticalmente dentro de la row. La row necesita una altura definida para que el efecto sea visible. Para alinear una sola columna, usa align-self-* en esa columna.

Salto de línea forzado
<div class="row">
  <div class="col-6">Columna 1</div>
  <div class="col-6">Columna 2</div>

  <!-- Salto forzado -->
  <div class="w-100"></div>

  <div class="col-6">Columna 3</div>
  <div class="col-6">Columna 4</div>
</div>

Un <div class="w-100"> vacío fuerza un salto de línea en el grid (ocupa el 100% del ancho). Útil cuando quieres controlar dónde saltan las columnas sin crear múltiples rows. Puede ser responsivo: d-none d-md-block.

col-auto — se ajusta al contenido
<div class="row">
  <div class="col-auto">Texto corto</div>
  <div class="col">Ocupa el resto</div>
</div>

<div class="row justify-content-center">
  <div class="col-auto">Centrado al contenido</div>
</div>

col-auto hace que la columna tenga solo el ancho de su contenido (como width: auto). Combínalo con col para tener una columna fija y otra que rellena lo restante. Útil para labels + inputs uno al lado del otro.

Gutters (espaciado)
<div class="row g-3">Gap general (x+y)</div>
<div class="row gx-2">Solo horizontal</div>
<div class="row gy-4">Solo vertical</div>
<div class="row g-0">Sin espaciado</div>

<!-- Responsivo -->
<div class="row g-2 g-md-4">Más espacio en desktop</div>

g-0 a g-5 controla el espacio entre columnas (gutters). gx = horizontal, gy = vertical. g-0 lo quita totalmente (útil para layouts pegados). Acepta prefijos responsivos: g-md-4.

Alineación horizontal
<div class="row justify-content-start">
  <div class="col-4">Izquierda</div>
</div>

<div class="row justify-content-center">
  <div class="col-4">Centro</div>
</div>

<div class="row justify-content-between">
  <div class="col-4">Izq</div>
  <div class="col-4">Der</div>
</div>

justify-content-* distribuye las columnas horizontalmente en la row. Opciones: start, center, end, between, around, evenly. Funciona porque la row es un flex container.

col-{n} — ancho fijo
<div class="row">
  <div class="col-6">50%</div>
  <div class="col-6">50%</div>
</div>

<div class="row">
  <div class="col-8">Principal (66%)</div>
  <div class="col-4">Lateral (33%)</div>
</div>

<div class="col-12">100% (fila entera)</div>

El numero indica columnas de 12: col-6 = 50%, col-4 = 33%, col-3 = 25%. La suma debe dar 12 (o menos). Si excede 12, las columnas extra pasan a la línea siguiente (wrap automático).

Offset (desplazar)
<div class="row">
  <div class="col-md-6 offset-md-3">
    Centrado (3 + 6 + 3 = 12)
  </div>
</div>

<div class="row">
  <div class="col-md-4 offset-md-4">
    Desplazado al centro
  </div>
</div>

offset-{bp}-{n} empuja la columna N posiciones a la derecha (margen izquierdo). Para centrar una col-6: offset-md-3 (3+6+3=12). En mobile, usa offset-0 para resetear. Alternativa: mx-auto con una col fija.

Anidar 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">Lateral</div>
</div>

Pon una row dentro de una col para crear sub-grillas. Las 12 columnas de la sub-row son relativas a la columna padre (no al container). Los gutters se anidan correctamente. No necesitas un container extra.

Caja flexible


12 cards
Activar flex
<div class="d-flex">Contenedor flex</div>
<div class="d-inline-flex">Flex inline</div>

<!-- Responsivo -->
<div class="d-flex d-md-none">Flex solo en mobile</div>
<div class="d-none d-lg-flex">Flex solo en lg+</div>

d-flex convierte el elemento en un flex container; los hijos pasan a ser flex items. d-inline-flex es la versión inline. Acepta prefijos responsivos: d-md-flex activa flex solo a partir de md. La row del grid ya es flex por defecto.

align-self (un item)
<div class="d-flex align-items-start" style="height:200px">
  <div>Arriba</div>
  <div class="align-self-center">Centro</div>
  <div class="align-self-end">Abajo</div>
  <div class="align-self-stretch">Estirado</div>
</div>

align-self-* sobrepone align-items en un único item. Mismos valores: start, center, end, baseline, stretch. Útil cuando un item necesita una alineación diferente a la de sus hermanos.

align-content (varias líneas)
/* Requiere flex-wrap para tener efecto */
align-content-start
align-content-end
align-content-center
align-content-between
align-content-around
align-content-stretch  /* por defecto */

<div class="d-flex flex-wrap align-content-center"
  style="height:300px">

align-content-* alinea las líneas cuando hay flex-wrap y múltiples líneas. Sin wrap, no tiene efecto. stretch (por defecto) distribuye las líneas por el espacio. Útil para centrar un grupo de items que saltan en varias líneas.

Dirección (eje principal)
flex-row             /* fila → (por defecto) */
flex-row-reverse     /* fila ← */
flex-column          /* columna ↓ */
flex-column-reverse  /* columna ↑ */

<!-- Responsivo -->
flex-column flex-md-row  /* columna en mobile, fila en md+ */

flex-row (por defecto) coloca los items en fila; flex-column en columna. -reverse invierte el orden. El patrón mobile-first es flex-column flex-md-row — se apila en mobile, uno al lado del otro en desktop.

flex-wrap (salto de línea)
flex-wrap          /* permite saltar a la línea siguiente */
flex-nowrap        /* no salta (por defecto) */
flex-wrap-reverse  /* salto invertido */

<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 permite que los items pasen a la línea siguiente cuando no caben. flex-nowrap (por defecto) fuerza todo en una línea (puede causar overflow). Esencial para listas de tags, chips o grids de cards con flex.

Centrar a la perfección
<div class="d-flex justify-content-center
  align-items-center" style="height:100vh">
  <div class="text-center">
    Centrado en los 2 ejes
  </div>
</div>

La combinación d-flex + justify-content-center + align-items-center centra cualquier contenido horizontal y verticalmente. El contenedor necesita una altura (ej.: 100vh, h-100). El patrón moderno de centrado.

justify-content (eje principal)
justify-content-start     /* inicio (por defecto) */
justify-content-end       /* fin */
justify-content-center    /* centro */
justify-content-between   /* espacio entre */
justify-content-around    /* espacio alrededor */
justify-content-evenly    /* espacio igual */

justify-content-* distribuye los items a lo largo del eje principal (horizontal en flex-row). between = primero al inicio, último al final, espacio igual entre ellos. evenly = espacio igual en todos. Los más usados son center y between.

gap (espacio entre 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      /* espacio entre filas */
column-gap-4   /* espacio entre columnas */

<!-- Responsivo -->
<div class="d-flex gap-2 gap-md-4">

gap-0 a gap-5 define el espaciado entre flex items (sustituye a los márgenes). row-gap = entre filas, column-gap = entre columnas. Más limpio que usar me-*/mb-* en cada item. Acepta prefijos responsivos.

Barra con espacio entre
<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="#">Inicio</a>
    <a href="#">Sobre</a>
    <a href="#">Contacto</a>
  </nav>
</div>

Patrón clásico: justify-content-between + align-items-center coloca el logo a la izquierda y el menú a la derecha, ambos centrados verticalmente. gap-3 espacia los links del nav sin márgenes individuales.

align-items (eje cruzado)
align-items-start      /* arriba */
align-items-end        /* abajo */
align-items-center     /* centro vertical */
align-items-baseline   /* línea de base del texto */
align-items-stretch    /* estirar (por defecto) */

align-items-* alinea los items perpendicularmente al eje principal (vertical en flex-row). stretch (por defecto) hace que los items tengan la misma altura. center centra verticalmente. El contenedor necesita una altura para que el efecto sea visible.

flex-fill y grow/shrink
<div class="d-flex">
  <div class="flex-fill">Ocupa todo</div>
  <div>Fijo</div>
</div>

flex-grow-0    /* no crece (por defecto) */
flex-grow-1    /* crece para rellenar */
flex-shrink-0  /* no encoge */
flex-shrink-1  /* encoge (por defecto) */

flex-fill hace que el item crezca para ocupar todo el espacio disponible (como flex: 1 1 auto). flex-grow-1 = crece; flex-shrink-0 = no encoge (útil para botones/labels que no deben comprimirse).

Flex responsivo
<!-- Columna en mobile, fila en md+ -->
<div class="d-flex flex-column flex-md-row gap-3">
  <div>Sidebar</div>
  <div class="flex-fill">Contenido</div>
</div>

<!-- Gap responsivo -->
<div class="d-flex gap-2 gap-lg-4">

<!-- Wrap solo en mobile -->
<div class="d-flex flex-wrap flex-md-nowrap">

Todas las clases flex aceptan prefijos de breakpoint: flex-md-row, gap-lg-4, justify-content-md-between. Se aplica el patrón mobile-first: define el mobile primero y sobrescribe en breakpoints mayores.

Componentes


12 cards
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">Título</button>
    </h2>
    <div id="c1" class="accordion-collapse collapse show"
      data-bs-parent="#acc">
      <div class="accordion-body">Contenido</div>
    </div>
  </div>
</div>

El Accordion muestra paneles expansibles. data-bs-toggle="collapse" + data-bs-target controla la apertura. data-bs-parent="#acc" hace que solo un panel esté abierto a la vez. show = abierto por defecto.

Collapse
<button class="btn btn-primary" data-bs-toggle="collapse"
  data-bs-target="#contenido">Mostrar/Ocultar</button>

<div class="collapse" id="contenido">
  <div class="card card-body">
    Contenido plegable
  </div>
</div>

<!-- Horizontal -->
<div class="collapse collapse-horizontal" id="h">

collapse oculta/muestra contenido. data-bs-toggle="collapse" + data-bs-target lo controla. Añade show para empezar abierto. collapse-horizontal anima el ancho en vez de la altura. La base del Accordion y del Navbar mobile.

Tooltip y Popover
<!-- Tooltip (requiere init JS) -->
<button data-bs-toggle="tooltip" data-bs-placement="top"
  title="Dica útil">Passa o ratón</button>

<!-- Popover -->
<button data-bs-toggle="popover" title="Título"
  data-bs-content="Contenido do popover">Clica</button>

// JS (obligatorio):
document.querySelectorAll('[data-bs-toggle="tooltip"]')
  .forEach(el => new bootstrap.Tooltip(el));

Tooltip muestra una pista al hover; Popover muestra contenido al hacer clic. Ambos requieren inicialización JS manual. data-bs-placement: top, bottom, left, right. data-bs-html="true" permite HTML en el contenido.

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>

El Carousel es un slider de imágenes. data-bs-ride="carousel" lo inicia automáticamente. d-block w-100 en la imagen garantiza ancho total. Controles: data-bs-slide="prev/next". Añade carousel-indicators para puntos.

Offcanvas
<button class="btn btn-primary" data-bs-toggle="offcanvas"
  data-bs-target="#menu">Abrir 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 navegación...
  </div>
</div>

Offcanvas es un panel lateral deslizante. Posiciones: offcanvas-start (izquierda), offcanvas-end (derecha), offcanvas-top, offcanvas-bottom. data-bs-dismiss="offcanvas" lo cierra. Ideal para menús mobile y carritos.

Pagination
<nav>
  <ul class="pagination pagination-lg">
    <li class="page-item disabled">
      <a class="page-link" href="#">Anterior</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 crea navegación paginada. page-item active = página actual; disabled = no clicable. Tamaños: pagination-sm, pagination-lg. Céntrala con justify-content-center en la 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="#">Acción 1</a></li>
    <li><a class="dropdown-item" href="#">Acción 2</a></li>
    <li><hr class="dropdown-divider"></li>
    <li><a class="dropdown-item text-danger" href="#">Sair</a></li>
  </ul>
</div>

El Dropdown muestra un menú desplegable al hacer clic. data-bs-toggle="dropdown" lo activa. dropdown-divider separa grupos. Posiciones: dropup, dropend, dropstart en el div padre. Alineación: dropdown-menu-end.

Spinner
<div class="spinner-border text-primary" role="status">
  <span class="visually-hidden">A cargar...</span>
</div>

<div class="spinner-grow text-success" role="status"></div>

<!-- En un botón -->
<button class="btn btn-primary" disabled>
  <span class="spinner-border spinner-border-sm"></span>
  A procesar...
</button>

spinner-border = anillo giratorio; spinner-grow = punto que crece. spinner-border-sm = versión pequeña (para botones). Usa text-* para el color. Incluye siempre visually-hidden con texto para accesibilidad.

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">Sección 1</a>
  <a class="nav-link" href="#sec2">Sección 2</a>
</nav>

<div id="sec1" style="height:500px">...</div>
<div id="sec2" style="height:500px">...</div>

Scrollspy destaca automáticamente el link activo según el scroll. data-bs-spy="scroll" en el body + data-bs-target apunta al nav. Los links deben apuntar a los IDs de las secciones. data-bs-offset ajusta el punto de activación.

Tabs (pestañas)
<ul class="nav nav-tabs" role="tablist">
  <li class="nav-item">
    <button class="nav-link active" data-bs-toggle="tab"
      data-bs-target="#tab1">Pestaña 1</button>
  </li>
  <li class="nav-item">
    <button class="nav-link" data-bs-toggle="tab"
      data-bs-target="#tab2">Pestaña 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 crea pestañas con línea. data-bs-toggle="tab" + data-bs-target las liga al panel. tab-pane fade show active en el contenido. Usa nav-pills para la versión en píldora. fade añade una transición.

Progress bar
<div class="progress" style="height: 20px">
  <div class="progress-bar bg-success" style="width: 75%">
    75%
  </div>
</div>

<!-- Rayada y animada -->
<div class="progress">
  <div class="progress-bar progress-bar-striped
    progress-bar-animated" style="width: 50%"></div>
</div>

progress es la barra exterior; progress-bar es el relleno (ancho vía style o JS). progress-bar-striped añade rayas; progress-bar-animated las anima. bg-* cambia el color. Múltiples barras = progreso segmentado.

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 crea skeleton loading (esqueleto de carga). col-6 define el ancho de la barra. placeholder-glow anima con brillo; placeholder-wave anima con onda. Sustitúyelo por el contenido real cuando los datos carguen.

Botones e insignias


10 cards
Botón básico
<button class="btn btn-primary">Clica</button>
<a href="#" class="btn btn-success">Link como botón</a>
<input type="submit" class="btn btn-danger" value="Enviar">

btn es la clase base; la segunda clase define el color. Funciona en <button>, <a> e <input>. Usa <button> para acciones JS y <a> para navegación (accesibilidad).

Botón en bloque (full width)
<div class="d-grid gap-2">
  <button class="btn btn-primary btn-lg">
    Ancho total
  </button>
  <button class="btn btn-outline-secondary">
    Secundario
  </button>
</div>

<!-- Responsivo: bloque solo en mobile -->
<div class="d-grid d-md-inline-block">

d-grid en el contenedor hace que los botones ocupen el 100% del ancho. gap-2 espacia botones apilados. En Bootstrap 5 no existe btn-block — usa d-grid. Para responsivo: d-grid d-md-inline-block.

Grupo de botones
<div class="btn-group" role="group">
  <button class="btn btn-outline-primary">Esq</button>
  <button class="btn btn-outline-primary">Medio</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 agrupa botones uno al lado del otro (bordes fundidos). btn-group-vertical los apila. btn-toolbar combina múltiples grupos. Añade role="group" para accesibilidad. Tamaños: btn-group-sm, btn-group-lg.

Colores de botón
btn-primary     /* azul (acción principal) */
btn-secondary   /* gris */
btn-success     /* verde (confirmación) */
btn-danger      /* rojo (peligro/eliminar) */
btn-warning     /* amarillo (atención) */
btn-info        /* cian (información) */
btn-light       /* claro */
btn-dark        /* oscuro */
btn-link        /* parece un link */

Los colores son semánticos: primary para la acción principal, danger para acciones destructivas, success para confirmación. btn-link quita el fondo y el borde (parece un link pero mantiene el padding de botón). Personalízalos vía $theme-colors en Sass.

Botón desactivado y loading
<button class="btn btn-primary" disabled>Desativado</button>

<!-- Estado de loading -->
<button class="btn btn-primary" disabled>
  <span class="spinner-border spinner-border-sm"></span>
  A procesar...
</button>

<a class="btn btn-primary disabled" aria-disabled="true">
  Link desativado
</a>

disabled quita la interacción y aplica opacidad. En <a>, usa la clase disabled + aria-disabled="true" (no existe el atributo disabled en links). Combínalo con spinner-border-sm para el estado de loading.

Close button
<button class="btn-close" aria-label="Cerrar"></button>

<!-- Versión blanca (para fondos oscuros) -->
<button class="btn-close btn-close-white"
  aria-label="Cerrar"></button>

<!-- Desactivado -->
<button class="btn-close" disabled></button>

btn-close es el botón X estándar (usa un SVG de fondo). btn-close-white lo invierte a blanco (fondos oscuros). Incluye siempre aria-label="Cerrar" porque el botón no tiene texto visible. Se usa en modales, alertas y offcanvas.

Botón outline
<button class="btn btn-outline-primary">Primário</button>
<button class="btn btn-outline-danger">Peligro</button>
<button class="btn btn-outline-dark">Escuro</button>

<!-- Al hover, se rellena con el color -->

btn-outline-* crea botones con solo contorno y fondo transparente. Al hover/focus, se rellena con el color. Ideal para acciones secundarias que no deben competir visualmente con el btn-primary. Todos los colores están disponibles.

Badge
<span class="badge bg-primary">Nuevo</span>
<span class="badge bg-danger">5</span>
<span class="badge rounded-pill bg-success">12</span>
<span class="badge text-bg-warning">Atención</span>

<!-- En un heading -->
<h2>Notificaciones <span class="badge bg-secondary">4</span></h2>

badge es una pequeña etiqueta. bg-* define el color de fondo. rounded-pill lo redondea totalmente. text-bg-* (BS 5.3+) define fondo + color de texto con contraste automático. Posiciónalo con position-absolute para las esquinas.

Tamaño de botón
<button class="btn btn-primary btn-lg">Grande</button>
<button class="btn btn-primary">Normal</button>
<button class="btn btn-primary btn-sm">Pequeño</button>

btn-lg = grande (más padding y fuente); btn-sm = pequeño. El tamaño normal no necesita una clase extra. Usa btn-lg para CTAs principales y btn-sm para acciones en tablas o toolbars.

Badge en un botón
<button class="btn btn-primary position-relative">
  Notificaciones
  <span class="position-absolute top-0 start-100
    translate-middle badge rounded-pill bg-danger">
    99+
    <span class="visually-hidden">no lidas</span>
  </span>
</button>

Posiciona el badge en la esquina del botón con position-absolute + top-0 start-100 translate-middle. rounded-pill le da la forma circular. visually-hidden añade contexto para lectores de pantalla (accesibilidad).

Formularios


10 cards
Campo de texto
<div class="mb-3">
  <label for="nombre" class="form-label">Nombre</label>
  <input type="text" class="form-control" id="nombre"
    placeholder="O su nombre">
  <div class="form-text">Nombre completo.</div>
</div>

form-control da estilo a inputs y textareas. form-label formatea el label. form-text muestra texto de ayuda debajo. mb-3 espacia los campos. Usa siempre for en el label ligado al id del input (accesibilidad).

Range y 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">Fichero</label>
  <input class="form-control" type="file" id="file">
</div>

<!-- Múltiples ficheros -->
<input class="form-control" type="file" multiple>

form-range da estilo al slider nativo. min, max, step controlan los valores. Para ficheros, usa type="file" con form-control. multiple permite varios ficheros. El estilo se adapta al browser.

Formulario inline (grid)
<form class="row g-3 align-items-end">
  <div class="col-auto">
    <label class="form-label">Nombre</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">Enviar</button>
  </div>
</form>

Usa el grid (row g-3) para formularios inline. col-auto se ajusta al contenido. align-items-end alinea los campos por la base (útil cuando hay labels). Responsivo: añade col-12 col-md-auto para apilar en mobile.

Select
<select class="form-select" aria-label="Elija">
  <option selected>Elija uma opción...</option>
  <option value="1">Opción 1</option>
  <option value="2">Opción 2</option>
</select>

<!-- Múltiple -->
<select class="form-select" multiple size="3">

<!-- Tamaño -->
<select class="form-select form-select-sm">

form-select da estilo al dropdown nativo. multiple + size permite selección múltiple. form-select-sm/form-select-lg ajustan el tamaño. aria-label describe el campo sin label visible.

Floating labels
<div class="form-floating mb-3">
  <input type="email" class="form-control" id="email"
    placeholder="nombre@ejemplo.com">
  <label for="email">Email</label>
</div>

<div class="form-floating">
  <textarea class="form-control" id="msg"
    placeholder="Mensaje" style="height:100px"></textarea>
  <label for="msg">Mensaje</label>
</div>

form-floating hace que el label flote sobre el campo cuando está relleno. El placeholder es obligatorio (aunque esté vacío) para que el efecto funcione. El label va DESPUÉS del input en el HTML. Funciona con textarea (define la height).

Formulario desactivado
<fieldset disabled>
  <div class="mb-3">
    <label class="form-label">Nombre</label>
    <input class="form-control" value="Ana">
  </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">Enviar</button>
</fieldset>

<fieldset disabled> desactiva todos los campos y botones dentro de él a la vez. Más práctico que disabled en cada elemento. El estilo se aplica automáticamente (opacidad, cursor). Ideal para formularios en modo lectura.

Checkbox y 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="opción" id="r1">
  <label class="form-check-label" for="r1">Opción A</label>
</div>

<!-- Inline -->
<div class="form-check form-check-inline">

form-check envuelve cada checkbox/radio. form-check-input da estilo al control; form-check-label al texto. form-check-inline los coloca uno al lado del otro. checked lo marca por defecto. Los radios del mismo grupo comparten el name.

Validación
<div class="mb-3">
  <label class="form-label">Email</label>
  <input class="form-control is-valid" value="a@b.com">
  <div class="valid-feedback">¡Parece bien!</div>
</div>

<div class="mb-3">
  <label class="form-label">Password</label>
  <input class="form-control is-invalid">
  <div class="invalid-feedback">Mínimo 8 caracteres.</div>
</div>

is-valid muestra un borde verde + icono; is-invalid muestra un borde rojo. valid-feedback/invalid-feedback muestran el mensaje (solo visible con el estado correspondiente). Combínalo con la validación JS del browser (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">
    Ativar notificaciones
  </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">Sempre activo</label>
</div>

form-switch convierte el checkbox en un interruptor (toggle). role="switch" mejora la semántica para lectores de pantalla. Funciona con checked y disabled. Un look moderno sin JS adicional.

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="Buscar...">
  <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 adjunta texto, iconos o botones al input. input-group-text es el addon (prefijo/sufijo). Puedes tener addons en ambos lados. Útil para @, €, unidades o botones de acción pegados al campo.

Barra de navegación y navegación


8 cards
Navbar básica
<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="#">Inicio</a>
        </li>
        <li class="nav-item">
          <a class="nav-link" href="#">Sobre</a>
        </li>
      </ul>
    </div>
  </div>
</nav>

navbar-expand-lg define cuándo colapsa el menú (por debajo de lg). navbar-toggler es el botón hamburguesa. navbar-collapse envuelve los links. ms-auto empuja el menú a la derecha. bg-body-tertiary le da fondo.

Formulario en la 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="Buscar...">
    <button class="btn btn-outline-success">Buscar</button>
  </form>
</div>

Usa d-flex en el form para alinear input + botón. me-auto en el navbar-nav empuja el form a la derecha. me-2 espacia el input del botón. type="search" da semántica y un icono nativo de limpiar.

Colores de la navbar
<!-- Clara (por defecto BS 5.3) -->
<nav class="navbar bg-body-tertiary">

<!-- Oscura -->
<nav class="navbar bg-dark" data-bs-theme="dark">

<!-- Color personalizado -->
<nav class="navbar" style="background-color: #6f42c1"
  data-bs-theme="dark">

<!-- Transparente -->
<nav class="navbar bg-transparent">

En BS 5.3+, usa data-bs-theme="dark" para texto claro sobre fondos oscuros. bg-body-tertiary es el fondo claro por defecto. bg-dark + data-bs-theme="dark" = navbar oscura. Puedes usar cualquier color con style inline.

Offcanvas como navbar mobile
<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>

Alternativa al collapse: usa offcanvas para un menú lateral en mobile. data-bs-toggle="offcanvas" en el toggler. offcanvas-end se desliza desde la derecha. Más espacio y flexibilidad que el collapse tradicional. Popular en apps mobile-first.

Navbar fija y sticky
<!-- Siempre visible arriba -->
<nav class="navbar fixed-top">

<!-- Se pega arriba al hacer scroll -->
<nav class="navbar sticky-top">

<!-- Fija abajo -->
<nav class="navbar fixed-bottom">

<!-- Con offset para el contenido -->
<body style="padding-top: 70px">

fixed-top = siempre visible (se quita del flujo; añade padding-top al body). sticky-top = se pega arriba cuando el scroll llega ahí (se mantiene en el flujo). fixed-bottom = barra fija abajo. Prefiere sticky-top cuando sea posible.

Breadcrumb
<nav aria-label="breadcrumb">
  <ol class="breadcrumb">
    <li class="breadcrumb-item">
      <a href="#">Inicio</a>
    </li>
    <li class="breadcrumb-item">
      <a href="#">Productos</a>
    </li>
    <li class="breadcrumb-item active" aria-current="page">
      Detalhes
    </li>
  </ol>
</nav>

breadcrumb muestra el rastro de navegación. El último item tiene active + aria-current="page" (página actual, sin link). El separador (/) viene vía CSS (--bs-breadcrumb-divider). Usa siempre <nav aria-label="breadcrumb"> para accesibilidad.

Dropdown en la navbar
<ul class="navbar-nav">
  <li class="nav-item dropdown">
    <a class="nav-link dropdown-toggle" href="#"
      data-bs-toggle="dropdown">Servicios</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="#">Todos</a></li>
    </ul>
  </li>
</ul>

Añade dropdown al nav-item y dropdown-toggle + data-bs-toggle="dropdown" al link. El dropdown-menu contiene los items. En mobile (colapsado), el dropdown se abre en acordeón. dropdown-divider separa grupos.

Nav pills y underline
<!-- Pills -->
<ul class="nav nav-pills">
  <li class="nav-item">
    <a class="nav-link active" href="#">Activo</a>
  </li>
  <li class="nav-item">
    <a class="nav-link" href="#">Outro</a>
  </li>
</ul>

<!-- Underline (BS 5.3+) -->
<ul class="nav nav-underline">
  <li class="nav-item">
    <a class="nav-link active" href="#">Activo</a>
  </li>
</ul>

nav-pills = fondo redondeado en el item activo. nav-underline (BS 5.3+) = subrayado en el activo. nav-tabs = pestañas con borde. Todos aceptan nav-fill (ancho igual) y nav-justified (100% del ancho).

Tarjetas y listas


10 cards
Card básica
<div class="card" style="width: 18rem">
  <div class="card-body">
    <h5 class="card-title">Título</h5>
    <h6 class="card-subtitle mb-2 text-body-secondary">
      Subtítulo</h6>
    <p class="card-text">Descripcion do contenido.</p>
    <a href="#" class="btn btn-primary">Ver mais</a>
  </div>
</div>

card es el contenedor flexible. card-body añade padding. card-title, card-subtitle, card-text formatean el contenido. text-body-secondary le da un color sutil al subtítulo. Ancho vía style o el grid.

Card horizontal
<div class="card mb-3" style="max-width: 540px">
  <div class="row g-0">
    <div class="col-md-4">
      <img src="foto.jpg" class="img-fluid rounded-start"
        alt="Foto">
    </div>
    <div class="col-md-8">
      <div class="card-body">
        <h5 class="card-title">Título</h5>
        <p class="card-text">Descripcion lateral.</p>
      </div>
    </div>
  </div>
</div>

Usa el grid dentro de la card para un layout horizontal: imagen en una columna, texto en otra. g-0 quita los gutters. rounded-start redondea solo la izquierda de la imagen. img-fluid la hace responsiva. Se apila en mobile automáticamente.

Table responsiva
<div class="table-responsive">
  <table class="table">
    <thead>...</thead>
    <tbody>...</tbody>
  </table>
</div>

<!-- Responsiva hasta un breakpoint -->
<div class="table-responsive-md">
  <table class="table">...</table>
</div>

table-responsive envuelve la tabla y añade scroll horizontal en pantallas pequeñas. table-responsive-{bp} solo añade scroll por debajo del breakpoint (ej.: -md = scroll solo en mobile). Esencial para tablas con muchas columnas.

Card con imagen
<div class="card">
  <img src="foto.jpg" class="card-img-top" alt="Foto">
  <div class="card-body">
    <h5 class="card-title">Título</h5>
    <p class="card-text">Texto descritivo.</p>
  </div>
</div>

<!-- Imagen al fondo -->
<div class="card">
  <div class="card-body">Texto</div>
  <img src="foto.jpg" class="card-img-bottom" alt="Foto">
</div>

card-img-top coloca la imagen arriba (con esquinas redondeadas). card-img-bottom abajo. La imagen debe tener un alt descriptivo. Combina con object-fit-cover + una altura fija para imágenes de tamaños diferentes.

List group
<ul class="list-group">
  <li class="list-group-item active">Activo</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>

<!-- Sin bordes exteriores -->
<ul class="list-group list-group-flush">

<!-- Numerado -->
<ol class="list-group list-group-numbered">

list-group crea listas estilizadas. active destaca; disabled desactiva. list-group-flush quita los bordes laterales (para usar dentro de cards). list-group-numbered numera automáticamente. Los items pueden ser links (list-group-item-action).

Card group y Masonry
<!-- Card group (bordes fundidos) -->
<div class="card-group">
  <div class="card">...</div>
  <div class="card">...</div>
  <div class="card">...</div>
</div>

<!-- Masonry (requiere Masonry JS) -->
<div class="row" data-masonry='{"percentPosition": true}'>
  <div class="col-sm-6 col-lg-4 mb-4">
    <div class="card">Altura variable</div>
  </div>
</div>

card-group funde los bordes de las cards (sin gap). Masonry (vía una lib externa) crea un layout tipo Pinterest con alturas variables. El grid normal alinea por filas; masonry rellena los huecos verticales. Requiere la biblioteca masonry.pkgd.min.js.

Header, footer y overlay
<div class="card">
  <div class="card-header">Highlight</div>
  <div class="card-body">Contenido principal</div>
  <div class="card-footer text-body-secondary">
    Há 2 días
  </div>
</div>

<!-- Overlay sobre una imagen -->
<div class="card bg-dark text-white">
  <img src="bg.jpg" class="card-img" alt="Fondo">
  <div class="card-img-overlay">
    <h5 class="card-title">Título sobre imagen</h5>
  </div>
</div>

card-header/card-footer son secciones con un fondo sutil. card-img-overlay posiciona contenido sobre la imagen (posición absoluta). Usa bg-dark text-white para legibilidad sobre fotos. Ideal para hero cards.

List group con badges y checkboxes
<ul class="list-group">
  <li class="list-group-item d-flex
    justify-content-between align-items-center">
    Mensajes
    <span class="badge bg-primary rounded-pill">14</span>
  </li>
  <li class="list-group-item">
    <input class="form-check-input me-1" type="checkbox">
    Tarea completada
  </li>
</ul>

Combina d-flex justify-content-between para un badge a la derecha. rounded-pill le da forma circular al contador. Los checkboxes dentro de list-group-item crean listas de tareas. me-1 espacia el checkbox del texto.

Cuadrícula de cards
<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">Texto variable...</p>
      </div>
    </div>
  </div>
  <div class="col">
    <div class="card h-100">...</div>
  </div>
</div>

row-cols-1 row-cols-md-3 = 1 columna en mobile, 3 en md+. g-4 espacia las cards. h-100 asegura alturas iguales en la misma fila. El patrón más usado para listados de productos, artículos y equipos.

Table
<table class="table table-striped table-hover">
  <thead>
    <tr>
      <th>#</th>
      <th>Nombre</th>
      <th class="text-end">Valor</th>
    </tr>
  </thead>
  <tbody>
    <tr class="table-warning">
      <td>1</td>
      <td>Ana</td>
      <td class="text-end">€120</td>
    </tr>
  </tbody>
</table>

table da estilo a la tabla. table-striped = filas alternadas; table-hover = resaltado al hover. table-bordered, table-sm (compacta), table-responsive (scroll horizontal). Colores por fila: table-warning, table-danger.

Modal, Alertas y Brindis


9 cards
Modal básico
<button class="btn btn-primary" data-bs-toggle="modal"
  data-bs-target="#meuModal">Abrir</button>

<div class="modal fade" id="meuModal" tabindex="-1">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title">Título</h5>
        <button class="btn-close"
          data-bs-dismiss="modal"></button>
      </div>
      <div class="modal-body">Contenido aqui.</div>
      <div class="modal-footer">
        <button class="btn btn-secondary"
          data-bs-dismiss="modal">Cerrar</button>
        <button class="btn btn-primary">Guardar</button>
      </div>
    </div>
  </div>
</div>

data-bs-toggle="modal" + data-bs-target="#id" abre el modal. fade añade una transición. data-bs-dismiss="modal" lo cierra. Estructura: modalmodal-dialogmodal-content → header/body/footer.

Alerta dismissible
<div class="alert alert-warning alert-dismissible fade show"
  role="alert">
  <strong>Atención!</strong> Espacio casi lleno.
  <button class="btn-close" data-bs-dismiss="alert"
    aria-label="Cerrar"></button>
</div>

alert-dismissible + btn-close con data-bs-dismiss="alert" hace que la alerta se pueda cerrar. fade show añade una animación de cierre. El botón X se posiciona automáticamente a la derecha. Tras cerrar, el elemento se elimina del DOM.

Backdrop y static
<!-- No se cierra al clicar fuera -->
<div class="modal" data-bs-backdrop="static"
  data-bs-keyboard="false">

<!-- Sin backdrop (fondo transparente) -->
<div class="modal" data-bs-backdrop="false">

<!-- Vía JS -->
new bootstrap.Modal(el, {
  backdrop: 'static',
  keyboard: false
});

data-bs-backdrop="static" impide cerrar al clicar fuera. data-bs-keyboard="false" desactiva el Escape. data-bs-backdrop="false" quita el overlay oscuro. Útil para formularios importantes donde perder datos sería un problema.

Tamaños de modal
<div class="modal-dialog modal-sm">Pequeño</div>
<div class="modal-dialog modal-lg">Grande</div>
<div class="modal-dialog modal-xl">Extra grande</div>
<div class="modal-dialog modal-fullscreen">Pantalla entero</div>

<!-- Fullscreen solo en mobile -->
<div class="modal-dialog modal-fullscreen-md-down">

<!-- Centrado verticalmente -->
<div class="modal-dialog modal-dialog-centered">

<!-- Con scroll en el body -->
<div class="modal-dialog modal-dialog-scrollable">

Tamaños: modal-sm, modal-lg, modal-xl, modal-fullscreen. modal-fullscreen-md-down = pantalla completa solo por debajo de md. modal-dialog-centered centra verticalmente. modal-dialog-scrollable hace scroll solo en el 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">Notificación</strong>
      <small>ahora</small>
      <button class="btn-close" data-bs-dismiss="toast"></button>
    </div>
    <div class="toast-body">
      Fichero enviado com éxito!
    </div>
  </div>
</div>

// JS para mostrarlo:
new bootstrap.Toast(document.querySelector('.toast')).show();

Toast = una notificación pequeña y temporal. toast-container la posiciona (usa position-fixed bottom-0 end-0). data-bs-delay="5000" = se cierra solo en 5s. Requiere .show() vía JS. Apila varios toasts en el container.

Modal vía JavaScript
// Abrir
const modal = new bootstrap.Modal(
  document.getElementById('meuModal')
);
modal.show();

// Cerrar
modal.hide();

// Toggle
modal.toggle();

// Eventos
document.getElementById('meuModal')
  .addEventListener('hidden.bs.modal', () => {
    console.log('Modal cerrado');
  });

La API JS: new bootstrap.Modal(el) crea la instancia; .show(), .hide(), .toggle() la controlan. Eventos: show.bs.modal, shown.bs.modal, hide.bs.modal, hidden.bs.modal. Útil para abrir tras una validación o un fetch.

Popover (detallado)
<button class="btn btn-lg btn-danger" data-bs-toggle="popover"
  data-bs-title="Título" data-bs-content="Contenido detalhado
  do popover com mais información."
  data-bs-placement="right">Clica para ver</button>

// JS (obligatorio):
const popover = new bootstrap.Popover(el, {
  trigger: 'focus',  // se cierra al clicar fuera
  html: true         // permite HTML en el contenido
});

Popover muestra contenido rico al hacer clic. data-bs-title + data-bs-content definen el contenido. data-bs-placement: top/bottom/left/right. Requiere init JS. trigger: 'focus' se cierra al clicar fuera. html: true permite HTML.

Alertas
<div class="alert alert-success" role="alert">
  Operación completada com éxito!
</div>

<div class="alert alert-danger" role="alert">
  Error ao procesar o pedido.
</div>

<div class="alert alert-warning" role="alert">
  <strong>Atención!</strong> Verifique os campos.
</div>

<div class="alert alert-info" role="alert">
  Nueva versión disponible.
</div>

alert alert-* muestra mensajes de feedback. Colores: success, danger, warning, info, primary, secondary, light, dark. Usa siempre role="alert" para accesibilidad. Links dentro: alert-link.

Modal con formulario
<div class="modal fade" id="formModal">
  <div class="modal-dialog">
    <div class="modal-content">
      <form>
        <div class="modal-header">
          <h5 class="modal-title">Nuevo registro</h5>
          <button class="btn-close"
            data-bs-dismiss="modal"></button>
        </div>
        <div class="modal-body">
          <div class="mb-3">
            <label class="form-label">Nombre</label>
            <input class="form-control" required>
          </div>
        </div>
        <div class="modal-footer">
          <button class="btn btn-secondary"
            data-bs-dismiss="modal">Cancelar</button>
          <button class="btn btn-primary"
            type="submit">Guardar</button>
        </div>
      </form>
    </div>
  </div>
</div>

Coloca el <form> dentro de modal-content (envolviendo header/body/footer). El type="submit" del botón envía el form. Usa el evento hidden.bs.modal para resetear el formulario tras cerrar. Valida antes de cerrar.

Utilidades


19 cards
Margin (espaciado exterior)
m-0, m-1, m-2, m-3, m-4, m-5   /* todos los lados */
mt-3    /* margin-top */
mb-2    /* margin-bottom */
ms-1    /* margin-start (izquierda en LTR) */
me-4    /* margin-end (derecha en LTR) */
mx-auto /* centra horizontalmente */
my-3    /* margin-top + bottom */

m = margin. Sufijos: t (top), b (bottom), s (start/izquierda), e (end/derecha), x (horizontal), y (vertical). Escala: 0 a 5 (0, 0.25rem, 0.5rem, 1rem, 1.5rem, 3rem). mx-auto centra bloques.

Colores de fondo
bg-primary, bg-success, bg-danger
bg-warning, bg-info, bg-dark
bg-light, bg-white, bg-transparent

<!-- Sutiles (BS 5.3+) -->
bg-primary-subtle
bg-danger-subtle

<!-- Gradiente -->
bg-primary bg-gradient

bg-* define el color de fondo. bg-*-subtle (BS 5.3+) da tonos pastel (ideal para alertas custom). bg-gradient añade un gradiente sutil. Combina con text-white o text-dark para un contraste legible.

Sombras
shadow-none   /* sin sombra */
shadow-sm     /* sutil */
shadow        /* por defecto */
shadow-lg     /* pronunciada */

<div class="card shadow">
<div class="btn shadow-sm">

shadow añade una box-shadow. Niveles: shadow-sm (sutil), shadow (por defecto), shadow-lg (pronunciada). shadow-none la quita (útil para sobrescribir el default de cards/botones). Para un efecto de elevación al hover: combina con CSS custom.

Overflow y scroll
overflow-auto      /* scroll solo si es necesario */
overflow-hidden    /* corta lo que sobra */
overflow-visible   /* muestra (por defecto) */
overflow-scroll    /* siempre scroll */

<!-- Ejes separados -->
overflow-x-auto    /* scroll horizontal */
overflow-y-hidden  /* corta vertical */

overflow-* controla el contenido que excede la caja. overflow-auto = scroll solo cuando es necesario. overflow-hidden = corta (útil con text-truncate). overflow-x-auto para tablas o listas horizontales. overflow-y-hidden evita el scroll vertical.

Visually hidden (accesibilidad)
<span class="visually-hidden">
  Texto para leitores de pantalla
</span>

<!-- Visible al enfocar (skip links) -->
<a class="visually-hidden-focusable" href="#contenido">
  Saltar para o contenido
</a>

<label class="visually-hidden" for="search">Buscar</label>
<input id="search" class="form-control">

visually-hidden oculta visualmente pero lo mantiene accesible para lectores de pantalla (a diferencia de d-none). visually-hidden-focusable aparece al recibir el foco (skip links). Esencial para labels de campos con placeholder e iconos sin texto.

Padding (espaciado interior)
p-0, p-1, p-2, p-3, p-4, p-5   /* todos los lados */
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, misma lógica que margin. px = horizontal, py = vertical. La escala es idéntica: 0 a 5. Usa p-3 para padding consistente en cards custom, py-5 para secciones con mucho espacio vertical.

Display
d-none          /* oculto */
d-block         /* bloque */
d-inline        /* inline */
d-inline-block  /* inline-block */
d-flex          /* flexbox */
d-grid          /* grid */
d-inline-flex   /* inline flex */

<!-- Responsivo -->
d-none d-md-block  /* oculto en mobile, visible en md+ */
d-md-none          /* visible solo en mobile */

d-* controla el tipo de visualización. d-none oculta por completo. d-flex activa flexbox. El patrón responsivo más usado: d-none d-md-block (oculta en mobile, muestra en md+). d-md-none = muestra solo en mobile.

Ancho y alto
w-25, w-50, w-75, w-100   /* width % */
w-auto                     /* ancho automático */
h-25, h-50, h-75, h-100   /* height % */
h-auto                     /* alto automático */
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-* = ancho en porcentaje; h-* = alto. vw-100/vh-100 = viewport. min-vh-100 = altura mínima de pantalla completa (hero sections). mw-100 impide el overflow de imágenes. w-auto resetea a automático.

Object-fit (imágenes/vídeos)
<img src="foto.jpg" class="object-fit-cover"
  style="height:200px; width:100%">

object-fit-contain     /* cabe todo (puede tener barras) */
object-fit-cover       /* rellena (recorta) */
object-fit-fill        /* estira (distorsiona) */
object-fit-scale-down  /* el menor entre contain/none */
object-fit-none        /* tamaño original */

<!-- Responsivo -->
object-fit-md-cover

object-fit-* controla cómo se ajustan las imágenes/vídeos a la caja. cover = rellena recortando (el más usado para thumbnails). contain = muestra todo (puede tener barras). Combina con una altura fija + w-100 para grids de imágenes uniformes.

Vertical align y float
/* Vertical align (inline/table-cell) */
align-baseline, align-top
align-middle, align-bottom
align-text-top, align-text-bottom

/* Float (legacy — prefiere flex) */
float-start    /* izquierda */
float-end      /* derecha */
float-none
clearfix       /* limpia floats en el padre */

align-* alinea verticalmente elementos inline o table-cell. float-* es legacy — hoy prefiere d-flex. clearfix en el padre limpia los floats (evita el colapso de altura). Se mantiene por compatibilidad con código antiguo.

Espaciado responsivo
p-2 p-md-4       /* más padding en el desktop */
mt-3 mt-lg-5     /* más margen en lg+ */
d-none d-md-block /* oculto en mobile */
gap-2 gap-lg-4   /* gap mayor en pantallas grandes */
text-center text-md-start /* alinea a la izquierda en md+ */

Todas las clases utilitarias aceptan prefijos de breakpoint: p-md-4, mt-lg-5, d-none d-md-block. El patrón es mobile-first: la clase sin prefijo aplica a todos; con prefijo, sobrescribe a partir de ese breakpoint.

Texto y tipografía
text-center, text-start, text-end  /* alineación */
fw-bold, fw-semibold, fw-normal    /* peso */
fst-italic                         /* itálica */
text-uppercase, text-lowercase     /* transformación */
text-decoration-none               /* sin subrayado */
text-truncate                      /* corta con ... */
fs-1, fs-2, fs-3, fs-4, fs-5, fs-6 /* tamaño de fuente */
lh-1, lh-sm, lh-base, lh-lg       /* line-height */

text-* alinea; fw-* controla el peso; fs-1 a fs-6 definen el tamaño de fuente (1=mayor). text-truncate corta texto largo con puntos suspensivos (requiere display: block o inline-block). lh-* ajusta el interlineado.

Position (posicionamiento)
position-static
position-relative
position-absolute
position-fixed
position-sticky

<!-- Coordenadas -->
top-0, top-50, top-100
bottom-0, start-0, end-0, start-50
translate-middle      /* centra en el punto */
translate-middle-x    /* centra solo horizontal */

position-* define el tipo de posicionamiento. Coordenadas: top-0, start-50, etc. (0%, 50%, 100%). translate-middle desplaza -50% en ambos ejes (centrado perfecto). Usa position-relative en el padre para absolute en el hijo.

Opacidad e interacción
opacity-0, opacity-25, opacity-50, opacity-75, opacity-100

pe-none    /* pointer-events: none (no clicable) */
pe-auto    /* pointer-events: auto */
user-select-none  /* no seleccionable */
user-select-all   /* selecciona todo al clicar */

visible     /* visibility: visible */
invisible   /* visibility: hidden (ocupa espacio) */

opacity-* define la transparencia. pe-none desactiva los clics (overlays, loading). user-select-none impide la selección de texto (botones, labels). invisible oculta pero mantiene el espacio (a diferencia de d-none que lo quita del flujo).

Z-index
z-0, z-1, z-2, z-3   /* valores bajos */
z-n1                  /* z-index: -1 */

/* Bootstrap usa internamente: */
/* dropdown: 1000, sticky: 1020 */
/* fixed: 1030, modal-backdrop: 1040 */
/* modal: 1050, popover: 1070, tooltip: 1080 */

<div class="position-relative z-1">Sobreposto</div>

z-0 a z-3 y z-n1 para stacking simple. Bootstrap reserva valores altos para los componentes (modal: 1050, tooltip: 1080). Para superponer contenido sobre un modal, necesitas un z-index > 1050. Usa position-relative para que el z-index funcione.

Colores de texto
text-primary     /* azul */
text-success     /* verde */
text-danger      /* rojo */
text-warning     /* amarillo */
text-info        /* cian */
text-dark        /* oscuro */
text-muted       /* gris sutil (BS 5.3: text-body-secondary) */
text-white       /* blanco */
text-body-secondary  /* gris (nuevo en BS 5.3) */

text-* define el color del texto. En BS 5.3+, text-body-secondary reemplaza a text-muted (se adapta al dark mode). Combina con bg-* para contraste. Usa colores semánticos: danger para errores, success para éxito.

Bordes y redondeo
border, border-0           /* todos / ninguno */
border-top, border-end     /* lados específicos */
border-primary, border-danger  /* color */
border-1, border-2, border-3   /* grosor */

rounded, rounded-0, rounded-1, rounded-2, rounded-3
rounded-circle    /* círculo (imágenes cuadradas) */
rounded-pill      /* píldora (botones/badges) */
rounded-top, rounded-start  /* lados específicos */

border añade borde; border-0 lo quita. border-{color} cambia el color; border-{1-5} el grosor. rounded redondea esquinas (0 a 5). rounded-circle para avatares; rounded-pill para badges/botones.

Centrar con position
<!-- Centrar absolutamente -->
<div class="position-relative" style="height:300px">
  <div class="position-absolute top-50 start-50
    translate-middle">
    Centrado!
  </div>
</div>

<!-- Badge en la esquina -->
<div class="position-relative">
  <span class="position-absolute top-0 start-100
    translate-middle badge bg-danger">5</span>
</div>

Patrón de centrado: padre position-relative + hijo position-absolute top-50 start-50 translate-middle. Para badges en la esquina: top-0 start-100 translate-middle. Alternativa moderna: d-flex + justify-content-center + align-items-center.

Ratio (proporción de aspecto)
<div class="ratio ratio-16x9">
  <iframe src="https://youtube.com/embed/..."
    title="Vídeo"></iframe>
</div>

ratio-1x1    /* cuadrado */
ratio-4x3    /* TV antigua */
ratio-16x9   /* widescreen */
ratio-21x9   /* ultrawide */

<!-- Custom vía CSS variable -->
<div class="ratio" style="--bs-aspect-ratio: 66.67%">

ratio + ratio-16x9 mantiene una proporción responsiva para vídeos/iframes. El contenido se estira para rellenar. ratio-1x1 para avatares cuadrados. Custom: --bs-aspect-ratio: 66.67% (2:3). Reemplaza el viejo hack de padding-bottom.

Sensible


8 cards
Breakpoints
xs   < 576px    (móvil — sin prefijo)
sm  ≥ 576px     (móvil landscape)
md  ≥ 768px     (tablet)
lg  ≥ 992px     (desktop pequeño)
xl  ≥ 1200px    (desktop)
xxl ≥ 1400px    (pantalla grande)

Los breakpoints son mobile-first: las clases sin prefijo aplican a todos; con prefijo, sobrescriben a partir de ese ancho. xs no tiene prefijo (col-6 = col-xs-6). Los valores están en em en el Sass (576px = 36em).

Tipografía responsiva
<h1 class="display-1">Título enorme</h1>
<h1 class="display-4">Título grande</h1>

<!-- Tamaño de fuente responsivo -->
<p class="fs-6 fs-md-4 fs-lg-3">Texto que cresce</p>

<!-- Alineación responsiva -->
<p class="text-center text-md-start">
  Centrado no mobile, izquierda no desktop
</p>

display-1 a display-6 son títulos extra-grandes. fs-1 a fs-6 definen tamaños (aceptan prefijos: fs-md-4). Alineación responsiva: text-center text-md-start. Bootstrap ya usa clamp() en los headings por defecto.

Ocultar/mostrar por breakpoint
d-none d-sm-block     /* oculto en xs, visible en sm+ */
d-sm-none             /* visible SOLO en xs */
d-none d-md-block     /* oculto hasta md */
d-md-none             /* visible solo en xs y sm */
d-none d-lg-block d-xl-none  /* visible solo en lg */

<!-- Ejemplo práctico -->
<span class="d-none d-md-inline">Menu completo</span>
<button class="d-md-none">☰</button>

Combina d-none + d-{bp}-block para mostrar a partir de un breakpoint. d-{bp}-none oculta a partir de ese breakpoint. Patrón clásico: menú completo en desktop (d-none d-md-inline) + hamburguesa en mobile (d-md-none).

Containers responsivos
<!-- Ancho máximo por breakpoint -->
.container       /* fijo en cada bp */
.container-sm    /* 100% hasta sm, fijo después */
.container-md    /* 100% hasta md, fijo después */
.container-lg    /* 100% hasta lg, fijo después */
.container-xl    /* 100% hasta xl, fijo después */
.container-xxl   /* 100% hasta xxl, fijo después */
.container-fluid /* siempre 100% */

container-{bp} es 100% hasta el breakpoint y ancho fijo después. Ej.: container-lg = 100% en mobile/tablet, fijo (960px) en lg+. Útil cuando quieres full-width en mobile pero limitado en desktop. container-fluid = siempre 100%.

Imagen responsiva
<img src="foto.jpg" class="img-fluid" alt="Responsiva">

<img src="foto.jpg" class="img-thumbnail" alt="Miniatura">

<!-- Picture con sources -->
<picture>
  <source srcset="grande.webp" media="(min-width:768px)">
  <img src="pequena.webp" class="img-fluid" alt="Foto">
</picture>

img-fluid = max-width: 100%; height: auto (nunca excede al padre). img-thumbnail añade borde + padding + redondeo. Usa <picture> + srcset para servir imágenes diferentes por breakpoint (rendimiento).

Espaciado por breakpoint
<!-- Padding progresivo -->
<section class="py-3 py-md-5">
  <div class="container px-3 px-lg-5">

<!-- Margin responsivo -->
<div class="mb-3 mb-lg-5">

<!-- Gap responsivo -->
<div class="d-flex gap-2 gap-md-4">

<!-- Sección hero full-height solo en desktop -->
<section class="min-vh-100 d-none d-md-flex">

Ajusta el espaciado por pantalla: py-3 py-md-5 (menos padding en mobile). gap-2 gap-md-4 (más espacio en desktop). min-vh-100 para hero sections. El mobile necesita menos espacio; el desktop puede ser más generoso.

Grid responsivo (patrones)
<!-- 1 col mobile → 2 tablet → 4 desktop -->
<div class="row row-cols-1 row-cols-md-2 row-cols-xl-4 g-4">

<!-- Sidebar + contenido -->
<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">Contenido</div>
</div>

<!-- Apilar en mobile -->
<div class="d-flex flex-column flex-md-row gap-3">

Patrones comunes: row-cols-1 row-cols-md-2 row-cols-xl-4 para grids progresivos. Sidebar: col-md-4 col-lg-3 + contenido col-md-8 col-lg-9. Siempre mobile-first: empieza con 1 columna y añade anchos en breakpoints mayores.

Media queries en Sass
// Mixins de Bootstrap
@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) {
  .título { font-size: 1.5rem; }
}

Los mixins media-breakpoint-up/down/between/only generan media queries con los breakpoints de Bootstrap. up(md) = @media (min-width: 768px). down(md) = @media (max-width: 767.98px). Úsalos en Sass custom para consistencia.

Consejos y buenas prácticas


8 cards
El bundle incluye Popper
<!-- bootstrap.bundle.min.js = Bootstrap + Popper.js -->
<script src="bootstrap.bundle.min.js"></script>

<!-- bootstrap.min.js = solo Bootstrap (sin Popper) -->
<script src="bootstrap.min.js"></script>

// Popper es necesario para:
// - Dropdowns
// - Tooltips
// - Popovers

El bundle incluye Popper.js (posicionamiento de dropdowns, tooltips, popovers). Si usas bootstrap.min.js (sin bundle), necesitas cargar Popper por separado. En caso de duda, usa siempre el bundle — es lo más simple.

Accesibilidad (ARIA)
<button aria-label="Cerrar" class="btn-close"></button>
<nav aria-label="breadcrumb">
<div class="alert" role="alert">
<div class="modal" aria-labelledby="título"
  aria-hidden="true">
<input aria-describedby="ajuda">
<span id="ajuda" class="form-text">Texto de ajuda</span>

Usa siempre atributos ARIA: aria-label en botones sin texto, role="alert" en alertas, aria-labelledby en modales, aria-describedby para la ayuda. aria-hidden="true" en elementos decorativos. Bootstrap ya incluye algunos, pero verifícalo.

Atributos data-bs-*
data-bs-toggle="modal"       /* abre un modal */
data-bs-toggle="collapse"    /* colapsa */
data-bs-toggle="dropdown"    /* dropdown */
data-bs-toggle="tooltip"     /* tooltip */
data-bs-toggle="offcanvas"   /* offcanvas */
data-bs-target="#id"         /* objetivo */
data-bs-dismiss="modal"      /* cierra */
data-bs-ride="carousel"      /* auto-play */

En Bootstrap 5, todos los atributos usan el prefijo data-bs- (antes era data-). toggle define el comportamiento; target el elemento objetivo; dismiss cierra. No hace falta jQuery — todo funciona con atributos HTML.

CSS variables (BS 5.3)
/* Bootstrap expone variables CSS: */
:root {
  --bs-primary: #0d6efd;
  --bs-body-font-size: 1rem;
  --bs-border-radius: 0.375rem;
}

/* Úsalas directamente: */
.card {
  border-radius: var(--bs-border-radius);
  color: var(--bs-primary);
}

/* Sobrescribe por componente: */
.btn-custom { --bs-btn-bg: #6f42c1; }

Bootstrap 5.3 expone variables CSS (--bs-*) que puedes usar y sobrescribir sin Sass. --bs-primary, --bs-border-radius, --bs-body-font-size. Los componentes usan --bs-btn-*, --bs-card-*. Ideal para theming en runtime (dark mode toggle).

Sin jQuery (BS 5)
// Bootstrap 5 NO necesita jQuery
// API JavaScript nativa:

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);

// Obtener una instancia existente:
const m = bootstrap.Modal.getInstance(el);

Bootstrap 5 eliminó la dependencia de jQuery. Usa la API nativa: new bootstrap.Modal(el), .getInstance(el). Cada componente tiene .show(), .hide(), .toggle(), .dispose(). Eventos: el.addEventListener('shown.bs.modal', fn).

Utilidades combinadas (patrones)
<!-- 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">Título</h1>
    <p class="lead text-body-secondary">Subtítulo</p>
    <a class="btn btn-primary btn-lg mt-3">CTA</a>
  </div>
</section>

<!-- Card de perfil -->
<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">Nombre</h5>
    <p class="text-body-secondary small">Cargo</p>
  </div>
</div>

Combina utilidades para patrones comunes: hero = bg-dark text-white py-5 min-vh-100 d-flex align-items-center. Card de perfil = text-center shadow-sm + rounded-circle mx-auto. Componer utilidades evita el CSS custom en la mayoría de los casos.

Reboot (reset global)
/* El Reboot de Bootstrap normaliza: */
- box-sizing: border-box (todos los elementos)
- margin: 0 en el body
- font-family y line-height base
- links con el color primario
- botones con cursor: pointer
- tablas con border-collapse
- imágenes con vertical-align: middle

El Reboot es el reset global de Bootstrap (basado en Normalize). Aplica box-sizing: border-box a todo, quita los márgenes del body, define la tipografía base. Se importa automáticamente. Si no lo quieres, puedes importar solo componentes específicos vía Sass.

Documentación y recursos
# Documentación oficial
https://getbootstrap.com/docs/5.3/

# Iconos (2000+)
https://icons.getbootstrap.com/

# Ejemplos y 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

La documentación oficial (getbootstrap.com/docs) tiene ejemplos interactivos de todos los componentes. icons.getbootstrap.com lista los 2000+ iconos. La sección Examples tiene templates completos (album, dashboard, sign-in). El CDN vía jsDelivr es el más rápido.