ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

仿京东数码页实战:纯HTML+CSS+JavaScript动态效果与3D翻转

仿京东数码页实战:纯HTML+CSS+JavaScript动态效果与3D翻转 简介这是一份面向前端初学者与进阶练习者的仿京东数码页面实战项目使用HTML、CSS与JavaScript三种核心技术实现动态网页效果帮助读者在真实电商场景中理解页面结构搭建、样式布局与交互逻辑。压缩包共20个文件包含2个HTML页面、1个CSS样式表以及10张jpg与7张png图片素材整体约503KB涵盖页面骨架、样式控制与商品图资源可直接运行对照学习。已有134人学习下载。项目覆盖导航栏、商品列表、搜索框与购物车等模块涉及Flexbox或Grid布局、CSS伪类悬停效果、DOM操作与轮播图等动态功能并包含响应式设计思路便于读者掌握从静态布局到交互实现的完整流程积累可复用的前端开发经验。1. 仿京东数码页拆包一份能直接跑起来的纯 HTMLCSSJavaScript 实战素材前阵子帮一个刚转前端的兄弟看简历他项目栏里写着「仿京东数码商城」我让他把源码发过来解压一看整个页面就一个index.html加一个style.css商品列表是写死的静态div轮播图靠一张 GIF 硬撑。这种「仿站」在招聘方眼里基本等于没做。真正能拿得出手的仿站素材得把结构、样式、交互三层拆干净还得有真实的切图资源兜底。这次拆的这份「京东数码.zip」就是后者里面躺着京东数码.html、234.html两个页面文件css和images两个目录外加banner.jpg、li_bg.jpg、nav_ba.jpg、arr.jpg、logo.jpg、con_ima_r1_c1.jpg到con_ima_r1_c5.jpg这一整套切图还有一张网页234 效果图.png和京东数码 current.jpg作为视觉参照。它解决的不是「从零写一个电商首页」的问题而是「拿到一套完整切图和结构后怎么用纯 CSSHTMLJavaScript 把动态效果还原出来」的问题。适合刚学完三件套、想找一个有真实素材练手的中级练习者也适合需要快速搭一个静态电商原型页面的从业者。下面我按拆包、还原、避坑、进阶的顺序把这份素材里能复用的东西一条条抠出来。2. 拆包与结构还原从京东数码.html到234.html的骨架怎么搭2.1 先认清目录里每个文件是干什么的拿到压缩包别急着双击 HTML先把目录结构在脑子里过一遍。这份素材的文件命名带着明显的切图工具痕迹con_ima_r1_c1.jpg这种r1_c1是「第一行第一列」的意思说明原设计稿被切成了一张张独立图片而不是整图导出。这对还原布局很关键——意味着你可以用background-position或者独立img标签精确控制每个模块的位置。文件/目录类型在页面里的角色京东数码.html页面主页面承载完整布局234.html页面第二版或子页面用于对比结构差异css/目录样式表控制布局、颜色、动画images/目录切图资源含 banner、导航背景、箭头、logobanner.jpg图片顶部轮播或主视觉区背景li_bg.jpg图片列表项背景常用于导航或分类条nav_ba.jpg图片导航栏背景条arr.jpg图片箭头图标轮播或下拉菜单用logo.jpg图片站点 logocon_ima_r1_c1.jpg~c5.jpg图片内容区第一行五个切图通常是商品或分类图标网页234 效果图.png图片设计稿参照用来比对还原度京东数码 current.jpg图片当前效果截图用于自查看清这张表你就知道哪些图是背景、哪些是内容图。nav_ba.jpg和li_bg.jpg这种带bg或ba的基本是 CSS 背景图con_ima_r1_c1这种带行列编号的是内容区独立元素适合用img直接插入方便后续做悬停放大或替换。2.2 用语义化标签把页面骨架立起来很多人仿站上来就一堆div结果 CSS 选择器写得又长又乱。这份素材的 HTML 结构其实可以按电商首页的标准分区来组织头部logo 搜索 购物车、导航栏、主视觉 banner、商品分类、商品列表、页脚。下面是我按素材切图重新整理的一份骨架你可以直接对着京东数码.html改!DOCTYPE html html langzh-CN head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 title京东数码 - 仿站练习/title link relstylesheet hrefcss/style.css /head body !-- 头部logo、搜索框、购物车 -- header classjd-header div classlogo img srcimages/logo.jpg alt京东数码 /div form classsearch-box action# methodget input typetext namekeyword placeholder搜索数码产品 button typesubmit搜索/button /form a href# classcart-btn购物车/a /header !-- 导航栏背景用 nav_ba.jpg -- nav classjd-nav ul lia href#手机/a/li lia href#电脑/a/li lia href#相机/a/li lia href#配件/a/li /ul /nav !-- 主视觉轮播区 -- section classbanner img srcimages/banner.jpg alt主视觉 button classarrow previmg srcimages/arr.jpg alt上一张/button button classarrow nextimg srcimages/arr.jpg alt下一张/button /section !-- 商品分类用 con_ima_r1_c1 到 c5 五个切图 -- section classcategory div classcat-itemimg srcimages/con_ima_r1_c1.jpg alt分类1/div div classcat-itemimg srcimages/con_ima_r1_c2.jpg alt分类2/div div classcat-itemimg srcimages/con_ima_r1_c3.jpg alt分类3/div div classcat-itemimg srcimages/con_ima_r1_c4.jpg alt分类4/div div classcat-itemimg srcimages/con_ima_r1_c5.jpg alt分类5/div /section !-- 商品列表 -- section classgoods-list idgoodsList !-- 动态插入商品卡片 -- /section script srcjs/main.js/script /body /html这段骨架的逻辑说明header用 flex 布局把 logo、搜索框、购物车排成一行搜索框用form而不是纯div是为了后续接真实搜索接口时不用改结构。nav里的li_bg.jpg不直接写在 HTML 里而是交给 CSS 做背景这样导航项增减时不用动图片路径。banner区放了一个img和两个箭头按钮箭头用arr.jpg这是轮播图最简结构。category区五个cat-item对应五张切图命名和素材里的con_ima_r1_c1到c5一一对应方便你比对效果图。goods-list留空商品卡片由 JavaScript 动态生成这是后面做「加载更多」和「加入购物车」的基础。参数上要注意viewport的widthdevice-width是响应式的前提少了它媒体查询在手机上会失效。link引入的css/style.css路径要和实际目录一致素材里css是文件夹别写成css.css。script放在body末尾避免阻塞渲染这是纯静态页面的常规做法。2.3 CSS 布局Flexbox 排导航Grid 排商品骨架立好后样式层要解决两个核心布局导航栏横向排列、商品列表网格排列。素材里nav_ba.jpg是导航背景li_bg.jpg是列表项背景这两个背景图用background属性挂上去比用img更合适因为背景图不参与文档流不会把文字挤下去。/* 导航栏背景图 Flex 横向排列 */ .jd-nav { background: url(../images/nav_ba.jpg) repeat-x; height: 40px; } .jd-nav ul { display: flex; justify-content: center; list-style: none; margin: 0; padding: 0; } .jd-nav li { background: url(../images/li_bg.jpg) no-repeat center; padding: 0 20px; line-height: 40px; } .jd-nav a { color: #fff; text-decoration: none; font-size: 14px; } .jd-nav a:hover { color: #f10215; /* 京东红 */ } /* 商品列表Grid 三列自适应 */ .goods-list { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; padding: 20px; } .goods-card { border: 1px solid #eee; border-radius: 4px; overflow: hidden; transition: box-shadow 0.3s; } .goods-card:hover { box-shadow: 0 4px 12px rgba(0,0,0,0.15); } .goods-card img { width: 100%; display: block; }逻辑说明.jd-nav用repeat-x让nav_ba.jpg横向平铺高度固定 40px这是电商导航的常见高度。ul用display: flex加justify-content: center让导航项居中li挂li_bg.jpg作为每项背景line-height等于高度实现文字垂直居中。.goods-list用grid-template-columns: repeat(3, 1fr)做三列等宽gap控制间距比 float 或 inline-block 少很多清除浮动的麻烦。.goods-card的transition和:hover阴影是提升交互质感的关键成本极低但效果明显。参数上1fr表示剩余空间等分三列就是每列三分之一。gap: 16px是列间距和行间距想更紧凑可以改 8px。border-radius: 4px是圆角京东实际页面用的是 8px 左右按效果图调。#f10215是京东品牌红悬停变色用这个色值比随便写个红色更还原。2.4 JavaScript 动态渲染商品卡片静态 HTML 里商品卡片如果一个个手写改价格、改库存会疯掉。用 JavaScript 从数组渲染是这份素材里最值得复用的部分。下面这段代码把商品数据抽成数组循环生成 DOM 插入goodsList// 商品数据实际项目里来自接口这里先写死 const goodsData [ { id: 1, name: 智能手机, price: 2999, img: images/con_ima_r1_c1.jpg }, { id: 2, name: 笔记本电脑, price: 5999, img: images/con_ima_r1_c2.jpg }, { id: 3, name: 数码相机, price: 4299, img: images/con_ima_r1_c3.jpg }, { id: 4, name: 蓝牙耳机, price: 399, img: images/con_ima_r1_c4.jpg }, { id: 5, name: 智能手表, price: 1299, img: images/con_ima_r1_c5.jpg } ]; // 渲染函数 function renderGoods(list) { const container document.getElementById(goodsList); container.innerHTML ; // 清空避免重复追加 list.forEach(item { const card document.createElement(div); card.className goods-card; card.innerHTML img src${item.img} alt${item.name} h3${item.name}/h3 p classprice¥${item.price}/p button classadd-cart>const banner document.querySelector(.banner); const track banner.querySelector(.banner-track); const prevBtn banner.querySelector(.prev); const nextBtn banner.querySelector(.next); let index 0; const total 3; // 假设三张轮播图 function updateSlide() { // 每次移动一张图的宽度用百分比更通用 track.style.transform translateX(-${index * 100}%); track.style.transition transform 0.5s ease; } nextBtn.addEventListener(click, () { index (index 1) % total; updateSlide(); }); prevBtn.addEventListener(click, () { index (index - 1 total) % total; updateSlide(); }); // 自动播放 let timer setInterval(() { index (index 1) % total; updateSlide(); }, 3000); // 鼠标移入暂停 banner.addEventListener(mouseenter, () clearInterval(timer)); banner.addEventListener(mouseleave, () { timer setInterval(() { index (index 1) % total; updateSlide(); }, 3000); });逻辑说明track是包裹所有轮播图的容器宽度设为300%三张图每张图占33.33%。translateX(-index * 100%)里的100%是相对track自身宽度所以移动的是整张图的宽度。index用取模运算% total实现循环点到最后一张再点下一张回到第一张。自动播放用setInterval鼠标移入clearInterval暂停移出重新开启这是电商轮播的标准交互。参数上transition: transform 0.5s ease控制切换动画时长0.5 秒比较跟手太慢显得拖沓。3000是自动播放间隔3 秒是常见值资讯类可以短到 2 秒商品类 4 到 5 秒更合适。注意translateX的百分比是相对元素自身宽度如果track宽度不是100% * 张数移动距离会算错这是轮播翻车的高频点。3.2 悬停放大与 CSS 涟漪光圈扩散热搜里「css 涟漪光圈扩散」是个很实用的效果用在按钮或商品卡片上点击时从鼠标位置扩散一圈光晕。纯 CSS 可以用::after伪元素加transform: scale和opacity过渡实现不需要 JavaScript 计算坐标也能做出近似效果.add-cart { position: relative; overflow: hidden; background: #f10215; color: #fff; border: none; padding: 8px 16px; cursor: pointer; } .add-cart::after { content: ; position: absolute; top: 50%; left: 50%; width: 0; height: 0; background: rgba(255, 255, 255, 0.5); border-radius: 50%; transform: translate(-50%, -50%); transition: width 0.4s, height 0.4s, opacity 0.4s; opacity: 0; } .add-cart:active::after { width: 200px; height: 200px; opacity: 1; transition: 0s; }逻辑说明::after伪元素定位在按钮中心初始宽高为 0border-radius: 50%让它变成圆。:active时宽高瞬间变成 200pxopacity变 1因为transition: 0s取消了过渡所以是瞬间扩散松开鼠标后:active失效opacity回到 0width和height在 0.4 秒内缩回形成光圈扩散后消散的效果。overflow: hidden保证光圈不会溢出按钮。参数上200px是光圈最大直径按钮越大这个值要越大一般取按钮宽高的两倍以上。rgba(255,255,255,0.5)是半透明白在红色按钮上对比明显。transition: 0s只写在:active里是为了让扩散瞬间完成而消散走 0.4 秒过渡这个不对称是效果的关键。3.3 商品卡片悬停transform与box-shadow的组合商品卡片悬停上浮是电商页面的基本操作但很多人只加box-shadow不加位移看起来像卡片变厚而不是浮起来。正确做法是transform: translateY(-4px)配合阴影加深.goods-card { transition: transform 0.3s ease, box-shadow 0.3s ease; } .goods-card:hover { transform: translateY(-4px); box-shadow: 0 8px 20px rgba(0,0,0,0.15); }逻辑说明translateY(-4px)让卡片向上移动 4 像素视觉上像被鼠标「吸」起来。阴影从无到有、从浅到深配合位移形成层次感。transition同时监听transform和box-shadow保证两个属性同步过渡不会一个先动一个后动。参数上-4px是上浮距离太大显得飘2 到 6 像素之间比较自然。阴影的rgba(0,0,0,0.15)透明度别超过 0.2否则像脏了一块。0 8px 20px分别是水平偏移、垂直偏移、模糊半径垂直偏移大于水平偏移才像从上方打光。4. 避坑与排查仿站过程中最容易翻车的五个点4.1 图片路径大小写不一致本地能跑线上 404现象本地双击 HTML 图片正常显示部署到服务器后部分图片裂开。原因Windows 文件系统不区分大小写images/Logo.jpg和images/logo.jpg都能找到文件Linux 服务器区分大小写路径写错就 404。解决统一用素材里的原始命名logo.jpg全小写con_ima_r1_c1.jpg里的r1_c1保持小写CSS 里url(../images/nav_ba.jpg)的路径和文件名逐字符核对。我一般会在编辑器里开「显示文件大小写」插件或者部署前用grep -r images/ .把所有引用列出来对一遍。4.2 Flex 布局下图片被拉伸变形现象导航栏或商品卡片里的图片被拉得又扁又长。原因Flex 容器默认align-items: stretch子元素高度被拉伸或者img没设width/height被父容器挤压。解决给图片加object-fit: cover或object-fit: contain前者裁剪填满后者完整显示留白。商品图一般用coverlogo 用contain。同时给img设display: block消除底部间隙这个间隙是行内元素基线对齐造成的很多人以为是 margin。4.3 轮播图translateX百分比算错切换时跳帧现象轮播切换时图片位置对不上有时露出半张。原因track宽度没设成100% * 张数或者每张图宽度不是100% / 张数导致translateX(-100%)移动的距离和单张图宽度不等。解决track设display: flex; width: 300%三张图每张图width: 33.333%这样translateX(-100%)正好移动一张图。如果图片数量动态变化用 JavaScript 算track.style.width total * 100 %每张图width 100 / total %。4.4 事件委托里e.target和e.currentTarget搞混现象点击商品卡片里的按钮有时触发有时不触发。原因e.target是实际点击的元素可能是按钮里的文字节点或图标e.currentTarget是绑定事件的元素。用e.target.classList.contains(add-cart)时如果按钮里套了span点 span 就匹配不到。解决要么用e.target.closest(.add-cart)向上找最近的匹配祖先要么给按钮里的子元素加pointer-events: none让点击穿透到按钮本身。我一般用closest兼容性好且逻辑清晰。4.5 CSS 动画在低端机上卡顿box-shadow是元凶现象商品卡片悬停动画在手机上掉帧。原因box-shadow和border-radius同时动画会触发重绘GPU 加速用不上。解决把动画属性换成transform和opacity这两个属性走合成层不触发重排重绘。阴影变化可以用伪元素预先画好通过opacity过渡而不是直接动画box-shadow。具体做法是.goods-card::after放一个带阴影的层opacity: 0悬停时opacity: 1这样只动opacity性能好很多。5. 进阶技巧用transform: rotateY做 3D 卡片翻转与验证方法热搜里有人问「css 中 transform: rotatey(60deg) translatez(300px) 这个出来是什么样子」这其实是 3D 变换里顺序和透视的问题。在仿京东数码这个场景里商品卡片可以加一个 3D 翻转效果鼠标悬停时卡片沿 Y 轴旋转露出背面的商品详情。先看核心代码.goods-card { perspective: 1000px; /* 给父元素加透视否则 3D 效果扁平 */ } .card-inner { position: relative; width: 100%; height: 100%; transition: transform 0.6s; transform-style: preserve-3d; /* 让子元素保留 3D 空间 */ } .goods-card:hover .card-inner { transform: rotateY(180deg); } .card-front, .card-back { position: absolute; width: 100%; height: 100%; backface-visibility: hidden; /* 背面隐藏避免透视穿帮 */ } .card-back { transform: rotateY(180deg); /* 背面预先翻转正面朝后 */ background: #f5f5f5; padding: 16px; }逻辑说明perspective: 1000px加在父元素上数值越小透视越强1000px 是比较自然的距离。transform-style: preserve-3d加在旋转元素上让它的子元素也在 3D 空间里否则子元素会被压平。rotateY(180deg)让卡片绕 Y 轴转半圈正面转过去、背面转过来。backface-visibility: hidden让元素背面不可见这样正面转过去后不会看到它的镜像。背面预先rotateY(180deg)是为了在未翻转时它朝后翻转后正好朝前。参数上0.6s是翻转时长比普通悬停的 0.3s 慢因为 3D 旋转需要更多时间让人看清。perspective的值和卡片尺寸有关卡片越大透视距离要越大一般取卡片宽度的 2 到 3 倍。rotateY的正负决定旋转方向正角度是逆时针从上方看负角度是顺时针这个规则在调试时很关键转反了就把符号改一下。验证 3D 效果有没有生效我一般用两个方法。一是打开浏览器开发者工具的「Layers」面板看卡片有没有被提升为合成层有的话说明transform生效了。二是临时把perspective改成200px透视夸张后如果能看到明显的近大远小说明 3D 空间正常如果还是平的检查transform-style是不是加在了正确的元素上。还有一个土办法在rotateY(60deg) translateZ(300px)这种组合里translateZ是在旋转后的坐标系里移动所以 60 度旋转后再沿 Z 轴推 300px元素会往斜后方飞出去而不是正对屏幕放大。想让它正对屏幕放大得把translateZ写在rotateY前面或者用translate3d一次性指定。这个顺序坑我踩过不止一次血泪经验就是3D 变换里先写的先作用坐标系跟着变。从那以后我每次写 3D 变换都强制自己在纸上画一遍坐标轴确认旋转和位移的顺序再打开浏览器的 3D 视图模式对一遍。这份京东数码素材里的切图和结构足够你把轮播、悬停、涟漪、3D 翻转这几个效果都练一遍练完再回头看那些只写静态div的仿站差距一目了然。希望帮到你。本文还有配套的精品资源点击获取
返回列表