Descubra como os detalhes e elementos de resumo muito úteis funcionam e onde usá-los.
Um widget de declaração é um controle de interface do usuário que oculta e mostra conteúdo. Se você estiver lendo isso no web.dev e sua janela de visualização tiver menos de 106 ems de largura, clicar em "Nesta página" acima deste parágrafo revelará o índice dessa seção. Se essa opção não estiver disponível, reduza o navegador para que a navegação do sumário nesta página seja mostrada como um widget de divulgação.
A interface gráfica do usuário acordeão é uma série de widgets de divulgação empilhados verticalmente. Um caso de uso comum para a interface do usuário do Acordeão é a página de Perguntas frequentes em muitos sites. Uma seção de Perguntas frequentes do accordion contém uma lista de perguntas visíveis. Ao clicar em uma pergunta, a resposta a essa pergunta é expandida, ou "divulga".
O jQuery inclui um padrão de interface de usuário sanfona desde pelo menos 2009. A solução original de acordeão sem JavaScript
incluía tornar cada pergunta de perguntas frequentes um <label>
seguido pela marca de seleção rotulada e, em seguida, exibir a resposta <div>
quando a marca de seleção estava marcada. O CSS era mais ou menos assim:
#FAQ [type="checkbox"] + div.answer {
/* all the answer styles */
display: none;
}
#FAQ [type="checkbox"]:checked + div.answer {
display: block;
}
Por que a história? Os widgets de divulgação, como accordions, sem JavaScript ou hacks de controle de formulário, são uma adição
relativa. Os elementos <details>
e <summary>
só têm suporte total em todos os navegadores mais recentes desde janeiro de 2020. Agora é possível criar widgets funcionais, embora menos atraentes, de divulgação usando apenas HTML semântico. Os elementos <details>
e <summary>
são tudo de que você precisa: eles são uma forma integrada de processar
conteúdos que podem ser expandidos e recolhidos. Quando um usuário clica ou toca em <summary>
ou libera a tecla Enter quando
<summary>
está em foco, o conteúdo do <details>
pai fica visível.
Como em todo o conteúdo semântico, você pode melhorar progressivamente os recursos e a aparência padrão. Nesse caso, um pequeno pedaço de CSS foi adicionado, mas nada mais:
Esses Codepenss não contêm JavaScript.
Como alternar a visibilidade: o atributo open
O elemento <details>
é o contêiner do widget de declaração. O <summary>
é o resumo ou a legenda da <details>
mãe. O
resumo é sempre mostrado, agindo como um botão que alterna a exibição do restante do conteúdo do elemento pai. A interação
com o <summary>
alterna a exibição dos irmãos de resumo autorotulados, alternando o atributo open
do elemento <details>
.
O atributo open
é booleano. Se estiver presente, independentemente do valor ou da falta dele, ele indica que todo o conteúdo de <details>
é mostrado ao usuário. Se o atributo open
não estiver presente, somente o conteúdo do <summary>
será mostrado.
Como o atributo open
é adicionado e removido automaticamente à medida que o usuário interage com o controle, ele pode ser usado no CSS para estilizar o elemento de maneira diferente com base no estado.
É possível criar um acordeão com uma lista de vários elementos <details>
, cada um com um filho <summary>
. A omissão do atributo open
no HTML significa que <details>
será recolhido, ou fechado, com apenas os títulos do resumo visíveis quando a página for carregada. Cada cabeçalho abre o restante do conteúdo no <details>
pai. Se você incluir o atributo open
no HTML, o <details>
será renderizado expandido, com o conteúdo visível, quando a página for carregada.
O conteúdo oculto no estado recolhido pode ser pesquisado em alguns navegadores, mas não em outros, mesmo que o conteúdo recolhido não faça parte do DOM. Se você pesquisar no Edge ou no Chrome, os detalhes que contêm um termo de pesquisa serão expandidos para mostrar a ocorrência. Esse comportamento não é replicado no Firefox ou no Safari.
O <summary>
precisa ser o primeiro filho de um elemento <details>
, representando um resumo, legenda ou legenda para o restante
do conteúdo do elemento <details>
pai em que está aninhado. O conteúdo do elemento <summary>
pode ser qualquer conteúdo de cabeçalho, texto simples ou HTML que possa ser usado em um parágrafo.
Como alternar o marcador de resumo
Nos dois Codepenss anteriores, a seta para o lado inline-start do resumo vai aparecer. Um widget de divulgação normalmente é apresentado na tela usando um pequeno triângulo que gira (ou gira)
para indicar o status aberto/fechado, com um rótulo ao lado do triângulo. O conteúdo do elemento <summary>
rotula o widget de declaração.
A seta giratória na parte de cima de cada seção é um ::marker
definido no
elemento <summary>
. Assim como os itens de lista, o elemento <summary>
oferece suporte à propriedade abreviada list-style
e às propriedades longas, incluindo list-style-type
.
É possível definir o estilo do triângulo de divulgação com CSS, incluindo a mudança do marcador usado de um triângulo para qualquer outro tipo de marcador, incluindo
uma imagem com list-style-image
.
Para aplicar outros estilos, use um seletor semelhante a details summary::marker
. O pseudoelemento ::marker
aceita apenas um número limitado de estilos. Remover o
::marker
e substituí-lo pelo ::before
, que é mais fácil de estilizar, é
uma prática comum, com estilos CSS mudando ligeiramente o estilo do conteúdo gerado com base na presença (ou ausência)
do atributo aberto. É possível remover o ícone do widget de divulgação definindo list-style: none
ou definir o conteúdo do marcador como none
, mas sempre inclua indicadores visuais para informar aos usuários com deficiência visual que o conteúdo do resumo é um botão de ativação que mostra e oculta o conteúdo após a ativação.
details summary::before {
/* all the styles */
}
details[open] summary::before {
/* changes applied when open only */
}
Este exemplo remove o marcador padrão e adiciona conteúdo gerado para criar uma +
quando os detalhes são fechados e uma -
quando os detalhes estão abertos.
Se você quiser que o bloco de detalhes seja aberto por padrão, inclua o atributo open
na tag de abertura <details>
. Você também pode adicionar espaço entre cada caixa de diálogo e fazer a transição da rotação do marcador criado com o conteúdo gerado para melhorar a aparência:
Como os erros são tratados
Se você não incluir uma <summary>
, o navegador vai criar uma para você: com um marcador e a palavra "detalhes". Esse resumo
faz parte de uma raiz paralela e, portanto, não terá estilos de resumo de CSS do autor aplicados. Infelizmente, o Safari não inclui
os detalhes na ordem de foco do teclado.
Se você incluir um <summary>
, mas ele não for o primeiro elemento na <details>
, o navegador ainda exibirá o resumo
como deveria. Ele também não falhará se você incluir um link, uma etiqueta ou outro elemento interativo no resumo, mas os navegadores processarem o conteúdo interativo de maneira diferente. Por exemplo, se você incluir um link em um resumo, alguns navegadores adicionarão o resumo e o link à ordem de tabulação padrão, mas outros navegadores não se concentrarão no link por padrão.
Se você clicar em um <label>
aninhado em um <summary>
, alguns navegadores darão foco para o controle de formulário associado. Outros navegadores vão focar o controle do formulário e abrir ou fechar a <details>
.
A interface HTMLDetailsElement
.
Como todos os elementos HTML, o HTMLDetailsElement
herda todas
as propriedades, métodos e eventos de HTMLElement
e adiciona a
propriedade de instância open
e um evento
toggle
. A propriedade HTMLDetailsElement.open
é um valor booleano
que reflete o atributo HTML open
, indicando
se o conteúdo do elemento (sem contar o <summary>
) será mostrado ao usuário. O evento de alternância é disparado
quando o elemento <details>
é aberto ou fechado. É possível ouvir este evento usando addEventListener()
.
Se você quiser escrever um script para fechar os detalhes abertos quando o usuário abrir outros detalhes, remova o atributo aberto
usando removeAttribute("open")
:
Esse é o único exemplo que usa JavaScript. Você provavelmente não precisa de JavaScript, exceto para o recurso de fechar outros widgets de declaração abertos.
Lembre-se de que <details>
e <summary>
podem ser bastante estilosos e até mesmo usados para criar dicas de ferramentas.
No entanto, se você quiser usar esses elementos semânticos para casos de uso em que a semântica nativa não é correspondente, mantenha a acessibilidade.
A maior parte do HTML é acessível por padrão. Nosso trabalho como desenvolvedores é garantir que o conteúdo continue acessível.
Teste seu conhecimento
Teste seus conhecimentos sobre detalhes e resumo.
O <summary>
precisa ser o primeiro filho de qual elemento?
<p>
<details>
<fieldset>