文章目录
- 实战练习
*
实战练习
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
而已
//img14.360buyimg.com/babel/s380x300_jfs/t1/168591/2/9328/64891/603ddb1aE93567699/3e4e717eeac051b2.jpg
//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 - 三张图片高度和为1503=450 < 470,注意到图片之间存在210px的外边距
这样,整个京东的图片列表的整体布局就非常清晰了
但是,我们不会那么去实现代码。因为 li
元素应该包裹在 ul
元素或者 ol
元素中,而这里并没有遵循css中的语义标签使用规范
我们先看一下这么写会有什么问题
<link rel="stylesheet" href="assets/reset.css">
<ul>
<li>ul lili>
<li>ul lili>
<li>ul lili>
ul>
<div>
<li>div lili>
<li>div lili>
<li>div lili>
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{
height: 150px;
}
当然这只是其中写法,我们还可以换个思路,退一步来思考
方式2
我们呢不去限制图片的宽或高,而是对超出 ul
元素部分(溢出部分)进行隐藏
ul {
width: 190px;
height: 470px;
overflow: hidden;
}
但是因为图片本身的大小还没有做限制,所以图片保持了原来的图片比例和大小
小剧场:
我们发现下载下来的图片分辨率大小为380*300,宽和高都刚好是浏览器中图片宽高的2倍
这只是巧合么?
不!这是京东为了高分辨率设备而做的适配,保证在一些高清屏下也能够保持清晰
那我们再对图片添加固定的宽或高不就行了?
不!我们直接指定宽或高的话, overflow
属性不就显得多此一举嘛
我们给img元素设定一个 100%
的 width
属性
ul>li img {
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;
}
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>
<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>
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>
<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>
li>
ul>
我们引入reset.css样式来去除浏览器的默认样式
<link rel="stylesheet" href="css/reset.css">
到这里,基本的骨架就有了
Q:那有些人会问了,我们不是引入了 reset.css
重置了浏览器的默认样式吗?为什么超链接还有样式?
A:其实,如果仔细看reset.css的源代码,会发现 a
元素只是重置了一些基本的内外边距、边框和字体大小,并没有做完全把 a
元素的样式去除。这个下面会具体介绍
样式添加
根据布局剖析,我们可以直接设置整体的样式
body{
background-color: #F4F4F4;
}
ul {
width: 190px;
height: 450px;
padding: 10px 0;
margin: 10px auto;
overflow: hidden;
background-color: #fefefe;
}
ul>li {
height: 25px;
padding-left: 18px;
background-color: #bfa;
}
ul>li span{
padding: 0 2px;
}
到这里整体样式就添加完毕,但我们发现有点问题
别急!我们继续进行细节上的样式调整和优化
细节完善
要求效果
目前的效果
两个主要问题
- 要求效果文字居中显示,而我们的文字偏左上角,底部有一定间距
- 文字存在换行和重叠现象
我们一个一个处理
文字调整
只需要给 li
元素添加一行属性
line-height: 25px;
文字虽然在一行上了,但是依然有重叠问题啊,需要怎么处理呢?
要知道文字有几个属性:
- 文字大小
- 文字颜色
- 文字样式
我们通过F12看下这些属性
废话少说,直接写代码
font-size: 14px;
color: #333;
我们这里先不写 text-decoration
属性,看下效果
写上 text-decoration
属性,再看下效果
text-decoration: none;
这里可以看到文字下划线消失了,因为我们使用的 a
标签包裹文字,而超链接具有一定的文字样式(就是蓝色字体带下划线),所以 text-decoration
属性就是调整文字样式的
到这里,我们的重叠问题还是没有解决
稳住,我们能赢! 我们再对比下要求的效果和我们现在的效果
看出来区别了吗?(当然重点不是我们的背景色,这无关紧要)
我们是把 /
符号用 span
包裹起来的,但是我们的 /
符号似乎又大又粗
符号调整
废话少说,上代码
ul>li span {
padding: 0 2px;
font-size: 12px;
}
不过到这里,还是存在问题,我把 span
元素的内边距去除才可以 (这里我没搞清楚为什么,知道的小伙伴可以评论或私信我哦;不过对比各个元素的盒子模型没什么区别,而且字体样式我也调整了;而且总感觉 /
符号之间间隙大了一点,这里存疑先不管了,我们继续往下)
悬浮样式
我们注意到,当鼠标悬浮在某一行时,其背景颜色会有变化;同时,悬浮在某一个超链接上时,字体颜色变红
这里要用到一个伪类选择器 :hover
,我们还是直接上代码
ul>li {
height: 25px;
padding-left: 18px;
line-height: 25px;
}
ul>li:hover {
background-color: #D9D9D9;
}
ul>li a:hover {
color: #C81724;
}
至此,我们的 京东左侧导航栏
的前端样式就基本完成了
最终效果
核心代码
<link rel="stylesheet" href="css/reset.css">
<style>
body {
background-color: #F4F4F4;
}
ul {
width: 190px;
height: 450px;
padding: 10px 0;
margin: 10px auto;
overflow: hidden;
background-color: #FEFEFE;
}
ul>li {
height: 25px;
padding-left: 18px;
line-height: 25px;
}
ul>li:hover {
background-color: #D9D9D9;
}
ul>li a {
font-size: 14px;
color: #333;
text-decoration: none;
}
ul>li a:hover {
color: #C81724;
}
ul>li span {
font-size: 12px;
}
style>
存疑问题
通过一番折腾和研究,终于发现问题的关键所在
因为在编写HTML代码时,每个 li
元素中的 a
的 span
标签都是换行的
而HTML中会将多个空格合并成一个,所以 a
的 span
之间都多了一个空格
有几种解决这个问题的方式
- 一是调整HTML中每个
li
元素中的代码,使之在一行上 - 二是给ul元素或li元素设置一个
font-size: 0
的属性值 - 三是通过js去除多余的换行字符(目前还没有学习到,所以不用这种方式,而且较麻烦)
我这里采用第二种方式
ul>li {
height: 25px;
padding-left: 18px;
line-height: 25px;
font-size: 0;
}
ul>li span {
padding: 0 2px;
font-size: 12px;
}
到这里,我们往往会忍不住赞叹一下自己:Nice !
3. 网易新闻列表
有了上面的实战步骤,对于网易新闻列表,我们就不进行那么详细的剖析了,直接上代码
结构搭建
<div class="news_money">
<div class="news_title">
<h2 class="title"><a href="#">财经a>h2>
div>
<div class="news_img">
<a href="#">
<img width="300" height="150" alt="楼市"加息潮"来了?" src="assets/news.png">
<div class="bg">
<h3>楼市"加息潮"来了?h3>
div>
a>
div>
<ul class="news_list">
<li>
<a href="#">太疯狂!1000万芯片投资 "换来"7个涨停a>
li>
<li>
<a href="#">重磅定调!打击比特币挖矿和交易行为a>
li>
<li>
<a href="#">拜登愿将基建规模砍去6000亿美元a>
li>
<li>
<a href="#">呷哺呷哺高管大换血 经营模式要变?a>
li>
ul>
div>
样式添加
.news_money {
width: 300px;
height: 324px;
margin: 35px auto;
}
a {
text-decoration: none;
}
.news_title {
height: 40px;
border-top: 1px #ddeedd solid;
}
.news_title .title {
width: 32px;
height: 24px;
line-height: 24px;
padding-top: 6px;
border-top: 1px #f34540 solid;
margin-top: -1px;
}
.news_title a {
font-size: 16px;
font-weight: bold;
color: #404040;
}
.news_title a:hover {
color: red;
}
.new_img {
height: 150px;
}
.news_img:hover {
transform: scale(2);
}
.news_img .img_title {
height: 40px;
line-height: 40px;
margin-top: -40px;
padding-left: 30px;
}
.news_img a {
color: #fff;
font-weight: bold;
}
.news_list {
height: 120px;
margin-top: 12px;
}
.news_list li {
width: 285px;
height: 30px;
line-height: 30px;
padding-left: 15px;
}
.news_list a {
font-size: 14px;
color: #666;
}
.news_list a:hover {
color: red;
}