07.京东导航栏练习
实战练习
1. 京东图片列表
开发准备
本来我们是想直接右键图片另存为
的,但是发现并没有该选项,应该是京东对图片做了一定的限制
不过,这不妨碍我们获取这些图片,当然你也可以采用截图的方式获取,这里我们采用另外一种方式
通过 F12 可以看到,img
元素的src
属性,我们将三张图片的这些地址 copy 出来,直接在地址栏进行访问
//img14.360buyimg.com/babel/s380x300_jfs/t1/168591/2/9328/64891/603ddb1aE93567699/3e4e717eeac051b2.jpg.webp
//img12.360buyimg.com/babel/s380x300_jfs/t1/152314/13/19839/57522/603e118dE941f0ce9/fdff58457adbef3e.jpg.webp
//img10.360buyimg.com/babel/s380x300_jfs/t1/154848/7/7426/82296/5fc072eeE20809200/34dca267e049d035.jpg.webp
这里就可以进行图片另存为
了,当然你也可以直接在src
上填写这些地址
不过,细心的同学会发现,这张图片的格式是jpg.webp
后缀结尾的
因为我是在谷歌浏览器中访问的,而谷歌浏览器有自己的特有的一种图片格式 webp(这个我们在第三节-字符实体与语义标签中介绍过)
当然这个格式不是谷歌自己进行转换的,而应该是京东做了不同浏览器之间的适配,即不同的浏览器传递不同格式的图片
Q:怎么验证这种说法呢?
A:我们可以打开非 Chrome 内核的浏览器,使用 F12 查看img
的src
地址就会发现不一样的地方了
这里我用微软自带的 IE 浏览器(温馨提示:微软官宣定于 2022 年 6 月 15 日完全停止对 IE 的支持)
对比就可以发现,无非就是在 Chrome 浏览器里后缀名多了一个.webp
而已
<!-- IE中的src地址 -->
//img14.360buyimg.com/babel/s380x300_jfs/t1/168591/2/9328/64891/603ddb1aE93567699/3e4e717eeac051b2.jpg
<!-- Chrome中的src地址 -->
//img14.360buyimg.com/babel/s380x300_jfs/t1/168591/2/9328/64891/603ddb1aE93567699/3e4e717eeac051b2.jpg.webp
知道这个原理,我们除了可以直接在图片另存为
保存为jpg
格式,其实还可以直接修改 url 地址
最后,我们将下载的图片放入assets
(自定义目录)工程目录下即可
布局剖析
我们使用 F12 进行调试,可以看到京东图片列表的具体元素及属性
- 整体使用一个
li
元素包裹,里面又套了一层 div`元素,宽高比:190:470 - 每张图片使用一个
img
元素,同时分别用a
元素包裹,宽高比:190:150 - 三张图片高度和为 150*3=450 < 470,注意到图片之间存在 2*10px 的外边距
这样,整个京东的图片列表的整体布局就非常清晰了
但是,我们不会那么去实现代码。因为li
元素应该包裹在ul
元素或者ol
元素中,而这里并没有遵循 css 中的语义标签使用规范
我们先看一下这么写会有什么问题
<link rel="stylesheet" href="assets/reset.css" />
<!-- ul包裹li -->
<ul>
<li>ul li</li>
<li>ul li</li>
<li>ul li</li>
</ul>
<!-- div包裹li -->
<div>
<li>div li</li>
<li>div li</li>
<li>div li</li>
</div>
效果
由于使用了 reset 样式,浏览器的默认样式被我们去除了。但是使用ul
包裹的li
元素和使用div
包裹的li
元素存在明显的区别:
- 使用
ul
包裹的li
元素是没有默认样式的 - 使用
div
包裹的li
元素前仍然存在黑点
我想是因为京东在这里实现了自己的样式替换,所以为了避免重复 reset 默认样式,我们采用正常的列表标签
结构搭建
<ul>
<li>
<a href="javascript:;"><img src="assets/1.jpg" /></a>
</li>
<li>
<a href="javascript:;"><img src="assets/2.jpg" /></a>
</li>
<li>
<a href="javascript:;"><img src="assets/3.jpg" /></a>
</li>
</ul>
到这里我们基本骨架已经有了,不过因为没有写 css 样式,图片几乎占据了整个浏览器页面
样式添加
方式 1
还记得上面分析对布局结构的分析吗?
我们首先调整整体的宽高比和单个图片的宽高比
ul {
width: 190px;
height: 470px;
}
ul > li img {
/*
这里其实只调整高度即可,因为我们下载的图片宽高比跟F12中调试的是一致的
而且一般情况下,不会固定或修改图片在网页中显示的宽高比
因为如果我们随意调整css中的宽高比,会导致图片变形
这里任意只调整高度或宽度,图片可以保持原比例大小
*/
/* width: 190px; */
height: 150px;
}
当然这只是其中写法,我们还可以换个思路,退一步来思考
方式 2
我们呢不去限制图片的宽或高,而是对超出ul
元素部分(溢出部分)进行隐藏
ul {
width: 190px;
height: 470px;
overflow: hidden;
}
但是因为图片本身的大小还没有做限制,所以图片保持了原来的图片比例和大小
小剧场:
我们发现下载下来的图片分辨率大小为 380*300,宽和高都刚好是浏览器中图片宽高的 2 倍
这只是巧合么?
不!这是京东为了高分辨率设备而做的适配,保证在一些高清屏下也能够保持清晰
那我们再对图片添加固定的宽或高不就行了?
不!我们直接指定宽或高的话,overflow
属性不就显得多此一举嘛
我们给 img 元素设定一个100%
的width
属性
ul > li img {
/* height: 150px; */
width: 100%;
}
Q:为什么不能用auto
呢?
A:我们前一节-盒模型中讲过,水平布局必须要满足一个等式,不满足即存在过渡约束,会做自动调整
而ul
元素是块元素,块元素什么特点?独占一行啊!
图片宽度为 380px,浏览器宽度为 1920px(我本机中最大化浏览器的宽度)
现在的等式为0 + 0 + 0 + 380px + 0 + 0 + 0 = 1920px
这七个值中没有auto
的情况,所以浏览器会自动调整margin-right
值以使等式满足
0 + 0 + 0 + 380px + 0 + 0 + (1920-380)px = 1920px
所以如果使用auto
属性值,整个过程中图片的width
不会发生变化,展现出来的效果就依然是裁剪的样式
Q:为什么100%
可以呢?
A:我们知道100%
是会按照父元素计算的,img
的父元素是a
,a的
父元素是li
,li
的父元素是ul
也就是说,由于我们没有给a
和li
单独设置样式,因此img
最终会根据ul
的宽度计算
而如果只调整图片的宽或高,图片是会保持原比例进行缩放的
所以这个时候就相当于给img
设置了一个width=190px
的属性值
细节完善
背景色
通过颜色拾取器,识别背景色(我这里使用的是FastStone Capture中自带的Screen Color Picker
)
ul{
...
/* 添加背景色 */
background-color: #F4F4F4;
}
外边距
根据布局剖析结果,我们给每个li
元素添加一个 10px 的下边距
ul > li {
margin-bottom: 10px;
}
/*
但是上述写法有些问题,最后一张图片也有10px的外边距,有可能会影响到页面布局
所以我们可以指定最后一个没有外边距,可以使用之前讲到的伪类选择器
*/
ul > li:not(:last-child) {
margin-bottom: 10px;
}
Q:为什么是给li
元素添加呢?
A:我们在调整布局结构的时候,特别是设置外边距,一般是设置块元素的,而不建议去调整行内元素或行内块元素
最终效果
核心代码
<link rel="stylesheet" href="css/reset.css" />
<style>
ul {
/* 宽高 */
width: 190px;
height: 470px;
/* 处理溢出部分,这块不写效果也是一样的 */
overflow: hidden;
/* 设置背景色 */
background-color: #f4f4f4;
}
ul > li:not(:last-child) {
/* 设置下外边距 */
margin-bottom: 10px;
}
ul > li img {
/* 设定图片宽度 */
width: 100%;
}
</style>
<ul>
<li>
<a href="javascript:;"><img src="assets/1.jpg" /></a>
</li>
<li>
<a href="javascript:;"><img src="assets/2.jpg" /></a>
</li>
<li>
<a href="javascript:;"><img src="assets/3.jpg" /></a>
</li>
</ul>
2. 京东左侧导航条
开发准备
我们需要的就是这些文字,事先复制下来
家用电器 手机 / 运营商 / 数码 电脑 / 办公 家居 / 家具 / 家装 / 厨具 男装 / 女装
/ 童装 / 内衣 美妆 / 个护清洁 / 宠物 女鞋 / 箱包 / 钟表 / 珠宝 男鞋 / 运动 /
户外 房产 / 汽车 / 汽车用品 母婴 / 玩具乐器 食品 / 酒类 / 生鲜 / 特产 艺术 /
礼品鲜花 / 农资绿植 医药保健 / 计生情趣 图书 / 文娱 / 教育 / 电子书 机票 / 酒店
/ 旅游 / 生活 理财 / 众筹 / 白条 / 保险 安装 / 维修 / 清洗 / 二手 工业品
布局剖析
- 整体使用
ul
和li
元素,宽高比=190px:470px,其中上下存在 10px 的内边距(影响盒子大小)和 10px 的外边距(影响盒子布局)
li
中每个元素也比较简单,用a
包裹文字,用span
包裹斜杠- 每个
li
元素的宽高比=190px:25px,其中左边存在 18px 的内边距(注意右边是不存在的)
- a 元素没有什么大的布局,
span
元素左右存在 2px 的内边距
结构搭建
<ul>
<li>
<a href="javascript:;">家用电器</a>
</li>
<li>
<a href="javascript:;">手机</a>
<span>/</span>
<a href="javascript:;">运营商</a>
<span>/</span>
<a href="javascript:;">数码</a>
</li>
<li>
<a href="javascript:;">电脑</a>
<span>/</span>
<a href="javascript:;">办公</a>
</li>
<li>
<a href="javascript:;">家居</a>
<span>/</span>
<a href="javascript:;">家具</a>
<span>/</span>
<a href="javascript:;">家装</a>
<span>/</span>
<a href="javascript:;">厨具</a>
</li>
<li>
<a href="javascript:;">男装</a>
<span>/</span>
<a href="javascript:;">女装</a>
<span>/</span>
<a href="javascript:;">童装</a>
<span>/</span>
<a href="javascript:;">内衣</a>
</li>
<li>
<a href="javascript:;">美妆</a>
<span>/</span>
<a href="javascript:;">个护清洁</a>
<span>/</span>
<a href="javascript:;">宠物</a>
</li>
<li>
<a href="javascript:;">女鞋</a>
<span>/</span>
<a href="javascript:;">箱包</a>
<span>/</span>
<a href="javascript:;">钟表</a>
<span>/</span>
<a href="javascript:;">珠宝</a>
</li>
<li>
<a href="javascript:;">男鞋</a>
<span>/</span>
<a href="javascript:;">运动</a>
<span>/</span>
<a href="javascript:;">户外</a>
</li>
<li>