Tutorial WordPress: Diseñar tarjetas de equipo con efecto hover y redes sociales

·

·

Introducción

En este tutorial detallado se explica cómo diseñar tarjetas de equipo (team cards) con un efecto hover elegante que descubre enlaces a redes sociales. Incluye el marcado HTML para la tarjeta, el CSS para animaciones y estilos, JavaScript opcional para mejorar la accesibilidad en dispositivos táctiles, y una integración práctica en WordPress mediante un shortcode y/o un Custom Post Type. Los ejemplos de código van dentro de bloques ltpre class=EnlighterJSRAW …gt para que puedas copiarlos directamente.

Resumen del resultado

Requisitos y consideraciones

1) Estructura HTML (ejemplo estático)

A continuación tienes un ejemplo completo de la estructura HTML de una tarjeta. Este fragmento es para uso directo en una página o en un bloque HTML dentro de WordPress si vas a insertar contenido estático.

lt!-- Card container --gt
ltdiv class=team-gridgt
  ltarticle class=team-cardgt
    ltfigure class=team-photogt
      ltimg src=ruta/a/imagen.jpg alt=Nombre Apellido - Cargo /gt
    lt/figuregt
    ltdiv class=team-infogt
      lth3 class=team-namegtNombre Apellidolt/h3gt
      ltp class=team-rolegtCargo / Especialidadlt/pgt
    lt/divgt
    ltdiv class=team-overlay aria-hidden=truegt
      ltnav class=team-socials aria-label=Redes sociales de Nombre Apellidogt
        lta href=https://twitter.com/usuario target=_blank rel=noopener noreferrergtlti class=fab fa-twittergtlt/igtlt/agt
        lta href=https://linkedin.com/in/usuario target=_blank rel=noopener noreferrergtlti class=fab fa-linkedin-ingtlt/igtlt/agt
        lta href=https://instagram.com/usuario target=_blank rel=noopener noreferrergtlti class=fab fa-instagramgtlt/igtlt/agt
      lt/navgt
    lt/divgt
  lt/articlegt
  lt!-- Repite article por cada miembro --gt
lt/divgt

2) CSS para diseño y efecto hover

Este CSS proporciona el diseño base, disposición en grid, efecto hover y animaciones. Ajusta variables (colores, sombras, radios) según tu identidad visual.

:root{
  --card-bg: #ffffff
  --accent: #1e90ff
  --overlay-bg: rgba(20,20,20,0.6)
  --text-color: #111
  --muted: #666
  --radius: 12px
  --transition: 300ms cubic-bezier(.2,.8,.2,1)
}

/ Grid contenedor /
.team-grid{
  display: grid
  grid-template-columns: repeat(3, 1fr)
  gap: 1.25rem
  align-items: start
}

/ Card base /
.team-card{
  position: relative
  overflow: hidden
  background: var(--card-bg)
  border-radius: var(--radius)
  box-shadow: 0 6px 18px rgba(10,10,10,0.08)
  transition: transform var(--transition), box-shadow var(--transition)
  text-align: center
  padding: 1rem
}

/ Elevación al hover /
.team-card:hover,
.team-card:focus-within{
  transform: translateY(-6px)
  box-shadow: 0 18px 40px rgba(10,10,10,0.12)
}

/ Imagen /
.team-photo{
  width: 110px
  height: 110px
  margin: 0 auto 0.75rem
  border-radius: 50%
  overflow: hidden
  display: block
  box-shadow: 0 6px 18px rgba(10,10,10,0.06)
}
.team-photo img{
  width: 100%
  height: 100%
  object-fit: cover
  display: block
}

/ Información /
.team-name{
  margin: .25rem 0 .125rem
  font-size: 1.05rem
  color: var(--text-color)
}
.team-role{
  margin: 0
  color: var(--muted)
  font-size: .9rem
}

/ Overlay con redes (inicialmente oculto) /
.team-overlay{
  position: absolute
  inset: 0
  display: flex
  align-items: center
  justify-content: center
  background: linear-gradient(180deg, rgba(0,0,0,0.0) 0%, var(--overlay-bg) 60%)
  opacity: 0
  transform: translateY(6%)
  transition: opacity var(--transition), transform var(--transition)
  pointer-events: none
}

/ Al pasar hover o focus mostrar overlay /
.team-card:hover .team-overlay,
.team-card:focus-within .team-overlay,
.team-card.show-overlay .team-overlay{ / .show-overlay para JS en touch /
  opacity: 1
  transform: translateY(0)
  pointer-events: auto
}

/ Iconos sociales /
.team-socials{
  display: flex
  gap: 0.6rem
}
.team-socials a{
  width: 44px
  height: 44px
  display: inline-grid
  place-items: center
  border-radius: 50%
  background: rgba(255,255,255,0.12)
  color: white
  transition: transform var(--transition), background var(--transition)
  text-decoration: none
}
.team-socials a:hover,
.team-socials a:focus{
  background: var(--accent)
  transform: translateY(-4px) scale(1.03)
  outline: none
}

/ Responsive /
@media (max-width: 900px){
  .team-grid{ grid-template-columns: repeat(2, 1fr) }
}
@media (max-width: 600px){
  .team-grid{ grid-template-columns: 1fr }
  .team-card{ padding: 1.25rem }
  .team-photo{ width: 96px height: 96px }
}

3) Accesibilidad y comportamiento en dispositivos táctiles

En escritorio el hover muestra la capa. En móviles, donde no hay hover, conviene exponer la capa con un toque. El siguiente JavaScript añade la clase show-overlay al tocar la tarjeta y la elimina si se toca fuera o se toca otra tarjeta. Además permite navegar con teclado gracias a focus-within.

// Agrega comportamiento touch: al tocar una tarjeta muestra la overlay
document.addEventListener(click, function(e){
  var card = e.target.closest  e.target.closest(.team-card)
  if(!card){
    // clic fuera: eliminar todas las clases
    document.querySelectorAll(.team-card.show-overlay).forEach(function(c){
      c.classList.remove(show-overlay)
    })
    return
  }
  // Si la card ya tiene overlay, permitir que los enlaces funcionen
  if(card.classList.contains(show-overlay)){
    return
  }
  // Evitar comportamiento por defecto del primer tap (abre overlay)
  e.preventDefault()
  // cerrar otras
  document.querySelectorAll(.team-card.show-overlay).forEach(function(c){
    c.classList.remove(show-overlay)
  })
  // abrir esta
  card.classList.add(show-overlay)
})

4) Uso de iconos (Font Awesome)

Para usar las clases fab fa-twitter en los ejemplos necesitas cargar Font Awesome. En una plantilla o header de tu tema coloca el enlace recomendado por Font Awesome o usa su kit. Ejemplo de inclusión (colócalo en header.php o en wp_enqueue_style):

lt!-- Ejemplo de carga rápida desde CDN: sustituye por kit propio en producción --gt
ltlink rel=stylesheet href=https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css integrity= crossorigin=anonymous /gt

5) Integración en WordPress: Shortcode simple

Si quieres generar tarjetas desde WordPress sin programar un CPT, el siguiente shortcode permite pasar un array de miembros (ideal para bloques personalizados o contenido donde admin copie/pegue un JSON simple). Para un uso más profesional se recomienda crear un Custom Post Type y ACF/Meta Boxes.

/ Añadir esto en functions.php o en un plugin propio /
function team_cards_shortcode(atts){
  // atributos por defecto
  atts = shortcode_atts(array(
    items => [] // JSON con los miembros
  ), atts, team_cards)

  items = json_decode(atts[items], true)
  if(!is_array(items)  empty(items)){
    return 

No hay miembros configurados.

} ob_start() echo ltdiv class=team-gridgt foreach(items as member){ img = esc_url(member[img] ?? ) name = esc_html(member[name] ?? Nombre) role = esc_html(member[role] ?? ) socials = member[socials] ?? array() echo ltarticle class=team-cardgt echo ltfigure class=team-photogtltimg src=. img . alt=. name . - . role . /gtlt/figuregt echo ltdiv class=team-infogtlth3 class=team-namegt. name . lt/h3gtltp class=team-rolegt. role . lt/pgtlt/divgt echo ltdiv class=team-overlay aria-hidden=truegtltnav class=team-socialsgt foreach(socials as s){ url = esc_url(s[url] ?? #) icon = esc_attr(s[icon] ?? fab fa-link) // ejemplo: fab fa-twitter echo lta href=. url . target=_blank rel=noopener noreferrergtlti class=. icon .gtlt/igtlt/agt } echo lt/navgtlt/divgt echo lt/articlegt } echo lt/divgt return ob_get_clean() } add_shortcode(team_cards, team_cards_shortcode)

Ejemplo de uso del shortcode en el editor (reemplaza rutas e iconos):

[team_cards items=[
  {img:https://midominio.com/wp-content/uploads/miembro1.jpg,name:Ana Pérez,role:Directora,socials:[{url:https://twitter.com/ana,icon:fab fa-twitter},{url:https://linkedin.com/in/ana,icon:fab fa-linkedin-in}]},
  {img:https://midominio.com/wp-content/uploads/miembro2.jpg,name:Carlos Ruiz,role:Desarrollador,socials:[{url:https://github.com/carlos,icon:fab fa-github}]}
]]

6) Integración profesional: Custom Post Type (opcional)

Para un equipo dinámico y gestionable en el panel, registra un CPT team_member y usa campos personalizados para foto y enlaces sociales. A continuación se muestra el registro básico del CPT y una plantilla parcial para mostrar los miembros.

// Registrar CPT
function register_team_member_cpt(){
  labels = array(
    name => Miembros,
    singular_name => Miembro
  )
  args = array(
    labels => labels,
    public => true,
    has_archive => false,
    show_in_rest => true,
    supports => array(title,editor,thumbnail,excerpt),
    menu_position => 20,
    menu_icon => dashicons-groups
  )
  register_post_type(team_member, args)
}
add_action(init,register_team_member_cpt)

// Plantilla para obtener miembros
members = new WP_Query(array(post_type=>team_member,posts_per_page=>-1))
if(members->have_posts()){
  echo ltdiv class=team-gridgt
  while(members->have_posts()){
    members->the_post()
    name = get_the_title()
    role = get_post_meta(get_the_ID(), role, true)
    img = get_the_post_thumbnail_url(get_the_ID(),medium)
    // Asume campos meta para social_links como array serializado o múltiples meta claves
    socials = get_post_meta(get_the_ID(), social_links, true) // ajusta según cómo guardes
    echo ltarticle class=team-cardgt
    echo ltfigure class=team-photogtltimg src=. esc_url(img) . alt=. esc_attr(name) . /gtlt/figuregt
    echo ltdiv class=team-infogtlth3 class=team-namegt. esc_html(name) . lt/h3gtltp class=team-rolegt. esc_html(role) . lt/pgtlt/divgt
    echo ltdiv class=team-overlaygtltnav class=team-socialsgt
    if(is_array(socials)){
      foreach(socials as s){ echo lta href=. esc_url(s[url]) . target=_blank rel=noopener noreferrergtlti class=. esc_attr(s[icon]) .gtlt/igtlt/agt }
    }
    echo lt/navgtlt/divgtlt/articlegt
  }
  echo lt/divgt
  wp_reset_postdata()
}

7) Personalización y variaciones

8) Problemas comunes y soluciones

  1. La overlay no aparece en móvil: Asegúrate de incluir el JavaScript opcional que añade la clase show-overlay al tocar la tarjeta, o considera mostrar los iconos siempre visibles en pantallas pequeñas mediante media queries.
  2. Iconos no se ven: Verifica que Font Awesome esté cargado correctamente o que las clases de icono sean las correctas según la versión de FA.
  3. Imágenes distorsionadas: Usa object-fit: cover y dimensiones fijas en el contenedor para mantener proporciones.
  4. Problemas de contraste: Ajusta el color de fondo de la overlay y el color de los iconos para cumplir con ratios de contraste mínimos.

Conclusión

Con los fragmentos y las indicaciones anteriores puedes construir tarjetas de equipo visuales, accesibles y fáciles de gestionar en WordPress tanto de manera estática como dinámica. Ajusta variables y estilos al diseño de tu sitio, y si necesitas soporte para convertir esto en un bloque de Gutenberg o en un plugin autónomo, puedes partir de la base del shortcode y el CPT descritos arriba.



Leave a Reply

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