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:
- Registrar un tipo de contenido personalizado review (opcional si ya usas otro método).
- Guardar una valoración numérica (por ejemplo, meta rating de 0 a 5).
- Crear un shortcode que genere una rejilla de tarjetas con la información de cada reseña.
- Renderizar las estrellas mediante CSS con una capa que recorta el relleno para permitir medias estrellas y ofrecer texto alternativo legible por lectores de pantalla.
- Añadir prácticas de accesibilidad: roles, aria-labels, texto visible para lector de pantalla y alto contraste.
Requisitos y decisiones de diseño
- Compatibilidad: funciona en themes modernos (WordPress 5.x ), se adapta a Gutenberg o a shortcodes clásicos.
- Accesibilidad: cada tarjeta incluye contenido textual de la valoración (por ejemplo 4 de 5), un aria-label en el elemento visual y una clase sr-only para texto oculto visualmente pero accesible a lectores de pantalla.
- Flexibilidad: el CSS usa técnicas simples (caracteres de estrella y una capa de relleno recortada mediante ancho) para permitir medias estrellas sin depender de imágenes raster.
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
- 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.
- Semántica: uso de ltarticlegt para cada reseña y role=list / role=listitem en la rejilla para afirmar la colección.
- No depender solo de color: además de color dorado, el texto y el aria-label describen la cantidad.
- Soporte de teclado: las tarjetas responden a :focus-within y se puede hacer focus en enlaces o elementos interactivos dentro.
- Contraste: reglas CSS para mejora de contraste con media queries de preferencia.
7) Variantes y mejoras posibles
- Mostrar número de votos junto a la valoración: añade un meta rating_count o usa comentarios para calcularlo.
- Soporte de medias estrellas: el método de ancho permite medias estrellas sin cambios adicionales.
- Usar SVG en lugar de caracteres para un control pixel-perfect y escalado más fino.
- Añadir filtros (ordenar por fecha, rating) en el shortcode o interfaz pública mediante parámetros del mismo.
- Incluir microdatos (Schema.org Review/Rating) para enriquecer resultados en buscadores si corresponde.
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:
- Sanitiza y escapa siempre la salida en PHP (esc_html, esc_attr, wp_kses_post).
- Si las reseñas provienen de usuarios externos, revisa y modera el contenido antes de publicarlo.
- Prueba con lectores de pantalla (NVDA, VoiceOver) y herramientas de evaluación de accesibilidad (axe, Lighthouse).
- Si usas cache, invalida cuando se publiquen/editen reseñas para que la valoración en la interfaz siempre esté actualizada.
- Para SEO, piensa si necesitas añadir marcado estructurado con Schema y validarlo con la herramienta de Google.
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.
Leave a Reply