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

基于React实现居中卡片高亮、其余淡出的水平卡片滑块

实现居中卡片高亮的水平滑块方案

方案一:基于react-slick改造

react-slick本身支持centerMode模式,结合CSS就能实现淡出效果,步骤如下:

  1. 先安装依赖:
npm install react-slick slick-carousel
  1. 编写组件代码:
import React from 'react';
import Slider from 'react-slick';
// 引入slick的基础样式
import 'slick-carousel/slick/slick.css';
import 'slick-carousel/slick/slick-theme.css';
import './CustomSlider.css';

const HighlightSlider = () => {
  const sliderSettings = {
    centerMode: true, // 开启居中模式
    centerPadding: '60px', // 两侧留白
    slidesToShow: 3, // 同时显示3张卡片
    infinite: true,
    speed: 500,
    arrows: true,
    dots: false,
  };

  // 模拟卡片数据
  const cardList = [1,2,3,4,5].map(num => (
    <div className="slide-card" key={num}>
      <h3>Card {num}</h3>
    </div>
  ));

  return (
    <div className="slider-container">
      <Slider {...sliderSettings}>
        {cardList}
      </Slider>
    </div>
  );
};

export default HighlightSlider;
  1. 添加自定义CSS:
.slider-container {
  width: 80%;
  margin: 0 auto;
}

.slide-card {
  background: #fff;
  padding: 40px;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0,0,0,0.1);
  opacity: 0.5; /* 默认淡出 */
  transition: all 0.3s ease;
}

/* 选中的居中卡片高亮 */
.slick-center .slide-card {
  opacity: 1;
  transform: scale(1.1);
  box-shadow: 0 4px 16px rgba(0,0,0,0.2);
}

这个方案利用react-slick内置的slick-center类标记居中卡片,通过CSS控制透明度和样式,快速实现需求。

方案二:自定义滑块组件

如果需要更灵活的淡出逻辑(比如根据距离设置不同透明度),可以自己实现滑块:

import React, { useState, useRef, useEffect } from 'react';
import './CustomSlider.css';

const CustomHighlightSlider = () => {
  const [activeIndex, setActiveIndex] = useState(2); // 默认选中中间卡片
  const sliderContainerRef = useRef(null);
  const cardList = [1,2,3,4,5];

  // 监听滚动,自动计算居中的卡片
  useEffect(() => {
    const handleScroll = () => {
      const container = sliderContainerRef.current;
      const scrollLeft = container.scrollLeft;
      const singleCardWidth = container.querySelector('.slide-card').offsetWidth;
      const centerOffset = container.offsetWidth / 2;
      // 计算当前居中的卡片索引
      const currentIndex = Math.round((scrollLeft + centerOffset) / singleCardWidth);
      setActiveIndex(Math.max(0, Math.min(cardList.length - 1, currentIndex)));
    };

    const container = sliderContainerRef.current;
    container.addEventListener('scroll', handleScroll);
    return () => container.removeEventListener('scroll', handleScroll);
  }, [cardList.length]);

  // 上一张按钮逻辑
  const goToPrev = () => {
    const newIndex = Math.max(0, activeIndex - 1);
    setActiveIndex(newIndex);
    const container = sliderContainerRef.current;
    const singleCardWidth = container.querySelector('.slide-card').offsetWidth;
    container.scrollTo({ left: singleCardWidth * newIndex, behavior: 'smooth' });
  };

  // 下一张按钮逻辑
  const goToNext = () => {
    const newIndex = Math.min(cardList.length - 1, activeIndex + 1);
    setActiveIndex(newIndex);
    const container = sliderContainerRef.current;
    const singleCardWidth = container.querySelector('.slide-card').offsetWidth;
    container.scrollTo({ left: singleCardWidth * newIndex, behavior: 'smooth' });
  };

  return (
    <div className="custom-slider-wrapper">
      <button onClick={goToPrev} className="slider-btn">←</button>
      <div className="custom-slider-container" ref={sliderContainerRef}>
        {cardList.map((num, index) => {
          // 根据与选中卡片的距离设置透明度
          const distance = Math.abs(index - activeIndex);
          let opacity = 1;
          if (distance === 1) opacity = 0.7;
          else if (distance >= 2) opacity = 0.3;

          return (
            <div
              className="slide-card"
              key={num}
              style={{ opacity, transition: 'opacity 0.3s ease' }}
            >
              <h3>Card {num}</h3>
            </div>
          );
        })}
      </div>
      <button onClick={goToNext} className="slider-btn">→</button>
    </div>
  );
};

export default CustomHighlightSlider;

对应的CSS:

.custom-slider-wrapper {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 20px;
  width: 90%;
  margin: 0 auto;
}

.custom-slider-container {
  display: flex;
  gap: 20px;
  overflow-x: auto;
  scroll-behavior: smooth;
  padding: 20px 0;
  width: 100%;
  max-width: 800px;
}

/* 隐藏滚动条 */
.custom-slider-container::-webkit-scrollbar {
  display: none;
}

.slide-card {
  flex: 0 0 200px;
  background: #fff;
  padding: 40px;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}

.slider-btn {
  padding: 10px 15px;
  font-size: 20px;
  border: none;
  background: #eee;
  border-radius: 4px;
  cursor: pointer;
}

这个方案可以完全控制淡出规则,比如距离选中卡片越远,透明度越低,适合定制化需求高的场景。

内容的提问来源于stack exchange,提问作者missgoyal

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 16:43:10