Přidání popisků nástrojů ve WordPressu bez zásuvných modulů

Seleccionar idioma
Přidání popisků nástrojů ve WordPressu bez zásuvných modulů
Příklad zde použitého tooltipu

Termín tooltip nemá jednoznačný překlad do češtiny, může být popsán jako "nápověda", "balón nápovědy", "vyskakovací popis" nebo dokonce "text nápovědy" v závislosti na kontextu, ve kterém je použit.

Tip nástroje je vyskakovací zpráva, která se zobrazí při interakci s prvkem, a to buď kliknutím na něj, nebo najetím myší. Tyto tooltipy slouží k poskytování dodatečných informací, aniž by trvale zabíraly místo. Ideální pro vysvětlení ikon, technických termínů nebo akcí v rozhraních.

Škodí nebo prospívají popisky nástrojů SEO?

No, jako téměř u všeho, odpověď je vždy záleží na tom, co se stane. SEO puristé sice upozorňují, že Google nemá rád "skrytý" nebo maskovaný obsah a jeho používání tvrdě trestá, ale to by byl extrém pro případy zneužití , které by mohly "kanibalizovat" váš obsah. Nicméně tooltipy, používané s určitou vyvážeností a minimem logiky, mohou být přínosné.

Výhody používání popisků nástrojů

Obecně řečeno, tato sdělení, pokud jsou přátelská a nevtíravá, mohou přispět ke zlepšení různých aspektů uživatelské zkušenosti. Mimo jiné snižují míru odmítnutí a zlepšují přístupnost. Mohou také poskytnout příležitost k použití dalších klíčových slov, která přirozeně nezapadají do hlavního obsahu, což pomáhá sémantické SEO.

Kromě toho mohou zvýšit míru prokliku. Nabídkou tooltipů v navigaci nebo tlačítek s výzvou k akci mohou uživatele efektivněji navést, což vede k vyšší míře prokliků. Aby to však bylo všechno možné, je třeba dodržet několik minimálních zásad.

Doporučení pro vzhled, obsah a provoz

  • Použití prvků HTML a atributů ARIA k zajištění přístupu čteček obrazovky a vyhledávačů k informacím, které obsahují.
  • Nápověda musí být stručná. Je zřejmé, že nikdo nebude číst obrovské množství informací ve vyskakovacím okně a vy tak pokryjete velkou část obsahu. Měla by obsahovat minimum přesných a nezbytných informací, které by neměly být pro uživatele rozhodující při provádění nebo dokončování akce.
  • Obsah by neměl být nadbytečný nebo se opakovat, ujistěte se, že poskytujete další užitečné a potřebné informace a že se v obsahu neopakují, abyste se vyhnuli "duplicitnímu obsahu".
  • Snažte se co nejvíce vyhýbat nástrojovým popiskům, které zmizí při pohybu kurzoru, nebo je používejte pouze ve zprávách, které neobsahují mnoho informací a/nebo obsahu. V ideálním případě by se měly zobrazovat na jedno kliknutí a zavírat se při opětovném kliknutí kdekoli na obrazovce.
  • Ujistěte se, že jsou čitelné a mají správnou velikost.
  • Nepřidávejte dvacet různých designů ikon nebo odkazů tooltipů, to jen vytváří zmatek. Pevný a konzistentní design pomůže návštěvníkům identifikovat je na první pohled.
  • Nepřehánějte to, dobře si naplánujte strategii a přidávejte je pouze tam, kde si myslíte, že usnadňují přístup k relevantním a/nebo nezbytným doplňujícím informacím.

Vlastnosti a funkce kódu

Pro tento případ byl použit tento obrázek.png s průhledným pozadím.

Zde si můžete vyzkoušet konečný výsledek práce [tooltip text="Příklad tooltipu použitého v jrmora.com" position="auto"].

Adresa URL obrázku se přidá mezi uvozovky na tomto řádku:

$default_image = 'URL-de-tu-imagen';

Pokud se rozhodnete upravit kód tak, aby používal ikonu SVG HTML, jako je tato, budete si moci snadněji hrát s barvou, pozadím, tloušťkou atd..

Inteligentní automatické nastavení polohy, aby se zabránilo okrajům obrazovky. Tj. při přiblížení k hornímu okraji se nápověda zobrazí dole a podobně.

Do nápovědy lze přidat plně funkční odkazy s přizpůsobitelnými styly. Ačkoli se nedoporučuje přidávat odkazy, je možné, že to budete občas potřebovat. V případě, že tooltip obsahuje odkaz, dochází k automatickému skrytí s 200ms zpožděním, aby bylo snazší na něj kliknout.

Zabezpečená podpora HTML. Podporuje:

<strong>, <em>, <a>, <br>, <span>

Poloha, pevné a přizpůsobitelné atributy.

Atributos de posición disponibles:  position="auto" (default), top, bottom, left, right

Atributy ARIA (aria-expanded, role="tooltip").

Aktualizace. Do obrázku bylo přidáno aria-hidden="true" a role="presentation" a skryta ozdobná ikona pro čtečky obrazovky.

Zbytečnost je vyloučena pomocí aria-label, který umožňuje přizpůsobení textu přístupného ze zkráceného kódu.

[tooltip text="Contenido" aria_label="Ver detalles sobre este elemento"]

Toto řešení je v souladu s WCAG 2.1 AA a řeší varování služby PageSpeed Insights, že tlačítko nemá přístupný název.

Responzivní design.

Přizpůsobení pro mobilní zařízení (klikací přepínač).

Obnovení při změně velikosti, otáčení nebo posunu

Hlavní třídy CSS:

.tooltip-container /* Contenedor principal */
.tooltip-trigger  /* Botón/icono que activa el tooltip */
.tooltip          /* Caja del mensaje emergente */
.tooltip-arrow    /* Flecha indicadora */

Klíčové funkce JS:

calculateBestPosition() // Determina si colocar el tooltip arriba, abajo, etc.
showTooltip()          // Muestra el tooltip
hideTooltip()          // Oculta el tooltip con retraso

Příklady zkratek:

[tooltip text="Texto a mostrar"] 

[tooltip text="Texto a mostrar <strong>en negrita</strong> donde sea" position="auto"] 

[tooltip text="Texto <strong>importante</strong> y <em>énfasis</em>"]

[tooltip text="<a href='https://ejemplo.com' target='_blank'>Visite nuestro sitio</a>"]

Pokud jde o výkon:

  1. Předem načtené prostředky: Předem načtené obrázky a CSS.
  2. Lazy loading: Atributy loading="lazy" a decoding="async" pro obrázek.
  3. Podmíněné načítání: JS se načte pouze při použití zkratky.
  4. Debounce: Optimalizace událostí změny velikosti a posouvání.
  5. Optimalizované CSS: Použití will-change a moderních jednotek (min()).
  6. Verze v mezipaměti: Použijte funkci filemtime(), abyste se vyhnuli zastaralému ukládání do mezipaměti.

Tento kód jsem použil pro své konkrétní potřeby. Chápejte ho jako výchozí bod. Lze jej vylepšit. Můžete o něm uvažovat i bez použití Javascriptu a upravit ho tak, aby se dal použít i na slova v obsahu bez zobrazení ikony.

Chcete-li ji použít, přidejte ji jako vždy do souboru functions.php a do složky assets/css/ a asstes/js/ své šablony nebo svého podřízeného tématu, pokud chcete zachovat změny při aktualizaci šablony.

Kód

Toto je struktura souborů:

vaše-šablona/
├── functions.php (na konec přidejte PHP kód)
├── assets/
│ ├─── css/
│ │ └└──── tooltip.css (styly CSS)
│ └└└──── js/
│ └└─── tooltip.js (Javascript)

Kód pro přidání do šablony functions.php

/**
 * Shortcode para tooltip accesible y optimizado
 * Uso: [tooltip text="Texto" position="auto" color="#6a0000" aria_label="Descripción"]
 */
function accessible_tooltip_shortcode($atts) {
    $default_image = 'https://jrmora.com/wp-content/uploads/2025/07/tooltip-negro.png';
    
    $atts = shortcode_atts(
        array(
            'text' => __('Información adicional', 'text-domain'),
            'position' => 'auto',
            'color' => '#6a0000',
            'shadow' => '#9c9c9c',
            'width' => '18px',
            'id' => 'tooltip-' . uniqid(),
            'aria_label' => __('Mostrar información adicional', 'text-domain')
        ),
        $atts,
        'tooltip'
    );

    // HTML permitido (seguro)
    $allowed_html = array(
        'strong' => array(),
        'b' => array(),
        'em' => array(),
        'i' => array(),
        'br' => array(),
        'span' => array(
            'style' => array(),
            'class' => array()
        ),
        'a' => array(
            'href' => array(),
            'title' => array(),
            'target' => array(),
            'style' => array(),
            'rel' => array()
        )
    );
    
    $text = wp_kses($atts['text'], $allowed_html);
    $position = in_array($atts['position'], ['top', 'bottom', 'left', 'right', 'auto']) ? $atts['position'] : 'auto';
    $color = sanitize_hex_color($atts['color']);
    $shadow = sanitize_hex_color($atts['shadow']);
    $width = esc_attr($atts['width']);
    $id = sanitize_html_class($atts['id']);
    $aria_label = esc_attr($atts['aria_label']);

    // Preload para la imagen (mejora rendimiento)
    add_action('wp_head', function() use ($default_image) {
        echo '<link rel="preload" href="' . esc_url($default_image) . '" as="image">';
    });

    return '
    <span class="tooltip-container" data-position="' . esc_attr($position) . '">
        <button class="tooltip-trigger" 
                aria-describedby="' . $id . '" 
                aria-expanded="false"
                aria-label="' . $aria_label . '">
            <img src="' . esc_url($default_image) . '" 
                 width="' . $width . '" 
                 alt=""
                 aria-hidden="true"
                 loading="lazy"
                 decoding="async"
                 role="presentation"/>
        </button>
        <span id="' . $id . '" role="tooltip" class="tooltip" style="background-color: ' . $color . '; box-shadow: 0 5px 10px ' . $shadow . ';">
            ' . $text . '
            <span class="tooltip-arrow"></span>
        </span>
    </span>';
}
add_shortcode('tooltip', 'accessible_tooltip_shortcode');

/**
 * Carga optimizada de assets
 */
function load_tooltip_assets() {
    global $post;
    
    // CSS externo
    wp_enqueue_style(
        'tooltip-css',
        get_theme_file_uri('/assets/css/tooltip.css'),
        array(),
        filemtime(get_theme_file_path('/assets/css/tooltip.css'))
    );
    
    // JS solo si se usa el shortcode
    if (is_a($post, 'WP_Post') && has_shortcode($post->post_content, 'tooltip')) {
        wp_enqueue_script(
            'tooltip-js',
            get_theme_file_uri('/assets/js/tooltip.js'),
            array(),
            filemtime(get_theme_file_path('/assets/js/tooltip.js')),
            true
        );
    }
}
add_action('wp_enqueue_scripts', 'load_tooltip_assets');

CSS / tooltip.css (musí být uložen v této cestě /assets/css/tooltip.css)

/* Contenedor principal */
.tooltip-container {
    display: inline-block;
    position: relative;
    vertical-align: middle;
}

/* Botón activador */
.tooltip-trigger {
    background: none;
    border: none;
    padding: 0;
    margin: 0 2px;
    cursor: pointer;
    line-height: 1;
}

/* Caja del tooltip */
.tooltip {
    position: absolute;
    color: #fff;
    padding: 10px 12px;
    border-radius: 4px;
    font-size: 14px;
    line-height: 1.5;
    width: 220px;
    max-width: min(90vw, 220px);
    text-align: left;
    visibility: hidden;
    opacity: 0;
    transition: opacity 0.25s ease;
    z-index: 100000;
    pointer-events: none;
    will-change: transform, opacity;
}

/* Flecha indicadora */
.tooltip-arrow {
    position: absolute;
    width: 0;
    height: 0;
    border: 7px solid transparent;
}

/* Posiciones */
.tooltip[data-position="top"] {
    bottom: 100%;
    left: 50%;
    transform: translateX(-50%);
    margin-bottom: 10px;
}
.tooltip[data-position="top"] .tooltip-arrow {
    top: 100%;
    left: 50%;
    transform: translateX(-50%);
    border-top-color: inherit;
}

.tooltip[data-position="bottom"] {
    top: 100%;
    left: 50%;
    transform: translateX(-50%);
    margin-top: 10px;
}
.tooltip[data-position="bottom"] .tooltip-arrow {
    bottom: 100%;
    left: 50%;
    transform: translateX(-50%);
    border-bottom-color: inherit;
}

/* Interacción */
.tooltip-trigger:hover + .tooltip,
.tooltip-trigger:focus + .tooltip,
.tooltip-trigger[aria-expanded="true"] + .tooltip {
    visibility: visible;
    opacity: 1;
}

/* Enlaces dentro del tooltip */
.tooltip a {
    color: #fff !important;
    text-decoration: underline;
    pointer-events: auto !important;
}

/* Focus para accesibilidad */
.tooltip-trigger:focus {
    outline: 2px solid #005fcc;
    outline-offset: 2px;
}

Javascript / Tooltip.js (Musí být uložen v cestě /assets/js/tooltip.js)

document.addEventListener("DOMContentLoaded", () => {
    const tooltips = document.querySelectorAll('.tooltip-container[data-position="auto"]');
    if (!tooltips.length) return;

    // Debounce para optimización
    const debounce = (func, wait = 50) => {
        let timeout;
        return (...args) => {
            clearTimeout(timeout);
            timeout = setTimeout(() => func.apply(this, args), wait);
        };
    };

    // Configurar cada tooltip
    tooltips.forEach(container => {
        const tooltip = container.querySelector('.tooltip');
        const trigger = container.querySelector('.tooltip-trigger');
        let hoverTimeout;
        let isMouseIn = false;

        // Calcular mejor posición
        const calculatePosition = () => {
            const rect = trigger.getBoundingClientRect();
            const viewportHeight = window.innerHeight;
            return (rect.top < viewportHeight / 2) ? 'bottom' : 'top';
        };

        // Actualizar posición (optimizado)
        const updatePosition = debounce(() => {
            tooltip.dataset.position = calculatePosition();
        });

        // Mostrar tooltip
        const showTooltip = () => {
            clearTimeout(hoverTimeout);
            tooltip.style.visibility = 'visible';
            tooltip.style.opacity = '1';
            trigger.setAttribute('aria-expanded', 'true');
        };

        // Ocultar con retraso (para enlaces)
        const hideTooltip = () => {
            if (!isMouseIn) {
                hoverTimeout = setTimeout(() => {
                    tooltip.style.visibility = 'hidden';
                    tooltip.style.opacity = '0';
                    trigger.setAttribute('aria-expanded', 'false');
                }, 200);
            }
        };

        // Eventos
        trigger.addEventListener('mouseenter', showTooltip);
        trigger.addEventListener('mouseleave', hideTooltip);
        trigger.addEventListener('focus', showTooltip);
        trigger.addEventListener('blur', hideTooltip);

        tooltip.addEventListener('mouseenter', () => {
            isMouseIn = true;
            clearTimeout(hoverTimeout);
        });

        tooltip.addEventListener('mouseleave', () => {
            isMouseIn = false;
            hideTooltip();
        });

        // Inicialización
        updatePosition();
        window.addEventListener('resize', updatePosition);
        window.addEventListener('scroll', updatePosition, { passive: true });
    });

    // Cerrar al hacer clic fuera
    document.addEventListener('click', (e) => {
        if (!e.target.closest('.tooltip-container') && !e.target.closest('.tooltip a')) {
            document.querySelectorAll('.tooltip').forEach(t => {
                t.style.visibility = 'hidden';
                t.style.opacity = '0';
            });
        }
    });
});

Související články

Este blog se aloja en LucusHost

LucusHost, el mejor hosting