本案例仿照星巴克官网的视觉风格与交互模式,使用 Bootstrap 4 构建一个左右分栏的品牌首页。左侧为可切换的固定导航,右侧主体包括轮播广告、产品推荐、登录注册、特色展示与咖啡讲堂等模块,重点练习导航组件、轮播插件、卡片瀑布流与响应式断点切换。

一、案例概述

1.1 业务背景

品牌官网需要在 PC 端展示丰富的视觉内容(轮播、产品矩阵、讲堂),同时在移动端自动切换为简洁的底部 Tab 导航。本案例通过同一套 HTML + CSS 媒体查询,一份代码适配 PC 与手机两种交互。

1.2 涉及知识点

知识点 在本案例中的作用
导航 .nav 左侧主导航、隐藏式二级导航
轮播 .carousel 首页轮播广告
卡片 .card-columns 产品推荐瀑布流
徽章 .btn + 圆角 .rounded-pill 登录/注册胶囊按钮
媒体查询 PC 固定导航、手机底部 Tab
jQuery 动画 animate 咖啡讲堂左右切换
切换类 d-none 主导航与隐藏导航互斥显示

1.3 页面结构

1
2
3
4
5
6
7
8
9
10
11
12
仿星巴克首页
├── 左侧导航(PC 固定,移动折叠到底部)
│ ├── 主导航(账户、菜单)
│ └── 隐藏导航(俱乐部、门店、烘焙工厂等)
├── 右侧主体内容
│ ├── 轮播广告区
│ ├── 产品推荐区(card-columns 瀑布流)
│ ├── 登录注册区 + Logo
│ ├── 咖啡精选区(套餐 1-4)
│ └── 咖啡讲堂区(左右切换)
└── 底部 Tab 导航(仅移动端显示)
├── 主页 / 门店 / 我的账户 / 菜单 / 更多

二、实现步骤拆解

2.1 首页整体布局

使用 body.container > .row 框架,左侧 col-12 col-lg-3、右侧 col-12 col-lg-9,小屏时自动堆叠:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<body class="container">
<div class="row">
<!--左侧导航-->
<div class="col-12 col-lg-3 left">
<ul class="nav"></ul>
<div id="template2" class="d-none"></div>
</div>
<!--右侧主体内容-->
<div class="col-12 col-lg-9 right p-0 clearfix">
<div id="carouselExampleControls" class="carousel slide" data-ride="carousel"></div>
<div class="p-4 list"></div>
<div class="row py-5"></div>
<div class="p-4 list"></div>
<div class="p-4"></div>
</div>
</div>
<!--底部隐藏导航栏-->
<div class="row fixed-bottom d-block d-sm-none bg-light border-top py-1" id="footer"></div>
</body>

2.2 可切换导航

通过 d-none 工具类控制主导航与隐藏导航互斥显示,点击汉堡按钮 #a1 切换:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
<div class="col-12 col-lg-3 left">
<!--主导航 template1-->
<div id="template1">
<div class="row">
<div class="col-10">
<ul class="nav">
<li class="nav-item">
<a href="index.html" class="nav-link active">
<img src="http://pic.58pic.com/58pic/12/06/74/07258PICNyX.jpg" width="40" class="rounded-circle" alt="">
</a>
</li>
<li class="nav-item mt-1"><a href="javascript:void(0);" class="nav-link">账户</a></li>
<li class="nav-item mt-1"><a href="javascript:void(0);" class="nav-link">菜单</a></li>
</ul>
</div>
<div class="col-2 mt-2 font-menu text-right">
<a href="javascript:void(0);" id="a1"><i class="fa fa-bars"></i></a>
</div>
</div>
<div class="margin1">
<h5 class="ml-3 my-3 d-none d-sm-block text-lg-center">
<b>心情惬意、来杯咖啡吧</b>&nbsp;&nbsp;<i class="fa fa-coffee"></i>
</h5>
<div class="ml-3 my-3 d-none d-sm-block text-lg-center">
<a href="#" class="card-link btn rounded-pill text-success">
<i class="fa fa-user-circle"></i>&nbsp;&nbsp;
</a>
<a href="#" class="card-link btn btn-outline-success rounded-pill text-success">&nbsp;</a>
</div>
</div>
</div>
<!--隐藏导航 template2-->
<div id="template2" class="d-none">
<div class="row">
<div class="col-10">
<ul class="nav">
<li class="nav-item">
<a href="index.html" class="nav-link active">
<img src="http://pic.58pic.com/58pic/12/06/74/07258PICNyX.jpg" alt="" width="40" class="rounded-circle">
</a>
</li>
<li class="nav-item"><a href="index.html" class="nav-link mt-2">咖啡俱乐部</a></li>
</ul>
</div>
<div class="col-2 mt-2 font-menu text-right">
<a href="javascript:void(0);" id="a2"><i class="fa fa-times"></i></a>
</div>
</div>
<div class="margin2">
<div class="ml-5 mt-5">
<h6><a href="javascript:;">门店</a></h6>
<h6><a href="javascript:;">俱乐部</a></h6>
<h6><a href="javascript:;">菜单</a></h6>
<hr>
<h6><a href="javascript:;">移动应用</a></h6>
<h6><a href="javascript:;">秦选精品</a></h6>
<h6><a href="javascript:;">专星送</a></h6>
<h6><a href="javascript:;">咖啡讲堂</a></h6>
<h6><a href="javascript:;">烘焙工厂</a></h6>
<h6><a href="javascript:;">帮助中心</a></h6>
</div>
</div>
</div>
</div>

2.3 轮播广告区

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<div id="carouselExampleControls" class="carousel slide" data-ride="carousel">
<div class="carousel-inner max-h">
<div class="carousel-item active">
<img src="https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=3764483885,4083168537&fm=26&gp=0.jpg"
class="d-block w-100" alt="...">
</div>
<div class="carousel-item">
<img src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1592932077110&di=cd7fb84e36a5c1676a00ab4a23579bc8&imgtype=0&src=http%3A%2F%2Fattachment.jmw.com.cn%2Fuploadfile%2F2015%2F0403%2F20150403013807493.jpg"
class="d-block w-100" alt="...">
</div>
<div class="carousel-item">
<img src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1592932114630&di=8016378ca877749b296f64347715841d&imgtype=0&src=http%3A%2F%2Fimg4.imgtn.bdimg.com%2Fit%2Fu%3D3596133729%2C855335225%26fm%3D214%26gp%3D0.jpg"
class="d-block w-100" alt="...">
</div>
</div>
<a href="#carouselExampleControls" class="carousel-control-prev" data-slide="prev">
<span class="carousel-control-prev-icon"></span>
</a>
<a href="#carouselExampleControls" class="carousel-control-next" data-slide="next">
<span class="carousel-control-next-icon"></span>
</a>
</div>

2.4 产品推荐(卡片瀑布流)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<div class="p-4 list">
<h5 class="text-center my-3">咖啡推荐</h5>
<h5 class="text-center mb-4 text-secondary"><small>在购物旗舰店可以发现更多咖啡心意</small></h5>
<!--多列卡片浮动排版-->
<div class="card-columns">
<div class="my-4 my-sm-0">
<img src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1592933913255&di=3cfd49ae1b46e2f9f514532950714019&imgtype=0&src=http%3A%2F%2Fb-ssl.duitang.com%2Fuploads%2Fitem%2F201301%2F28%2F20130128141904_5AwPK.jpeg" class="card-img-top" alt="">
</div>
<div class="my-4 my-sm-0">
<img src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1592933801297&di=adf480a55bf0abf7f224be6f21a9ecca&imgtype=0&src=http%3A%2F%2Fbpic.588ku.com%2Felement_origin_min_pic%2F16%2F08%2F10%2F2157ab2a01b5f6c.jpg" class="card-img-top" alt="">
</div>
<div class="my-4 my-sm-0">
<img src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1592933817124&di=22ba5098fcefd4442a902e8b2ea12b32&imgtype=0&src=http%3A%2F%2Fimg2.imgtn.bdimg.com%2Fit%2Fu%3D2793055047%2C2676139222%26fm%3D214%26gp%3D0.jpg" class="card-img-top" alt="">
</div>
</div>
</div>

2.5 咖啡讲堂(左右切换)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<div class="p-4">
<h5 class="text-center my-3">咖啡讲堂</h5>
<h5 class="text-center mb-4 text-secondary"><small>了解更多咖啡文化</small></h5>
<div class="box">
<ul class="clearfix" id="ulList">
<li class="list-border rounded"><img src="http://img2.imgtn.bdimg.com/it/u=3541722414,3884659824&fm=26&gp=0.jpg" alt="" width="300"><h6 class="text-center mt-3">咖啡种植</h6></li>
<li class="list-border rounded"><img src="http://hiphotos.baidu.com/feed/pic/item/9358d109b3de9c82918990246781800a18d843a8.jpg" alt="" width="300"><h6 class="text-center mt-3">咖啡调制</h6></li>
<li class="list-border rounded"><img src="http://img3.imgtn.bdimg.com/it/u=2725276117,4103638164&fm=26&gp=0.jpg" alt="" width="300"><h6 class="text-center mt-3">咖啡烘焙</h6></li>
<li class="list-border rounded"><img src="http://img2.imgtn.bdimg.com/it/u=3335899916,2513047612&fm=26&gp=0.jpg" alt="" width="300"><h6 class="text-center mt-3">手冲咖啡</h6></li>
</ul>
<div id="left"><i class="fa fa-chevron-circle-left"></i></div>
<div id="right"><i class="fa fa-chevron-circle-right"></i></div>
</div>
</div>

2.6 底部移动端 Tab

1
2
3
4
5
6
7
8
9
<div class="row fixed-bottom d-block d-sm-none bg-light border-top py-1" id="footer">
<ul class="text-center p-0" id="myTab">
<li><a href="index.html" class="ab"><i class="fa fa-home fa-2x p-1"></i><br>主页</a></li>
<li><a href="javascript:void(0);"><i class="fa fa-calendar-minus-o fa-2x p-1"></i><br>门店</a></li>
<li><a href="javascript:void(0);"><i class="fa fa-user-circle-o fa-2x p-1"></i><br>我的账户</a></li>
<li><a href="javascript:void(0);"><i class="fa fa-bitbucket-square fa-2x p-1"></i><br>菜单</a></li>
<li><a href="javascript:void(0);"><i class="fa fa-table fa-2x p-1"></i><br>更多</a></li>
</ul>
</div>

三、关键脚本

3.1 咖啡讲堂左右切换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$(function () {
var nowIndex = 0;
var liNumber = $('#ulList li').length;
function change(index) {
var ulMove = index * 300;
$('#ulList').animate({ left: '-' + ulMove + 'px' }, 500);
}
$('#left').click(function () {
nowIndex = (nowIndex > 0) ? (--nowIndex) : 0;
change(nowIndex);
});
$('#right').click(function () {
nowIndex = (nowIndex < liNumber - 1) ? (++nowIndex) : (liNumber - 1);
change(nowIndex);
});
});

3.2 主导航与隐藏导航互斥

1
2
3
4
5
6
7
8
9
10
11
12
$(function () {
$('#a1').click(function () {
$('#template1').addClass('d-none');
$('.right').addClass('d-none d-lg-block');
$('#template2').removeClass('d-none');
});
$('#a2').click(function () {
$('#template2').addClass('d-none');
$('.right').removeClass('d-none');
$('#template1').removeClass('d-none');
});
});

3.3 底部 Tab 高亮

1
2
3
4
5
6
$(function () {
$('#footer ul li').click(function () {
$(this).find('a').addClass('ab');
$(this).siblings().find('a').removeClass('ab');
});
});

四、核心 CSS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@media (max-width: 992px){ .left{ margin: 1rem 0; } }
@media (min-width: 992px){
.left{ position: fixed; top: 0; left: 0; height: 100vh; }
.right{ margin-left: 25%; }
.margin1{ margin-top: 40vh; }
}
.margin2 h6{ margin: 20px 0; font-weight: bold; }
ul{ list-style-type: none; }
.left{ border-right: 2px solid #eeeeee; }
.left a{ font-weight: bold; color: #000; }
.max-h{ max-height: 300px; }
.max-h img{ height: 300px; }
.list{ background: #eeeeee; }
.list-border{ border: 2px solid #DBDBDB; border-top: 1px solid #BDBDBD; }
.box{ width: 100%; height: 300px; overflow: hidden; position: relative; }
#ulList{ list-style: none; width: 1400px; position: absolute; }
#ulList li{ float: left; margin-left: 15px; z-index: 1; }
#left{ position: absolute; left: 20px; top: 30%; z-index: 10; cursor: pointer; }
#right{ position: absolute; right: 20px; top: 30%; z-index: 10; cursor: pointer; }
.font-menu{ font-size: 1.3rem; }
.ab{ color: #00A862 !important; }
#myTab li{ float: left; width: 20vw; min-width: 30px; font-size: 0.8rem; color: #919191; }

五、关键技术解析

5.1 PC 与移动端导航切换

  • PC 端(≥992px):左侧导航 position: fixed 固定显示,底部 Tab 通过 d-sm-none 隐藏。
  • 移动端(<992px):左侧导航 margin: 1rem 0 普通文档流,底部 Tab 通过 d-block d-sm-none 显示。

5.2 轮播控制

carousel-control-prev / carousel-control-next 配合 data-slide="prev|next" 实现上一张/下一张;data-ride="carousel" 让轮播在加载时自动开始。

5.3 card-columns 瀑布流

card-columns 是 Bootstrap 4 提供的瀑布流容器,子元素自动按列排布,比手写 CSS 浮动省心(Bootstrap 5 已移除此组件,可用 row-cols-* 替代)。

5.4 animate 切换动画

通过 animate({left: -ulMove})ul 横向偏移一格宽度,再配合左右按钮的边界判断,形成类似轮播图的横向滑动效果。

六、小结

本案例覆盖了导航、轮播、卡片、按钮、媒体查询切换等多项核心技能,是练习”PC + 移动端一体化响应式布局”的优质范例。建议扩展练习:

  • 给咖啡讲堂加自动播放定时器。
  • 把隐藏导航的展开/收起改为 jQuery slideDown/slideUp 动画。
  • 抽出独立 style.css、拆分 index.js,按工程化方式管理资源。