إضافة تلميحات أدوات في ووردبريس بدون إضافات

Seleccionar idioma
إضافة تلميحات أدوات في ووردبريس بدون إضافات
مثال على تلميح الأداة المستخدم هنا

ليس لمصطلح تلميح الأدوات ترجمة فريدة إلى اللغة الإنجليزية، ويمكن وصفه بـ "تلميح الأدوات" أو "بالون المساعدة" أو "وصف منبثق" أو حتى "نص مساعدة" اعتمادًا على السياق الذي يستخدم فيه.

تلميح الأدوات هو عبارة عن رسالة منبثقة تظهر عند التفاعل مع عنصر ما، إما بالنقر عليه أو بتمرير الماوس. تُستخدم تلميحات الأدوات هذه لتوفير معلومات إضافية دون أن تشغل مساحة دائمة. مثالية لشرح الرموز أو المصطلحات التقنية أو الإجراءات في الواجهات.

هل تلميحات الأدوات تضر أم تفيد تحسين محركات البحث؟

حسناً، كما هو الحال بالنسبة لكل شيء تقريباً، فإن الإجابة دائماً تعتمد على ذلك. بينما يحذّر أنصار تحسين محركات البحث من أن جوجل لا يحب المحتوى "المخفي" أو المقنّع ويعاقب على استخدامه بقسوة، إلا أن هذا سيكون تطرفًا في حالات إساءة الاستخدام التي يمكن أن "تفكك" المحتوى الخاص بك. ومع ذلك، يمكن أن تكون تلميحات الأدوات، التي تُستخدم بتوازن معين وبحد أدنى من المنطق، مفيدة.

مزايا استخدام تلميحات الأدوات

بشكل عام، يمكن أن تساهم هذه الرسائل، إذا كانت ودية وغير مزعجة، في تحسين جوانب مختلفة من تجربة المستخدم. من بين أمور أخرى، فهي تقلل من معدلات الارتداد وتحسن إمكانية الوصول. كما يمكن أن توفر فرصًا لاستخدام كلمات رئيسية إضافية لا تتناسب بشكل طبيعي مع المحتوى الرئيسي، مما يساعد في تحسين محركات البحث الدلالية.

بالإضافة إلى ذلك، يمكنها تحسين معدلات النقر إلى الظهور. من خلال تقديم تلميحات الأدوات في التصفح أو أزرار الحث على اتخاذ إجراء، يمكنهم توجيه المستخدمين بشكل أكثر فعالية، مما يؤدي إلى ارتفاع معدلات النقر إلى الظهور. ولكن لكي يكون كل ذلك ممكنًا، يجب اتباع بعض الإرشادات الدنيا.

توصيات بشأن المظهر والمحتوى والتشغيل

  • استخدام عناصر HTML وسمات ARIA لضمان قدرة قارئات الشاشة ومحركات البحث على الوصول إلى المعلومات التي تحتويها.
  • يجب أن يكون تلميح الأدوات موجزًا. من الواضح أنه لا أحد سيقرأ كمًا هائلاً من المعلومات في نافذة منبثقة وستغطي جزءًا كبيرًا من المحتوى. يجب أن تحتوي على الحد الأدنى من المعلومات الدقيقة والضرورية، ويجب ألا يكون ذلك حرجًا للمستخدم عند تنفيذ أو إكمال إجراء ما.
  • يجب ألا يكون المحتوى زائدًا عن الحاجة أو مكررًا، تأكد من أنك تقدم معلومات إضافية مفيدة وضرورية وأنك لا تكرر المحتوى الخاص بك لتجنب "المحتوى المكرر".
  • حاول قدر الإمكان تجنب تلميحات الأدوات التي تختفي عند تحريك المؤشر أو استخدمها فقط في الرسائل التي لا تحتوي على الكثير من المعلومات و/أو المحتوى. من الناحية المثالية، يجب عرضها عند كل نقرة وإغلاقها عند النقر مرة أخرى في أي مكان على الشاشة.
  • احرص على أن تكون واضحة ومقروءة وبالحجم الصحيح.
  • لا تقم بإضافة عشرين تصميمًا مختلفًا لأيقونات تلميحات الأدوات أو روابط تلميحات الأدوات، فهذا لن يؤدي إلا إلى حدوث ارتباك. سيساعد التصميم الثابت والمتسق زوارك على التعرف عليها من الوهلة الأولى.
  • لا تبالغ في ذلك، خطط استراتيجيتك جيدًا لإضافتها فقط في الأماكن التي تعتقد أنها تسهل الوصول إلى المعلومات التكميلية ذات الصلة و/أو الضرورية.

ميزات ووظائف الكود

تم استخدام هذه الصورة.png ذات الخلفية الشفافة لهذه الحالة.

هنا يمكنك اختبار النتيجة النهائية التي تعمل [نص تلميح الأداة="مثال على تلميح الأداة المستخدم في jrmora.com" الموضع="تلقائي"].

تتم إضافة عنوان URL الخاص بالصورة بين علامتي الاقتباس المفردة في هذا السطر:

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

إذا اخترت تعديل الشيفرة لاستخدام أيقونة SVG HTML، مثل هذه الأيقونة، ستتمكن من التلاعب باللون والخلفية والسماكة وما إلى ذلك بسهولة أكبر.

تعديل الموضع التلقائي الذكي لتجنب حواف الشاشة. على سبيل المثال، عند الاقتراب من الحافة العلوية، يتم عرض تلميح الأداة في الأسفل و vivecersa.

يمكن إضافة روابط كاملة الوظائف داخل تلميح الأدوات مع أنماط قابلة للتخصيص. على الرغم من أنه لا يُنصح بإ ضافة روابط، إلا أنه من الممكن أن تحتاج إلى القيام بذلك في بعض الأحيان. في حالة احتواء تلميح الأدوات على رابط، هناك تأخير 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" والدور="عرض تقديمي" إلى الصورة وإخفاء الرمز الزخرفي لقارئات الشاشة.

يتم تجنب التكرار من خلال التسمية الآرية التي تسمح بتخصيص النص الذي يمكن الوصول إليه من الرمز المختصر.

[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 */

الوظائف الرئيسية للخدمات المشتركة:

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. تحميل كسول: سمات التحميلالبطيء: سمات التحميل="كسول" وفك التشفير="غير متزامن" للصورة.
  3. تحميل مشروط: يتم تحميل JS فقط عند استخدام الرمز القصير.
  4. Debounce: تحسين أحداث تغيير الحجم والتمرير.
  5. CSS المحسّن: استخدام وحدات تغيير الإرادة والوحدات الحديثة (min()).
  6. الإصدارات المخبأة مؤقتًا: استخدم filemtime() لتجنب التخزين المؤقت المتقادم.

هذا الرمز هو الرمز الذي استخدمته لاحتياجاتي الخاصة. افهمها كنقطة بداية. يمكن تحسينه. يمكنك حتى التفكير فيه دون استخدام جافا سكريبت وتكييفه بحيث يمكن تطبيقه أيضًا على الكلمات في المحتوى دون إظهار الرمز.

لاستخدامه، كما هو الحال دائمًا، ما عليك سوى إضافته إلى functions.php وفي مجلد assets/css/ و asstes/js/js/ في قالبك أو قالبك الفرعي إذا كنت تريد الاحتفاظ بالتغييرات عند تحديث قالبك.

الكود

هذه هي بنية الملفات:

القالب الخاص بك/
̄ ̄ وظائف.php (أضف كود PHP في النهاية)
̄ ̄ الأصول/
│ │ ─ ─ ─ css/
││تعريف │تعريف │تعريف ─تلميح الأدوات.css (أنماط CSS)
(التعليمات-التعليمات- js/
تلميحات الأدوات (جافا سكريبت)

رمز لإضافته إلى قالب الوظائف.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