Cheatsheet Bootstrap
Framework CSS para desenvolvimento responsivo
Bootstrap
Instalação e Setup
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: functions → variables → mixins primeiro. Depois os componentes (grid, buttons, forms). Útil para projetos com build otimizado.
Grid e Layout
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 é container → row → col. 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
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
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
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
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
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
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
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: modal → modal-dialog → modal-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
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
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
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.