Painel opaco que cobre a tela inteira deslizando da direita. Marca e botão de fechar no topo, alinhados com a altura do menu fixo; links grandes em display, empilhados com divisória; CTA no pé. Trava o scroll da página enquanto está aberto e devolve o foco ao botão que o abriu.
Quando usar
- Sempre que houver um menu fixo que colapsa no mobile. É o par natural do
navegacao/nav-fixa-vidro. - Navegação de até 8 itens mais um CTA.
Quando não usar
- Navegação com submenus. Este drawer é uma lista plana.
- Como painel lateral de filtros ou carrinho — ali você quer overlay parcial e clique-fora, não tela cheia.
Padrão editorial
| Slot | Regra |
|---|---|
| Links | Os mesmos do menu de desktop, na mesma ordem. Divergir entre desktop e mobile é erro, não variação. |
| CTA | O mesmo do desktop, aqui em botão cheio em vez de pílula pequena. |
Como usar
<link rel="stylesheet" href="componentes/navegacao/drawer-fullscreen/estilo.css">
<script src="core/motion.js"></script>
<script src="componentes/navegacao/drawer-fullscreen/script.js"></script>
Cole logo depois do menu fixo. Qualquer elemento da página com [data-drawer-open] passa a abri-lo — não é preciso ligar nada.
O core/motion.js entra por causa da trava de rolagem (LIB.travarRolagem()). Sem ele o menu continua abrindo, fechando e devolvendo o foco; só a página atrás passa a rolar por baixo do painel. Está protegido por guard, então a ausência não vira erro no console — mas é degradação de verdade, não detalhe.
Ganchos
| Gancho | Papel |
|---|---|
[data-drawer] |
raiz do painel |
[data-drawer-open] |
qualquer gatilho na página |
[data-drawer-close] |
botão de fechar dentro do painel |
.drawer.is-open |
estado aberto |
Variações
- Abrir pela esquerda —
translateX(-100%)no estado fechado.
Gotchas
- O
hiddenno HTML não é decoração. Sem ele, Tab e leitor de tela alcançam os links do menu fechado, que está fora da tela. O script remove o atributo ao abrir e devolve depois da transição. - Um frame entre remover
hiddene aplicar.is-open. Sem orequestAnimationFrame, o elemento nasce na posição final e o translate não anima. - O
.wrapdo topo levapadding-inline:0. É a única exceção à regra do grid em toda a biblioteca: o.drawerjá aplicou--pad, e o topo precisa alinhar com o topo do menu fixo. Está documentado no CSS. - A trava de rolagem é a do core, e vem com contador.
LIB.travarRolagem()/LIB.soltarRolagem()escrevem no<html>, guardam o valor anterior e só soltam na última chamada. Até 2026-09 este script faziabody.style.overflow = 'hidden'e depois= '': o= ''apagava qualqueroverflowinline que a página já tivesse, em vez de devolvê-lo (medido: uma página combody{overflow:auto}inline saía do ciclo com o atributo vazio). E dois painéis abertos ao mesmo tempo — este e um modal — destravavam a página no primeiro fechamento. O contador do core resolve os dois de graça. - A trava tem um
travadode par obrigatório. Contador não perdoa uma chamada sobrando, e sem foco preso oTabchega ao[data-drawer-open]que está atrás do painel: um segundoopen()travaria a página para sempre. O flag no script é o que garante uma trava por abertura. - Em iOS a trava não impede o rubber band do documento. Vale para o
<html>como valia para obody. Se virar problema, é assunto do core, não deste componente — a solução conhecida éposition:fixedguardando oscrollY, e ela mudaria a trava das quatro sobreposições ao mesmo tempo. - Sem foco preso (focus trap). Tab sai do painel depois do último link. Aceitável para uma lista de 5 itens com Esc funcionando; se o drawer crescer, vale implementar. Enquanto não tiver, o
travadoacima é o que segura a consequência. - O degrau de empilhamento é
--z-overlay, não um 200 cravado. O token vale exatamente 200 e nasceu deste número — a troca não move nada (computado medido: 200 antes e depois). Ele fica acima do--nav-hde propósito: sobreposição que passa por baixo do menu fixo é bug caro de achar.
Histórico
| Projeto | Onde | Data | Diferenças |
|---|---|---|---|
| Liberta Wealth | index.html e quem-somos.html, #drawer |
2026-08 | Origem. Classes .dl e .logo sem prefixo, .open em vez de .is-open, ids #burger/#drawerClose conhecidos pelo script, sem hidden (o menu fechado era tabulável), sem devolução de foco, borda #1e1e1e crua. |
Normalizações aplicadas na extração: prefixo em tudo; .open → .is-open; ids → [data-drawer-open] / [data-drawer-close], o que desacopla o gatilho do painel; adicionado hidden no estado fechado e devolução de foco ao gatilho; borda crua → --rule; escopo de tom explícito no elemento; adicionado prefers-reduced-motion.