O que Sistema de Design de Bottom Sheet faz?
Propósito
O Sistema de Design de Bottom Sheet fornece uma estrutura de design padronizada e mobile-first para painéis inferiores deslizantes, folhas de ação e gavetas modais inferiores em interfaces web e aplicações web progressivas (PWAs). Dispositivos móveis modernos com grandes proporções de tela tornam overlays posicionados no topo e popups modais centrados difíceis de alcançar com uma mão. Os painéis inferiores ancoram tarefas interativas, menus de contexto, controles de filtro e sub-visões detalhadas na parte inferior da tela, dentro do alcance natural do polegar do usuário.
Projetar um sistema de bottom sheet eficaz requer estabelecer alturas de encaixe (recolhido/peek, parcial/metade, completo), affordances de arrasto (alças de toque), escurecimento de fundo (scrim/backdrop), mecanismos de travamento de rolagem do corpo, insets de área segura da viewport (env(safe-area-inset-bottom)) e uma transformação responsiva perfeita para desktop (convertendo painéis inferiores em modais centrados ou popovers em viewports mais largas).
Casos de Uso
- Seletores de Opções de Produto Mobile: Apresentar seletores de tamanho, cor, quantidade e cadência de assinatura em páginas de detalhes de produto de e-commerce sem navegar para fora da PDP.
- Controles de Filtro e Ordenação Mobile: Fornecer opções de filtragem multifacetada para páginas de catálogo de e-commerce ou visualizações de pesquisa SaaS com barras de ação "Aplicar Filtros" fixas na parte inferior.
- Folhas de Ação Contextuais: Acionar ações rápidas de 1 toque (Compartilhar, Favoritar, Adicionar à Lista, Denunciar) em feeds sociais, cartões de mídia ou tabelas de dados.
- Cartões de Detalhes de Localização e Mapa: Exibir detalhes expansíveis de pontos de interesse ou cronogramas de rastreamento de entrega que deslizam sobre visualizações de mapa (encaixe recolhido até expansão total).
- Subfluxos de Trabalho de Múltiplas Etapas Mobile: Completar tarefas inline rápidas, como seleção de método de pagamento no checkout, escolha de endereço ou envio rápido de feedback.
Quando NÃO Usar
- Roteamento de Navegação Global: Para navegação primária do aplicativo entre seções principais, use
bottom-navigation-systemousite-navigation-system. - Alertas de Confirmação Destrutiva: Para ações críticas e irreversíveis (ex.: "Excluir Conta"), use um diálogo modal centralizado
overlay-and-dialog-system(role="alertdialog") que exija confirmação explícita. - Conteúdo Colapsável na Página: Para alternar conteúdo expansível inline no fluxo da página, use
accordion-ui-systemoutab-ui-system. - Layouts de Desktop de Tela Larga (>1024px): Não exiba painéis inferiores de largura total em telas de desktop. Adapte a UI para diálogos modais centrados (
overlay-and-dialog-system), gavetas laterais (dashboard-layout-system) ou popovers ancorados (tooltip-and-hint-system).
Entradas
- Tipo e Profundidade da Tarefa: Natureza do conteúdo (lista de ação rápida de 1 toque vs. formulário de múltiplos campos vs. lista de detalhes rolável).
- Configuração de Encaixe: Escolha das alturas de encaixe (Único Encaixe: 100% altura total; Duplo Encaixe: 50% metade e 100% total; Triplo Encaixe: 20% recolhido, 50% metade, 90% total).
- Contexto do Gatilho: Elemento ou ação do usuário que inicia o painel (toque em botão, pressão longa, gesto de deslizar ou link profundo).
- Design Tokens: Cores de fundo da superfície, raio da borda, dimensões da alça de arrasto, sombras de elevação, opacidade do backdrop e escala tipográfica.
- Estratégia de Adaptação para Desktop: Transição de layout escolhida para viewports ≥1024px (Converter para Modal Centralizado, Converter para Popover Ancorado ou Converter para Gaveta Lateral Deslizante).
Saídas
- Especificação da Anatomia do Bottom Sheet: Planta de layout definindo a Barra de Alça de Arrasto, Cabeçalho (Título + Botão Fechar), Corpo Rolável, Rodapé Fixo (Barra de CTA) e Padding do Inset de Área Segura.
- Matriz de Altura de Encaixe e Token de Gesto: Variáveis CSS e definições de limite de encaixe (
--sheet-detent-peek,--sheet-detent-half,--sheet-detent-full) com regras de descarte por velocidade de arrasto. - Especificação de Backdrop e Elevação: Tokens de opacidade do backdrop, configurações de filtro de desfoque do backdrop, hierarquia de z-index e regras de travamento de rolagem do corpo (
overflow: hiddenno body). - Mapeamento ARIA para Teclado e Leitor de Tela:
role="dialog",aria-modal="true",aria-labelledby, especificação de armadilha de foco e definições do manipulador de teclaEscape. - Planta de Adaptação Responsiva para Desktop: Breakpoints de media query transformando painéis inferiores móveis em diálogos modais centrados ou popovers para tablet e desktop.
Fluxo de Trabalho
1. Categorizar Tipo de Painel e Estrutura de Encaixe
Selecione o modo de encaixe apropriado com base no volume de conteúdo e na frequência de interação:
- Folha de Ação Não Modal (Recolhido/Fit-Content): Auto-dimensiona para caber conteúdo curto (2–5 ações de menu). Alturas geralmente variam entre 180px e 320px. Dispensa ao selecionar uma ação ou tocar no backdrop.
- Painel de Meia Altura / Duplo Encaixe (50% e 90% da Viewport): Usado para tarefas de densidade média, como seleção de variação de produto ou ordenação. Abre a 50% da altura (
50vh); arrastar para cima encaixa a 90% da altura (90vh). - Painel de Altura Total / Expansível (90%–100% da Viewport): Usado para fluxos de trabalho móveis complexos, como filtros multifacetados ou etapas de checkout. Fornece um cabeçalho e rodapé fixos com um corpo rolável interno.
2. Definir Anatomia Visual e Hierarquia Espacial
Construa o painel usando cinco camadas anatômicas distintas:
- Backdrop (Scrim): Overlay fixo cobrindo toda a viewport (
background: rgba(0, 0, 0, 0.5); backdrop-filter: blur(4px); z-index: 1000;). - Container do Painel: Painel fixo ancorado na borda inferior da tela (
position: fixed; bottom: 0; left: 0; right: 0; border-radius: 16px 16px 0 0; background: var(--surface-bg); z-index: 1001;). - Barra de Alça de Arrasto (Affordance): Pílula visual centralizada no topo (
width: 36px; height: 5px; border-radius: 999px; background: var(--border-neutral); margin: 8px auto; cursor: grab;). - Camada do Cabeçalho: Contém o título do painel (
h2), subtítulo opcional e botão de fechar explícito (<button aria-label="Fechar painel">✕</button>). - Camada do Corpo Rolável: Container de conteúdo interno configurado com
overflow-y: auto; -webkit-overflow-scrolling: touch;. - Camada do Rodapé CTA Fixo: Barra de ação ancorada na parte inferior com botões primário/secundário e padding do inset de área segura (
padding-bottom: calc(16px + env(safe-area-inset-bottom, 0px))).
3. Estabelecer Mecanismos de Gesto, Encaixe e Dispensa
Configure interações de toque suaves para feedback de gesto físico:
- Interação de Arrasto: Arrastar para baixo na alça de arrasto ou no cabeçalho move o painel para baixo suavemente usando
transform: translateY(). - Limites de Encaixe:
- Se arrastado para baixo além de 30% da altura atual ou sacudido para baixo com velocidade > 0.5px/ms, acionar o fechamento completo.
- Se arrastado entre 30% e 70% no modo de duplo encaixe, encaixar no detent mais próximo (50% ou 90%).
- Colisão de Travamento de Rolagem: Ao arrastar dentro da camada do corpo rolável, inicie o arrasto para dispensar o painel somente se a posição de rolagem do corpo estiver em
scrollTop === 0e o usuário deslizar para baixo. - Travamento de Rolagem do Corpo: Quando o painel inferior modal estiver aberto, aplique
overflow: hiddenaodocument.bodypara evitar vazamentos de rolagem da página de fundo.
4. Implementar Áreas Seguras da Viewport e Contraste de Superfície
Garanta integração visual completa com recortes de hardware móvel e modos claro/escuro:
- Manipulação de Inset de Área Segura: Sempre aplique
padding-bottom: env(safe-area-inset-bottom, 16px)ao container do painel ou rodapé fixo para que conteúdo/botões não sejam cobertos pelos indicadores de início do iOS. - Limite Máximo de Altura: Limite painéis de altura total a
max-height: calc(100vh - 48px)oumax-height: calc(100dvh - 48px)para deixar uma fatia visível de 48px do contexto da página pai escurecida no topo. - Elevação de Superfície: Use tokens de sombra de elevação profunda (
box-shadow: 0 -4px 24px rgba(0, 0, 0, 0.15)) para criar separação do conteúdo da página de fundo.
5. Configurar Acessibilidade e Navegação por Teclado
Garanta conformidade total com os padrões WCAG 2.1 / 2.2 AA:
- Funções ARIA: O container deve usar
role="dialog"ourole="region"(para painéis não modais de visualização),aria-modal="true"earia-labelledby="sheet-title-id". - Gerenciamento de Foco:
- Ao abrir, desloque programaticamente o foco para o primeiro elemento focalizável dentro do painel ou para o botão de fechar.
- Implemente uma armadilha de foco impedindo que
TabouShift+Tabescapem do painel para o fundo inerte. - Ao fechar, restaure o foco para o elemento gatilho que abriu o painel.
- Controles de Teclado: Pressionar
Escapedeve fechar imediatamente o painel. - Anúncios do Leitor de Tela: Mudanças dinâmicas de conteúdo dentro do painel devem usar regiões
aria-live="polite".
6. Projetar Adaptação Responsiva para Desktop
Painéis inferiores parecem sem polimento quando esticados em largura total em monitores de desktop (≥1024px). Implemente regras explícitas de transformação responsiva:
- Modo Modal Desktop (Padrão): Em viewports ≥1024px, transforme o painel inferior em um diálogo modal centralizado (
width: 100%; max-width: 540px; border-radius: 16px; margin: auto; position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%);). - Modo Popover Desktop (Menus de Contexto): Para folhas de ação rápidas, transforme o painel em um popover ancorado posicionado adjacente ao botão gatilho.
- Modo Gaveta Lateral Desktop (Formulários/Filtros Complexos): Para filtros multifacetados profundos ou fluxos de múltiplas etapas, transforme em uma gaveta lateral deslizante alinhada à direita (
width: 400px; height: 100vh; top: 0; right: 0; border-radius: 16px 0 0 16px;).
Regras de Decisão
Matriz de Seleção de Encaixe
| Tipo de Painel | Configuração de Encaixe | Volume de Conteúdo | Caso de Uso Ideal |
|---|---|---|---|
| Folha de Ação | Fit-content (Encaixe Único) | 2–6 links/ações de ação | Compartilhamento rápido, menu contextual, troca de opção simples. |
| Painel de Seleção | Duplo Encaixe (50vh inicial, 90vh expandido) | 5–15 itens roláveis | Seletor de tamanho/cor de produto, seletor de endereço, método de pagamento. |
| Gaveta Interativa | Triplo Encaixe (120px recolhido, 50vh, 90vh) | Dados espaciais/de mapa complexos | Cartões de mapa de rastreamento de entrega, paradas de trânsito ao vivo, detalhes de carona compartilhada. |
| Painel de Fluxo Completo | Encaixe Único (90vh - 100vh fixo) | Formulário/filtros de múltiplas seções | Multifiltros de catálogo, etapa de checkout móvel, fluxo de pesquisa. |
Escolha de Transformação para Desktop
- Usar Modal Centralizado: Quando o painel contém formulários estruturados, seletores de variação ou opções de checkout.
- Usar Popover Ancorado: Quando o painel contém ações contextuais curtas (Compartilhar, Editar, Excluir).
- Usar Gaveta Lateral: Quando o painel contém controles de filtro ou painéis de edição em dashboards e tabelas de dados.
Restrições
- Acessibilidade (WCAG 2.1 / 2.2 AA):
- Deve fornecer armadilha de foco explícita quando
aria-modal="true"estiver ativo. - Alvos de toque para todos os itens internos e botões de fechar devem medir pelo menos 44x44px (WCAG 2.5.8 / 2.5.5).
- O conteúdo de fundo atrás dos painéis inferiores modais deve ser marcado como
inertou oculto da tecnologia assistiva.
- Deve fornecer armadilha de foco explícita quando
- Dimensionamento de Toque e Gesto:
- O alvo de toque da alça de arrasto deve ser ampliado com padding invisível (
min-height: 24px,min-width: 60px) mesmo que a alça visual seja 36x5px.
- O alvo de toque da alça de arrasto deve ser ampliado com padding invisível (
- Unidades Dinâmicas da Viewport:
- Use
dvh(dynamic viewport height) onde houver suporte (height: 90dvh), com fallback paravhpara acomodar expansões e recolhimentos dinâmicos da barra de endereço móvel.
- Use
Padrões Comuns de Falha
- O Padding de Área Segura Ausente: Omitir
env(safe-area-inset-bottom), fazendo com que os botões de ação primária do rodapé se sobreponham às barras de gesto do iOS. - Painéis de Desktop Esticados em Largura Total: Permitir que um bottom sheet móvel se expanda para 1920px de largura em monitores de desktop.
- Travamento por Roubo de Rolagem: Falha em separar a rolagem de conteúdo dos gestos de arrasto para dispensar o painel, fazendo com que o painel colapse quando o usuário tenta rolar para baixo através do texto.
- Manipulador de Tecla Escape Ausente: Omitir o ouvinte de evento da tecla
Escape, prendendo usuários de teclado desktop dentro do overlay do painel modal. - Vazamento de Foco para o Fundo: Deixar elementos da página de fundo acessíveis via tecla
Tabenquanto um painel inferior modal está aberto.
Critérios de Validação
- O layout do painel inclui affordance visual de arrasto, cabeçalho com título, corpo rolável e rodapé fixo.
- O inset de área segura (
padding-bottom: env(safe-area-inset-bottom)) está implementado no rodapé fixo e no container do painel. - A zona de toque da alça de arrasto atende à altura mínima de 44px para acessibilidade por toque.
- O painel usa
role="dialog",aria-modal="true",aria-labelledbye prende o foco enquanto estiver ativo. - Pressionar
Escapeou tocar no backdrop fecha o painel modal e restaura o foco para o botão gatilho. - A rolagem do corpo de fundo está travada (
overflow: hidden) quando o painel modal está aberto. - Viewports ≥1024px transformam claramente o bottom sheet em um diálogo modal centralizado, popover ou gaveta lateral.