DevTools

Cheatsheet Bootstrap

Framework CSS para desenvolvimento responsivo

Voltar às linguagens
Bootstrap
128 cards encontrados
Categorias:
Versões:

Instalação e Setup


8 cards
Via CDN
<!-- CSS no <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>

O CSS vai no <head>; o bundle.min.js (que inclui Popper.js) vai antes de </body>. O bundle é necessário para dropdowns, modais e tooltips funcionarem.

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>

O pacote Bootstrap Icons tem 2000+ ícones SVG em fonte. Use bi bi-nome para outline e bi bi-nome-fill para preenchido. Combine com utilitários como fs-4 e text-primary para estilizar.

Template base
<!DOCTYPE html>
<html lang="pt">
<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>

O meta viewport é essencial para responsividade — sem ele, o site não escala em mobile. O lang="pt" ajuda acessibilidade e SEO. Sempre incluir o charset UTF-8.

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

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

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

Bootstrap 5.3+ suporta data-bs-theme="dark" nativamente. Aplique no <html> para global ou num elemento para local. As cores adaptam-se automaticamente (fundos, textos, bordas). Combine com prefers-color-scheme via JS.

Via npm
npm install bootstrap

// CSS (no seu ficheiro principal):
import 'bootstrap/dist/css/bootstrap.min.css';

// JS:
import 'bootstrap';

// Ou só componentes específicos:
import { Modal, Dropdown } from 'bootstrap';

Via npm tem controlo total do build. Importe o CSS completo ou use Sass para personalizar. O import do JS regista todos os plugins; pode importar só os que precisa para reduzir o bundle.

Sass (personalização)
// custom.scss — sobrescrever ANTES de importar
$primary: #6f42c1;
$font-family-base: 'Inter', sans-serif;
$border-radius: 0.5rem;
$enable-shadows: true;

@import "bootstrap/scss/bootstrap";

Personalize o Bootstrap via Sass: defina variáveis ($primary, $font-family-base) antes do @import. Pode importar só partes: bootstrap/scss/functions, variables, mixins, e os componentes que precisa.

Contentores
<div class="container">Largura fixa por breakpoint</div>
<div class="container-fluid">100% sempre</div>
<div class="container-md">100% até md, fixo depois</div>
<div class="container-lg">100% até lg, fixo depois</div>
<div class="container-xxl">100% até xxl, fixo depois</div>

container tem largura máxima que muda por breakpoint. container-fluid é sempre 100%. container-{breakpoint} é 100% até ao breakpoint indicado e fixo depois — útil para layouts que só precisam de limite em ecrãs grandes.

Importar só partes
// Importar só o necessário (menor 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 reduzir o CSS final, importe só os módulos necessários. A ordem importa: functionsvariablesmixins primeiro. Depois os componentes (grid, buttons, forms). Útil para projetos com build otimizado.

Grid e Layout


14 cards
Estrutura do grid
<div class="container">
  <div class="row">
    <div class="col">Coluna 1</div>
    <div class="col">Coluna 2</div>
    <div class="col">Coluna 3</div>
  </div>
</div>

A hierarquia é containerrowcol. O grid tem 12 colunas. A row é um flex container com margens negativas para alinhar com o padding do container. Nunca coloque conteúdo diretamente na row.

col-{breakpoint}-{n} — responsiva
<div class="col-12 col-md-6 col-lg-4">
  <!-- 100% no 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% em sm → 25% em xl -->
</div>

O prefixo do breakpoint define a partir de que largura a regra se aplica. Abaixo do breakpoint, a coluna empilha (100%). Padrão mobile-first: comece com col-12 e adicione larguras maiores progressivamente.

Ordem das colunas
<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">Primeiro</div>
<div class="col order-last">Último</div>

order-0 a order-5, order-first e order-last reordenam visualmente sem mudar o HTML. Útil para responsivo: order-1 order-md-2 muda a ordem só no desktop. O padrão é order-0.

Colunas com alturas iguais
<div class="row row-cols-1 row-cols-md-3 g-4">
  <div class="col">
    <div class="card h-100">
      <div class="card-body">Conteúdo variável...</div>
    </div>
  </div>
  <div class="col">
    <div class="card h-100">
      <div class="card-body">Mais texto aqui...</div>
    </div>
  </div>
</div>

Use h-100 no card dentro de cada col para garantir alturas iguais na mesma linha. As colunas do grid já têm a mesma altura (flex stretch), mas o conteúdo interno precisa de h-100 para preencher.

col — largura 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 sem número divide o espaço em partes iguais automaticamente. O Bootstrap calcula a largura com base no número de colunas irmãs. Funciona em todos os breakpoints (empilha no mobile por padrão com col simples).

row-cols-{n} — colunas por linha
<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 quantas colunas cabem por linha, sem precisar de classes em cada col. Ideal para grelhas de cards: row-cols-1 row-cols-md-3 = 1 coluna no mobile, 3 no tablet. Todas as colunas ficam com largura igual.

Alinhamento vertical
<div class="row align-items-start" style="height:200px">
  <div class="col">Topo</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">Fundo</div>
</div>

align-items-start/center/end alinha todas as colunas verticalmente dentro da row. A row precisa de altura definida para o efeito ser visível. Para alinhar uma só coluna, use align-self-* nessa coluna.

Quebra de linha forçada
<div class="row">
  <div class="col-6">Coluna 1</div>
  <div class="col-6">Coluna 2</div>

  <!-- Quebra forçada -->
  <div class="w-100"></div>

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

Um <div class="w-100"> vazio força uma quebra de linha no grid (ocupa 100% da largura). Útil quando quer controlar onde as colunas quebram sem criar múltiplas rows. Pode ser responsivo: d-none d-md-block.

col-auto — ajusta ao conteúdo
<div class="row">
  <div class="col-auto">Texto curto</div>
  <div class="col">Ocupa o resto</div>
</div>

<div class="row justify-content-center">
  <div class="col-auto">Centrado ao conteúdo</div>
</div>

col-auto faz a coluna ter apenas a largura do seu conteúdo (como width: auto). Combine com col para ter uma coluna fixa e outra que preenche o restante. Útil para labels + inputs lado a lado.

Gutters (espaçamento)
<div class="row g-3">Gap geral (x+y)</div>
<div class="row gx-2">Só horizontal</div>
<div class="row gy-4">Só vertical</div>
<div class="row g-0">Sem espaçamento</div>

<!-- Responsivo -->
<div class="row g-2 g-md-4">Mais espaço no desktop</div>

g-0 a g-5 controla o espaço entre colunas (gutters). gx = horizontal, gy = vertical. g-0 remove totalmente (útil para layouts colados). Aceita prefixos responsivos: g-md-4.

Alinhamento horizontal
<div class="row justify-content-start">
  <div class="col-4">Esquerda</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">Esq</div>
  <div class="col-4">Dir</div>
</div>

justify-content-* distribui as colunas horizontalmente na row. Opções: start, center, end, between, around, evenly. Funciona porque a row é um flex container.

col-{n} — largura fixa
<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% (linha inteira)</div>

O número indica colunas de 12: col-6 = 50%, col-4 = 33%, col-3 = 25%. A soma deve dar 12 (ou menos). Se exceder 12, as colunas extras passam para a linha seguinte (wrap automático).

Offset (deslocar)
<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">
    Deslocado para o centro
  </div>
</div>

offset-{bp}-{n} empurra a coluna N posições para a direita (margem esquerda). Para centrar uma col-6: offset-md-3 (3+6+3=12). Em mobile, use offset-0 para resetar. Alternativa: mx-auto com col fixa.

Aninhar 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>

Coloque uma row dentro de uma col para criar sub-grelhas. As 12 colunas da sub-row são relativas à coluna pai (não ao container). Os gutters aninham-se corretamente. Não precisa de container extra.

Flexbox


12 cards
Ativar flex
<div class="d-flex">Contentor flex</div>
<div class="d-inline-flex">Flex inline</div>

<!-- Responsivo -->
<div class="d-flex d-md-none">Flex só no mobile</div>
<div class="d-none d-lg-flex">Flex só em lg+</div>

d-flex torna o elemento um flex container; os filhos viram flex items. d-inline-flex é a versão inline. Aceita prefixos responsivos: d-md-flex ativa flex só a partir de md. A row do grid já é flex por padrão.

align-self (um item)
<div class="d-flex align-items-start" style="height:200px">
  <div>Topo</div>
  <div class="align-self-center">Centro</div>
  <div class="align-self-end">Fundo</div>
  <div class="align-self-stretch">Esticado</div>
</div>

align-self-* sobrepõe o align-items num único item. Mesmo valores: start, center, end, baseline, stretch. Útil quando um item precisa de alinhamento diferente dos irmãos.

align-content (várias linhas)
/* Requer flex-wrap para ter efeito */
align-content-start
align-content-end
align-content-center
align-content-between
align-content-around
align-content-stretch  /* padrão */

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

align-content-* alinha as linhas quando há flex-wrap e múltiplas linhas. Sem wrap, não tem efeito. stretch (padrão) distribui as linhas pelo espaço. Útil para centrar um grupo de itens que quebram em várias linhas.

Direção (eixo principal)
flex-row             /* linha → (padrão) */
flex-row-reverse     /* linha ← */
flex-column          /* coluna ↓ */
flex-column-reverse  /* coluna ↑ */

<!-- Responsivo -->
flex-column flex-md-row  /* coluna no mobile, linha em md+ */

flex-row (padrão) coloca itens em linha; flex-column em coluna. -reverse inverte a ordem. O padrão mobile-first é flex-column flex-md-row — empilha no mobile, lado a lado no desktop.

flex-wrap (quebra de linha)
flex-wrap          /* permite quebrar para linha seguinte */
flex-nowrap        /* não quebra (padrão) */
flex-wrap-reverse  /* quebra invertida */

<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 os itens passem para a linha seguinte quando não cabem. flex-nowrap (padrão) força tudo numa linha (pode causar overflow). Essencial para listas de tags, chips ou grids de cards com flex.

Centrar na perfeição
<div class="d-flex justify-content-center
  align-items-center" style="height:100vh">
  <div class="text-center">
    Centrado nos 2 eixos
  </div>
</div>

A combinação d-flex + justify-content-center + align-items-center centra qualquer conteúdo horizontal e verticalmente. O contentor precisa de altura (ex.: 100vh, h-100). O padrão moderno de centragem.

justify-content (eixo principal)
justify-content-start     /* início (padrão) */
justify-content-end       /* fim */
justify-content-center    /* centro */
justify-content-between   /* espaço entre */
justify-content-around    /* espaço à volta */
justify-content-evenly    /* espaço igual */

justify-content-* distribui os itens ao longo do eixo principal (horizontal em flex-row). between = primeiro no início, último no fim, espaço igual entre. evenly = espaço igual em todos. O mais usado é center e between.

gap (espaço entre itens)
<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      /* espaço entre linhas */
column-gap-4   /* espaço entre colunas */

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

gap-0 a gap-5 define o espaçamento entre flex items (substitui margens). row-gap = entre linhas, column-gap = entre colunas. Mais limpo que usar me-*/mb-* em cada item. Aceita prefixos responsivos.

Barra com espaço 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="#">Início</a>
    <a href="#">Sobre</a>
    <a href="#">Contacto</a>
  </nav>
</div>

Padrão clássico: justify-content-between + align-items-center coloca o logo à esquerda e o menu à direita, ambos centrados verticalmente. gap-3 espaça os links do nav sem margens individuais.

align-items (eixo cruzado)
align-items-start      /* topo */
align-items-end        /* fundo */
align-items-center     /* centro vertical */
align-items-baseline   /* linha de base do texto */
align-items-stretch    /* esticar (padrão) */

align-items-* alinha os itens perpendicularmente ao eixo principal (vertical em flex-row). stretch (padrão) faz os itens terem a mesma altura. center centra verticalmente. O contentor precisa de altura para o efeito ser visível.

flex-fill e grow/shrink
<div class="d-flex">
  <div class="flex-fill">Ocupa tudo</div>
  <div>Fixo</div>
</div>

flex-grow-0    /* não cresce (padrão) */
flex-grow-1    /* cresce para preencher */
flex-shrink-0  /* não encolhe */
flex-shrink-1  /* encolhe (padrão) */

flex-fill faz o item crescer para ocupar todo o espaço disponível (como flex: 1 1 auto). flex-grow-1 = cresce; flex-shrink-0 = não encolhe (útil para botões/labels que não devem comprimir).

Flex responsivo
<!-- Coluna no mobile, linha em md+ -->
<div class="d-flex flex-column flex-md-row gap-3">
  <div>Sidebar</div>
  <div class="flex-fill">Conteúdo</div>
</div>

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

<!-- Wrap só no mobile -->
<div class="d-flex flex-wrap flex-md-nowrap">

Todas as classes flex aceitam prefixos de breakpoint: flex-md-row, gap-lg-4, justify-content-md-between. O padrão mobile-first aplica-se: defina o mobile primeiro e sobrescreva em breakpoints maiores.

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">Conteúdo</div>
    </div>
  </div>
</div>

O Accordion mostra painéis expansíveis. data-bs-toggle="collapse" + data-bs-target controla a abertura. data-bs-parent="#acc" faz com que só um painel esteja aberto de cada vez. show = aberto por padrão.

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

<div class="collapse" id="conteudo">
  <div class="card card-body">
    Conteúdo colapsável
  </div>
</div>

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

collapse esconde/mostra conteúdo. data-bs-toggle="collapse" + data-bs-target controla. Adicione show para começar aberto. collapse-horizontal anima a largura em vez da altura. Base do Accordion e Navbar mobile.

Tooltip e Popover
<!-- Tooltip (requer init JS) -->
<button data-bs-toggle="tooltip" data-bs-placement="top"
  title="Dica útil">Passa o rato</button>

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

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

Tooltip mostra dica ao hover; Popover mostra conteúdo ao clicar. Ambos requerem inicialização JS manual. data-bs-placement: top, bottom, left, right. data-bs-html="true" permite HTML no conteúdo.

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>

O Carousel é um slider de imagens. data-bs-ride="carousel" inicia automaticamente. d-block w-100 na imagem garante largura total. Controles: data-bs-slide="prev/next". Adicione carousel-indicators para pontos.

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 navegação...
  </div>
</div>

Offcanvas é um painel lateral deslizante. Posições: offcanvas-start (esquerda), offcanvas-end (direita), offcanvas-top, offcanvas-bottom. data-bs-dismiss="offcanvas" fecha. Ideal para menus mobile e carrinhos.

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 cria navegação paginada. page-item active = página atual; disabled = não clicável. Tamanhos: pagination-sm, pagination-lg. Centralize com justify-content-center na 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="#">Ação 1</a></li>
    <li><a class="dropdown-item" href="#">Ação 2</a></li>
    <li><hr class="dropdown-divider"></li>
    <li><a class="dropdown-item text-danger" href="#">Sair</a></li>
  </ul>
</div>

O Dropdown mostra um menu suspenso ao clicar. data-bs-toggle="dropdown" ativa. dropdown-divider separa grupos. Posições: dropup, dropend, dropstart na div pai. Alinhamento: dropdown-menu-end.

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

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

<!-- Em botão -->
<button class="btn btn-primary" disabled>
  <span class="spinner-border spinner-border-sm"></span>
  A processar...
</button>

spinner-border = anel giratório; spinner-grow = ponto que cresce. spinner-border-sm = versão pequena (para botões). Use text-* para cor. Sempre inclua visually-hidden com texto para acessibilidade.

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">Secção 1</a>
  <a class="nav-link" href="#sec2">Secção 2</a>
</nav>

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

Scrollspy destaca automaticamente o link ativo conforme o scroll. data-bs-spy="scroll" no body + data-bs-target aponta para o nav. Os links devem apontar para IDs das secções. data-bs-offset ajusta o ponto de ativação.

Tabs (separadores)
<ul class="nav nav-tabs" role="tablist">
  <li class="nav-item">
    <button class="nav-link active" data-bs-toggle="tab"
      data-bs-target="#tab1">Aba 1</button>
  </li>
  <li class="nav-item">
    <button class="nav-link" data-bs-toggle="tab"
      data-bs-target="#tab2">Aba 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 cria separadores com linha. data-bs-toggle="tab" + data-bs-target liga ao painel. tab-pane fade show active no conteúdo. Use nav-pills para versão em pílula. fade adiciona transição.

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

<!-- Listrado e animado -->
<div class="progress">
  <div class="progress-bar progress-bar-striped
    progress-bar-animated" style="width: 50%"></div>
</div>

A progress é a barra exterior; progress-bar é o preenchimento (largura via style ou JS). progress-bar-striped adiciona listas; progress-bar-animated anima-as. bg-* muda a cor. Múltiplas barras = progresso 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 cria skeleton loading (esqueleto de carregamento). col-6 define a largura da barra. placeholder-glow anima com brilho; placeholder-wave anima com onda. Substitua pelo conteúdo real quando os dados carregarem.

Botões e Badges


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

btn é a classe base; a segunda classe define a cor. Funciona em <button>, <a> e <input>. Use <button> para ações JS e <a> para navegação (acessibilidade).

Botão em bloco (full width)
<div class="d-grid gap-2">
  <button class="btn btn-primary btn-lg">
    Largura total
  </button>
  <button class="btn btn-outline-secondary">
    Secundário
  </button>
</div>

<!-- Responsivo: bloco só no mobile -->
<div class="d-grid d-md-inline-block">

d-grid no contentor faz os botões ocuparem 100% da largura. gap-2 espaça botões empilhados. No Bootstrap 5 não existe btn-block — use d-grid. Para responsivo: d-grid d-md-inline-block.

Grupo de botões
<div class="btn-group" role="group">
  <button class="btn btn-outline-primary">Esq</button>
  <button class="btn btn-outline-primary">Meio</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 botões lado a lado (bordas fundidas). btn-group-vertical empilha. btn-toolbar combina múltiplos grupos. Adicione role="group" para acessibilidade. Tamanhos: btn-group-sm, btn-group-lg.

Cores de botão
btn-primary     /* azul (ação principal) */
btn-secondary   /* cinza */
btn-success     /* verde (confirmação) */
btn-danger      /* vermelho (perigo/eliminar) */
btn-warning     /* amarelo (atenção) */
btn-info        /* ciano (informação) */
btn-light       /* claro */
btn-dark        /* escuro */
btn-link        /* parece um link */

As cores são semânticas: primary para ação principal, danger para ações destrutivas, success para confirmação. btn-link remove o fundo e borda (parece um link mas mantém padding de botão). Personalize via $theme-colors no Sass.

Botão desativado e 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 processar...
</button>

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

disabled remove a interação e aplica opacidade. Em <a>, use a classe disabled + aria-disabled="true" (não existe atributo disabled em links). Combine com spinner-border-sm para estado de loading.

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

<!-- Versão branca (para fundos escuros) -->
<button class="btn-close btn-close-white"
  aria-label="Fechar"></button>

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

btn-close é o botão X padrão (usa SVG background). btn-close-white inverte para branco (fundos escuros). Sempre inclua aria-label="Fechar" porque o botão não tem texto visível. Usado em modais, alertas e offcanvas.

Botão outline
<button class="btn btn-outline-primary">Primário</button>
<button class="btn btn-outline-danger">Perigo</button>
<button class="btn btn-outline-dark">Escuro</button>

<!-- Ao hover, preenche com a cor -->

btn-outline-* cria botões com apenas contorno e fundo transparente. Ao hover/focus, preenche com a cor. Ideal para ações secundárias que não devem competir visualmente com o btn-primary. Todas as cores estão disponíveis.

Badge
<span class="badge bg-primary">Novo</span>
<span class="badge bg-danger">5</span>
<span class="badge rounded-pill bg-success">12</span>
<span class="badge text-bg-warning">Atenção</span>

<!-- Em heading -->
<h2>Notificações <span class="badge bg-secondary">4</span></h2>

badge é um pequeno rótulo. bg-* define a cor de fundo. rounded-pill arredonda totalmente. text-bg-* (BS 5.3+) define fundo + cor de texto com contraste automático. Posicione com position-absolute para cantos.

Tamanho de botão
<button class="btn btn-primary btn-lg">Grande</button>
<button class="btn btn-primary">Normal</button>
<button class="btn btn-primary btn-sm">Pequeno</button>

btn-lg = grande (mais padding e fonte); btn-sm = pequeno. O tamanho normal não precisa de classe extra. Use btn-lg para CTAs principais e btn-sm para ações em tabelas ou toolbars.

Badge em botão
<button class="btn btn-primary position-relative">
  Notificações
  <span class="position-absolute top-0 start-100
    translate-middle badge rounded-pill bg-danger">
    99+
    <span class="visually-hidden">não lidas</span>
  </span>
</button>

Posicione o badge no canto do botão com position-absolute + top-0 start-100 translate-middle. rounded-pill dá o formato circular. visually-hidden adiciona contexto para leitores de ecrã (acessibilidade).

Formulários


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

form-control estiliza inputs e textareas. form-label formata o label. form-text mostra texto de ajuda abaixo. mb-3 espaça os campos. Sempre use for no label ligado ao id do input (acessibilidade).

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

<!-- Múltiplos ficheiros -->
<input class="form-control" type="file" multiple>

form-range estiliza o slider nativo. min, max, step controlam os valores. Para ficheiros, use type="file" com form-control. multiple permite vários ficheiros. O estilo adapta-se ao browser.

Formulário inline (grid)
<form class="row g-3 align-items-end">
  <div class="col-auto">
    <label class="form-label">Nome</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>

Use o grid (row g-3) para formulários inline. col-auto ajusta ao conteúdo. align-items-end alinha os campos pela base (útil quando há labels). Responsivo: adicione col-12 col-md-auto para empilhar no mobile.

Select
<select class="form-select" aria-label="Escolha">
  <option selected>Escolha uma opção...</option>
  <option value="1">Opção 1</option>
  <option value="2">Opção 2</option>
</select>

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

<!-- Tamanho -->
<select class="form-select form-select-sm">

form-select estiliza o dropdown nativo. multiple + size permite seleção múltipla. form-select-sm/form-select-lg ajustam o tamanho. aria-label descreve o campo sem label visível.

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

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

form-floating faz o label flutuar acima do campo quando preenchido. O placeholder é obrigatório (mesmo que vazio) para o efeito funcionar. O label vem DEPOIS do input no HTML. Funciona com textarea (defina height).

Formulário desativado
<fieldset disabled>
  <div class="mb-3">
    <label class="form-label">Nome</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> desativa todos os campos e botões dentro dele de uma vez. Mais prático que disabled em cada elemento. O estilo é aplicado automaticamente (opacidade, cursor). Ideal para formulários em modo leitura.

Checkbox e 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="opcao" id="r1">
  <label class="form-check-label" for="r1">Opção A</label>
</div>

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

form-check envolve cada checkbox/radio. form-check-input estiliza o controlo; form-check-label o texto. form-check-inline coloca lado a lado. checked marca por padrão. Radios do mesmo grupo partilham o name.

Validação
<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 bem!</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 mostra borda verde + ícone; is-invalid mostra borda vermelha. valid-feedback/invalid-feedback mostram a mensagem (só visível com o estado correspondente). Combine com validação JS do 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 notificações
  </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 ativo</label>
</div>

form-switch transforma o checkbox num interruptor (toggle). role="switch" melhora a semântica para leitores de ecrã. Funciona com checked e disabled. Visual moderno sem 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="Pesquisar...">
  <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 anexa texto, ícones ou botões ao input. input-group-text é o addon (prefixo/sufixo). Pode ter addons em ambos os lados. Útil para @, €, unidades ou botões de ação colados ao campo.

Navbar e Navegação


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="#">Início</a>
        </li>
        <li class="nav-item">
          <a class="nav-link" href="#">Sobre</a>
        </li>
      </ul>
    </div>
  </div>
</nav>

navbar-expand-lg define quando o menu colapsa (abaixo de lg). navbar-toggler é o botão hambúrguer. navbar-collapse envolve os links. ms-auto empurra o menu para a direita. bg-body-tertiary dá fundo.

Formulário na 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="Pesquisar...">
    <button class="btn btn-outline-success">Buscar</button>
  </form>
</div>

Use d-flex no form para alinhar input + botão. me-auto no navbar-nav empurra o form para a direita. me-2 espaça o input do botão. type="search" dá semântica e ícone de limpar nativo.

Cores da navbar
<!-- Clara (padrão BS 5.3) -->
<nav class="navbar bg-body-tertiary">

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

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

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

No BS 5.3+, use data-bs-theme="dark" para texto claro em fundos escuros. bg-body-tertiary é o fundo claro padrão. bg-dark + data-bs-theme="dark" = navbar escura. Pode usar qualquer cor com 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 ao collapse: use offcanvas para menu lateral no mobile. data-bs-toggle="offcanvas" no toggler. offcanvas-end desliza da direita. Mais espaço e flexibilidade que o collapse tradicional. Popular em apps mobile-first.

Navbar fixa e sticky
<!-- Sempre visível no topo -->
<nav class="navbar fixed-top">

<!-- Cola ao topo ao rolar -->
<nav class="navbar sticky-top">

<!-- Fixa no fundo -->
<nav class="navbar fixed-bottom">

<!-- Com offset para conteúdo -->
<body style="padding-top: 70px">

fixed-top = sempre visível (remove do fluxo; adicione padding-top ao body). sticky-top = cola ao topo quando o scroll chega lá (mantém no fluxo). fixed-bottom = barra fixa no fundo. Prefira sticky-top quando possível.

Breadcrumb
<nav aria-label="breadcrumb">
  <ol class="breadcrumb">
    <li class="breadcrumb-item">
      <a href="#">Início</a>
    </li>
    <li class="breadcrumb-item">
      <a href="#">Produtos</a>
    </li>
    <li class="breadcrumb-item active" aria-current="page">
      Detalhes
    </li>
  </ol>
</nav>

breadcrumb mostra o trilho de navegação. O último item tem active + aria-current="page" (página atual, sem link). O separador (/) é via CSS (--bs-breadcrumb-divider). Sempre use <nav aria-label="breadcrumb"> para acessibilidade.

Dropdown na navbar
<ul class="navbar-nav">
  <li class="nav-item dropdown">
    <a class="nav-link dropdown-toggle" href="#"
      data-bs-toggle="dropdown">Serviços</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>

Adicione dropdown ao nav-item e dropdown-toggle + data-bs-toggle="dropdown" ao link. O dropdown-menu contém os itens. No mobile (colapsado), o dropdown abre em accordion. dropdown-divider separa grupos.

Nav pills e underline
<!-- Pills -->
<ul class="nav nav-pills">
  <li class="nav-item">
    <a class="nav-link active" href="#">Ativo</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="#">Ativo</a>
  </li>
</ul>

nav-pills = fundo arredondado no item ativo. nav-underline (BS 5.3+) = sublinhado no ativo. nav-tabs = separadores com borda. Todos aceitam nav-fill (largura igual) e nav-justified (100% da largura).

Cards e Listas


10 cards
Card básico
<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">Descrição do conteúdo.</p>
    <a href="#" class="btn btn-primary">Ver mais</a>
  </div>
</div>

card é o contentor flexível. card-body adiciona padding. card-title, card-subtitle, card-text formatam o conteúdo. text-body-secondary dá cor subtil ao subtítulo. Largura via style ou 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">Descrição lateral.</p>
      </div>
    </div>
  </div>
</div>

Use o grid dentro do card para layout horizontal: imagem numa coluna, texto noutra. g-0 remove gutters. rounded-start arredonda só a esquerda da imagem. img-fluid torna responsiva. Empilha no mobile automaticamente.

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

<!-- Responsiva até breakpoint -->
<div class="table-responsive-md">
  <table class="table">...</table>
</div>

table-responsive envolve a tabela e adiciona scroll horizontal em ecrãs pequenos. table-responsive-{bp} só adiciona scroll abaixo do breakpoint (ex.: -md = scroll só no mobile). Essencial para tabelas com muitas colunas.

Card com imagem
<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>

<!-- Imagem no fundo -->
<div class="card">
  <div class="card-body">Texto</div>
  <img src="foto.jpg" class="card-img-bottom" alt="Foto">
</div>

card-img-top coloca a imagem no topo (com cantos arredondados). card-img-bottom no fundo. A imagem deve ter alt descritivo. Combine com object-fit-cover + altura fixa para imagens de tamanhos diferentes.

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

<!-- Sem bordas exteriores -->
<ul class="list-group list-group-flush">

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

list-group cria listas estilizadas. active destaca; disabled desativa. list-group-flush remove bordas laterais (para dentro de cards). list-group-numbered numera automaticamente. Itens podem ser links (list-group-item-action).

Card group e Masonry
<!-- Card group (bordas fundidas) -->
<div class="card-group">
  <div class="card">...</div>
  <div class="card">...</div>
  <div class="card">...</div>
</div>

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

card-group funde as bordas dos cards (sem gap). Masonry (via lib externa) cria layout tipo Pinterest com alturas variáveis. O grid normal alinha por linhas; masonry preenche espaços verticais. Requer a biblioteca masonry.pkgd.min.js.

Header, footer e overlay
<div class="card">
  <div class="card-header">Destaque</div>
  <div class="card-body">Conteúdo principal</div>
  <div class="card-footer text-body-secondary">
    Há 2 dias
  </div>
</div>

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

card-header/card-footer são secções com fundo subtil. card-img-overlay posiciona conteúdo sobre a imagem (posição absoluta). Use bg-dark text-white para legibilidade sobre fotos. Ideal para hero cards.

List group com badges e checkboxes
<ul class="list-group">
  <li class="list-group-item d-flex
    justify-content-between align-items-center">
    Mensagens
    <span class="badge bg-primary rounded-pill">14</span>
  </li>
  <li class="list-group-item">
    <input class="form-check-input me-1" type="checkbox">
    Tarefa concluída
  </li>
</ul>

Combine d-flex justify-content-between para badge à direita. rounded-pill dá formato circular ao contador. Checkboxes dentro de list-group-item criam listas de tarefas. me-1 espaça o checkbox do texto.

Grelha 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 variável...</p>
      </div>
    </div>
  </div>
  <div class="col">
    <div class="card h-100">...</div>
  </div>
</div>

row-cols-1 row-cols-md-3 = 1 coluna no mobile, 3 em md+. g-4 espaça os cards. h-100 garante alturas iguais na mesma linha. O padrão mais usado para listagens de produtos, artigos e equipas.

Table
<table class="table table-striped table-hover">
  <thead>
    <tr>
      <th>#</th>
      <th>Nome</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 estiliza a tabela. table-striped = linhas alternadas; table-hover = highlight ao hover. table-bordered, table-sm (compacta), table-responsive (scroll horizontal). Cores por linha: table-warning, table-danger.

Modal, Alertas e Toasts


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">Conteúdo aqui.</div>
      <div class="modal-footer">
        <button class="btn btn-secondary"
          data-bs-dismiss="modal">Fechar</button>
        <button class="btn btn-primary">Guardar</button>
      </div>
    </div>
  </div>
</div>

data-bs-toggle="modal" + data-bs-target="#id" abre o modal. fade adiciona transição. data-bs-dismiss="modal" fecha. Estrutura: modalmodal-dialogmodal-content → header/body/footer.

Alerta dismissible
<div class="alert alert-warning alert-dismissible fade show"
  role="alert">
  <strong>Atenção!</strong> Espaço quase cheio.
  <button class="btn-close" data-bs-dismiss="alert"
    aria-label="Fechar"></button>
</div>

alert-dismissible + btn-close com data-bs-dismiss="alert" torna o alerta fechável. fade show adiciona animação ao fechar. O botão X é posicionado automaticamente à direita. Após fechar, o elemento é removido do DOM.

Backdrop e static
<!-- Não fecha ao clicar fora -->
<div class="modal" data-bs-backdrop="static"
  data-bs-keyboard="false">

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

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

data-bs-backdrop="static" impede fechar ao clicar fora. data-bs-keyboard="false" desativa o Escape. data-bs-backdrop="false" remove o overlay escuro. Útil para formulários importantes onde perder dados seria problemático.

Tamanhos de modal
<div class="modal-dialog modal-sm">Pequeno</div>
<div class="modal-dialog modal-lg">Grande</div>
<div class="modal-dialog modal-xl">Extra grande</div>
<div class="modal-dialog modal-fullscreen">Ecrã inteiro</div>

<!-- Fullscreen só no mobile -->
<div class="modal-dialog modal-fullscreen-md-down">

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

<!-- Com scroll no body -->
<div class="modal-dialog modal-dialog-scrollable">

Tamanhos: modal-sm, modal-lg, modal-xl, modal-fullscreen. modal-fullscreen-md-down = ecrã inteiro só abaixo de md. modal-dialog-centered centra verticalmente. modal-dialog-scrollable faz scroll só no 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">Notificação</strong>
      <small>agora</small>
      <button class="btn-close" data-bs-dismiss="toast"></button>
    </div>
    <div class="toast-body">
      Ficheiro enviado com sucesso!
    </div>
  </div>
</div>

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

Toast = notificação pequena e temporária. toast-container posiciona (use position-fixed bottom-0 end-0). data-bs-delay="5000" = auto-fecha em 5s. Requer .show() via JS. Empilhe múltiplos toasts no container.

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

// Fechar
modal.hide();

// Toggle
modal.toggle();

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

A API JS: new bootstrap.Modal(el) cria a instância; .show(), .hide(), .toggle() controlam. Eventos: show.bs.modal, shown.bs.modal, hide.bs.modal, hidden.bs.modal. Útil para abrir após validação ou fetch.

Popover (detalhado)
<button class="btn btn-lg btn-danger" data-bs-toggle="popover"
  data-bs-title="Título" data-bs-content="Conteúdo detalhado
  do popover com mais informação."
  data-bs-placement="right">Clica para ver</button>

// JS (obrigatório):
const popover = new bootstrap.Popover(el, {
  trigger: 'focus',  // fecha ao clicar fora
  html: true         // permite HTML no content
});

Popover mostra conteúdo rico ao clicar. data-bs-title + data-bs-content definem o conteúdo. data-bs-placement: top/bottom/left/right. Requer init JS. trigger: 'focus' fecha ao clicar fora. html: true permite HTML.

Alertas
<div class="alert alert-success" role="alert">
  Operação concluída com sucesso!
</div>

<div class="alert alert-danger" role="alert">
  Erro ao processar o pedido.
</div>

<div class="alert alert-warning" role="alert">
  <strong>Atenção!</strong> Verifique os campos.
</div>

<div class="alert alert-info" role="alert">
  Nova versão disponível.
</div>

alert alert-* mostra mensagens de feedback. Cores: success, danger, warning, info, primary, secondary, light, dark. Sempre use role="alert" para acessibilidade. Links dentro: alert-link.

Modal com formulário
<div class="modal fade" id="formModal">
  <div class="modal-dialog">
    <div class="modal-content">
      <form>
        <div class="modal-header">
          <h5 class="modal-title">Novo registo</h5>
          <button class="btn-close"
            data-bs-dismiss="modal"></button>
        </div>
        <div class="modal-body">
          <div class="mb-3">
            <label class="form-label">Nome</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>

Coloque o <form> dentro de modal-content (envolve header/body/footer). O type="submit" no botão submete o form. Use o evento hidden.bs.modal para resetar o formulário após fechar. Valide antes de fechar.

Utilitários


19 cards
Margin (espaçamento exterior)
m-0, m-1, m-2, m-3, m-4, m-5   /* todos os lados */
mt-3    /* margin-top */
mb-2    /* margin-bottom */
ms-1    /* margin-start (esquerda em LTR) */
me-4    /* margin-end (direita em LTR) */
mx-auto /* centra horizontalmente */
my-3    /* margin-top + bottom */

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

Cores de fundo
bg-primary, bg-success, bg-danger
bg-warning, bg-info, bg-dark
bg-light, bg-white, bg-transparent

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

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

bg-* define a cor de fundo. bg-*-subtle (BS 5.3+) dá tons pastéis (ideal para alertas custom). bg-gradient adiciona gradiente subtil. Combine com text-white ou text-dark para contraste legível.

Sombras
shadow-none   /* sem sombra */
shadow-sm     /* subtil */
shadow        /* padrão */
shadow-lg     /* pronunciada */

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

shadow adiciona box-shadow. Níveis: shadow-sm (subtil), shadow (padrão), shadow-lg (pronunciada). shadow-none remove (útil para sobrepôr o default de cards/botões). Efeito de elevação em hover: combine com CSS custom.

Overflow e scroll
overflow-auto      /* scroll só se necessário */
overflow-hidden    /* corta o excedente */
overflow-visible   /* mostra (padrão) */
overflow-scroll    /* scroll sempre */

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

overflow-* controla conteúdo que excede a caixa. overflow-auto = scroll só quando necessário. overflow-hidden = corta (útil com text-truncate). overflow-x-auto para tabelas ou listas horizontais. overflow-y-hidden evita scroll vertical.

Visually hidden (acessibilidade)
<span class="visually-hidden">
  Texto para leitores de ecrã
</span>

<!-- Visível ao focar (skip links) -->
<a class="visually-hidden-focusable" href="#conteudo">
  Saltar para o conteúdo
</a>

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

visually-hidden oculta visualmente mas mantém acessível para leitores de ecrã (ao contrário de d-none). visually-hidden-focusable aparece ao receber focus (skip links). Essencial para labels de campos com placeholder e ícones sem texto.

Padding (espaçamento interior)
p-0, p-1, p-2, p-3, p-4, p-5   /* todos os 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, mesma lógica do margin. px = horizontal, py = vertical. A escala é idêntica: 0 a 5. Use p-3 para padding consistente em cards custom, py-5 para secções com muito espaço vertical.

Display
d-none          /* oculto */
d-block         /* bloco */
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 no mobile, visível em md+ */
d-md-none          /* visível só no mobile */

d-* controla o tipo de exibição. d-none oculta completamente. d-flex ativa flexbox. O padrão responsivo mais usado: d-none d-md-block (esconde no mobile, mostra em md+). d-md-none = mostra só no mobile.

Largura e altura
w-25, w-50, w-75, w-100   /* width % */
w-auto                     /* width automática */
h-25, h-50, h-75, h-100   /* height % */
h-auto                     /* height automática */
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-* = largura em percentagem; h-* = altura. vw-100/vh-100 = viewport. min-vh-100 = altura mínima de ecrã inteiro (hero sections). mw-100 impede overflow de imagens. w-auto reseta para automático.

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

object-fit-contain     /* cabe tudo (pode ter barras) */
object-fit-cover       /* preenche (corta) */
object-fit-fill        /* estica (distorce) */
object-fit-scale-down  /* menor entre contain/none */
object-fit-none        /* tamanho original */

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

object-fit-* controla como imagens/vídeos se ajustam à caixa. cover = preenche cortando (o mais usado para thumbnails). contain = mostra tudo (pode ter barras). Combine com altura fixa + w-100 para grids de imagens uniformes.

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

/* Float (legacy — prefira flex) */
float-start    /* esquerda */
float-end      /* direita */
float-none
clearfix       /* limpa floats no pai */

align-* alinha elementos inline ou table-cell verticalmente. float-* é legacy — hoje prefira d-flex. clearfix no pai limpa floats (evita colapso de altura). Mantido para compatibilidade com código antigo.

Espaçamento responsivo
p-2 p-md-4       /* mais padding no desktop */
mt-3 mt-lg-5     /* mais margem em lg+ */
d-none d-md-block /* oculto no mobile */
gap-2 gap-lg-4   /* gap maior em telas grandes */
text-center text-md-start /* alinha à esquerda em md+ */

Todas as classes utilitárias aceitam prefixos de breakpoint: p-md-4, mt-lg-5, d-none d-md-block. O padrão é mobile-first: a classe sem prefixo aplica em todos; com prefixo, sobrescreve a partir desse breakpoint.

Texto e tipografia
text-center, text-start, text-end  /* alinhamento */
fw-bold, fw-semibold, fw-normal    /* peso */
fst-italic                         /* itálico */
text-uppercase, text-lowercase     /* transformação */
text-decoration-none               /* sem sublinhado */
text-truncate                      /* corta com ... */
fs-1, fs-2, fs-3, fs-4, fs-5, fs-6 /* tamanho fonte */
lh-1, lh-sm, lh-base, lh-lg       /* line-height */

text-* alinha; fw-* controla o peso; fs-1 a fs-6 definem tamanho de fonte (1=maior). text-truncate corta texto longo com reticências (requer display: block ou inline-block). lh-* ajusta entrelinha.

Position (posicionamento)
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 no ponto */
translate-middle-x    /* centra só horizontal */

position-* define o tipo de posicionamento. Coordenadas: top-0, start-50, etc. (0%, 50%, 100%). translate-middle desloca -50% em ambos os eixos (centragem perfeita). Use position-relative no pai para absolute no filho.

Opacidade e interação
opacity-0, opacity-25, opacity-50, opacity-75, opacity-100

pe-none    /* pointer-events: none (não clica) */
pe-auto    /* pointer-events: auto */
user-select-none  /* não selecionável */
user-select-all   /* seleciona tudo ao clicar */

visible     /* visibility: visible */
invisible   /* visibility: hidden (ocupa espaço) */

opacity-* define transparência. pe-none desativa cliques (overlays, loading). user-select-none impede seleção de texto (botões, labels). invisible oculta mas mantém o espaço (ao contrário de d-none que remove do fluxo).

Z-index
z-0, z-1, z-2, z-3   /* valores baixos */
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 e z-n1 para stacking simples. O Bootstrap reserva valores altos para componentes (modal: 1050, tooltip: 1080). Para sobrepor conteúdo a um modal, precisa de z-index > 1050. Use position-relative para o z-index funcionar.

Cores de texto
text-primary     /* azul */
text-success     /* verde */
text-danger      /* vermelho */
text-warning     /* amarelo */
text-info        /* ciano */
text-dark        /* escuro */
text-muted       /* cinza subtil (BS 5.3: text-body-secondary) */
text-white       /* branco */
text-body-secondary  /* cinza (novo BS 5.3) */

text-* define a cor do texto. No BS 5.3+, text-body-secondary substitui text-muted (adapta ao dark mode). Combine com bg-* para contraste. Use cores semânticas: danger para erros, success para sucesso.

Bordas e arredondamento
border, border-0           /* todos / nenhum */
border-top, border-end     /* lados específicos */
border-primary, border-danger  /* cor */
border-1, border-2, border-3   /* espessura */

rounded, rounded-0, rounded-1, rounded-2, rounded-3
rounded-circle    /* círculo (imagens quadradas) */
rounded-pill      /* pílula (botões/badges) */
rounded-top, rounded-start  /* lados específicos */

border adiciona borda; border-0 remove. border-{cor} muda a cor; border-{1-5} a espessura. rounded arredonda cantos (0 a 5). rounded-circle para avatares; rounded-pill para badges/botões.

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

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

Padrão de centragem: pai position-relative + filho position-absolute top-50 start-50 translate-middle. Para badges no canto: top-0 start-100 translate-middle. Alternativa moderna: d-flex + justify-content-center + align-items-center.

Ratio (proporção de aspeto)
<div class="ratio ratio-16x9">
  <iframe src="https://youtube.com/embed/..."
    title="Vídeo"></iframe>
</div>

ratio-1x1    /* quadrado */
ratio-4x3    /* TV antiga */
ratio-16x9   /* widescreen */
ratio-21x9   /* ultrawide */

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

ratio + ratio-16x9 mantém proporção responsiva para vídeos/iframes. O conteúdo estica para preencher. ratio-1x1 para avatares quadrados. Custom: --bs-aspect-ratio: 66.67% (2:3). Substitui o antigo hack de padding-bottom.

Responsivo


8 cards
Breakpoints
xs   < 576px    (telemóvel — sem prefixo)
sm  ≥ 576px     (telemóvel landscape)
md  ≥ 768px     (tablet)
lg  ≥ 992px     (desktop pequeno)
xl  ≥ 1200px    (desktop)
xxl ≥ 1400px    (ecrã grande)

Os breakpoints são mobile-first: classes sem prefixo aplicam em todos; com prefixo, sobrescrevem a partir dessa largura. xs não tem prefixo (col-6 = col-xs-6). Os valores são em em no Sass (576px = 36em).

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

<!-- Font size responsivo -->
<p class="fs-6 fs-md-4 fs-lg-3">Texto que cresce</p>

<!-- Alinhamento responsivo -->
<p class="text-center text-md-start">
  Centrado no mobile, esquerda no desktop
</p>

display-1 a display-6 são títulos extra-grandes. fs-1 a fs-6 definem tamanhos (aceitam prefixos: fs-md-4). Alinhamento responsivo: text-center text-md-start. O Bootstrap já usa clamp() nos headings por padrão.

Ocultar/mostrar por breakpoint
d-none d-sm-block     /* oculto em xs, visível em sm+ */
d-sm-none             /* visível SÓ em xs */
d-none d-md-block     /* oculto até md */
d-md-none             /* visível só em xs e sm */
d-none d-lg-block d-xl-none  /* visível só em lg */

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

Combine d-none + d-{bp}-block para mostrar a partir de um breakpoint. d-{bp}-none oculta a partir desse breakpoint. Padrão clássico: menu completo em desktop (d-none d-md-inline) + hambúrguer no mobile (d-md-none).

Containers responsivos
<!-- Largura máxima por breakpoint -->
.container       /* fixo em cada bp */
.container-sm    /* 100% até sm, fixo depois */
.container-md    /* 100% até md, fixo depois */
.container-lg    /* 100% até lg, fixo depois */
.container-xl    /* 100% até xl, fixo depois */
.container-xxl   /* 100% até xxl, fixo depois */
.container-fluid /* sempre 100% */

container-{bp} é 100% até ao breakpoint e largura fixa depois. Ex.: container-lg = 100% em mobile/tablet, fixo (960px) em lg+. Útil quando quer full-width em mobile mas limitado em desktop. container-fluid = sempre 100%.

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

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

<!-- Picture com 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 o pai). img-thumbnail adiciona borda + padding + rounded. Use <picture> + srcset para servir imagens diferentes por breakpoint (performance).

Espaçamento por breakpoint
<!-- Padding progressivo -->
<section class="py-3 py-md-5">
  <div class="container px-3 px-lg-5">

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

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

<!-- Secção hero full-height só em desktop -->
<section class="min-vh-100 d-none d-md-flex">

Ajuste espaçamento por ecrã: py-3 py-md-5 (menos padding no mobile). gap-2 gap-md-4 (mais espaço em desktop). min-vh-100 para hero sections. O mobile precisa de menos espaço; desktop pode ser mais generoso.

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

<!-- Sidebar + conteúdo -->
<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">Conteúdo</div>
</div>

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

Padrões comuns: row-cols-1 row-cols-md-2 row-cols-xl-4 para grids progressivos. Sidebar: col-md-4 col-lg-3 + conteúdo col-md-8 col-lg-9. Sempre mobile-first: comece com 1 coluna e adicione larguras em breakpoints maiores.

Media queries no Sass
// Mixins do 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) {
  .titulo { font-size: 1.5rem; }
}

Os mixins media-breakpoint-up/down/between/only geram media queries com os breakpoints do Bootstrap. up(md) = @media (min-width: 768px). down(md) = @media (max-width: 767.98px). Use no Sass custom para consistência.

Dicas e Boas Práticas


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

<!-- bootstrap.min.js = só Bootstrap (sem Popper) -->
<script src="bootstrap.min.js"></script>

// Popper é necessário para:
// - Dropdowns
// - Tooltips
// - Popovers

O bundle inclui Popper.js (posicionamento de dropdowns, tooltips, popovers). Se usar bootstrap.min.js (sem bundle), precisa de carregar o Popper separadamente. Na dúvida, use sempre o bundle — é o mais simples.

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

Sempre use atributos ARIA: aria-label em botões sem texto, role="alert" em alertas, aria-labelledby em modais, aria-describedby para ajuda. aria-hidden="true" em elementos decorativos. O Bootstrap já inclui alguns, mas verifique.

Atributos data-bs-*
data-bs-toggle="modal"       /* abre 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"         /* alvo */
data-bs-dismiss="modal"      /* fecha */
data-bs-ride="carousel"      /* auto-play */

No Bootstrap 5, todos os atributos usam o prefixo data-bs- (antes era data-). toggle define o comportamento; target o elemento alvo; dismiss fecha. Não precisa de jQuery — tudo funciona com atributos HTML.

CSS variables (BS 5.3)
/* O Bootstrap expõe variáveis CSS: */
:root {
  --bs-primary: #0d6efd;
  --bs-body-font-size: 1rem;
  --bs-border-radius: 0.375rem;
}

/* Use diretamente: */
.card {
  border-radius: var(--bs-border-radius);
  color: var(--bs-primary);
}

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

Bootstrap 5.3 expõe variáveis CSS (--bs-*) que pode usar e sobrescrever sem Sass. --bs-primary, --bs-border-radius, --bs-body-font-size. Componentes usam --bs-btn-*, --bs-card-*. Ideal para theming runtime (dark mode toggle).

Sem jQuery (BS 5)
// Bootstrap 5 NÃO precisa de 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);

// Obter instância existente:
const m = bootstrap.Modal.getInstance(el);

Bootstrap 5 removeu a dependência do jQuery. Use a API nativa: new bootstrap.Modal(el), .getInstance(el). Cada componente tem .show(), .hide(), .toggle(), .dispose(). Eventos: el.addEventListener('shown.bs.modal', fn).

Utilitários combinados (padrões)
<!-- 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">Nome</h5>
    <p class="text-body-secondary small">Cargo</p>
  </div>
</div>

Combine utilitários para padrões comuns: 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. A composição de utilitários evita CSS custom na maioria dos casos.

Reboot (reset global)
/* O Reboot do Bootstrap normaliza: */
- box-sizing: border-box (todos os elementos)
- margin: 0 no body
- font-family e line-height base
- links com cor primária
- botões com cursor: pointer
- tabelas com border-collapse
- imagens com vertical-align: middle

O Reboot é o reset global do Bootstrap (baseado no Normalize). Aplica box-sizing: border-box em tudo, remove margens do body, define tipografia base. É importado automaticamente. Se não quiser, pode importar só componentes específicos via Sass.

Documentação e recursos
# Documentação oficial
https://getbootstrap.com/docs/5.3/

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

# Exemplos e 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

A documentação oficial (getbootstrap.com/docs) tem exemplos interativos de todos os componentes. icons.getbootstrap.com lista os 2000+ ícones. A secção Examples tem templates completos (album, dashboard, sign-in). O CDN via jsDelivr é o mais rápido.