如何仅通过CSS自动获取元素数量?Express+EJS轮播图问题
解决EJS动态图片数量下CSS自动轮播失效问题
问题背景
在Express的EJS页面中实现自动滚动轮播,需求是根据图片数量自动调整轮播的间距和滚动速度。尝试用CSS计数器获取图片数量,但轮播无法滚动,且CSS中.slide-track的width属性提示「无效属性值」。
现有代码
HTML(EJS)
<% if (screenshotsLength > 0) { %> <div class="slide-body"> <div class="slider"> <div class="slide-track"> <% for (let i=0; i<screenshotsLength; i++) { %> <div class="slide"> <a href="<%= game.screenshots[i].url %>" target="_blank"><img src="<%= game.screenshots[i].url %>" alt="screenshot" class="img-scroll"></a> </div> <% } %> <!-- same slides doubled --> <% for (let i=0; i<screenshotsLength; i++) { %> <div class="slide"> <a href="<%= game.screenshots[i].url %>" target="_blank"><img src="<%= game.screenshots[i].url %>" alt="screenshot" class="img-scroll"></a> </div> <% } %> </div> </div> </div> <% } %>
CSS
.slide-body { min-height: 20vh; display: grid; place-items: center; } .slider { height: 250px; margin: auto; position: relative; width: 90%; display: grid; place-items: center; overflow: hidden; } .slide-track { counter-reset: screenshot-counter 0; display: flex; width: calc((screenshot-counter) * 250px); animation: scroll 40s linear infinite; } @keyframes scroll { 0% { transform: translateX(0); } 100% { transform: translateX(calc(-250px * (screenshot-counter/2))); } } .slide { height: 200px; width: 250px; display: flex; align-items: center; padding: 15px; perspective: 100px; } .slide-track .slide { counter-increment: screenshot-counter 1; } .slide:hover { cursor: pointer; } .img-scroll { width: 100%; transition: transform 1s; } .img-scroll:hover { transform: translateZ(20px); } /* gradient shadows */ .slider::before, .slider::after { background: linear-gradient(to right, rgba(46,52,64,1) 0%, rgba(46,52,64,0) 100%); content: ''; height: 100%; position: absolute; width: 15%; z-index: 2; } .slider::before { left: 0; top: 0; } .slider::after { right: -1; top: 0; transform: rotateZ(180deg); }
问题原因
CSS计数器的screenshot-counter无法直接参与calc计算——计数器的counter()函数仅能用于content属性,不能作为数值变量在width或动画位移中使用,这直接导致.slide-track的宽度计算失效,轮播无法正常滚动。
解决方案
既然EJS已经通过screenshotsLength变量知道图片数量,直接用这个变量动态注入CSS自定义属性,替代CSS计数器的方案:
1. 修改HTML,注入动态变量
给.slide-track添加行内样式,传入图片数量和单张图片宽度:
<div class="slide-track" style="--slide-count: <%= screenshotsLength %>; --slide-width: 250px;">
2. 调整CSS代码
删除所有计数器相关代码,改用自定义属性计算宽度和动画参数:
.slide-track { display: flex; /* 总宽度=单张宽度 * 图片数量 * 2(因为复制了一遍轮播项) */ width: calc(var(--slide-width) * var(--slide-count) * 2); /* 动画时长随图片数量调整,这里设为每张图4秒,可自行修改 */ animation: scroll calc(var(--slide-count) * 4s) linear infinite; } @keyframes scroll { 0% { transform: translateX(0); } /* 滚动位移= -单张宽度 * 图片数量,刚好滚完第一组轮播项 */ 100% { transform: translateX(calc(-1 * var(--slide-width) * var(--slide-count))); } } /* 给slide添加box-sizing,避免padding导致宽度计算偏差 */ .slide { box-sizing: border-box; height: 200px; width: 250px; display: flex; align-items: center; padding: 15px; perspective: 100px; } /* 修正slider伪元素的right值,原来的-1无效 */ .slider::after { right: 0; top: 0; transform: rotateZ(180deg); }
3. 效果说明
- 轮播总宽度会根据图片数量自动计算,确保所有轮播项能完整排列
- 动画时长随图片数量线性增加,保证每张图片的展示时长一致
- 滚动位移精准对应第一组轮播项的总宽度,配合复制的第二组轮播项,实现无缝循环滚动
内容的提问来源于stack exchange,提问作者Sami
相关产品推荐
相关产品推荐

