如何避免非等宽字体倒计时器跳动移位(HTML/CSS/JS实现)
解决非等宽字体倒计时数字跳动问题
核心思路是给每个倒计时数字单独分配固定宽度的容器,让数字在容器内居中显示,这样不管数字本身宽度如何变化,容器的占位空间始终一致,彻底避免切换时的移位跳动。
步骤1:重构HTML结构
把原来的单个文本容器拆分为独立的数字容器和冒号,确保每个数字都有专属的固定空间:
<link href="https://fonts.googleapis.com/css2?family=Karla:ital,wght@0,200..800;1,200..800&display=swap" rel="stylesheet"> <div id="timer-container"> <div id="time-left"> <span class="digit">2</span> <span class="digit">5</span> <span class="colon">:</span> <span class="digit">0</span> <span class="digit">0</span> </div> </div>
步骤2:添加CSS固定宽度样式
给每个数字容器设置固定宽度,同时让数字在容器内水平/垂直居中,冒号保持原有样式即可:
#timer-container { position: relative; margin-top: 0.5rem; display: flex; justify-content: center; align-items: center; background-color: transparent; cursor: pointer; border: 2px solid transparent; border-radius: 50px; transition: border-color 0.2s ease-in-out; overflow: hidden; max-height: 180px; padding: 0px 20px; } #timer-container:hover { border-color: black; } #time-left { font-family: "Karla", sans-serif; font-size: 10.375rem; font-weight: 600; margin-bottom: 1rem; user-select: none; position: relative; z-index: 1; opacity: 1; /* 用flex让数字和冒号整齐排列 */ display: flex; gap: 0.2rem; /* 调整数字和冒号的间距 */ } .digit { /* 设置固定宽度,根据字体大小调整,这里适配10.375rem的字号 */ width: 8rem; display: inline-block; text-align: center; /* 确保数字垂直居中 */ line-height: 1; } .colon { /* 冒号不需要固定宽度,保持原有紧凑感 */ letter-spacing: -5px; }
步骤3:修改JavaScript更新逻辑
不再直接修改整个文本内容,而是拆分分钟和秒的每一位数字,逐个更新对应的容器:
let timeLeft = 25 * 60; // seconds let timerInterval; // 获取所有数字容器 const digitElements = document.querySelectorAll('.digit'); // 启动计时器 function startTimer() { timerInterval = setInterval(() => { timeLeft--; updateTimeLeftDigits(); if (timeLeft === 0) { clearInterval(timerInterval); } }, 1000); } // 逐个更新数字容器内容 function updateTimeLeftDigits() { const minutes = Math.floor(timeLeft / 60); const seconds = timeLeft % 60; // 把分钟和秒转为两位字符串,拆成单个字符数组 const timeStr = `${minutes.toString().padStart(2, '0')}${seconds.toString().padStart(2, '0')}`; // 遍历更新每个数字容器 digitElements.forEach((el, index) => { el.textContent = timeStr[index]; }); } startTimer()
关键说明
- 固定宽度容器:
.digit的width值需要根据你的字体大小调整,确保能容纳Karla字体中最宽的数字(比如"8"),避免数字溢出。 - Flex布局:
#time-left用flex布局可以让数字和冒号整齐排列,gap属性控制间距,比原来的letter-spacing更可控。 - 数字拆分更新:通过把时间转为字符串并拆分,精准控制每个数字容器的内容,保证切换时只有容器内的数字变化,容器本身位置完全不动。
之前尝试的ch单位失效是因为非等宽字体中,1ch等于字体中"0"的宽度,但其他数字(比如"1"、"8")的宽度和"0"不一致,所以无法保证所有数字占相同空间,固定宽度的容器是更可靠的方案。
内容的提问来源于stack exchange,提问作者sameetpatil5
相关产品推荐
相关产品推荐

