Skip to content

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Fixed Width Peek Carousel

一个基于 Swiper.js 实现的响应式固定宽度卡片轮播组件。

它与常见的“一屏固定显示 3 张 / 4 张”轮播不同:本项目先为卡片定义合适的自然宽度,再通过 slidesPerView: 'auto' 让浏览器根据当前视口决定实际可见数量,并刻意露出下一张卡片的一部分,形成清晰的横向浏览暗示。

适合产品系列、案例展示、服务项目、作品集、区域方案、车型目录等需要突出大图视觉,同时又希望保留连续浏览感的页面场景。


效果特点

  • 固定宽度卡片,而不是按容器平均分栏
  • 使用 slidesPerView: 'auto' 自然决定可见数量
  • 右侧保留“下一张预览”,提示内容仍可继续浏览
  • 桌面端提供上一张 / 下一张方向按钮
  • 手机端隐藏方向按钮,优先使用触控滑动
  • 支持分类 Tabs,并为每个分类维护独立 Swiper
  • 隐藏分类首次打开时再初始化,避免隐藏容器尺寸计算异常
  • 卡片保持统一竖版比例
  • 图片底部渐变文字覆盖层
  • 轻量图片 Hover 放大效果
  • 首次显示使用错位上浮动画
  • 支持键盘方向键切换 Tabs
  • 支持 prefers-reduced-motion
  • Swiper JS / CSS 全部本地加载,运行时不依赖 CDN

核心设计思路

普通多卡片轮播经常使用:

slidesPerView: 4

这意味着卡片宽度通常由容器宽度反推:

容器宽度 ÷ 4 = 单张卡片宽度

本项目采用另一种思路:

先确定卡片最舒服的自然尺寸
        ↓
Swiper 使用 slidesPerView: 'auto'
        ↓
视口决定当前能够看到几张
        ↓
最后一张允许局部露出
        ↓
形成继续横向浏览的视觉提示

核心初始化参数非常简单:

new Swiper(swiperEl, {
  slidesPerView: 'auto',
  spaceBetween: 24,
  speed: 650,
  grabCursor: true,
  watchOverflow: true
});

真正决定布局效果的是 Swiper 与 CSS 卡片宽度共同配合,而不是不断增加 breakpoints 去规定每个屏幕必须显示几张。


关键尺寸

项目 桌面端 手机端
卡片宽度 370px 300px
卡片比例 370 / 497 保持相同比例
卡片间距 24px 24px
页面左右留白 80px 20px
方向按钮 显示 隐藏
主要交互 按钮 + 拖拽 Touch Swipe

项目通过 CSS 变量集中维护主要尺寸:

:root {
  --card-width: 370px;
  --card-gap: 24px;
  --page-padding: 80px;
}

手机端只需要调整核心变量:

@media (max-width: 960px) {
  :root {
    --card-width: 300px;
  }
}

@media (max-width: 600px) {
  :root {
    --page-padding: 20px;
  }
}

这种方式比为不同设备分别维护 1 / 2 / 3 / 4 张卡片数量更直观,也更容易长期维护。


为什么手机端能够露出下一张

以常见的 375px 手机视口为例:

左侧留白      20px
第一张卡片   300px
卡片间距      24px
-----------------
第二张起点   344px

因此当前视口还剩:

375 - 344 = 31px

第二张卡片会自然露出约 31px。

这种设计比单纯使用 width: 100% 的单卡片轮播更容易让用户意识到页面可以继续横向滑动。


Overflow 结构

“下一张预览”并不是通过特殊 Swiper Effect 实现,而是由两层不同的溢出规则共同完成:

Section / Viewport
└── overflow: hidden

Swiper
└── overflow: visible
.carousel-viewport {
  overflow: hidden;
}

.model-swiper {
  overflow: visible;
}

Swiper 轨道可以继续向右延伸,但最终由外层视口负责裁切,于是自然形成卡片局部露出的效果。


分类 Tabs

页面演示包含:

  • 全部
  • 布局
  • 交互
  • 响应式
  • 细节

每个 Tab 对应一个独立的 tabpanel 和 Swiper 容器。

项目没有在页面加载时一次性初始化所有隐藏轮播,而是:

页面首次加载
   ↓
只初始化当前可见分类
   ↓
点击其他 Tab
   ↓
显示对应 Panel
   ↓
首次进入时创建 Swiper
   ↓
再次进入直接复用已有实例

这样可以避免隐藏元素在 display: none 状态下初始化时出现宽度、位置或边界判断异常,同时保持逻辑简单。


卡片结构

单张卡片结构保持非常轻量:

<div class="swiper-slide">
  <a class="model-card" href="#">
    <span class="model-thumbnail">
      <img src="images/01.svg" alt="">
    </span>

    <span class="model-box">
      <strong class="model-title">标题</strong>
      <span class="model-subtitle">描述文字</span>
    </span>
  </a>
</div>

图片负责视觉内容,标题和描述始终保持为真实 HTML 文本,因此后期替换内容、添加链接、接入 CMS 或 WordPress 数据都比较方便。


图片与文字层

卡片使用:

aspect-ratio: 370 / 497;

图片:

object-fit: cover;

因此实际项目中不要求所有图片严格使用同一像素尺寸,只要构图适合竖版卡片即可。

为了保证白色文字在不同图片上都有稳定可读性,底部使用伪元素增加渐变遮罩:

.model-card::after {
  height: 58%;
  background: linear-gradient(
    0deg,
    rgba(0, 0, 0, .94) 0%,
    rgba(0, 0, 0, .72) 31%,
    rgba(0, 0, 0, 0) 100%
  );
}

文字本身并不写进图片中,因此更适合真实网站长期维护。


Hover 与入场动效

桌面端只做轻微图片放大:

.model-card:hover .model-thumbnail img {
  transform: scale(1.02);
}

放大幅度刻意保持克制,避免大尺寸图片卡片出现明显跳动。

卡片首次显示时使用轻量上浮动画,并通过 --slide-delay 制造简单的错位进入效果。

同时提供:

@media (prefers-reduced-motion: reduce)

当用户系统设置为“减少动态效果”时,会自动降低动画和过渡强度。


项目结构

fixed-width-peek-carousel/
├── index.html
├── README.md
├── css/
│   └── style.css
├── js/
│   └── main.js
├── images/
│   ├── 01.svg
│   ├── 02.svg
│   ├── ...
│   └── 12.svg
└── vendor/
    └── swiper/
        ├── swiper-bundle.min.css
        ├── swiper-bundle.min.js
        ├── LICENSE
        └── README.md

HTML、项目 CSS、项目 JS、演示图片和第三方依赖完全分离,方便后续单独复制组件或替换内容。


本地运行

项目没有构建流程,也不依赖 npm。

直接打开:

index.html

即可预览。

如果浏览器或后续功能涉及本地资源安全限制,也可以通过任意本地 HTTP Server 运行。


Swiper 本地依赖

项目使用本地 Swiper Bundle:

<link rel="stylesheet" href="vendor/swiper/swiper-bundle.min.css">

<script src="vendor/swiper/swiper-bundle.min.js"></script>
<script src="js/main.js"></script>

运行页面时不会请求远程 CDN。

Swiper 自身的许可证文件保留在:

vendor/swiper/LICENSE

第三方库建议保持独立目录,不要与项目自己的 css/style.css、js/main.js 混在一起,方便以后升级或替换。


如何替换成真实内容

1. 替换图片

把:

<img src="images/01.svg" alt="">

替换为真实项目图片即可。

2. 修改标题和描述

<strong class="model-title">产品名称</strong>
<span class="model-subtitle">产品或案例说明</span>

3. 修改链接

<a class="model-card" href="product-detail.html">

4. 增加卡片

复制一个完整的:

<div class="swiper-slide">...</div>

Swiper 会自动重新计算轨道长度,不需要修改 slidesPerView。


如何调整卡片尺寸

桌面端只需要修改:

--card-width: 370px;

例如改为:

--card-width: 420px;

卡片会变宽,同时视口中自然显示更少的卡片。

这也是本组件最重要的设计原则:

不优先决定“一屏显示几张”,而是优先决定“单张卡片应该多宽”。


如何调整卡片比例

当前比例:

aspect-ratio: 370 / 497;

如果用于横向案例图,可以直接修改,例如:

aspect-ratio: 4 / 3;

或者:

aspect-ratio: 16 / 10;

Swiper 逻辑不需要同步修改。


适用场景

产品系列

适合家具、地板、墙板、建材、机械设备、消费品等视觉型产品目录。

项目案例

适合建筑、室内设计、网站设计、品牌设计、工程案例和 Portfolio。

服务展示

适合:

Web Design
Development
SEO
Hosting
Maintenance
AI Integration

区域解决方案

适合按照国家、区域或市场展示不同解决方案。

分类作品库

顶部 Tabs + 下方独立轮播的结构可以直接用于按类别浏览作品。


与普通响应式多卡片轮播的区别

对比项 普通多卡片轮播 本项目
核心参数 slidesPerView: 1/2/4 slidesPerView: 'auto'
卡片宽度 随容器平均变化 保持自然固定宽度
可见数量 人工规定 由视口自然决定
下一张提示 通常没有 刻意局部露出
手机端 经常整屏单卡 300px 卡片 + 下一张预览
响应逻辑 多个 breakpoint 主要调整卡片宽度与留白
适合方向 标准信息卡片 视觉型产品 / 案例展示

两种方案没有绝对优劣,关键是页面目标不同。

如果要求严格保持整齐网格感,固定 slidesPerView 更合适;如果希望卡片拥有稳定视觉尺寸,并强化连续浏览感,本项目这种方式更合适。


维护建议

建议长期保持

  • slidesPerView: 'auto'
  • CSS 控制 .swiper-slide 宽度
  • spaceBetween: 24
  • 外层裁切、Swiper 内部允许可见溢出
  • 桌面按钮 + 手机 Touch Swipe
  • Swiper 依赖本地化

不建议为了功能继续复杂化

如果真实项目没有明确需求,不建议默认增加:

  • Autoplay
  • Pagination Bullets
  • Loop
  • 多层嵌套 Swiper
  • 复杂 3D Effect
  • 大量设备断点

这个组件的价值就在于:

用较少的结构和参数,获得稳定、自然、易理解的横向浏览体验。


可访问性

当前演示已经包含:

  • Tabs 使用 role="tablist" / role="tab" / role="tabpanel"
  • aria-selected
  • aria-controls
  • 键盘左右方向键切换 Tabs
  • Home / End 快速移动
  • 轮播按钮包含 aria-label
  • Swiper A11y 模块开启
  • Focus 状态可见
  • prefers-reduced-motion 动画降级

真实项目中替换图片后,建议根据图片内容补充有意义的 alt 文本。


技术要点总结

Fixed Width Card
        +
slidesPerView: auto
        +
spaceBetween
        +
overflow hidden / visible
        +
Touch Drag
        +
Desktop Navigation
        +
Responsive CSS Variables

可以把这一类效果理解为:

Fixed-Width Peek Carousel

即:

固定宽度卡片 + 下一张局部预览的响应式横向轮播。


后续扩展方向

如真实项目确有需要,可以在当前结构基础上继续扩展:

  • WordPress / Gutenberg 动态数据
  • 产品分类动态生成 Tabs
  • API / JSON 数据驱动
  • 图片懒加载策略优化
  • 卡片数量较多时的性能优化
  • 分类 URL 状态同步
  • 深色主题

建议继续保持当前组件边界,不为了增加功能而破坏原本简单清晰的结构。

About

基于 Swiper.js 的响应式固定宽度卡片轮播组件,通过 slidesPerView: auto、固定卡片宽度和下一张局部预览,实现适合产品、案例与作品展示的自然横向浏览体验。

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages