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
- Tarjeta con imagen circular o cuadrada del miembro del equipo.
- Nombre y posición visibles siempre.
- Al pasar el ratón (hover) o enfocar con teclado aparece una capa semitransparente con iconos de redes sociales.
- Animaciones suaves con transform y transition soporte para tamaños responsivos.
- Shortcode de WordPress para insertar listas de miembros dinámicamente.
Requisitos y consideraciones
- Preferible contar con Font Awesome o similar para los iconos de redes sociales (se indica cómo cargarlo).
- Optimiza las imágenes (webp/avif, cargas responsivas) para reducir peso.
- Piensa en accesibilidad: usa roles, alt en imágenes (en la versión dinámica en WP, guarda el alt), y permite interacción por teclado.
- Compatibilidad móvil: en pantallas táctiles se puede mostrar la capa mediante un toque (se incluye JS opcional).
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
- Diseño de la overlay: puedes cambiar la dirección del gradiente, usar un blur (backdrop-filter) para un efecto vidrio (recuerda añadir prefijos y fallback para navegadores no compatibles).
- Tamaños y forma de la foto: cambia border-radius para cuadrados o esquinas redondeadas para avatar circular usa 50%.
- Animaciones: sustituye transform por scale o añade delays escalonados para listas.
- Iconos SVG: si prefieres no depender de Font Awesome, coloca inline SVG en los enlaces para mejor control visual y rendimiento.
8) Problemas comunes y soluciones
- 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.
- 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.
- Imágenes distorsionadas: Usa object-fit: cover y dimensiones fijas en el contenedor para mantener proporciones.
- 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