Tutorial WordPress: Mostrar reseñas como tarjetas con estrella CSS y accesibles

·

·

Introducción

Este tutorial explica, paso a paso y con todo lujo de detalles, cómo mostrar reseñas (reviews) en WordPress como tarjetas visuales tipo card con valoración por estrellas usando CSS, garantizando además la accesibilidad para personas que usan lectores de pantalla y dispositivos de asistencia. Incluye ejemplos completos de PHP (para integrar con WordPress), HTML de plantilla y CSS listo para usar. Todos los fragmentos de código se entregan en bloques listos para pegar en un tema o plugin.

Resumen de la solución

La solución propone:

Requisitos y decisiones de diseño

1) Registrar el Custom Post Type (opcional)

Si prefieres almacenar reseñas como un custom post type en lugar de usar comentarios o campos globales, añade este código a functions.php o a un plugin personalizado.

/ Registrar CPT review /
function my_reviews_post_type() {
    labels = array(
        name               =gt Reseñas,
        singular_name      =gt Reseña,
        add_new_item       =gt Añadir nueva reseña,
        edit_item          =gt Editar reseña,
    )
    args = array(
        labels             =gt labels,
        public             =gt true,
        has_archive        =gt false,
        show_in_rest       =gt true,
        supports           =gt array(title,editor,author,custom-fields),
        menu_position      =gt 20,
        menu_icon          =gt dashicons-star-filled,
    )
    register_post_type(review, args)
}
add_action(init, my_reviews_post_type)

Guarda la valoración (rating) como post meta con clave rating (valor numérico entre 0 y 5). Puedes usar un metabox o ACF para gestionarlo en el editor.

2) Shortcode para mostrar las tarjetas

Este shortcode consulta reseñas y devuelve una rejilla de tarjetas. Cada tarjeta incluye título, contenido, autor, fecha y la representación visual y textual de la valoración.

/ Shortcode [reviews_cards] /
function my_reviews_cards_shortcode(atts) {
    atts = shortcode_atts(array(
        posts_per_page =gt 6,
    ), atts, reviews_cards)

    query = new WP_Query(array(
        post_type =gt review,
        posts_per_page =gt intval(atts[posts_per_page]),
        post_status =gt publish,
    ))

    if ( ! query-gthave_posts() ) {
        return ltpgtNo hay reseñas disponibles.lt/pgt
    }

    output = ltdiv class=reviews-grid role=listgt
    while ( query-gthave_posts() ) {
        query-gtthe_post()
        rating = floatval(get_post_meta(get_the_ID(), rating, true))
        if (rating gt 5) rating = 5
        if (rating lt 0) rating = 0
        rating_text = sprintf(%s de 5, rating)
        rating_pct = round((rating / 5)  100, 2)

        output .= ltarticle class=review-card role=listitemgt
        output .= lth3 class=review-titlegt . esc_html(get_the_title()) . lt/h3gt
        output .= ltdiv class=review-metagtltspan class=review-authorgt . esc_html(get_the_author()) . lt/spangt • lttime datetime= . get_the_date(c) . gt . get_the_date() . lt/timegtlt/divgt
        output .= ltdiv class=review-contentgt . wp_kses_post(get_the_excerpt()) . lt/divgt

        // Estrellas accesibles: capa visual   texto para lectores de pantalla
        output .= ltdiv class=rating aria-label= . esc_attr(rating_text) . gt
        output .= ltspan class=stars aria-hidden=truegt
        output .= ltspan class=stars-fill style=width: . esc_attr(rating_pct) . %gtlt/spangt
        output .= lt/spangt // .stars
        output .= ltspan class=sr-onlygt . esc_html(rating_text) . lt/spangt
        output .= lt/divgt // .rating

        output .= lt/articlegt
    }
    wp_reset_postdata()
    output .= lt/divgt

    return output
}
add_shortcode(reviews_cards, my_reviews_cards_shortcode)

3) HTML de ejemplo de una tarjeta (salida esperada)

Este es el HTML que genera cada tarjeta. Se incluye para que puedas integrarlo directamente en plantillas si lo prefieres.

ltarticle class=review-card role=listitemgt
  lth3 class=review-titlegtExcelente productolt/h3gt
  ltdiv class=review-metagtltspan class=review-authorgtMaría Lópezlt/spangt • lttime datetime=2025-09-01gt1 sept 2025lt/timegtlt/divgt
  ltdiv class=review-contentgtMuy buena experiencia, entrega rápida y atención impecable.lt/divgt

  ltdiv class=rating aria-label=4 de 5gt
    ltspan class=stars aria-hidden=truegt
      ltspan class=stars-fill style=width:80%gtlt/spangt
    lt/spangt
    ltspan class=sr-onlygt4 de 5lt/spangt
  lt/divgt
lt/articlegt

4) CSS recomendado

Este CSS proporciona apariencia de tarjeta, rejilla responsiva, y la lógica visual de estrellas: un texto con 5 estrellas grises y una capa dorada recortada por ancho para simular la puntuación (incluyendo medias estrellas).

/ Rejilla de tarjetas /
.reviews-grid {
  display: grid
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr))
  gap: 1.25rem
  margin: 0
  padding: 0
}

/ Tarjeta /
.review-card {
  background: #ffffff
  border: 1px solid #e6e6e6
  border-radius: 8px
  padding: 1rem
  box-shadow: 0 1px 3px rgba(0,0,0,0.04)
}

/ Meta y contenido /
.review-title { font-size: 1.05rem margin: 0 0 0.25rem }
.review-meta { font-size: 0.86rem color: #666 margin-bottom: 0.6rem }
.review-content { font-size: 0.95rem color: #333 margin-bottom: 0.8rem }

/ Estrellas: base con 5 estrellas grises /
.stars {
  display: inline-block
  font-size: 1.125rem
  line-height: 1
  position: relative
  color: #d1d1d1 / color de estrellas vacías /
  font-family: Helvetica Neue, Arial, sans-serif
}
/ Creamos las estrellas visibles con pseudoelemento /
.stars::before {
  content: ★★★★★
  letter-spacing: 3px
  display: inline-block
}

/ Capa que representa el relleno (estrellas doradas) /
.stars-fill {
  display: block
  position: absolute
  top: 0
  left: 0
  white-space: nowrap
  overflow: hidden
  color: #f5a623 / color de estrellas llenas (dorado) /
  pointer-events: none
}
.stars-fill::before {
  content: ★★★★★
  letter-spacing: 3px
  display: inline-block
}

/ Asegurar que .stars tenga el ancho del texto de 5 estrellas /
.stars { width: 5.2ch }

/ Texto solo para lectores de pantalla /
.sr-only {
  position: absolute !important
  height: 1px width: 1px
  overflow: hidden
  clip: rect(1px, 1px, 1px, 1px)
  white-space: nowrap
  border: 0
  padding: 0
  margin: -1px
}

/ Accesibilidad visual: foco visible para teclado /
.review-card:focus-within, .review-card:focus {
  outline: 3px solid rgba(37,99,235,0.15)
  outline-offset: 3px
}

/ Contraste alto para quienes lo necesiten /
@media (prefers-contrast: more) {
  .review-card { border-color: #000 background: #fff }
  .review-title, .review-content { color: #000 }
}

5) JavaScript opcional (para casos dinámicos)

Normalmente no hace falta JavaScript para renderizar las estrellas si el servidor ya inyecta el ancho en la capa .stars-fill. Si las valoraciones se obtienen vía AJAX o quieres animaciones, puedes usar este pequeño script que convierte un atributo data-rating a un ancho.

/ Ejemplo simple: buscar elementos con data-rating y ajustar .stars-fill /
document.addEventListener(DOMContentLoaded, function(){
  document.querySelectorAll(.rating[data-rating]).forEach(function(el){
    var rating = parseFloat(el.getAttribute(data-rating))  0
    if (rating lt 0) rating = 0
    if (rating gt 5) rating = 5
    var pct = (rating / 5)  100
    var fill = el.querySelector(.stars-fill)
    if (fill) fill.style.width = pct   %
    // actualizar aria-label
    el.setAttribute(aria-label, rating    de 5)
  })
})

6) Buenas prácticas de accesibilidad aplicadas

  1. Texto alternativo: la valoración numérica aparece como texto dentro de .sr-only y también en aria-label del contenedor visual, así lectores de pantalla obtienen la puntuación exacta.
  2. Semántica: uso de ltarticlegt para cada reseña y role=list / role=listitem en la rejilla para afirmar la colección.
  3. No depender solo de color: además de color dorado, el texto y el aria-label describen la cantidad.
  4. Soporte de teclado: las tarjetas responden a :focus-within y se puede hacer focus en enlaces o elementos interactivos dentro.
  5. Contraste: reglas CSS para mejora de contraste con media queries de preferencia.

7) Variantes y mejoras posibles

8) Ejemplo de microdatos (opcional)

Si quieres añadir Schema.org para que los motores lean rating/review, inserta el marcado apropiado en la salida. Ejemplo simple:

ltdiv itemscope itemtype=http://schema.org/Reviewgt
  ltspan itemprop=authorgtMaría Lópezlt/spangt
  ltdiv itemprop=reviewRating itemscope itemtype=http://schema.org/Ratinggt
    ltmeta itemprop=ratingValue content=4gt
    ltmeta itemprop=bestRating content=5gt
    ltmeta itemprop=worstRating content=0gt
    ltspan aria-hidden=truegt★★★★☆lt/spangt
  lt/divgt
lt/divgt

9) Puntos finales y recomendaciones técnicas

Al implementar en producción:

Recuerda

La combinación de una representación visual agradable (tarjetas con estrellas) junto a un marcado accesible garantiza que tanto usuarios visuales como usuarios que dependen de tecnologías de asistencia puedan entender y usar la información de las reseñas correctamente.

Enlaces útiles



Leave a Reply

Your email address will not be published. Required fields are marked *