Referência:
https://www.gov.br/ds/components/breadcrumb?tab=desenvolvedor
https://www.gov.br/ds/components/breadcrumb?tab=designer
Breadcrumb, Breadcrumb Navigation ou Breadcrumb Trail (literalmente, navegação por migalhas de pão ou trilha de migalhas de pão, em alusão à história de João e Maria) é um sistema de navegação estrutural usado para proporcionar ao usuário um meio de localização dentro da estrutura de navegação do site ou sistema.
Use breadcrumb para melhorar o SEO e para facilitar a identificação de onde o usuário se encontra na estrutura de navegação de um website. Esta funcionalidade não é recomendada para websites que não possuem um agrupamento ou hierarquia de usabilidade.
ID | Nome | Referência | Uso |
---|---|---|---|
1 | Botão | Button | Obrigatório |
2 | Separador | Iconografia | Obrigatório |
3 | Link | Estados | Obrigatório |
4 | Título da página atual | Tipografia | Obrigatório |
O componente breadcrumb na forma padrão funciona de maneira única, listando a hierarquia de links da tela inicial à tela atual. Cada item do breadcrumb é um link, exceto o último, que define a tela atual em que o usuário se encontra. Ao clicar-se em qualquer link do breadcrumb, o usuário é direcionado à página correspondente. O botão terciário Home direciona sempre para a tela inicial.
Nos casos das resoluções de 4 colunas (dispositivos móveis), deve-se necessariamente optar pela forma especial de breadcrumb. Nesse formato o breadcrumb é apresentado sempre com todos os links deslocados para o menu, exceto a Página Atual.
Também é permitido utilizar o breadcrumb especial no lugar do padrão. Esta decisão deve ser tomada de acordo com o planejamento de arquitetura do produto mas, uma vez tomada a decisão, jamais poderá revertê-la em um mesmo produto.
A seguir, as recomendações de uso em cada tipo de grid que podem ser utilizados na maioria dos casos:
Grid de 12 colunas: prefira o tipo padrão;
Grid de 8 colunas: prefira o tipo padrão em conjunto com o comportamento de truncamento ou o tipo especial;
Grid de 4 colunas: prefira o tipo especial;
Atenção: com a diminuição da resolução da tela o espaço disponível para o breadcrumb, em certos casos, pode ser insuficiente. A seguir é detalhado como proceder com a falta de espaço utilizando o recurso de truncamento nos textos.
O breadcrumb pode ser truncado quando não há espaço suficiente para exibir todos os níveis da lista de localização atual ou como uma forma de gerenciar a relevância dos itens visíveis da localização atual em uma hierarquia profundamente aninhada. O truncamento de itens de breadcrumb começa quando não há espaço suficiente para exibir todos os itens ou se houver mais de cinco itens do breadcrumb a serem exibidos. Considere o botão terciário Home e o título como itens.
Nestes casos, os links intermediários são organizados em forma de list dropdown e são acionáveis pelo botão correspondente. Os itens são listados com a hierarquia ordenada de cima para baixo.
Comportamento do componente breadcrumb com recurso de truncamento.
Atenção: Não faça truncamento dos seguintes itens: botão Home, última página ancestral e o Título da página atual.
Evite nomes de links muito grandes. Procure sempre que possível resumi-lo de modo que fique claro para o usuário o nome da tela a qual se refere.
Se ainda assim o nome continuar grande, utilize o recurso de truncar parte do nome, conforme o exemplo abaixo:
Atenção: utilize o componente tooltip para fornecer ao usuário o nome completo do link truncado.
Sinta-se livre para truncar os nomes da forma que melhor fizer sentido para o usuário.
Este recurso pode ser usado também nos nomes dos links que estiverem dentro da list dropdown.
O Botão terciário Home deve estar sempre presente no breadcrumb (exceto no tipo especial) e direcionado para a tela inicial do website ou sistema.
O título do breadcrumb deve ser sempre a tela atual em que o usuário se encontra e deve estar em destaque (semi bold). Todos os demais elementos são interativos exceto os ícones separadores que possuem a função de separar os itens.
Posicione os breadcrumb no topo da página imediatamente abaixo do header e use de forma consistente em todas as telas do website.
Breadcrumbs geralmente são encontrados em websites que possuem uma grande quantidade de conteúdos organizados de forma hierárquica. Também é possível vê-los em aplicações web que têm mais de uma etapa, com uma função semelhante a de uma barra de progresso. No entanto, é um recurso opcional.
Não é aconselhável usar breadcrumb em websites que não têm agrupamento ou hierarquia lógica. Uma ótima maneira de determinar se um site se beneficiará com a navegação por breadcrumb é construir um mapa do site ou um diagrama representando sua arquitetura de navegação e analisar se o recurso melhora a capacidade do usuário de navegar dentro e entre as categorias.
Breadcrumbs devem ser considerados como um recurso extra e não deve substituir o menu principal do website ou aplicativo. É uma característica de conveniência, um regime secundário de navegação que permite aos usuários determinar onde se encontram e deve ser usado como uma forma alternativa ou um auxiliar de navegação.
Breadcrumbs podem trazer uma série de benefícios para os usuários, como:
Dar a usuário um meio secundário de navegação em um website;
Ao invés de usar o botão “Voltar” do navegador ou a navegação principal do site para voltar à página de nível superior, os usuários podem usar o breadcrumb para realizar a mesma ação com um menor número de cliques;
Geralmente os breadcrumbs são em sentido horizontal e de estilo “clean” ocupando pouquíssimo espaço na página. A vantagem é que eles têm pouco ou nenhum impacto negativo em termos de sobrecarga de conteúdo;
Breadcrumbs podem ser uma ótima maneira de atrair visitantes pela primeira vez para examinar um website depois de ter visto a página de destino. Por exemplo, digamos que um usuário chega a uma página através de uma pesquisa no Google, vendo um breadcrumb, este pode “seduzir” o visitante para as páginas de nível superior para visualizar os tópicos relacionados ao seu interesse. Isso reduz a Taxa de rejeição (bounce rate) do website.
Name | Size | Weight | Text-transform |
---|---|---|---|
Links | --font-size-scale-down-01 |
--font-weight-medium |
uppercase |
Título | --font-size-scale-down-01 |
--font-weight-medium |
uppercase |
Name | Size | Class (Font Awesome) |
---|---|---|
Separador | --icon-size-sm |
fa-chevron-right |
Name | Class (Font Awesome) |
---|---|
Home | --icon-size-sm |
Folder-plus | --icon-size-sm |
Folder-minus | --icon-size-sm |
Name | Property | Color Token |
---|---|---|
Links | text color | --blue-warm-vivid-70 |
Título | text color | --gray-80 |
Botão Terciário Home | icon | --blue-warm-vivid-70 |
Separador | icon | --gray-20 |
Botão Terciário Expandir | icon | --blue-warm-vivid-70 |
Name | Property | Type | Spacing Scale Token |
---|---|---|---|
breadcrumb | padding-top |
Externo |
--spacing-scale-default |
Name | Property | Spacing Horizontal Token |
---|---|---|
right | spacing-horizontal | --spacing-horizontal-left |
HTML
<div class="br-breadcrumb">
<ul class="crumb-list">
<li class="crumb home"><a class="br-button circle" href="javascript:void(0)"><span class="sr-only">Página inicial</span><i class="fas fa-home"></i></a></li>
<li class="crumb"><i class="icon fas fa-chevron-right"></i><a href="javascript:void(0)">Página Ancestral 01</a>
</li>
<li class="crumb"><i class="icon fas fa-chevron-right"></i><a href="javascript:void(0)">Página Ancestral 02</a>
</li>
<li class="crumb"><i class="icon fas fa-chevron-right"></i><a href="javascript:void(0)">Página Ancestral 03</a>
</li>
<li class="crumb" data-active="active"><i class="icon fas fa-chevron-right"></i><span>Página atual</span>
</li>
</ul>
</div>
HTML
<div class="br-breadcrumb">
<ul class="crumb-list">
<li class="crumb home"><a class="br-button circle" href="javascript:void(0)"><span class="sr-only">Página inicial</span><i class="fas fa-home"></i></a></li>
<li class="crumb"><i class="icon fas fa-chevron-right"></i><a href="javascript:void(0)">Página Ancestral 01</a>
</li>
<li class="crumb"><i class="icon fas fa-chevron-right"></i><a href="javascript:void(0)">Página Ancestral 02</a>
</li>
<li class="crumb"><i class="icon fas fa-chevron-right"></i><a href="javascript:void(0)">Página Ancestral 03</a>
</li>
<li class="crumb"><i class="icon fas fa-chevron-right"></i><a href="javascript:void(0)">Página Ancestral Com Título Grande</a>
<div class="br-tooltip" role="tooltip" info="info" place="top"><span class="text" role="tooltip">Página Ancestral Com Título Grande</span>
</div>
</li>
<li class="crumb" data-active="active"><i class="icon fas fa-chevron-right"></i><span>Página atual</span>
</li>
</ul>
</div>
CSS
.br-breadcrumb {
display: inline-grid;
font-size: var(--font-size-scale-down-01);
font-weight: var(--font-weight-medium);
position: relative;
}
.br-breadcrumb .crumb-list {
align-items: center;
border: 0;
display: flex;
list-style: none;
margin: 0;
overflow-x: auto;
overflow-y: hidden;
padding: 0;
}
.br-breadcrumb .crumb {
align-items: center;
display: flex;
height: var(--spacing-scale-5x);
margin: auto 0 auto -5px;
}
.br-breadcrumb .crumb .icon {
color: var(--border-color);
font-size: var(--icon-size-sm);
margin-right: -6px;
}
.br-breadcrumb .crumb a {
max-width: 180px;
overflow: hidden;
padding: 0 6px;
text-decoration: none;
text-overflow: ellipsis;
white-space: nowrap;
}
.br-breadcrumb .crumb:last-child span {
font-weight: var(--font-weight-medium);
padding: 0 0 0 var(--spacing-scale-base);
white-space: nowrap;
}
.br-breadcrumb .home,
.br-breadcrumb .menu-mobil {
--focus-offset: calc(var(--spacing-scale-half) * -1);
margin-left: 0;
margin-right: -3px;
}
@media (max-width: 991px) {
.br-breadcrumb .crumb a {
display: block;
max-width: 180px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.br-breadcrumb .menu-mobil,
.br-breadcrumb .menu-mobil + .crumb,
.br-breadcrumb .home + .crumb {
display: flex;
}
}
.br-breadcrumb .br-card {
left: var(--spacing-scale-9x);
min-width: fit-content;
position: absolute;
top: var(--spacing-scale-7x);
z-index: var(--z-index-layer-1);
}
.br-breadcrumb .br-item {
color: var(--color);
cursor: pointer;
padding: 0;
}
.br-breadcrumb .br-item:not(:last-child) {
border-bottom: 1px solid var(--border-color);
}
.br-breadcrumb .br-item a {
--interactive: var(--color);
--interactive-rgb: var(--color-rgb);
display: block;
padding: var(--spacing-scale-2x);
}
@media (max-width: 575px) {
.br-breadcrumb .menu-mobil > .icon {
display: none;
}
.br-breadcrumb .br-card {
left: var(--spacing-scale-base);
width: 250px;
}
}
/*# sourceMappingURL=breadcrumb.css.map*/
Javascript
class BRBreadcrumb {
/**
* Instancia um componente breadcrumb
* @param {string} name - nome do componente
* @param {object} component - referencia ao objeto do DOM
**/
constructor(name, component) {
this.name = name
this.component = component
this._setBehavior()
}
/**
* Define os comportamentos do componente
* @private
*/
_setBehavior() {
this._setView()
window.addEventListener('resize', () => {
this._setView()
})
window.document.addEventListener('click', (event) => {
if (
!this.component.contains(event.target) &&
this.component.querySelector('.br-card')
) {
this.component.querySelector('.br-card').remove()
}
})
// window.addEventListener('resize', (event) => {})
}
/**
* Reseta a view do breadcrumb
*/
resetBreadcrumbs() {
this._reset()
const brcardBreadcrumb = this.component.querySelector('.br-card')
if (brcardBreadcrumb !== null) {
brcardBreadcrumb.remove()
}
this._setView()
}
/**
* Atualiza a visualização do componente
* @private
*/
_setView() {
this._reset()
for (const crumbList of this.component.querySelectorAll('.crumb-list')) {
const crumbs = crumbList.querySelectorAll('.crumb:not([data-active])')
if (window.innerWidth < 575) {
if (crumbs.length !== 1) {
crumbs.forEach((crumb) => {
crumb.classList.add('d-none')
})
this._insertExpandButton()
}
} else {
if (
crumbList.scrollWidth > crumbList.offsetWidth ||
crumbs.length > 5
) {
crumbs.forEach((crumb, index) => {
if (index > 0 && index < crumbs.length - 1) {
crumb.classList.add('d-none')
}
})
this._insertExpandButton()
}
}
}
}
/**
* Insere botao de expandir
* @private
*/
_insertExpandButton() {
const crumb = this._createCrumb()
const crumbList = this.component.querySelector('.crumb-list')
const crumbs = crumbList.querySelectorAll('.crumb')
crumbList.insertBefore(crumb, crumbs[1])
}
/**
* Reinicia componente
* @private
*/
_reset() {
this.component.querySelectorAll('.crumb-list .crumb').forEach((crumb) => {
if (crumb.classList.contains('menu-mobil')) {
crumb.remove()
} else {
crumb.classList.remove('d-none')
}
})
}
/**
* Insere elementos
* @private
*/
_createCrumb() {
const crumb = document.createElement('li')
crumb.classList.add('crumb', 'menu-mobil')
crumb.setAttribute('data-toggle', 'dropdown')
const button = document.createElement('button')
button.classList.add('br-button', 'circle')
const span = document.createElement('span')
span.classList.add('sr-only')
span.innerHTML = 'Botão Menu'
const folderIcon = document.createElement('i')
folderIcon.classList.add('fas', 'fa-folder-plus')
const chevronIcon = document.createElement('i')
chevronIcon.classList.add('icon', 'fas', 'fa-chevron-right')
crumb.appendChild(chevronIcon)
crumb.appendChild(button)
button.appendChild(span)
button.appendChild(folderIcon)
crumb.addEventListener('click', () => {
let card = this.component.querySelector('.br-card')
if (card) {
folderIcon.classList.remove('fas', 'fa-folder-minus')
folderIcon.classList.add('fas', 'fa-folder-plus')
this.component.querySelector('.br-card').remove()
} else {
folderIcon.classList.remove('fas', 'fa-folder-plus')
folderIcon.classList.add('fas', 'fa-folder-minus')
card = this._createList()
this.component.appendChild(card)
}
})
return crumb
}
/**
* Cria lista
* @private
*/
_createList() {
const card = document.createElement('div')
card.classList.add('br-card')
this.component.querySelectorAll('.crumb-list .crumb').forEach((crumb) => {
if (crumb.classList.contains('d-none')) {
const item = document.createElement('div')
item.classList.add('br-item')
if (!crumb.classList.contains('home')) {
item.appendChild(crumb.querySelector('a').cloneNode(true))
card.appendChild(item)
}
}
})
return card
}
}
export default BRBreadcrumb
Atributo | Tipo | Valor Padrão | Descrição |
---|---|---|---|
class | string | br-breadcrumb | Container do componente. |
class | string | crumb-list | Lista interna de links. |
class | string | crumb | Cada item da lista. |
class | string | home | Primeiro link da lista. |
class | string | icon | Cada separador da lista. |
Incluir o arquivo core.min.js
no html.
<script src="node_modules/@govbr-ds/core/dist/core.min.js"></script>
O arquivo core.min.js expõe um objeto chamado core
contendo as referências para todas as classes exportadas.
Usar o seguinte código JavaScript para instanciar a classe BRBreadcrumb
, passando os seguintes parâmetros:
const breadcrumbList = []
for (const brBreadcrumb of window.document.querySelectorAll('.br-breadcrumb')) {
breadcrumbList.push(new core.BRBreadcrumb('br-breadcrumb', brBreadcrumb))
}