如何在left、translate等CSS属性中结合CSS变量使用calc?
问题描述
我为每个.item项定义了--index变量,希望在项激活时让蓝色指示器拥有正确偏移量并实现动画效果。但目前只有font-size属性能正常读取该参数,left和translate属性均无法生效,求解决办法。
原因分析
你的--index变量是定义在每个.item元素上的,而蓝色指示器.indicator是独立的兄弟元素,无法直接读取其他元素上的CSS变量,这就是left/translate不生效的核心原因。
解决方案
点击切换tab时,把当前激活项的--index值同步到父容器(或直接给指示器)上,让指示器能读取到这个变量,再配合transition实现动画。
修改后的代码
JavaScript
const items = document.querySelectorAll('.item') const container = document.querySelector('.container') const tabClicked = (e)=>{ if(e.target.classList.contains('active')){ return; } items.forEach(item=>{ item.classList.remove('active') }) e.target.classList.add('active') // 获取当前激活项的--index值并同步到容器 const index = getComputedStyle(e.target).getPropertyValue('--index') container.style.setProperty('--active-index', index) } items.forEach(item=>{ item.addEventListener('click', tabClicked) })
CSS
.container { display: flex; flex-direction: column; position: relative; /* 默认值,对应第一个tab */ --active-index: 1; } .item-container { width: 800px; background: gray; display: flex; height: 50px; } .container .item { width: 150px; background-color: red; display: grid; place-items: center; font-size: calc(5px * var(--index, 1)); } .container .item.active { background-color: yellow; } .indicator { width: 150px; height: 5px; background-color: blue; position:absolute; bottom:0; /* 使用容器上的--active-index变量,计算偏移时要减1,因为第一个index是1,偏移应该是0 */ left: calc(150px * (var(--active-index) - 1)); /* 添加过渡动画 */ transition: left 0.3s ease; }
HTML(无需修改)
<div class="container"> <div class="item-container"> <div class="item" style="--index:1">A sample</div> <div class="item active" style="--index:2">B sample</div> <div class="item" style="--index:3">C sample</div> <div class="item" style="--index:4">D sample</div> </div> <div class="indicator"></div> </div>
关键说明
- 同步变量:通过
getComputedStyle获取激活项的--index值,再用setProperty设置到父容器的--active-index上,让指示器可以读取 - 偏移修正:计算
left时要(var(--active-index) - 1),因为第一个tab的--index是1,偏移应该是0(150px*(1-1)=0),第二个是150px*(2-1)=150px,以此类推 - 动画实现:给指示器添加
transition: left 0.3s ease,实现平滑的偏移过渡
内容的提问来源于stack exchange,提问作者George Guo
相关产品推荐
相关产品推荐

