Додавання підказок у WordPress без плагінів

Seleccionar idioma
Додавання підказок у WordPress без плагінів
Приклад підказки, що використовується тут

Термін tooltip не має однозначного перекладу на англійську мову, його можна описати як "підказка", "спливаюча підказка", "спливаючий опис" або навіть "текст підказки", залежно від контексту, в якому він використовується.

Підказка - це спливаюче повідомлення, яке з'являється при взаємодії з елементом: при натисканні на нього або при наведенні миші. Ці підказки використовуються для надання додаткової інформації, не займаючи постійного місця. Ідеально підходять для пояснення піктограм, технічних термінів або дій в інтерфейсах.

Підказки шкодять чи допомагають SEO?

Що ж, як і для майже всього, відповідь завжди залежить від обставин. Хоча SEO-пуристи попереджають, що Google не любить "прихований" або замаскований контент і суворо карає за його використання, це було б крайністю у випадках зловживання , яке може "з'їсти" ваш контент. Однак, підказки, використані з певним балансом і мінімумом логіки, можуть бути корисними.

Переваги використання підказок

Загалом, ці повідомлення, якщо вони доброзичливі та ненав'язливі, можуть сприяти покращенню різних аспектів користувацького досвіду. Серед іншого, вони зменшують показник відмов і покращують доступність. Вони також можуть надати можливість використовувати додаткові ключові слова, які не вписуються в основний контент, що допомагає в семантичному SEO.

Крім того, вони можуть покращити показники кліків. Пропонуючи підказки в навігації або на кнопках заклику до дії, вони можуть ефективніше спрямовувати користувачів, що призводить до збільшення кількості кліків. Але для того, щоб все це стало можливим, необхідно дотримуватися кількох мінімальних рекомендацій.

Рекомендації щодо зовнішнього вигляду, змісту та експлуатації

  • Використання елементів HTML та атрибутів ARIA для забезпечення доступу до інформації, що міститься в них, для зчитувачів з екрану та пошукових систем.
  • Підказка повинна бути короткою. Очевидно, що ніхто не збирається читати величезну кількість інформації у спливаючому вікні, а ви охоплюєте значну частину контенту. Вона повинна містити мінімальну, точну і необхідну інформацію, яка не повинна бути критичною для користувача при виконанні або завершенні будь-якої дії.
  • Контент не повинен бути надлишковим або повторюватися, переконайтеся, що ви надаєте додаткову корисну та необхідну інформацію і що вона не повторюється у вашому контенті, щоб уникнути "дублюючого контенту".
  • Намагайтеся максимально уникати підказок, які зникають при наведенні курсору, або використовуйте їх лише в повідомленнях, які не містять багато інформації та/або контенту. В ідеалі, вони повинні відображатися при натисканні і закриватися при повторному натисканні в будь-якій точці екрана.
  • Переконайтеся, що вони розбірливі і мають правильний розмір.
  • Не додавайте двадцять різних дизайнів іконок підказок або посилань на підказки, це лише створює плутанину. Фіксований і послідовний дизайн допоможе відвідувачам ідентифікувати їх з першого погляду.
  • Не перестарайтеся, добре сплануйте свою стратегію, щоб додавати їх лише там, де, на вашу думку, вони полегшують доступ до релевантної та/або необхідної додаткової інформації.

Особливості та функціональні можливості коду

Для цього випадку було використано зображення у форматі .png з прозорим фоном.

Тут ви можете перевірити роботу кінцевого результату [tooltip text="Приклад підказки, що використовується в jrmora.com" position="auto"].

URL-адреса зображення додається між одинарними лапками в цьому рядку:

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

Якщо ви вирішите змінити код, щоб використовувати SVG HTML-іконку, як на цьому прикладі, ви зможете легше грати з кольором, фоном, товщиною і т.д.

Інтелектуальне автоматичне регулювання положення, щоб уникнути країв екрану. Тобто при наближенні до верхнього краю підказка відображається внизу, і так далі.

Повнофункціональні посилання можуть бути додані до підказки з настроюваними стилями. Хоча додавати посилання не рекомендується, можливо, що іноді вам доведеться це зробити. Якщо підказка містить посилання, вона автоматично приховується з затримкою в 200 мс, щоб полегшити натискання.

Безпечна підтримка HTML. Підтримує:

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

Позиційні, фіксовані та адаптивні атрибути.

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

Атрибути ARIA (aria-expanded, role="tooltip").

Оновлення. Додано aria-hidden="true" та role="presentation" до зображення, а також приховано декоративну іконку для зчитувачів з екрану.

Надмірності можна уникнути за допомогою aria-мітки, яка дозволяє кастомізувати текст, доступний за допомогою шорткоду.

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

Це рішення відповідає стандарту WCAG 2.1 AA і усуває попередження PageSpeed Insights про те, що кнопка не має доступної назви.

Адаптивний дизайн.

Адаптивність для мобільних пристроїв (перемикання за допомогою кліку).

Скидання в разі зміни розміру, повороту або зсуву

Основні класи CSS:

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

Ключові функції JS:

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

Приклади шорткодів:

[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>"]

З точки зору продуктивності:

  1. Попереднєзавантаження ресурсів: попередньо завантажені зображення та CSS.
  2. Ліниве завантаження: Атрибути loading="lazy" та decoding="async" для зображення.
  3. Умовне завантаження: JS завантажується лише тоді, коли використовується шорткод.
  4. Debounce: оптимізація подій зміни розміру та прокрутки.
  5. Оптимізовано CSS: використання зміни волі та сучасних одиниць (min()).
  6. Кешовані версії: Використовуйте filemtime(), щоб уникнути застарілого кешування.

Цей код я використовував для своїх конкретних потреб. Сприймайте його як відправну точку. Він може бути покращений. Ви навіть можете розглянути його без використання Javascript і адаптувати так, щоб він також міг застосовуватися до слів у контенті без показу іконки.

Щоб використовувати його, як завжди, просто додайте його до файлу functions.php та до папки assets/css/ і asstes/js/ вашого шаблону або дочірньої теми, якщо ви хочете зберегти зміни при оновленні вашого шаблону.

Код

Це структура файлів:

your-template/
├── functions.php (додайте PHP-код в кінці)
├── assets/
│ ├─── css/
│ │ └└── tooltip.css (стилі CSS)
│ └└└── js/
│ └└─── tooltip.js (JavaScript)

Код, який потрібно додати до шаблону 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 (має бути збережений за цим шляхом /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 (повинен бути збережений у шляху /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';
            });
        }
    });
});

Схожі статті

Este blog se aloja en LucusHost

LucusHost, el mejor hosting