Cómo Crear una Tabla de Contribuciones Estilo GitHub con CSS Puro

¿Alguna vez has visto esa genial tabla de contribuciones en GitHub que muestra tu actividad del año con cuadraditos
de colores? Hoy te voy a enseñar cómo crear una versión personalizada para tu sitio web, completamente desde cero y
con CSS puro.

Lo mejor de todo es que vamos a añadirle nuestro toque personal: tooltips personalizados que realmente se pueden leer
(nada de que el cursor tape el texto) y una escala de colores azules en lugar de los verdes de GitHub.

 

¿Qué vamos a construir?

Vamos a crear una tabla de contribuciones que incluye:

  • Una cuadrícula de 365 días organizados por semanas
  • Etiquetas de meses en la parte superior
  • Días de la semana en el lateral
  • Escala de colores personalizada (azul en lugar de verde)
  • Tooltips personalizados que aparecen arriba del cursor
  • Diseño responsive

Paso 1: La Estructura HTML

Primero necesitamos crear la estructura básica. La tabla se organiza en semanas (columnas verticales), donde cada
semana contiene 7 días:

<div class="contributions-container">
    <div class="contributions-header">
        <h2 class="contributions-title">Actividad</h2>
    </div>
    
    <div class="contributions-calendar">
        <!-- Etiquetas de meses -->
        <div class="contributions-months">
            <div class="month-spacer"></div>
            <span class="month-label">Ene</span>
            <span class="month-label">Feb</span>
            <!-- ... más meses -->
        </div>
        
        <div class="contributions-grid">
            <!-- Días de la semana -->
            <div class="contributions-weekdays">
                <span class="weekday-label">L</span>
                <span class="weekday-label">M</span>
                <span class="weekday-label">X</span>
                <span class="weekday-label">J</span>
                <span class="weekday-label">V</span>
                <span class="weekday-label">S</span>
                <span class="weekday-label">D</span>
            </div>
            
            <!-- Semanas -->
            <div class="contributions-week">
                <div class="contribution-cell low" title="1 post el 01/01/2025"></div>
                <div class="contribution-cell none" title="Sin posts el 02/01/2025"></div>
                <!-- ... más días -->
            </div>
            <!-- ... más semanas -->
        </div>
    </div>
</div>

Paso 2: Estilo del Contenedor Principal

Vamos a darle un aspecto moderno al contenedor con gradientes y sombras:

.contributions-container {
    background: linear-gradient(135deg, 
        rgba(22, 27, 34, 0.95) 0%, 
        rgba(13, 17, 23, 0.95) 100%);
    border-radius: 12px;
    padding: 28px;
    margin-bottom: 32px;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3), 
                0 0 0 1px rgba(88, 166, 255, 0.1);
    transition: all 0.3s ease;
}

.contributions-container:hover {
    box-shadow: 0 6px 16px rgba(0, 0, 0, 0.4), 
                0 0 0 1px rgba(88, 166, 255, 0.2);
}

💡 Tip: El gradiente de fondo crea profundidad visual, mientras que las sombras múltiples (una
difusa y otra como borde) dan un efecto de «elevación».

Paso 3: La Cuadrícula de Días

Aquí viene la parte interesante. Usamos flexbox para organizar las semanas horizontalmente y los días verticalmente:

.contributions-grid {
    display: flex;
    gap: 2.5px;
    align-items: flex-start;
}

.contributions-week {
    display: flex;
    flex-direction: column;
    gap: 2.5px;
    width: 13px;
}

.contribution-cell {
    width: 13px;
    height: 13px;
    border-radius: 2px;
    background-color: #161b22;
    border: 1px solid rgba(255, 255, 255, 0.05);
    cursor: pointer;
    transition: border-color 0.2s;
    position: relative;
}

Paso 4: Escala de Colores Personalizada

En lugar de usar los verdes de GitHub, vamos a crear nuestra propia escala de azules. La clave está en crear una
progresión suave de colores:

/* Sin actividad */
.contribution-cell.none {
    background-color: #161b22;
}

/* Poca actividad (1 post) */
.contribution-cell.low {
    background-color: #0a3d62;
}

/* Actividad media (2-3 posts) */
.contribution-cell.medium {
    background-color: #1e6fba;
}

/* Mucha actividad (4-5 posts) */
.contribution-cell.high {
    background-color: #3a9efd;
}

/* Actividad muy alta (6+ posts) */
.contribution-cell.very-high {
    background-color: #5eb8ff;
}

🎨 Personalización: Puedes cambiar estos colores por cualquier escala que quieras. Prueba con
morados, verdes, o incluso un degradado arcoíris si te sientes aventurero.

Paso 5: Tooltips Personalizados (La Magia)

Aquí está el truco que hace que los tooltips sean realmente útiles. En lugar de usar el tooltip nativo del navegador
(que aparece donde está el cursor), vamos a crear uno personalizado que aparece arriba:

.contribution-cell::before {
    content: attr(title);
    position: absolute;
    bottom: 100%;
    left: 50%;
    transform: translateX(-50%) translateY(-8px);
    background: linear-gradient(135deg, 
        rgba(22, 27, 34, 0.98) 0%, 
        rgba(13, 17, 23, 0.98) 100%);
    color: #c9d1d9;
    padding: 8px 12px;
    border-radius: 6px;
    font-size: 12px;
    white-space: nowrap;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.2s ease, transform 0.2s ease;
    z-index: 1000;
    border: 1px solid rgba(88, 166, 255, 0.3);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.5);
}

/* Flecha del tooltip */
.contribution-cell::after {
    content: "";
    position: absolute;
    bottom: 100%;
    left: 50%;
    transform: translateX(-50%) translateY(-2px);
    border: 5px solid transparent;
    border-top-color: rgba(22, 27, 34, 0.98);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.2s ease, transform 0.2s ease;
    z-index: 999;
}

/* Mostrar al hacer hover */
.contribution-cell:hover::before {
    opacity: 1;
    transform: translateX(-50%) translateY(-12px);
}

.contribution-cell:hover::after {
    opacity: 1;
    transform: translateX(-50%) translateY(-6px);
}

.contribution-cell:hover {
    border-color: rgba(88, 166, 255, 0.6);
}

¿Cómo funciona esto?

  1. attr(title): Toma el contenido del atributo title del HTML
  2. bottom: 100%: Posiciona el tooltip arriba de la celda
  3. transform: Centra el tooltip y lo desplaza hacia arriba
  4. opacity: 0: Lo mantiene oculto por defecto
  5. :hover: Al pasar el ratón, lo hace visible y lo anima

Paso 6: Días de la Semana

Para los días de la semana, usamos letras individuales centradas:

.contributions-weekdays {
    display: flex;
    flex-direction: column;
    gap: 2.5px;
    margin-right: 8px;
    width: 30px;
}

.weekday-label {
    width: 30px;
    height: 13px;
    font-size: 11px;
    color: #8b949e;
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 600;
    letter-spacing: 0.5px;
}

Paso 7: Alineación de Meses

Para que los meses se alineen correctamente con las semanas, necesitamos un espaciador:

.contributions-months {
    display: flex;
    gap: 2.5px;
    margin-bottom: 4px;
    height: 19px;
}

.month-spacer {
    width: 38px; /* Mismo ancho que weekdays + margen */
    height: 19px;
}

.month-label {
    width: 13px;
    min-width: 13px;
    font-size: 13.5px;
    color: #8b949e;
}

Paso 8: Scrollbar Personalizado

Para darle el toque final, vamos a personalizar el scrollbar (si la tabla es muy larga):

.contributions-calendar {
    overflow-x: auto;
}

.contributions-calendar::-webkit-scrollbar {
    height: 6px;
}

.contributions-calendar::-webkit-scrollbar-track {
    background: rgba(88, 166, 255, 0.05);
    border-radius: 3px;
}

.contributions-calendar::-webkit-scrollbar-thumb {
    background: rgba(88, 166, 255, 0.3);
    border-radius: 3px;
}

.contributions-calendar::-webkit-scrollbar-thumb:hover {
    background: rgba(88, 166, 255, 0.5);
}

Responsive: Adaptando para Móviles

Para pantallas pequeñas, reducimos los tamaños:

@media (max-width: 768px) {
    .contributions-container {
        padding: 16px;
    }
    
    .contribution-cell {
        width: 12px;
        height: 12px;
    }
    
    .contributions-week {
        width: 12px;
        gap: 2px;
    }
    
    .contributions-grid {
        gap: 2px;
    }
    
    .weekday-label {
        font-size: 10px;
        height: 12px;
    }
}

Generando los Datos con PHP (WordPress)

Si estás usando WordPress, puedes generar la tabla dinámicamente basándote en tus posts:

function generar_tabla_contribuciones() {
    global $wpdb;
    
    // Obtener posts del año actual
    $year = date('Y');
    $posts = $wpdb->get_results($wpdb->prepare(
        "SELECT DATE(post_date) as fecha, COUNT(*) as cantidad
        FROM {$wpdb->posts}
        WHERE post_status = 'publish'
        AND post_type = 'post'
        AND YEAR(post_date) = %d
        GROUP BY DATE(post_date)",
        $year
    ));
    
    // Crear array de contribuciones
    $contribuciones = array();
    foreach ($posts as $post) {
        $contribuciones[$post->fecha] = $post->cantidad;
    }
    
    // Generar HTML...
    // (código para generar las semanas y días)
}

Consejos y Trucos

1. Caché para Mejor Rendimiento

Si tienes muchos posts, guarda los datos en un transient de WordPress:

$cache_key = 'contribuciones_' . $year;
$datos = get_transient($cache_key);

if ($datos === false) {
    // Generar datos
    set_transient($cache_key, $datos, 12 * HOUR_IN_SECONDS);
}

2. Animación de Entrada

Puedes añadir una animación cuando la tabla aparece en pantalla:

@keyframes fadeInUp {
    from {
        opacity: 0;
        transform: translateY(20px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

.contributions-container {
    animation: fadeInUp 0.6s ease-out;
}

3. Accesibilidad

No olvides añadir atributos ARIA para usuarios con lectores de pantalla:

<div class="contribution-cell low" 
     title="1 post el 01/01/2025"
     role="gridcell"
     aria-label="1 post publicado el 1 de enero de 2025">
</div>

Resultado Final

Al terminar, tendrás una tabla de contribuciones completamente funcional con:

  • ✅ Diseño moderno con gradientes y sombras
  • ✅ Tooltips personalizados que realmente se pueden leer
  • ✅ Escala de colores personalizada
  • ✅ Responsive para móviles
  • ✅ Scrollbar personalizado
  • ✅ Animaciones suaves