Sei un recruiter? Clicca qui!
Tag cloud tridimensionale in WordPress senza plugin come crearla per i singoli articoli

Tag cloud tridimensionale in WordPress senza plugin: come crearla per i singoli articoli

Scritto da Sergio Pinna il

08/06/2026

Una tag cloud tridimensionale è una nuvola di tag animata, in cui le parole sembrano ruotare nello spazio come se fossero distribuite su una sfera. È un elemento visivo molto interessante per un blog, soprattutto quando vuoi dare più risalto agli argomenti trattati nel sito senza usare il classico elenco statico di tag.

In WordPress esistono diversi plugin per creare una tag cloud animata, ma spesso installare un plugin solo per questo effetto è eccessivo. Se usi un tema leggero come GeneratePress, magari insieme a GenerateBlocks, ha molto più senso creare una soluzione personalizzata, pulita e controllabile.

In questa guida vediamo come costruire una tag cloud 3D senza plugin, usando uno shortcode personalizzato. Lo snippet che andremo a creare ha tre caratteristiche importanti:

  1. viene visualizzato solo nei singoli articoli;
  2. permette di modificare facilmente la velocità di rotazione;
  3. preleva automaticamente i tag già presenti in WordPress.

Il risultato sarà una tag cloud dinamica, leggera, personalizzabile e inseribile dove vuoi all’interno del singolo articolo.

Perché creare una tag cloud 3D senza plugin

Quando si lavora su WordPress, la tentazione di installare un plugin per ogni piccola funzionalità è sempre dietro l’angolo. Il problema è che ogni plugin aggiunge codice, file CSS, JavaScript, impostazioni, possibili conflitti e, in alcuni casi, un impatto sulle prestazioni del sito.

Una tag cloud tridimensionale è un effetto abbastanza semplice da realizzare con poche righe di PHP, CSS e JavaScript. Non serve caricare un plugin dedicato, soprattutto se l’obiettivo è avere un sito veloce, ordinato e facile da mantenere.

Creandola manualmente possiamo decidere:

  • dove deve comparire;
  • quanti tag mostrare;
  • quanto deve essere veloce la rotazione;
  • quale tassonomia utilizzare;
  • che stile grafico darle;
  • se mostrarla solo negli articoli e non nelle pagine;
  • come integrarla nel layout del sito.

Questa è una soluzione particolarmente adatta per chi usa un tema come GeneratePress, perché permette di mantenere il sito leggero e modulare.

Cosa andremo a costruire

L’obiettivo è creare uno shortcode di questo tipo:

[sergio_tag_cloud_3d_]

Una volta inserito dentro un articolo, lo shortcode mostrerà automaticamente una tag cloud tridimensionale con i tag presenti nel sito WordPress.

Potremo anche personalizzarla in questo modo:

[sergio_tag_cloud_3d number="35" speed="0.003" radius="210"]

Dove:

  • number indica il numero massimo di tag da mostrare;
  • speed controlla la velocità di rotazione;
  • radius controlla la grandezza della sfera tridimensionale.

Lo shortcode funzionerà solo nei singoli articoli. Questo significa che anche se per errore lo inserisci in una pagina, in un archivio o in un altro contesto, non verrà stampato nulla.

Dove inserire il codice in WordPress

Per aggiungere questa funzionalità possiamo usare il plugin Code Snippets, oppure inserirla nel file functions.php del tema child.

Personalmente, per questo tipo di personalizzazioni, consiglio di usare Code Snippets, perché è più ordinato e permette di attivare o disattivare facilmente il codice senza modificare direttamente i file del tema.

Il percorso è questo:

  1. vai nella dashboard di WordPress;
  2. entra in Snippet > Aggiungi nuovo;
  3. assegna un nome allo snippet, per esempio “Tag cloud 3D articoli”;
  4. incolla il codice completo;
  5. imposta l’esecuzione sul frontend;
  6. salva e attiva lo snippet.

Lo snippet completo per creare la tag cloud 3D

Questo è il codice completo da inserire in WordPress:

add_shortcode('sergio_tag_cloud_3d', 'sergio_tag_cloud_3d_shortcode');

function sergio_tag_cloud_3d_shortcode($atts) {

    if (is_admin() || !is_singular('post')) {
        return '';
    }

    static $assets_printed = false;

    $atts = shortcode_atts(
        array(
            'number'   => 30,
            'taxonomy' => 'post_tag',
            'speed'    => 0.0025,
            'radius'   => 0,
        ),
        $atts,
        'sergio_tag_cloud_3d'
    );

    $number   = max(5, min(80, absint($atts['number'])));
    $taxonomy = sanitize_key($atts['taxonomy']);
    $speed    = floatval($atts['speed']);
    $radius   = absint($atts['radius']);

    if (!taxonomy_exists($taxonomy)) {
        $taxonomy = 'post_tag';
    }

    $terms = get_terms(
        array(
            'taxonomy'   => $taxonomy,
            'hide_empty' => true,
            'number'     => $number,
            'orderby'    => 'count',
            'order'      => 'DESC',
        )
    );

    if (is_wp_error($terms) || empty($terms)) {
        return '<p class="sergio-tag-cloud-3d-empty">Non ci sono ancora tag da mostrare.</p>';
    }

    $counts = wp_list_pluck($terms, 'count');
    $min_count = min($counts);
    $max_count = max($counts);

    $uid = wp_unique_id('sergio-tag-cloud-3d-');

    $output = '';

    if (!$assets_printed) {
        $assets_printed = true;

        $output .= '
<style>
.sergio-tag-cloud-3d {
    position: relative;
    min-height: 300px;
    height: min(56vw, 300px);
    overflow: hidden;
    perspective: 1000px;
    isolation: isolate;
    cursor: grab;
    user-select: none;
    touch-action: none;
    padding: 0;
    width: 100%;
    max-width: 530px;
}

.sergio-tag-cloud-3d.is-dragging {
    cursor: grabbing;
}

.sergio-tag-cloud-3d::before {
    content: "";
    position: absolute;
    inset: 12%;
    border-radius: 999px;
    background: radial-gradient(circle, rgba(30,41,70,0.08), transparent 62%);
    z-index: 0;
    pointer-events: none;
}

.sergio-tag-cloud-3d__sphere {
    position: absolute;
    inset: 0;
    transform-style: preserve-3d;
    z-index: 1;
}

.sergio-tag-cloud-3d__item {
    position: absolute;
    top: 50%;
    left: 50%;
    display: inline-flex !important;
    width: auto;
    align-items: center;
    justify-content: center;
    padding: 0.48rem 0.78rem;
    border-radius: 999px;
    font-size: clamp(8px, var(--sergio-tag-size), 12px);
    font-family: Arial, sans-serif;
    line-height: 1;
    font-weight: normal;
    text-decoration: none;
    white-space: nowrap;
    color: #1E2946;
    background: rgba(255, 255, 255, 1);
    border: 1px solid rgba(255, 255, 255, 0.25);
    backface-visibility: hidden;
    will-change: transform, opacity, filter;
    transition:
        color 0.25s ease,
        background-color 0.25s ease,
        border-color 0.25s ease,
        box-shadow 0.25s ease;
}

.sergio-tag-cloud-3d__item:hover,
.sergio-tag-cloud-3d__item:focus-visible {
    color: #041133;
    background: #fff;
    border: 1px solid rgba(255, 255, 255, 0.25);
    box-shadow: 0px 0px 5px #ffffff2e;
    outline: none;
}

.sergio-tag-cloud-3d__item:hover::before {
    display: none;
}

.sergio-tag-cloud-3d-empty {
    padding: 1rem;
    border-radius: 12px;
    background: #f5f5f5;
}

@media (max-width: 768px) {
    .sergio-tag-cloud-3d {
        min-height: 340px;
        border-radius: 22px;
        max-width: 100%;
    }

    .sergio-tag-cloud-3d__item {
        padding: 0.42rem 0.64rem;
        font-size: clamp(11px, var(--sergio-tag-size), 16px);
    }
}

@media (prefers-reduced-motion: reduce) {
    .sergio-tag-cloud-3d__item {
        transition: none;
    }
}
</style>

<script>
(function () {
    if (window.sergioTagCloud3DLoaded) {
        return;
    }

    window.sergioTagCloud3DLoaded = true;

    function initCloud(cloud) {
        if (!cloud || cloud.dataset.sergioReady === "1") {
            return;
        }

        cloud.dataset.sergioReady = "1";

        var sphere = cloud.querySelector(".sergio-tag-cloud-3d__sphere");
        var items = Array.prototype.slice.call(cloud.querySelectorAll(".sergio-tag-cloud-3d__item"));

        if (!sphere || !items.length) {
            return;
        }

        var prefersReducedMotion = window.matchMedia &&
            window.matchMedia("(prefers-reduced-motion: reduce)").matches;

        var cloudWidth = cloud.clientWidth;
        var cloudHeight = cloud.clientHeight;

        var customRadius = parseFloat(cloud.dataset.radius);
        var radius = customRadius > 0 ? customRadius : Math.min(cloudWidth, cloudHeight) / 2.45;

        var speed = parseFloat(cloud.dataset.speed) || 0.0025;

        var rotationX = 0;
        var rotationY = 0;

        var targetX = 0.25;
        var targetY = -0.35;

        var points = [];

        var isPointerDown = false;
        var isDragging = false;

        var dragStartX = 0;
        var dragStartY = 0;

        var lastX = 0;
        var lastY = 0;

        var lastDeltaX = 0;
        var lastDeltaY = 0;

        var dragThreshold = 6;
        var dragSensitivity = 0.008;

        function clamp(value, min, max) {
            return Math.max(min, Math.min(max, value));
        }

        function buildSphere() {
            cloudWidth = cloud.clientWidth;
            cloudHeight = cloud.clientHeight;

            customRadius = parseFloat(cloud.dataset.radius);
            radius = customRadius > 0 ? customRadius : Math.min(cloudWidth, cloudHeight) / 2.45;

            if (window.innerWidth < 768) {
                radius = Math.min(cloudWidth, cloudHeight) / 2.75;
            }

            points = items.map(function (item, index) {
                var total = items.length;
                var phi = Math.acos(-1 + (2 * index + 1) / total);
                var theta = Math.sqrt(total * Math.PI) * phi;

                return {
                    item: item,
                    x: radius * Math.cos(theta) * Math.sin(phi),
                    y: radius * Math.sin(theta) * Math.sin(phi),
                    z: radius * Math.cos(phi)
                };
            });
        }

        function render() {
            var sinX = Math.sin(rotationX);
            var cosX = Math.cos(rotationX);
            var sinY = Math.sin(rotationY);
            var cosY = Math.cos(rotationY);

            points.forEach(function (point) {
                var y1 = point.y * cosX - point.z * sinX;
                var z1 = point.y * sinX + point.z * cosX;

                var x2 = point.x * cosY + z1 * sinY;
                var z2 = -point.x * sinY + z1 * cosY;

                var scale = (z2 + radius) / (2 * radius);
                var finalScale = 0.62 + scale * 0.58;
                var opacity = 0.32 + scale * 0.68;
                var blur = (1 - scale) * 1.1;

                point.item.style.transform =
                    "translate3d(" + x2 + "px, " + y1 + "px, " + z2 + "px) translate(-50%, -50%) scale(" + finalScale + ")";

                point.item.style.opacity = opacity.toFixed(3);
                point.item.style.filter = "blur(" + blur.toFixed(2) + "px)";
                point.item.style.zIndex = Math.round(scale * 1000);
            });
        }

        function animate() {
            if (prefersReducedMotion) {
                render();
                return;
            }

            rotationX += targetX * speed;
            rotationY += targetY * speed;

            render();

            window.requestAnimationFrame(animate);
        }

        cloud.addEventListener("pointerdown", function (event) {
            if (event.pointerType === "mouse" && event.button !== 0) {
                return;
            }

            isPointerDown = true;
            isDragging = false;

            dragStartX = event.clientX;
            dragStartY = event.clientY;

            lastX = event.clientX;
            lastY = event.clientY;

            lastDeltaX = 0;
            lastDeltaY = 0;

            targetX = 0;
            targetY = 0;
        });

        cloud.addEventListener("pointermove", function (event) {
            if (!isPointerDown) {
                var rect = cloud.getBoundingClientRect();

                var relativeX = (event.clientX - rect.left) / rect.width - 0.5;
                var relativeY = (event.clientY - rect.top) / rect.height - 0.5;

                targetY = relativeX * 1.6;
                targetX = -relativeY * 1.6;

                return;
            }

            var totalDeltaX = event.clientX - dragStartX;
            var totalDeltaY = event.clientY - dragStartY;

            if (
                !isDragging &&
                (
                    Math.abs(totalDeltaX) > dragThreshold ||
                    Math.abs(totalDeltaY) > dragThreshold
                )
            ) {
                isDragging = true;
                cloud.classList.add("is-dragging");

                if (cloud.setPointerCapture) {
                    try {
                        cloud.setPointerCapture(event.pointerId);
                    } catch (error) {}
                }
            }

            if (!isDragging) {
                return;
            }

            var deltaX = event.clientX - lastX;
            var deltaY = event.clientY - lastY;

            lastDeltaX = deltaX;
            lastDeltaY = deltaY;

            rotationY += deltaX * dragSensitivity;

            /*
             * Movimento verticale corretto:
             * trascini verso su, la nuvola segue verso su;
             * trascini verso giù, la nuvola segue verso giù.
             */
            rotationX -= deltaY * dragSensitivity;

            lastX = event.clientX;
            lastY = event.clientY;

            render();

            event.preventDefault();
        });

        function stopDragging(event) {
            if (!isPointerDown) {
                return;
            }

            var wasDragging = isDragging;

            isPointerDown = false;
            isDragging = false;

            cloud.classList.remove("is-dragging");

            if (wasDragging) {
                targetY = clamp(lastDeltaX * 0.22, -2, 2);

                /*
                 * Inerzia verticale coerente con il gesto del trascinamento.
                 */
                targetX = clamp(-lastDeltaY * 0.22, -2, 2);

                cloud.dataset.dragged = "1";

                setTimeout(function () {
                    cloud.dataset.dragged = "0";
                }, 160);
            } else {
                targetX = 0.25;
                targetY = -0.35;
            }

            if (cloud.releasePointerCapture) {
                try {
                    cloud.releasePointerCapture(event.pointerId);
                } catch (error) {}
            }
        }

        cloud.addEventListener("pointerup", stopDragging);
        cloud.addEventListener("pointercancel", stopDragging);

        cloud.addEventListener("pointerleave", function () {
            if (isPointerDown || isDragging) {
                return;
            }

            targetX = 0.25;
            targetY = -0.35;
        });

        cloud.addEventListener("click", function (event) {
            if (cloud.dataset.dragged !== "1") {
                return;
            }

            event.preventDefault();
            event.stopPropagation();
        }, true);

        window.addEventListener("resize", function () {
            buildSphere();
            render();
        });

        buildSphere();
        render();
        animate();
    }

    function initAllClouds() {
        document.querySelectorAll(".sergio-tag-cloud-3d").forEach(initCloud);
    }

    if (document.readyState === "loading") {
        document.addEventListener("DOMContentLoaded", initAllClouds);
    } else {
        initAllClouds();
    }
})();
</script>
';
    }

    $output .= '<div id="' . esc_attr($uid) . '" class="sergio-tag-cloud-3d" data-speed="' . esc_attr($speed) . '" data-radius="' . esc_attr($radius) . '" aria-label="Tag cloud 3D">';
    $output .= '<div class="sergio-tag-cloud-3d__sphere">';

    foreach ($terms as $term) {
        $term_link = get_term_link($term);

        if (is_wp_error($term_link)) {
            continue;
        }

        if ($max_count > $min_count) {
            $size = 0.78 + (($term->count - $min_count) / ($max_count - $min_count)) * 0.42;
        } else {
            $size = 0.95;
        }

        $output .= '<a class="sergio-tag-cloud-3d__item" href="' . esc_url($term_link) . '" style="--sergio-tag-size: ' . esc_attr(round($size, 2)) . 'rem;" data-count="' . esc_attr($term->count) . '">';
        $output .= esc_html($term->name);
        $output .= '</a>';
    }

    $output .= '</div>';
    $output .= '</div>';

    return $output;
}

Come usare lo shortcode nell’articolo

Dopo aver salvato e attivato lo snippet, puoi inserire la tag cloud direttamente dentro un articolo usando questo shortcode:

[sergio_tag_cloud_3d]

Puoi inserirlo in un blocco Shortcode di Gutenberg, oppure in un blocco HTML, oppure in un punto specifico del contenuto dove vuoi far comparire la nuvola.

La cosa importante è che lo shortcode è protetto da questa condizione:

if (is_admin() || !is_singular('post')) {
    return '';
}

Questa riga dice a WordPress:

“Mostra la tag cloud solo nel frontend e solo se siamo dentro un singolo articolo”.

Quindi la cloud non apparirà:

  • nella home;
  • nella pagina blog;
  • nelle pagine statiche;
  • negli archivi categoria;
  • negli archivi tag;
  • nelle pagine autore;
  • nei risultati di ricerca.

Questo è utile perché evita di caricare un elemento animato in zone del sito dove non serve.

Come modificare la velocità di rotazione

Uno degli aspetti più comodi dello shortcode è che puoi modificare la velocità direttamente dall’articolo, senza toccare il codice PHP.

Per esempio:

[sergio_tag_cloud_3d speed="0.0015"]

In questo caso la rotazione sarà più lenta.

Se invece vuoi una cloud più dinamica:

[sergio_tag_cloud_3d speed="0.004"]

Il valore predefinito è:

0.0025

Il mio consiglio è di non esagerare. Una tag cloud troppo veloce può diventare fastidiosa, soprattutto se si trova dentro un articolo lungo. Meglio un movimento morbido, elegante, quasi di sottofondo.

Una buona fascia di valori può essere questa:

0.0015 = molto lenta
0.0025 = equilibrata
0.0035 = più dinamica
0.0050 = abbastanza veloce

Dal punto di vista dell’esperienza utente, una rotazione lenta è quasi sempre la scelta migliore.

Come modificare il numero di tag mostrati

Di base lo shortcode mostra massimo 30 tag:

Di base lo shortcode mostra massimo 30 tag:

Ma puoi cambiare il numero direttamente nello shortcode:

[sergio_tag_cloud_3d_ number="20"]

Oppure:

[sergio_tag_cloud_3d_ number="40"]

Nel codice ho inserito un limite minimo e massimo:

$number = max(5, min(80, absint($atts['number'])));

Questo significa che la cloud mostrerà sempre almeno 5 tag e al massimo 80 tag.

Il limite massimo serve per evitare di creare una nuvola troppo pesante o troppo affollata. Tecnicamente potresti mostrare anche più tag, ma visivamente non avrebbe molto senso. Una tag cloud funziona bene quando è leggibile, non quando diventa una massa confusa di parole.

Per un blog normale, io resterei tra 20 e 40 tag.

Come modificare la dimensione della sfera

Lo shortcode permette anche di controllare il raggio della sfera tridimensionale.

Esempio:

[sergio_tag_cloud_3d radius="220"]

Se non inserisci nessun valore, il codice calcola automaticamente il raggio in base alla dimensione del contenitore:

'radius' => 0,

Questa è solitamente la soluzione migliore, perché rende la tag cloud più adattabile ai vari dispositivi.

Se però vuoi una sfera più ampia o più compatta, puoi usare il parametro radius.

Esempio con sfera più compatta:

[sergio_tag_cloud_3d_ radius="170"]

Esempio con sfera più larga:

[sergio_tag_cloud_3d_ radius="240"]

Anche qui vale la stessa logica: meglio non esagerare. Su mobile, una cloud troppo grande potrebbe diventare meno comoda da visualizzare.

Come vengono prelevati automaticamente i tag di WordPress

La parte che recupera automaticamente i tag è questa:

$terms = get_terms(
    array(
        'taxonomy'   => $taxonomy,
        'hide_empty' => true,
        'number'     => $number,
        'orderby'    => 'count',
        'order'      => 'DESC',
    )
);

WordPress recupera i termini della tassonomia post_tag, cioè i normali tag degli articoli.

Il parametro:

'hide_empty' => true

serve a mostrare solo i tag realmente utilizzati da almeno un articolo.

Il parametro:

'orderby' => 'count'
'orderby' => 'count'

ordina i tag in base al numero di articoli associati. In pratica, i tag più usati vengono presi per primi.

Questo rende la tag cloud più utile, perché mette in evidenza gli argomenti principali del blog.

Come usare una tassonomia diversa dai tag

Di base lo shortcode lavora con i tag standard di WordPress:

post_tag

Però il codice è stato scritto in modo flessibile. Volendo, puoi passare anche una tassonomia diversa.

Per esempio, se vuoi usare le categorie:

[sergio_tag_cloud_3d taxonomy="category"]

In questo caso la cloud non mostrerà i tag, ma le categorie.

Personalmente, però, per una tag cloud tridimensionale ha più senso usare i tag. Le categorie hanno di solito una struttura più ordinata e meno numerosa, mentre i tag sono più adatti a essere rappresentati come una nuvola di argomenti.

Come personalizzare lo stile grafico

La parte grafica della tag cloud è gestita dal CSS incluso nello snippet.

Il contenitore principale è questo:

.sergio-tag-cloud-3d {
    position: relative;
    width: 100%;
    margin: 40px auto;
    padding: 28px;
    overflow: hidden;
    border-radius: 24px;
    background:
        radial-gradient(circle at top left, rgba(255,255,255,0.16), transparent 35%),
        linear-gradient(135deg, #111827, #1f2937);
    box-shadow: 0 18px 45px rgba(0,0,0,0.18);
}

Qui puoi modificare:

  • il margine esterno;
  • il padding interno;
  • il bordo arrotondato;
  • il colore di sfondo;
  • l’ombra;
  • l’effetto grafico generale.

Per esempio, se vuoi una cloud più chiara, puoi sostituire lo sfondo scuro con qualcosa di più neutro:

background: linear-gradient(135deg, #f8fafc, #e5e7eb);

In quel caso, però, dovresti cambiare anche il colore dei link:

color: #111827;

Se invece vuoi mantenere un aspetto più “tech”, lo sfondo scuro funziona molto bene, soprattutto per articoli dedicati a WordPress, CSS, JavaScript o sviluppo web.

Come funziona l’effetto tridimensionale

L’effetto 3D non è generato da librerie esterne. È il JavaScript dello snippet a distribuire i tag su una sfera immaginaria.

Ogni tag riceve tre coordinate:

item.dataset.x
item.dataset.y
item.dataset.z

Queste coordinate rappresentano la posizione del tag nello spazio.

Poi, a ogni frame dell’animazione, il codice aggiorna la posizione degli elementi ruotandoli sugli assi X e Y. In questo modo i tag sembrano muoversi in profondità.

La profondità viene simulata anche con due accorgimenti:

item.style.opacity = opacity;
item.style.zIndex = Math.round(z2 + radius);

I tag più vicini risultano più visibili, mentre quelli più lontani diventano leggermente più trasparenti. Lo z-index, invece, aiuta a sovrapporre correttamente gli elementi.

Il risultato è una nuvola di tag che dà l’impressione di essere tridimensionale pur rimanendo molto leggera.

Interazione con il mouse

La tag cloud ruota automaticamente, ma cambia comportamento quando l’utente passa sopra con il mouse.

Questa parte del codice intercetta il movimento del puntatore:

wrapper.addEventListener('pointermove', function (event) {
    const rect = wrapper.getBoundingClientRect();

    pointerX = ((event.clientX - rect.left) / rect.width) - 0.5;
    pointerY = ((event.clientY - rect.top) / rect.height) - 0.5;

    isPointerInside = true;
});

Quando il puntatore entra nell’area della cloud, la rotazione viene influenzata dalla posizione del mouse. Questo rende l’elemento più interattivo e piacevole da usare.

Quando il puntatore esce, la cloud torna alla rotazione automatica:

wrapper.addEventListener('pointerleave', function () {
    isPointerInside = false;
});

È un piccolo dettaglio, ma migliora molto la percezione dell’effetto.

Attenzione alla leggibilità

Una tag cloud 3D deve essere bella, ma deve restare leggibile.

Per questo motivo conviene evitare:

  • troppi tag;
  • velocità eccessiva;
  • font troppo piccoli;
  • contrasto basso;
  • sfondi troppo elaborati;
  • animazioni troppo aggressive.

L’animazione deve accompagnare il contenuto, non distrarre il lettore.

Dentro un articolo, la tag cloud può funzionare bene:

  • dopo l’introduzione;
  • a metà articolo come elemento visivo;
  • prima della conclusione;
  • dopo il contenuto, come invito a esplorare altri argomenti.

Io eviterei di metterla subito all’inizio dell’articolo, perché rischia di rubare attenzione al testo principale. Meglio inserirla dopo qualche paragrafo, quando l’utente ha già iniziato a leggere.

Prestazioni e caricamento

Un aspetto importante dello snippet è che CSS e JavaScript vengono stampati una sola volta.

Questa riga:

static $assets_printed = false;

serve proprio a evitare che gli asset vengano duplicati se, per qualche motivo, lo shortcode viene usato più volte nello stesso articolo.

Inoltre, grazie alla condizione iniziale:

if (is_admin() || !is_singular('post')) {
    return '';
}

il codice non viene caricato in pagine dove non serve.

Questo è particolarmente utile se stai cercando di mantenere WordPress leggero e performante. Una personalizzazione di questo tipo, se usata con criterio, ha un impatto molto contenuto.

Accessibilità e movimento ridotto

Nel codice è presente anche un controllo per gli utenti che hanno impostato sul dispositivo la preferenza per il movimento ridotto:

const reduceMotion = window.matchMedia(‘(prefers-reduced-motion: reduce)’).matches;

Se l’utente preferisce ridurre le animazioni, la velocità viene portata a zero:

const baseSpeed = reduceMotion ? 0 : parseFloat(wrapper.dataset.speed || '0.0025');

Questo è un dettaglio importante, perché non tutti gli utenti apprezzano gli elementi animati. Alcune persone possono trovare fastidiose le animazioni continue, soprattutto se molto evidenti.

Inserire questa attenzione rende la soluzione più professionale e più rispettosa dell’esperienza utente.

Esempi pratici di shortcode

Cloud standard:

[sergio_tag_cloud_3d]

Cloud più lenta:

[sergio_tag_cloud_3d speed="0.0015"]

Cloud più veloce:

[sergio_tag_cloud_3d speed="0.004"]

Cloud con 20 tag:

[sergio_tag_cloud_3d number="20"]

Cloud con 40 tag e rotazione lenta:

[sergio_tag_cloud_3d number="40" speed="0.0018"]

Cloud con raggio personalizzato:

[sergio_tag_cloud_3d number="35" speed="0.0025" radius="220"]

Cloud basata sulle categorie invece che sui tag:

[sergio_tag_cloud_3d taxonomy="category"]

Dove conviene inserirla nel layout dell’articolo

Una tag cloud tridimensionale non dovrebbe essere usata solo perché “fa effetto”. Deve avere una funzione.

Può essere utile per:

  • far scoprire altri argomenti del blog;
  • aumentare la navigazione interna;
  • rendere più visibili i tag principali;
  • creare un elemento grafico diverso dentro articoli lunghi;
  • invitare l’utente a esplorare contenuti collegati.

Dal punto di vista del layout, io la inserirei dopo una sezione introduttiva, magari con un piccolo titolo prima dello shortcode.

Esempio:

<h2>Esplora gli argomenti del blog</h2>
<p>Qui trovi alcuni dei tag più utilizzati negli articoli pubblicati sul sito.</p>

[sergio_tag_cloud_3d number="30" speed="0.0025"]

In questo modo la tag cloud non appare come un elemento buttato lì, ma come una parte coerente del contenuto.

Conclusione

Creare una tag cloud tridimensionale in WordPress senza plugin è un ottimo modo per aggiungere un elemento dinamico al blog senza appesantire il sito.

Con uno shortcode personalizzato possiamo ottenere una soluzione flessibile, leggera e facile da gestire. La cloud viene mostrata solo nei singoli articoli, recupera automaticamente i tag presenti in WordPress e permette di modificare velocità, numero di tag e dimensione direttamente dallo shortcode.

Il vantaggio principale è il controllo. Non dipendiamo da plugin esterni, non carichiamo funzioni inutili e possiamo adattare lo stile al design del nostro sito.

Per un blog tecnico, un portfolio professionale o un sito costruito con GeneratePress e GenerateBlocks, questo tipo di soluzione è perfetta: semplice, pulita e completamente personalizzabile.

Potrebbe interessarti anche...

Come creare uno slider con GeneratePress e GenerateBlocks senza usare page builder pesanti

Come creare uno slider con GeneratePress e GenerateBlocks senza usare page builder pesanti

01/06/2026

Creare uno slider con GeneratePress e GenerateBlocks aggiunge dinamismo senza plugin pesanti. Lo costruiremo con Container, classi CSS, pulsanti e JavaScript leggero per scorrere le slide, mantenendolo responsive e modificabile da WordPress.

Leggi l'articolo
Timeline in HTML e CSS: creare una linea temporale responsive senza plugin

Timeline in HTML e CSS: creare una linea temporale responsive senza plugin

25/05/2026

Scopri come creare una timeline responsive in HTML e CSS senza usare plugin. In questa guida vediamo passo passo come costruire una linea temporale verticale, con card alternate su desktop e layout ottimizzato per mobile, utile per raccontare la storia di un progetto, le fasi di un servizio o il percorso professionale di una persona.

Leggi l'articolo
Accessibilità web in WordPress: come progettare siti più inclusivi, usabili e conformi agli standard italiani ed europei

Accessibilità web in WordPress: come progettare siti più inclusivi, usabili e conformi agli standard italiani ed europei

20/05/2026

L’accessibilità web in WordPress non è un dettaglio tecnico da sistemare alla fine, ma un elemento fondamentale nella progettazione di un sito professionale. Un sito accessibile è più inclusivo, più chiaro, più usabile e spesso anche più efficace per SEO, conversioni e qualità dell’esperienza utente.

Leggi l'articolo

Hai una domanda su questo articolo?

Scrivimi pure nei commenti: ti risponderò il prima possibile con un suggerimento pratico.

...aspetta un attimo!

Hai un’idea per un sito, una pagina da migliorare o un progetto ancora da mettere a fuoco? Raccontamelo: possiamo capire insieme da dove partire.

Parlami della tua idea