移动端签到日历需HTML结构、CSS响应式布局与JavaScript交互存储协同实现,采用div+CSS Grid构建42格日历,用button确保可访问性,适配小屏触控,localStorage持久化状态,并处理星期起始、跨月判断等细节。

移动端签到页里的日历网格,核心是「视觉对齐星期 + 状态可识别 + 操作可靠 + 适配小屏」。纯 HTML 做不了——它没有逻辑、记不住点击、刷一下就清空。真正跑得起来的签到日历,必须靠 HTML(结构)+ CSS(样式与响应式)+ JavaScript(计算、交互、存储)三者配合。
用 div + CSS Grid 实现移动端友好日历网格
表格 <table> 在手机上容易横向溢出、文字挤成一团,还难做圆角、阴影、动画。现代做法是用语义清晰的 div 配合 display: grid,既可控又易适配。
- 外层容器设为
display: grid; grid-template-columns: repeat(7, 1fr); - 生成 42 个格子(6 行 × 7 列),按顺序填充:前若干个是上月尾部日期(加
class="prev-month"),中间是当月日期,后面是下月开头(加class="next-month") - 当天日期加
class="today",已签到的加class="signed",CSS 单独定义颜色、边框或背景图标 - 所有格子用
<button>而不是<div>,确保可聚焦、可键盘操作、支持aria-pressed,提升无障碍体验
让格子在手机上真正可用
小屏不是“缩小桌面版”,而是重新设计触控体验:
- 每个按钮最小尺寸设为
min-width: 44px; min-height: 44px(iOS/Android 推荐最小点击区域) - 用
media query控制字体大小:font-size: clamp(14px, 3.5vw, 16px),避免横屏时字太大撑破布局 - 禁止缩放干扰:
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no"> - 上下滑动流畅:给日历容器加
overscroll-behavior: contain,防止滚动穿透到页面背景
签到状态得存住,不能一刷新就白签
localStorage 是最轻量的选择,适合个人工具或 MVP 版本:
- 键名统一用
'sign-' + YYYYMMDD(如'sign-20260729'),值为'true' - 页面加载时批量读取:
Object.keys(localStorage).filter(k => k.startsWith('sign-')),转成日期数组用于渲染高亮 - 点击签到时,先更新内存状态,再统一写入 localStorage(避免高频写入拖慢主线程)
- 加 try/catch 包裹读写逻辑——隐私模式或存储满时不会崩溃
月份切换要自然,别让用户迷路
移动端没有鼠标悬停,切换依赖明确按钮:
- 顶部放左右箭头按钮,绑定
click事件,调用函数更新year和month变量 - 更新后重新生成整个日历 DOM(清空容器 + 重建 42 个 button),比局部更新更稳
- 月份标题实时更新,例如
<h2 id="month-title">2026年7月</h2> - 禁用“跳转到今天”按钮时,用
opacity: 0.5; pointer-events: none,别只靠 class 隐藏
关键细节别漏掉
-
new Date(year, month, 1).getDay()返回 0(周日)~6(周六),但中国习惯以周一为每周起点,显示时表头顺序应为「一、二、三、四、五、六、日」,对应getDay()的 1~6、0 - 渲染当天格子时,用
new Date().getDate() === dayNum && sameMonth双重判断,避免跨月时把下月 1 号也标成 today - 已签到按钮加
aria-pressed="true",未签的保持aria-pressed="false"或不设该属性
不复杂但容易忽略



















