如何用CSS将12/24个数字像时钟表盘一样呈圆形排列?
纯CSS实现带数字标识的圆形时钟(12/24小时制)
核心原理拆解
不用复杂的坐标计算,靠CSS transform 的旋转+平移组合就能精准定位数字:
- 以表盘中心为原点,先将数字元素旋转到对应小时的角度(12小时制每格30°,24小时制每格15°)
- 向外平移到表盘边缘(平移距离=表盘半径 - 数字自身高度的一半,避免数字超出或未贴合边缘)
- 反向旋转数字,让文字保持水平显示
基础结构搭建
先写HTML结构,12小时制用12个<span>,24小时制用24个:
<!-- 12小时制表盘 --> <div class="clock clock-12"> <span>12</span> <span>1</span> <span>2</span> <span>3</span> <span>4</span> <span>5</span> <span>6</span> <span>7</span> <span>8</span> <span>9</span> <span>10</span> <span>11</span> </div> <!-- 24小时制表盘 --> <div class="clock clock-24"> <span>0</span> <span>1</span> <span>2</span> <span>3</span> <span>4</span> <span>5</span> <span>6</span> <span>7</span> <span>8</span> <span>9</span> <span>10</span> <span>11</span> <span>12</span> <span>13</span> <span>14</span> <span>15</span> <span>16</span> <span>17</span> <span>18</span> <span>19</span> <span>20</span> <span>21</span> <span>22</span> <span>23</span> </div>
CSS实现细节
通用表盘样式
.clock { width: 200px; height: 200px; border: 2px solid #000; border-radius: 50%; position: relative; /* 让内部数字以表盘为定位参考 */ margin: 20px; } .clock span { position: absolute; width: 20px; height: 20px; text-align: center; line-height: 20px; top: 50%; left: 50%; margin: -10px 0 0 -10px; /* 让数字中心与表盘中心重合 */ }
这里的margin: -10px是为了抵消数字自身宽高的一半,确保数字的中心点和表盘中心点完全重合,后续的旋转和平移都基于这个中心点。
12小时制数字定位
/* 12小时制:每个数字间隔30°(360°/12) */ .clock-12 span:nth-child(1) { transform: rotate(0deg) translate(0, -90px) rotate(0deg); } .clock-12 span:nth-child(2) { transform: rotate(30deg) translate(0, -90px) rotate(-30deg); } .clock-12 span:nth-child(3) { transform: rotate(60deg) translate(0, -90px) rotate(-60deg); } .clock-12 span:nth-child(4) { transform: rotate(90deg) translate(0, -90px) rotate(-90deg); } .clock-12 span:nth-child(5) { transform: rotate(120deg) translate(0, -90px) rotate(-120deg); } .clock-12 span:nth-child(6) { transform: rotate(150deg) translate(0, -90px) rotate(-150deg); } .clock-12 span:nth-child(7) { transform: rotate(180deg) translate(0, -90px) rotate(-180deg); } .clock-12 span:nth-child(8) { transform: rotate(210deg) translate(0, -90px) rotate(-210deg); } .clock-12 span:nth-child(9) { transform: rotate(240deg) translate(0, -90px) rotate(-240deg); } .clock-12 span:nth-child(10) { transform: rotate(270deg) translate(0, -90px) rotate(-270deg); } .clock-12 span:nth-child(11) { transform: rotate(300deg) translate(0, -90px) rotate(-300deg); } .clock-12 span:nth-child(12) { transform: rotate(330deg) translate(0, -90px) rotate(-330deg); }
rotate(30deg):把数字转到对应小时的角度位置translate(0, -90px):向外平移90px(表盘半径100px - 数字高度一半10px)rotate(-30deg):把数字反向旋转回来,保持文字水平
24小时制数字定位
/* 24小时制:每个数字间隔15°(360°/24) */ .clock-24 span:nth-child(1) { transform: rotate(0deg) translate(0, -90px) rotate(0deg); } .clock-24 span:nth-child(2) { transform: rotate(15deg) translate(0, -90px) rotate(-15deg); } .clock-24 span:nth-child(3) { transform: rotate(30deg) translate(0, -90px) rotate(-30deg); } .clock-24 span:nth-child(4) { transform: rotate(45deg) translate(0, -90px) rotate(-45deg); } .clock-24 span:nth-child(5) { transform: rotate(60deg) translate(0, -90px) rotate(-60deg); } .clock-24 span:nth-child(6) { transform: rotate(75deg) translate(0, -90px) rotate(-75deg); } .clock-24 span:nth-child(7) { transform: rotate(90deg) translate(0, -90px) rotate(-90deg); } .clock-24 span:nth-child(8) { transform: rotate(105deg) translate(0, -90px) rotate(-105deg); } .clock-24 span:nth-child(9) { transform: rotate(120deg) translate(0, -90px) rotate(-120deg); } .clock-24 span:nth-child(10) { transform: rotate(135deg) translate(0, -90px) rotate(-135deg); } .clock-24 span:nth-child(11) { transform: rotate(150deg) translate(0, -90px) rotate(-150deg); } .clock-24 span:nth-child(12) { transform: rotate(165deg) translate(0, -90px) rotate(-165deg); } .clock-24 span:nth-child(13) { transform: rotate(180deg) translate(0, -90px) rotate(-180deg); } .clock-24 span:nth-child(14) { transform: rotate(195deg) translate(0, -90px) rotate(-195deg); } .clock-24 span:nth-child(15) { transform: rotate(210deg) translate(0, -90px) rotate(-210deg); } .clock-24 span:nth-child(16) { transform: rotate(225deg) translate(0, -90px) rotate(-225deg); } .clock-24 span:nth-child(17) { transform: rotate(240deg) translate(0, -90px) rotate(-240deg); } .clock-24 span:nth-child(18) { transform: rotate(255deg) translate(0, -90px) rotate(-255deg); } .clock-24 span:nth-child(19) { transform: rotate(270deg) translate(0, -90px) rotate(-270deg); } .clock-24 span:nth-child(20) { transform: rotate(285deg) translate(0, -90px) rotate(-285deg); } .clock-24 span:nth-child(21) { transform: rotate(300deg) translate(0, -90px) rotate(-300deg); } .clock-24 span:nth-child(22) { transform: rotate(315deg) translate(0, -90px) rotate(-315deg); } .clock-24 span:nth-child(23) { transform: rotate(330deg) translate(0, -90px) rotate(-330deg); } .clock-24 span:nth-child(24) { transform: rotate(345deg) translate(0, -90px) rotate(-345deg); }
原理和12小时制完全一致,只是把旋转角度从30°改成了15°。
为什么不用top/left?
如果用top/left定位,需要手动计算每个数字的坐标:
- 坐标公式:
x = 圆心x + 半径 * cos(角度),y = 圆心y + 半径 * sin(角度) - CSS里无法直接计算三角函数,必须手动算出每个点的具体像素值,不仅麻烦,而且修改表盘尺寸时要重新计算所有坐标。
- 用旋转+平移的方式,只需要调整平移距离(根据表盘半径)和旋转角度,灵活性更高。
内容的提问来源于stack exchange,提问作者Kersmo
相关产品推荐
相关产品推荐

