Introducción
En este tutorial aprenderás a estilizar el calendario de entradas de WordPress con un enfoque minimalista, manteniendo la accesibilidad y el rendimiento. Veremos la estructura típica que genera WordPress, las decisiones de diseño minimalistas, un CSS completo listo para usar, y opciones avanzadas como indicadores de días con entradas y una pequeña mejora en PHP para añadir metadatos útiles.
Estructura HTML típica del calendario
La función get_calendar() de WordPress devuelve una tabla HTML con la estructura básica de calendario: encabezado con los días de la semana y celdas por cada día. Los días que tienen entradas salen como enlaces (ltagt) y los que no tienen entradas aparecen como texto plano. Un ejemplo simplificado de la salida sería:
| L | M | X | J | V | S | D |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | 7 |
Observa: la presencia de un enlace indica que hay entradas publicadas ese día la clase today o similar puede o no aparecer según la versión o theme.
Principios de diseño minimalista
- Paleta reducida: usa 1–2 colores principales y un neutro para fondo y líneas.
- Tipografía clara: tamaño legible, sin adornos.
- Sombra mínima o ninguna separar con espacios y líneas finas.
- Contraste accesible: garantizar foco y lectura para usuarios con baja visión.
- Respetar la semántica del table para accesibilidad y compatibilidad con scrapers/feeds.
CSS minimalista completo (lista para usar)
Este bloque CSS estiliza un calendario de WordPress manteniendo la semántica de tabla. Incluye variables para personalizar colores, estilo para días con enlace (indicador tipo punto), foco accesible y adaptación básica para móviles.
:root{
--cal-bg: #ffffff
--cal-border: #ececec
--cal-accent: #0b84ff
--cal-text: #222
--cal-muted: #7a7a7a
--cal-radius: 8px
--cal-day-size: 44px
--cal-gap: 6px
}
/ Contenedor y tabla base /
#wp-calendar.calendar,
#wp-calendar {
background: var(--cal-bg)
color: var(--cal-text)
border: 1px solid var(--cal-border)
border-radius: var(--cal-radius)
overflow: hidden
width: 100%
max-width: 320px / ajustar según diseño /
font-family: system-ui, -apple-system, Segoe UI, Roboto, Helvetica Neue, Arial
font-size: 14px
box-sizing: border-box
}
/ Encabezado de días de la semana /
#wp-calendar thead th {
font-weight: 600
color: var(--cal-muted)
padding: 8px 6px
font-size: 12px
text-align: center
background: transparent
border-bottom: 1px solid var(--cal-border)
}
/ Celdas del cuerpo /
#wp-calendar tbody td {
text-align: center
vertical-align: middle
padding: 8px 6px
width: calc(100% / 7)
height: var(--cal-day-size)
border-right: 1px solid var(--cal-border)
border-bottom: 1px solid var(--cal-border)
position: relative
box-sizing: border-box
}
/ Evitar doble borde en la última columna /
#wp-calendar tbody tr td:last-child {
border-right: none
}
/ Días sin enlace (no posts) /
#wp-calendar tbody td.pad,
#wp-calendar tbody td:not(:has(a)) {
color: var(--cal-muted)
background: transparent
}
/ Enlaces de días: apariencia minimalista, indicador de interactuación /
#wp-calendar tbody td a {
display: inline-block
width: 28px
height: 28px
line-height: 28px
border-radius: 6px
color: var(--cal-text)
text-decoration: none
transition: background .18s ease, color .18s ease, transform .08s ease
position: relative
font-weight: 600
}
/ Hover y foco (accesible) /
#wp-calendar tbody td a:hover,
#wp-calendar tbody td a:focus {
background: rgba(11,132,255,0.08)
color: var(--cal-accent)
transform: translateY(-1px)
outline: none
box-shadow: 0 0 0 3px rgba(11,132,255,0.06)
}
/ Indicador tipo punto para días con posts (pseudo-elemento) /
#wp-calendar tbody td a::after{
content:
position: absolute
left: 50%
transform: translateX(-50%)
bottom: 6px
width: 6px
height: 6px
background: var(--cal-accent)
border-radius: 50%
opacity: 0.95
}
/ Día actual (resaltado sutil) /
#wp-calendar tbody td.today,
#wp-calendar tbody td.today a {
background: linear-gradient(180deg, rgba(11,132,255,0.06), transparent)
border-radius: 6px
}
/ Lectura: aumentar contraste en modo foco por teclado /
#wp-calendar tbody td a:focus::after {
box-shadow: 0 0 0 3px rgba(11,132,255,0.12)
}
/ Responsividad: vista compacta en pantallas pequeñas /
@media (max-width: 420px) {
#wp-calendar {
max-width: 100%
font-size: 13px
}
#wp-calendar thead {
display: none / esconder encabezado para ahorrar espacio /
}
/ Crear un layout en grid manteniendo semántica de table /
#wp-calendar tbody {
display: grid
grid-template-columns: repeat(7, 1fr)
gap: var(--cal-gap)
}
#wp-calendar tbody tr {
display: contents
}
#wp-calendar tbody td {
border-right: none
border-bottom: none
height: 56px
padding: 6px 4px
}
}
Personalizaciones útiles y variantes
- Mostrar recuentos por día: la solución CSS anterior usa un punto para días con posts. Si quieres mostrar el número de entradas en vez del punto, añade un atributo data-count (requiere modificación del HTML o PHP) y usa el pseudo-elemento ::after con content: attr(data-count).
- Modo oscuro: redefine las variables en un media query o clase .dark para invertir colores manteniendo la misma estructura.
- Animaciones sutiles: evita animaciones pesadas pequeñas transiciones en hover/focus son suficientes.
- Impresión: añade una regla @media print para ocultar colores y ajustar tipografía si se necesita.
Añadir metadatos (data-count) por día — mejora en PHP
Si necesitas que cada enlace de día tenga un atributo data-count con el número de entradas publicadas ese día (útil para herramientas JS o mostrar números en CSS), puedes filtrar la salida de get_calendar() y añadir ese atributo. Ejemplo sencillo con cache para no sobrecargar la base de datos:
]href=[]([^] )[][^>]>(d )/i,
function(matches){
// Seleccionar el grupo apropiado (compatibilidad con entidades)
url = !empty(matches[1]) ? html_entity_decode(matches[1]) : (isset(matches[3]) ? matches[3] : )
day = !empty(matches[2]) ? matches[2] : (isset(matches[4]) ? matches[4] : )
if (empty(url) empty(day)) {
return matches[0]
}
// Extraer año y mes desde la URL del enlace (puede variar según estructura de permalinks)
parts = array_values(array_filter(explode(/, trim(wp_parse_url(url, PHP_URL_PATH), /))))
count = 0
// Suponemos que la URL termina en /YYYY/MM/DD/ o /YYYY/MM/DD
if (count(parts) >= 3) {
y = intval(parts[count(parts)-3])
m = intval(parts[count(parts)-2])
d = intval(parts[count(parts)-1])
if (y > 1970 m >= 1 m <= 12 d >= 1 d <= 31) {
// Uso de transiente para cachear el recuento por día (1 hora)
transient_key = cal_count_{y}_{m}_{d}
cached = get_transient(transient_key)
if (cached !== false) {
count = intval(cached)
} else {
q = new WP_Query(array(
date_query => array(array(year=>y,month=>m,day=>d)),
post_type => post,
posts_per_page => 1,
fields => ids,
))
count = isset(q->found_posts) ? intval(q->found_posts) : 0
set_transient(transient_key, count, HOUR_IN_SECONDS)
wp_reset_postdata()
}
}
}
// Reconstruir el enlace original y añadir data-count y aria-label
escaped_url = esc_url(url)
aria = esc_attr(sprintf(_n(%d entrada, %d entradas, count, text-domain), count))
day_text = esc_html(day)
return {day_text}
},
calendar_html
)
return html
}
?>
Notas sobre el PHP anterior: usar transients reduce consultas. Ajusta la lógica de extracción de fecha si tus permalinks tienen una estructura distinta. Siempre probar en entornos de desarrollo antes de pasarlo a producción.
Consejos finales y buenas prácticas
- Respeta la semántica: usa la tabla original salvo que tengas motivos claros para una versión totalmente personalizada.
- Prueba con lectores de pantalla (NVDA, VoiceOver) y verifica que los enlaces tienen aria-label si despliegas información adicional.
- Simplifica colores y mantén buen contraste revisa con herramientas como el comprobador de contraste WCAG.
- Si añades contadores o consultas extra, cachea resultados para proteger rendimiento.
Resumen
Con unas variables CSS, reglas limpias y un pequeño ajuste opcional en PHP, puedes transformar el calendario de WordPress en un componente minimalista, accesible y coherente con el resto de tu sitio. El enfoque propuesto prioriza legibilidad, usabilidad y bajo impacto en rendimiento.
Leave a Reply