CSS Grid 可直接实现7×52热力图布局:设grid-template-columns: repeat(52, 1fr)、grid-template-rows: repeat(7, 1fr),每格用aspect-ratio: 1保证等宽高,间隙用margin而非gap,颜色通过预设class(如bg-green-0至bg-green-4)和CSS变量控制,日期对齐需服务端计算首列起始日,响应式采用横向滚动+aria-label提升可访问性。

用 CSS Grid 生成热力图基础布局
Grid 是最直接的方案,不用 JS 算行列、不依赖第三方库,纯样式就能铺满 7×52 的格子。关键不是“怎么画”,而是“怎么让每格自动对齐、等宽高、无缝拼接”。
-
grid-template-columns设为repeat(52, 1fr),对应一年 52 周;grid-template-rows设为repeat(7, 1fr),对应周日到周六(注意顺序:CSS Grid 默认从上到下是 row 1→row 7,需配合grid-auto-flow: column或手动排列数据) - 每格必须设
aspect-ratio: 1或同时设width和height相同值,否则在缩放或不同字体下容易变形 - 别用
gap控制间距——它会在格子间插入空白,而 GitHub 热力图是靠 margin 实现间隙的,否则颜色块之间会漏出背景色
按提交次数映射颜色深浅(class 控制)
GitHub 用 5 级色阶(bg-green-0 到 bg-green-4),本质是根据数值落在哪个区间,加对应 class。CSS 里不能运算,所以得靠预设类 + HTML 层决定。
- 后端或构建时把每天提交数转成 0–4 的等级,输出为
class="contribution-day bg-green-2"这类结构 - 不要用内联
style="background-color: #xxx"—— 颜色值难维护,且无法利用 CSS 变量做主题切换 - 推荐用 CSS 自定义属性统一管理色阶:
:root { --green-0: #ebedf0; --green-1: #9be9a8; ... },再让各 class 引用,改主题只需换变量值
日期对齐和星期起始日问题
热力图第一列必须是当年第一个星期日(或周一,取决于配置),否则整张图偏移,用户一眼就能看出不对。这不是样式问题,是数据+布局协同问题。
- JavaScript 或服务端计算当年 1 月 1 日是星期几,再往前推到最近一个周日(或周一),得出「第一列起始日期」
- HTML 中每个
<div>格子需带data-date="2023-01-01"属性,方便调试和后续交互(比如 hover 显示具体日期) - CSS 本身不处理日期逻辑,但若用
grid-column/grid-row手动定位某天,极易出错——坚持用顺序流布局 + 数据顺序匹配,更稳
响应式与可访问性容易被忽略的点
小屏下 52 列挤在一起,格子太小看不清颜色,又不能简单缩放——缩放会导致文字/边框糊掉,而且 focus outline 会错位。
立即学习“前端免费学习笔记(深入)”;
- 用
@container(需父容器设container-type: inline-size)或媒体查询,在宽度< 768px时切为「滚动容器 + 固定高度」,横向滚动看全貌 - 每个格子加
aria-label="2023-01-01: 3 commits",屏幕阅读器能读出日期和数量,纯视觉方案不可替代 - 别给格子设
font-size: 0来隐藏文字——万一用户强制放大字体,内容就丢了;用visually-hidden类更安全
颜色深浅靠人眼分辨,色弱用户可能分不清 bg-green-1 和 bg-green-2,加数量 badge 或 hover 提示不是锦上添花,是必要补救。











