Tutorial WordPress: Crear tarjetas de post (card design) usando CSS Grid en el loop

·

·

Introducción

Este tutorial muestra, paso a paso y con todo lujo de detalles, cómo crear tarjetas de post (card design) usando CSS Grid dentro del loop de WordPress. Encontrarás ejemplos concretos de código PHP para el loop, CSS para la cuadrícula y las tarjetas, buenas prácticas de accesibilidad y rendimiento, y variantes para distintos casos de uso (imagen destacada, excerpt, overlay, responsive, lazy-loading, etc.).

Requisitos y consideraciones previas

1. Estructura HTML/PHP básica del loop

La idea es generar un marcado semántico por cada post que se convierta en una tarjeta. Cada tarjeta será un article con un a que cubre la tarjeta (link clickable accesible), imagen y contenido (título, excerpt, meta opcional).

Ejemplo de loop (colócalo en archive.php, index.php o template-part):


  lt!-- Contenedor de la grid --gt
  ltdiv class=posts-gridgt
    lt?php while ( have_posts() ) : the_post() ?gt
      ltarticle id=post-lt?php the_ID() ?gt lt?php post_class(post-card) ?gtgt
        lta class=post-card__link href=lt?php the_permalink() ?gt aria-labelledby=post-title-lt?php the_ID() ?gtgt

          lt?php if ( has_post_thumbnail() ): ?gt
            lt?php the_post_thumbnail(medium_large, array(
              class =gt post-card__image,
              alt =gt get_the_title(),
              loading =gt lazy
            )) ?gt
          lt?php else: ?gt
            ltimg class=post-card__image src=lt?php echo esc_url(get_template_directory_uri() . /assets/img/placeholder.jpg) ?gt alt=lt?php the_title_attribute() ?gt loading=lazygt
          lt?php endif ?gt

          ltdiv class=post-card__contentgt
            lth3 id=post-title-lt?php the_ID() ?gt class=post-card__titlegtlt?php the_title() ?gtlt/h3gt
            ltp class=post-card__excerptgtlt?php echo wp_trim_words( get_the_excerpt() ?: get_the_content(), 30, ... ) ?gtlt/pgt
          lt/divgt

        lt/agt
      lt/articlegt
    lt?php endwhile ?gt
  lt/divgt
lt?php endif ?gt

Observaciones clave del marcado:

2. Enqueue del CSS

Añade tu archivo CSS en functions.php para asegurarte de que se cargue correctamente.

function theme_enqueue_styles() {
  wp_enqueue_style( theme-cards, get_template_directory_uri() . /assets/css/cards.css, array(), 1.0 )
}
add_action( wp_enqueue_scripts, theme_enqueue_styles )

3. CSS Grid: diseño de la cuadrícula y tarjetas

A continuación tienes un CSS completo y comentado que implementa una grid responsiva, tarjetas con imagen, overlay sutil, foco accesible y un diseño que mantiene la consistencia entre filas.

:root{
  --gap: clamp(1rem, 1.2vw, 1.5rem)
  --card-radius: 12px
  --card-bg: #fff
  --card-shadow: 0 4px 18px rgba(16,24,40,0.06)
  --accent: #0066ff
}

/ Contenedor grid /
.posts-grid{
  display: grid
  grid-template-columns: repeat( auto-fill, minmax(280px, 1fr) )
  gap: var(--gap)
  align-items: start / que las tarjetas comiencen arriba /
  margin: 0
  padding: 0
}

/ Tarjeta /
.post-card{
  list-style: none
  background: var(--card-bg)
  border-radius: var(--card-radius)
  box-shadow: var(--card-shadow)
  overflow: hidden
  transition: transform .22s ease, box-shadow .22s ease
  display: block
}

/ Hacemos que el enlace ocupe toda la tarjeta /
.post-card__link{
  color: inherit
  text-decoration: none
  display: flex
  flex-direction: column
  height: 100%
}

/ Imagen: usar aspect-ratio para mantener proporción /
.post-card__image{
  width: 100%
  height: auto
  display: block
  object-fit: cover
  aspect-ratio: 16/9 / soporte moderno /
}

/ Contenido de la tarjeta: flex para empujar elementos al fondo si se desea /
.post-card__content{
  padding: 1rem
  display: flex
  flex-direction: column
  gap: .5rem
  flex: 1 1 auto
}

/ Título y excerpt /
.post-card__title{
  font-size: 1.05rem
  margin: 0
  line-height: 1.2
}
.post-card__excerpt{
  margin: 0
  color: #475569
  font-size: .95rem
  flex: 1 1 auto
}

/ Efectos hover / focus /
.post-card:focus-within,
.post-card:hover{
  transform: translateY(-6px)
  box-shadow: 0 10px 30px rgba(16,24,40,0.12)
}

/ Indicador de foco claro para teclado /
.post-card__link:focus{
  outline: 3px solid rgba(0,102,255,0.15)
  outline-offset: 3px
  border-radius: var(--card-radius)
}

/ Overlay sutil sobre imagen al hover /
.post-card__image{
  transition: transform .35s ease
}
.post-card:hover .post-card__image,
.post-card:focus-within .post-card__image{
  transform: scale(1.03)
}

/ Responsive: aumentar columnas en pantallas grandes /
@media (min-width: 1200px){
  .posts-grid{
    grid-template-columns: repeat(4, 1fr)
  }
}
@media (min-width: 900px) and (max-width:1199px){
  .posts-grid{
    grid-template-columns: repeat(3, 1fr)
  }
}
@media (min-width: 600px) and (max-width:899px){
  .posts-grid{
    grid-template-columns: repeat(2, 1fr)
  }
}

Explicación de decisiones CSS:

4. Imágenes responsive y lazy-loading

Para optimizar imágenes y servir tamaños correctos en cada viewport usa las funciones de WordPress que generan srcset y sizes. Ejemplo en el loop:

lt?php
  // Dentro de tu loop
  if ( has_post_thumbnail() ) {
    // medium_large es un ejemplo WP generará srcset automáticamente
    echo wp_get_attachment_image( get_post_thumbnail_id(), medium_large, false, array(
      class =gt post-card__image,
      loading =gt lazy,
      alt =gt get_the_title()
    ) )
  }
?gt

wp_get_attachment_image incluye srcset y sizes, lo que mejora la carga y usabilidad en móviles. Para un control más fino configura un atributo sizes acorde al ancho de la columna en la grid.

5. Variantes: overlay con título sobre la imagen

Si quieres un diseño donde el título aparezca sobre la imagen con un degradado para legibilidad, puedes usar este patrón:

.post-card__image-wrap{
  position: relative
  overflow: hidden
}
.post-card__image{
  display: block
  width: 100%
  height: auto
  aspect-ratio: 16/9
}
.post-card__overlay{
  position: absolute
  inset: auto 0 0 0 / pegado al bottom /
  padding: .75rem
  background: linear-gradient(180deg, rgba(0,0,0,0) 0%, rgba(0,0,0,0.5) 100%)
  color: #fff
}
ltdiv class=post-card__image-wrapgt
  ltimg class=post-card__image src=... alt=... /gt
  ltdiv class=post-card__overlaygt
    lth3 class=post-card__titlegtTítulo sobre imagenlt/h3gt
  lt/divgt
lt/divgt

6. Tarjetas de altura uniforme

Si buscas que todas las tarjetas de una fila tengan la misma altura visual, dos opciones fiables:

  1. Usar display:flex dentro de cada tarjeta y que el contenido crezca con flex: 1 así el pie o botón queda alineado.
  2. Usar grid-auto-rows una técnica que calcule span (más avanzada y requiere JS si quieres grid masonry-like). En la gran mayoría de casos, la opción flex es suficiente y más simple.

7. Accesibilidad

8. Rendimiento

9. Ejemplo de WP_Query personalizado (cards fuera del loop principal)

args = array(
  post_type =gt post,
  posts_per_page =gt 12,
  orderby =gt date,
  order =gt DESC,
)
query = new WP_Query( args )
if ( query-gthave_posts() ) :
?>
  ltdiv class=posts-gridgt
    lt?php while ( query-gthave_posts() ) : query-gtthe_post() ?gt
      lt!-- Reutiliza el mismo marcado de la tarjeta aquí --gt
    lt?php endwhile ?gt
  lt/divgt
lt?php
  wp_reset_postdata()
endif

10. Variaciones avanzadas y notas finales

Resumen final

Con CSS Grid y un marcado semántico dentro del loop, puedes construir tarjetas de post limpias, accesibles y responsive. Aplica optimizaciones de imágenes (srcset, loading), mantiene un enfoque modular (clases BEM o similar) y trabaja el diseño con variables CSS para facilitar ajustes. Los ejemplos incluidos son una base robusta que puedes extender con overlays, meta adicional (autor, fecha), botones o microinteracciones según el proyecto.



Leave a Reply

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