Executando verificação de segurança...
9

[ Conteúdo ] Crie tooltips rápido,eficiente e bonito com apenas HTML e CSS!

Descrição:

Recentemente eu descobri uma forma de criar tooltips apenas com HTML e CSS, o que é muito legal pois diminui a necessidade de utilizar JavaScript para algo tão simples. Além disso, irei mostrar um exemplo de como fazer utilizando Tailwindcss, caso você faça parte do time que odeie CSS puro.

O que precisamos?

Simples, tudo que você precisa é de qualquer coisa que possa escrever HTML e CSS, que pode ser até o bloco de notas. Além disso é importante ter familiaridade com HTML e ao menos um pouco com CSS

Para o exemplo com Tailwindcss, é importante que tenha os conhecimentos acima, e conhecimento sobre como o Tailwindcss funciona no geral. Você pode encontrar a documentação do Tailwindcss neste link: Tailwindcss

Resultado esperado:

O resultado será como este aqui:
example

Lembrando que o tooltip é completamente personalizavél ao seu gosto com CSS.

Uma pincelada antes do exemplo:

Para atingir este objetivo iremos utilizar um atributo bem interessante do HTML que eu aposto que poucos conhecem, chamado de data-*.

O que é o atributo data-*? Este atributo permite armazenar um valor associado a um elemento especifico do HTML. Por exemplo:

<div data-information="Eu pertenço a esta div!"></div>

Esta informação é invisível, e tem como finalidade ser extraída tanto no CSS, quanto no JavaScript. Como para este exemplo não é necessário utilizar JavaScript, focaremos no CSS.

Outro ponto a ser observado antes de prosseguir é: Qualquer valor armazenado dentro de data-* é convertido em string. Além disso, você pode estranha a sintaxe data-*, mas é isto que torna este atributo mágico!

O asterisco, também chamado de coringa as vezes, significa qualquer coisa na maioria dos casos. Aqui não é diferente. O atributo possui o prefixo data-, e o que vêm a seguir pode ser qualquer coisa!

Exemplos:

<div data-information="Eu pertenço a esta div!"></div>
<div data-hi="Eu pertenço a esta div!"></div>
<div data-i-really-like-programming-world="Eu pertenço a esta div!"></div>
<div data-tooltip="Eu pertenço a esta div!"></div>
<div data-is-invalid="Eu pertenço a esta div!" data-error-unknown="Eu também pertenço a esta div!"></div>

Você pode ver mais sobre data-* aqui: Use Data Attributes

Examplo prático:

Começaremos com o HTML:

<div data-tooltip="Adicionar tópico" class="tooltip">Adicionar</div>
<div data-tooltip="Classificar tópicos" class="tooltip">Classificar</div>
<div data-tooltip="Modo Deletar" class="tooltip">Deletar</div>

Tudo que fizemos aqui:

  • Criamos 3 <div>;
  • adicionamos nosso data-* atributo com o nome de tooltip para ficar semântico;
  • atribuímos uma classe chamada tooltip;

Agora no CSS:

/* configuração básica para a <div>. */  
.tooltip {
    position: relative;
    cursor: pointer;
    /* Estilos para o tooltip */
    &::after {
        position: absolute; /* Seu posicionamento é relativo a div pai */
        content: attr(data-tooltip) /* extrai o valor do atributo */
        /* para centralizar o elemento */
        left: 50%; 
        transform: translateX(-50%);
        /* Ajuste conforme necessário */
        bottom: 120%;
        /* estilos para dar o charme */
        padding: 0.62rem; /* aproximadamente 10px */
        border-radius: 1.25rem; /* 20px */
        background-color: #212121;
        color: #eeeeee;
        white-space: nowrap;
        /* ele é invisível por padrão*/
        visibility: hidden;
    }
    &:hover::after {
        /* Quando passar por cima da <div>, o tooltip irá aparecer */
        visibility: visible; 
    }
}

Pronto, simples, não? Se você colar ai na sua IDE, irá ser bem simples. Porém você pode costumizar a sua vontade tranquilamente. Inicalmente eu fiz o meu com animação de fade-in, que pode ser alcançado facilmente com animations. Algo como:

.tooltip {
    position: relative;
    cursor: pointer;
    /* Estilos para o tooltip */
    &::after {
        position: absolute; /* Seu posicionamento é relativo a div pai */
        content: attr(data-tooltip) /* extrai o valor do atributo */
        /* para centralizar o elemento */
        left: 50%; 
        transform: translateX(-50%);
        /* Ajuste conforme necessário */
        bottom: 120%;
        /* estilos para dar o charme */
        padding: 0.62rem; /* aproximadamente 10px */
        border-radius: 1.25rem; /* 20px */
        background-color: #212121;
        color: #eeeeee;
        white-space: nowrap;
        /* ele é invisível por padrão*/
        visibility: hidden;
    }
    &:hover::after {
        /* Quando passar por cima da <div>, o tooltip irá aparecer */
        animation: fade-in 0.4s forwards ease-in;
    }
}
    
@keyframe fade-in {
        0% {
            display: none;
            visibility: hidden;
            opacity: 0;
       }
       100% {
            display: block;
            visibility: visible;
            opacity: 1; 
       }
}

Agora vamos para o exemplo do Tailwindcss:

Criando no Tailwindcss:

Irei considerar que você tem o Tailwindcss instalado e que sabe utiliza-lo.

O processo é literalmente o mesmo, mas utilizando as classes do tailwindcss, como abaixo:

 <div data-tooltip="Classificar Tópicos" className={`relative whitespace-nowrap w-fit h-fit after:content-[attr(data-tooltip)] after:absolute px-5 after:left-2/4 after:translate-x-[-50%] after:bg-slate-700 after:border after:border-slate-500 after:rounded-lg after:bg-red after:text-white after:invisible hover:after:visible`}>
       <IconButton>
         <ArrowDownUp strokeWidth={1.5} absoluteStrokeWidth={true} className="h-full w-full"/>
       </IconButton>
</div>

Neste exemplo eu crei uma div, assim como no exemplo apenas com HTML e CSS. Coloquei um componente fictício para simular uma estrutura básica do dia a dia com frameworks como Next.js.

O <ArrowDownUp strokeWidth={1.5} absoluteStrokeWidth={true} className="h-full w-full"/> é apenas um svg fictício do lucide.

A única parte importante é a div com as classes e o data-tooltip.

Pronto, agora você pode criar tooltips apenas com HTML e CSS ou integrar ao seu projecto que utiliza Tailwindcss.

Conclusão:

HTML e CSS realmente evoluíram muito! A projetos que possui uma dependência apenas para ter este efeito.

O ideal e no dia a dia é usar com Tailwindcss. Criar um componente personalizavél e reutilizar em seu projeto.

Espero que tenham gostado!
anime_gif_bye

Carregando publicação patrocinada...
2

Programmer404, MUITO OBRIGADO por compartilhar esse conhecimento valioso e por abrir os olhos da comunidade para as possibilidades do data-* e para um desenvolvimento web mais "raiz", sempre que possível.

1 .Zero dependências? CHECK.
2. Acessível? CHECK.
3. Performático? CHECK ABSOLUTO

Continue cavando fundo, explorando essas ferramentas poderosas e nos mostrando o quão longe podemos ir com HTML e CS. Isso é só a ponta do iceberg.

Com todas as novidades e recursos FANTÁSTICOS que o CSS tem ganhado nos últimos anos, como variables e animations dá criar aplicações web INSTANTÂNEAS E COMPLEXAS, praticamente sem qualquer Javascript.

Por exemplo, uma prova de conceito de SPA/SSR: Ao invés de enfiar toneladas de dependencias, builds complexos e frameworks gigantescos, basta ter um data-fetch com um <scriptzinho> no html.

<!DOCTYPE html>
<html>
<head>
    <title>Minha App HTML/CSS + data-fetch</title>
</head>
<body>
    <nav>
        <a href="/" data-fetch="/conteudo-home">Home</a>
        <a href="/sobre" data-fetch="/conteudo-sobre">Sobre</a>
        <a href="/contato" data-fetch="/conteudo-contato">Contato</a>
    </nav>

    <main id="conteudo-principal">
        <h1>Bem-vindo!</h1>
        <p>Conteúdo da página inicial.</p>
    </main>

    <script>
        document.addEventListener('click', function(event) {
            if (event.target.matches('a[data-fetch]')) {
                event.preventDefault();
                const urlFetch = event.target.getAttribute('data-fetch');
                fetch(urlFetch)
                    .then(response => response.text())
                    .then(html => {
                        document.getElementById('conteudo-principal').innerHTML = html;
                        history.pushState({}, '', event.target.getAttribute('href'));
                    });
            }
        });
    </script>
</body>
</html>
    

"Hidratação"? "Estado"? "JSON"? ESQUECE! Aqui a gente volta pro BÁSICO, pro HTML QUE VOA e pro site que carrega NA HORA! É mais rápido e mais acessível do que as coisas mais otimizadas que os frameworks conseguirão criar. E sem npm install pra quando alguém achar seu repo daqui milhares de anos sua aplicação ainda funcionar.

O HTML e CSS são o FRAMEWORK DEFINITIVO da web que gente demais ignora...

E o MELHOR DE TUDO: SEM "BACKEND" VS "FRONTEND"!

O programador WEB "RAIZ" trabalha DIRETO COM OS DADOS gerando HTML BRUTO da forma mais eficiente possível. O DESIGNER reinando absoluto no CSS, criando interfaces LINDAS e INTUITIVAS. Sem Figma pra "copiar pro código".

PROGRAMADOR E DESIGNER, CONSTRUINDO A WEB [DO FUTURO]... QUE JÁ ERA HÁ 20 ANOS ATRÁS!

A moda é cíclica, e no desenvolvimento web não é diferente! Depois da era jQuery, Angular.js, React... estamos começando a RELEMBRAR o que a gente JÁ SABIA FAZER DE MELHOR! VOCÊ JÁ TÁ NA FRENTE, MEU AMIGO! Continue nessa cavando fundo.

Um abraço e bons estudos!

1

Concordo plenamente. HTML e CSS evoluiu muito! E técnicamente falando, não há necessidade de tanto JavaScript para no final ser o bom e velho HTML e CSS.

O único problema do HTML é o fato de tudo ficar no mesmo documento. Se existisse uma forma de modularizar isso para ficar mais fácil de manter, eu facilmente abandonava o uso de frameworks. É muito difícil manter um documento de mais de 5 mil linhas tudo junto.

Tirando esse aspecto, a mais no HTML do que muita gente pensa!

O CSS também possui muitas das features que estão presentes no Sass por exemplo. Hoje em CSS é possível utilizar CSS de forma mais simples que antes. Claro, ainda é um inferno organizar isso do mesmo jeito que o HTML, mas ao menos da para modularizar.

Fico feliz que gosto do post!

1

O único problema do HTML é o fato de tudo ficar no mesmo documento. Se existisse uma forma de modularizar isso para ficar mais fácil de manter, eu facilmente abandonava o uso de frameworks. É muito difícil manter um documento de mais de 5 mil linhas tudo junto.

É possível aproveitar os benefícios do HTML sem abrir mão da organização e manutenibilidade. Uma solução eficaz é apenas gerar os documentos HTML de forma automática. A aplicação é desenvolvida na linguagem de preferência, seguindo a organização e padrões desejados e o HTML gerado é simplesmente seu output. É destacar notar que o Javascript, sendo parte integrante do documento HTML, também pode e deve ser gerado automaticamente.

1

Eu sinceramente não sei como eu poderia fazer isso. Seria algo como SSG? Este é um problema que realmente me incomoda. Eu já cheguei a usar Next.js apenas pela a organização...

1

TEMPLATES É A SOLUÇÃO!

E para dominar templates, comece no BERÇO DA WEB DINÂMICA: PHP: O PRIMEIRO FRAMEWORK WEB, ESCRITO EM C CIRCA 96!!!

Sim, PHP nasceu como uma engine de templates.

Mergulhe no PHP PURO. O segredo é usar echo para imprimir HTML, junto com os já conhecidos if para condicionais e for para loops. É cru, é direto, é a base.

ENTENDA ISSO PRIMEIRO! PHP puro te ensina a raiz da geração HTML.

Para entender na prática a beleza da geração de HTML com templates, nada melhor que um exemplo real e robusto: Gazelle, o motor por trás do finado what.cd!

O Gazelle é uma ESCOLA de desenvolvimento web server-side em PHP. Um exemplo IMPERDÍVEL de como construir aplicações web ROBUSTAS e EFICIENTES com PHP "raiz" e templates.

A página de torrents do Gazelle é um PRIMOR de como gerar HTML. Ela não é um arquivo único, mas sim, MONTADA POR VÁRIAS OUTRAS PÁGINAS MENORES, cada uma focada em uma parte da interface. (Componentes??)

Explore a pasta sections/torrents: Lá, você verá arquivos como details.php, browse.php, upload.php e muitos outros. Cada um deles é responsável por uma FUNCIONALIDADE ESPECÍFICA da seção de torrents. E Para entender como TUDO SE ENCAIXA, estude com atenção para o index.php. É a COMPOSIÇÃO DE TEMPLATES em ação, no seu melhor!

Qualquer coincidência com a arquitetura de componentes do React NÃO É MERA COINCIDÊNCIA! 😉) A modularização, a quebra em partes menores, é um princípio de arquitetura ATEMPORAL

MAS ATENÇÃO: CLARO QUE NÃO É ASSIM QUE SE FAZ WEB EM 2025! O mundo mudou, as tecnologias evoluíram. Gazelle é um projeto com quase 20 anos, e as ferramentas e abordagens de desenvolvimento web de fato avançaram muito desde então. PORÉM, NÃO SE ENGANE: UMA VEZ QUE VOCÊ ENTENDE A BASE DE CÓDIGO DO GAZELLE, VOCÊ ESTARÁ MUITO MAIS PREPARADO PARA FAZER O DESENVOLVIMENTO WEB MODERNO DO JEITO CERTO!

A organização, a modularização, a clareza do código, a eficiência da geração de HTML server-side, os princípios de arquitetura do Gazelle... TUDO ISSO É EXTREMAMENTE RELEVANTE HOJE, INDEPENDENTE DA LINGUAGEM OU FRAMEWORK QUE VOCÊ ESCOLHA! Porque, sejamos sinceros, a web moderna SE PERDEU UM POUCO NO CAMINHO! Em busca de "melhorias", de "ferramentas mais modernas", a gente ESQUECEU do básico!

ENTÃO, ESTUDE O CÓDIGO DO GAZELLE! Entenda sua ESSÊNCIA, seus PRINCÍPIOS! Porque ali, naquele código "arcaico", há LIÇÕES VALIOSÍSSIMAS para o FUTURO DO DESENVOLVIMENTO WEB! Aquilo ali, em GO, combinado com HTML e CSS MODERNOS (como o do post original), é VISLUMBRE DO MELHOR QUE A WEB pode ser. E eu aposto dinheiro nisso.

Sem mais.
Um abraço e bons estudos!

0
1

Ótima solução! Queria que o React Native tivesse algumas dessas facilidades (ou hacks, dependendo do ponto de vista) do CSS

Queria deixar minha contribuição dizendo que seria bom o tooltip aparecer quando o componente está focado, isso ajuda muito na questão de acessibilidade.

1

Também é possível! Ao invés de hover, você poderia mudar para focus. Este é um exemplo generalista. Também é possível ter tanto o hover quanto o focus.

Exemplo:

/* configuração básica para a <div>. */  
.tooltip {
    position: relative;
    cursor: pointer;
    /* Estilos para o tooltip */
    &::after {
        position: absolute; /* Seu posicionamento é relativo a div pai */
        content: attr(data-tooltip) /* extrai o valor do atributo */
        /* para centralizar o elemento */
        left: 50%; 
        transform: translateX(-50%);
        /* Ajuste conforme necessário */
        bottom: 120%;
        /* estilos para dar o charme */
        padding: 0.62rem; /* aproximadamente 10px */
        border-radius: 1.25rem; /* 20px */
        background-color: #212121;
        color: #eeeeee;
        white-space: nowrap;
        /* ele é invisível por padrão*/
        visibility: hidden;
    }
    
    &:focus::after {
        /* é necessário substituir a <div> por algum <input> ou <button> */
        visibility: visible; 
    } 
    
    &:hover::after {
        /* Quando passar por cima da <div>, o tooltip irá aparecer */
        visibility: visible; 
    }
}

1
1

Mas é tudo nativo do HTML? Bom, imagino que você pensou algo como um componente pronto, correto? Seria bem simples mesmo, mas ainda assim, é assim não muda o fato que HTML e CSS fazem coisas incrível sozinhos!

1