如何实现一个可滚动的区域,并配有固定位置的自定义滚动按钮?

前端开发 2026-07-09

我正在尝试创建一个横向缩略图的可滚动托盘,带自定义滚动按钮且没有滚动条。

托盘的宽度将比父容器要宽,我希望按钮的div固定在父容器上,这样托盘滚动时它们保持在同一个位置。

我尝试把按钮的div设置为position: absolute,虽然它们锚定在父div上,但它们仍然会随托盘div一起向左向右滚动。

这是一个最小可运行的复现:

<html>

<head>
</head>

<body>

    <style>

        .folio_ss_cont {
            position: relative;
            width: 50%;
            overflow: hidden;
            overflow-x: auto;
            background: #faa;
            color: #fff;
        }

        .folio_ss_slider {
            width: fit-content;
            min-width: 100%;
            display: flex;
            flex-flow: row nowrap;
            background: #afa;
        }

        .folio_ss_slider a {
            margin: min(3vw, 3vh);
        }

        .folio_ss_item_cont {
            width: 30vw;
            background: #aaf;
        }

        .folio_ss_item_thm {
            width: 100%;
            aspect-ratio: 1;
            margin-bottom: min(1vw, 1vh);
        }

        .folio_ss_item_cont p {
            margin-bottom: 0 !important;
        }

        .folio_ss_btn_scroll_L,
        .folio_ss_btn_scroll_R {
            position: absolute;
            bottom: 0;
            height: 33%;
            aspect-ratio: 1.5;
            box-sizing: border-box;
            background: #000;
            opacity: 0.36;
            padding: 3vw;
            display: flex;
            justify-content: center;
            align-items: center;
            font-size: 2em;
        }

        .folio_ss_btn_scroll_L {
            left: 0;
        }

        .folio_ss_btn_scroll_R {
            right: 0;
        }

    </style>

    <div class="folio_ss_cont">

        <div class="folio_ss_slider" id="fss_slider_cine">

            <a>
                <div class="folio_ss_item_cont">
                    <img class="folio_ss_item_thm" alt="Thumbnail image" src="/img/folio_thumbs/1.jpg" />
                    <p>Item 1</p>
                </div>
            </a>

            <a>
                <div class="folio_ss_item_cont">
                    <img class="folio_ss_item_thm" alt="Thumbnail image" src="/img/folio_thumbs/2.jpg" />
                    <p>Item 2</p>
                </div>
            </a>

            <a>
                <div class="folio_ss_item_cont">
                    <img class="folio_ss_item_thm" alt="Thumbnail image" src="/img/folio_thumbs/3.jpg" />
                    <p>Item 3</p>
                </div>
            </a>

            <a>
                <div class="folio_ss_item_cont">
                    <img class="folio_ss_item_thm" alt="Thumbnail image" src="/img/folio_thumbs/4.jpg" />
                    <p>Item 4</p>
                </div>
            </a>



        </div>

        <div class="folio_ss_btn_scroll_L" onclick="folioSliderScroll('L')">❰</div>
        <div class="folio_ss_btn_scroll_R" onclick="folioSliderScroll('R')">❱</div>

    </div>

</body>
</html>

起初显示正常,但尝试向左滚动托盘时——大型灰色按钮会与托盘div一起滚动,尽管它们只是该div的兄弟节点而不是子元素!

我尝试把按钮的div设置为position: sticky,但这会把它们的整个高度加到容器div上,从而导致尺寸错乱。它还似乎只让左边的按钮div固定住——右边的按钮div被卡在托盘的最右边,并随托盘一起往左往右滚动。

如何让这些按钮的div固定在容器div的左下角和右下角,同时又让托盘div在它们下面可以滚动,并且托盘内的 元素也能被点击?

解决方案

你有没有理由让顶部的容器成为拥有overflow:auto的那个?把overflow:auto放在滑块上要简单得多。如果你这么做,事情就会变得很直接。

我也把你的按钮改成了真正的按钮。div只用于承载内容,它们不是交互元素。按钮不仅仅是外观,还有更多要考虑的点...

最后,既然你看起来像是在做某种轮播,我建议采用更现代的方法,使用CSS滚动捕捉(scroll snapping)和滚动锚点(scroll anchoring)。Chrome.dev有一套很棒的演示示例,像这个示例 甚至还有一个 配置器

.folio_ss_cont {
  position: relative;
  width: 50%;
  background: #faa;
  color: #fff;
}

.folio_ss_slider {
  overflow: auto;
  min-width: 100%;
  display: flex;
  flex-flow: row nowrap;
  background: #afa;
}

.folio_ss_slider a {
  margin: min(3vw, 3vh);
}

.folio_ss_item_cont {
  width: 30vw;
  background: #aaf;
}

.folio_ss_item_thm {
  width: 100%;
  aspect-ratio: 1;
  margin-bottom: min(1vw, 1vh);
}

.folio_ss_item_cont p {
  margin-bottom: 0 !important;
}

.folio_ss_btn_scroll_L,
.folio_ss_btn_scroll_R {
  all: unset;
  position: absolute;
  z-index: 10;
  bottom: 0;
  height: 33%;
  aspect-ratio: 1.5;
  box-sizing: border-box;
  background: #000;
  opacity: 0.36;
  padding: 3vw;
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 2em;
}

.folio_ss_btn_scroll_L {
  left: 0;
}

.folio_ss_btn_scroll_R {
  right: 0;
}
<div class="folio_ss_cont">

  <div class="folio_ss_slider" id="fss_slider_cine">

    <a>
                <div class="folio_ss_item_cont">
                    <img class="folio_ss_item_thm" alt="Thumbnail image" src="/img/folio_thumbs/1.jpg" />
                    <p>Item 1</p>
                </div>
            </a>

    <a>
                <div class="folio_ss_item_cont">
                    <img class="folio_ss_item_thm" alt="Thumbnail image" src="/img/folio_thumbs/2.jpg" />
                    <p>Item 2</p>
                </div>
            </a>

    <a>
                <div class="folio_ss_item_cont">
                    <img class="folio_ss_item_thm" alt="Thumbnail image" src="/img/folio_thumbs/3.jpg" />
                    <p>Item 3</p>
                </div>
            </a>

    <a>
                <div class="folio_ss_item_cont">
                    <img class="folio_ss_item_thm" alt="Thumbnail image" src="/img/folio_thumbs/4.jpg" />
                    <p>Item 4</p>
                </div>
            </a>



  </div>

  <button class="folio_ss_btn_scroll_L" onclick="folioSliderScroll('L')">❰</button>
  <button class="folio_ss_btn_scroll_R" onclick="folioSliderScroll('R')">❱</button>

</div>
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章