You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何仅通过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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 20:29:56