Skip to content

Padrão de Botão Icon-Only

Este padrão define quando e como usar botões que contêm apenas ícones, estabelecendo a obrigatoriedade de tooltips descritivos para garantir acessibilidade e usabilidade. O objetivo é manter interfaces limpas sem comprometer a compreensão das ações disponíveis.

Botões com apenas ícones podem economizar espaço e criar interfaces mais limpas, mas podem gerar confusão sobre sua função, especialmente para usuários com deficiências visuais ou quando os ícones não são universalmente reconhecidos. A falta de descrição textual pode tornar a interface inacessível.

  • Em barras de ferramentas com espaço limitado
  • Para ações secundárias frequentemente utilizadas
  • Em interfaces onde o contexto torna a ação óbvia
  • Quando há necessidade de manter design minimalista
  • Button (Console Kit Blocks)
  • Tooltip (Console Kit Blocks)
  • Icon (Console Kit Blocks)

Exemplo visual será adicionado em breve

Edge Applications > Lista com botões de ação

  1. Obrigatório: Todo botão icon-only deve ter um tooltip descritivo
  2. Descrição clara: O tooltip deve explicar exatamente qual ação será executada
  3. Timing adequado: Tooltip deve aparecer rapidamente no hover (300-500ms)
  4. Posicionamento: Tooltip deve ser posicionado para não obstruir conteúdo importante
iconOnlyButton.js
const IconOnlyButton = {
// Cria botão icon-only com tooltip obrigatório
create: (iconName, action, tooltipText, options = {}) => {
const button = document.createElement('button');
button.className = `btn-icon-only ${options.variant || 'secondary'}`;
button.setAttribute('aria-label', tooltipText);
button.setAttribute('data-tooltip', tooltipText);
// Adiciona ícone
const icon = document.createElement('i');
icon.className = `icon icon-${iconName}`;
button.appendChild(icon);
// Event listeners
button.addEventListener('click', action);
// Tooltip handlers
button.addEventListener('mouseenter', IconOnlyButton.showTooltip);
button.addEventListener('mouseleave', IconOnlyButton.hideTooltip);
button.addEventListener('focus', IconOnlyButton.showTooltip);
button.addEventListener('blur', IconOnlyButton.hideTooltip);
return button;
},
// Gerencia exibição de tooltip
showTooltip: (event) => {
const button = event.target.closest('[data-tooltip]');
const tooltipText = button.getAttribute('data-tooltip');
// Remove tooltip existente
IconOnlyButton.hideTooltip();
// Cria novo tooltip
const tooltip = document.createElement('div');
tooltip.className = 'tooltip';
tooltip.textContent = tooltipText;
tooltip.id = 'active-tooltip';
document.body.appendChild(tooltip);
// Posiciona tooltip
const buttonRect = button.getBoundingClientRect();
const tooltipRect = tooltip.getBoundingClientRect();
tooltip.style.left = `${buttonRect.left + (buttonRect.width - tooltipRect.width) / 2}px`;
tooltip.style.top = `${buttonRect.top - tooltipRect.height - 8}px`;
// Adiciona classe para animação
setTimeout(() => tooltip.classList.add('visible'), 10);
},
hideTooltip: () => {
const existingTooltip = document.getElementById('active-tooltip');
if (existingTooltip) {
existingTooltip.remove();
}
},
// Valida se botão tem tooltip
validateTooltip: (button) => {
const hasTooltip = button.hasAttribute('data-tooltip') ||
button.hasAttribute('aria-label') ||
button.hasAttribute('title');
if (!hasTooltip) {
console.warn('Icon-only button missing tooltip:', button);
return false;
}
return true;
}
};
// Exemplo de uso
const actionButtons = [
{
icon: 'edit',
action: () => editItem(),
tooltip: 'Edit item',
variant: 'primary'
},
{
icon: 'delete',
action: () => deleteItem(),
tooltip: 'Delete item',
variant: 'danger'
},
{
icon: 'copy',
action: () => copyItem(),
tooltip: 'Duplicate item'
}
];
// Renderiza botões na interface
const buttonContainer = document.querySelector('.action-buttons');
actionButtons.forEach(config => {
const button = IconOnlyButton.create(
config.icon,
config.action,
config.tooltip,
{ variant: config.variant }
);
buttonContainer.appendChild(button);
});
// Validação de acessibilidade
document.querySelectorAll('.btn-icon-only').forEach(button => {
IconOnlyButton.validateTooltip(button);
});
  • Obrigatório: Use aria-label ou title para descrever a ação
  • Implemente suporte completo para navegação por teclado
  • Garanta que tooltips sejam anunciados por leitores de tela
  • Mantenha contraste adequado entre ícone e fundo
  • Use role="button" quando necessário para elementos não-button
  • Considere aria-describedby para descrições mais detalhadas