您的位置:首页 > Web前端 > CSS

小米电视不同清晰度图片对比效果

2017-07-19 08:58 357 查看

一、案例介绍

Hello,大家好。今天和大家分享一个小案例。该案例来自于小米官网下小米电视部分(https://www.mi.com/mitv4/49/),效果如图所式。



通过拖动滚动轴,可以查看滚动轴左右两侧不同清晰度的图片对比。并且当我们将浏览器窗口缩小时,图片左右边侧超出窗口部分会被移出,大家可以自己缩小窗口试试。

提醒:显示器宽度分辨率为1920 px时,最能展示页面效果哦。

二、案例特点以及所学知识

这个案例对HTML、以及JS相关技能不要求太多,但是对于不擅长布局的同学可能会觉得有些麻烦。可能存在两个主要困惑:

①当浏览器窗口的宽度变小时,图片仿佛不断地从两侧移出消失,而当窗口宽度小到一定程度时,图片将不再移动,超出窗口部分被截掉。

②高清4k图与非高清4k图如何完全重叠,而非高清4k图却只显示一半的。

在本案例中,你将学习到绝对/相对定位以及max-width属性相关知识。

三、案例实现

实现原理:

这个案例效果实现原理,实际上是存在两张图片。一张图片是高清4k图片,另一张图片是非高清图片。非高清图片覆盖在4k图片

之上,通过滚动轴控制上层非高清图片的宽度。被覆盖区域显示非高清图片,而未被覆盖区域则显示底层的4k高清图。因此,我们

所要做的,就是实现两张不同清晰度图片完全重叠,并通过滚动轴来控制非高清图片的显示范围。

我们首先来写一下案例的结构。注意,此时是完全不需要考虑CSS和JS的内容的,案例需要哪些内容,我们就写哪些内容。案例需要两张不同清晰度的图片,以及一条滚动轴,滚动轴上有灰白两色圆球,圆球左右两侧有文字说明。据此,写出html结构。

HTML :

<img src="xxxxxx" alt="4k" /><!-- 4k高清图 -->
<img src="xxxxxx" alt="no-4k" /><!-- 非高清图 -->
<ul>
<li>优化前</li>
<li>优化后</li>
</ul>


注意 : HTML代码中图片的链接地址,大家可以下载附件后自己填写

说明 : 大家可以看到,上述HTML结构是非常简单的。这就是案例的主要内容,至于这些内容该如何展示,如何定位,那将是CSS所要完成的工作,此时可以完全不需要考虑。

同时,大家也一定发现,在上述HTML中怎么没有滚动轴的代码呢?实际上,无论是滚动轴还是黑白小球,都完全是用CSS来实现的,无非是设置填充色、圆角这些属性,其本质是不含任何内容的。因此,这些内容应该在写CSS、考虑页面布局等情况时再加入进来。大家可以先查看下此时页面的效果图。

思考: 上述HTML中采用img标签来放置图片,能否采用背景图形式来展示呢?

制作滚动轴

滚动轴是一个相对独立的部分。实际上,一条垂直白线,只是一个空div,只不过该div的宽度很小,只有1 px。此时填充背景色时,则显示为一条直线。灰白小球同理。这部分内容未提前写在HTML结构中,还有一个重要原因,那就是层级关系。虽然说,我们在写HTML时不考虑CSS的样式和布局,不会添加没有语义的空div,但是错误的HTML层级关系,会对CSS编写造成很大影响。比如说,一条垂直白线的空div,该放在上述HTML结构的哪部分呢?它是包裹ul,还是作为body元素的直接子元素呢?这些问题在不考虑CSS布局时,是完全没法回答的,因此,这也是一个未将滚动轴提前写入HTML结构中的一个原因。当然,对于简单布局,大家完全可以在编写HTML时将其布局结构一起考虑。

观察滚动轴部分,很明显,灰白小球以及文字说明都是相对于白色垂直线进行中心定位的。因此,作为白色垂直线的div要作为灰白小球以及文字的父元素,这样层级关系就确定下来了,修改上述HTML结构。

修改后HTML :

<img src="xxxxxx" alt="4k" /><!-- 4k高清图 -->
<img src="xxxxxx" alt="no-4k" /><!-- 非高清图 -->
<div id="axis"><!-- 滚动轴 -->
<ul>
<li>优化前</li>
<li>优化后</li>
</ul>
<div id="WHITE"></div><!-- 白色小球 -->
<div id="gray"></div><!-- 灰色小球 -->
</div>


这样,所有HTML部分代码就完成了。当然,这里所说的‘所有’,应当是加引号的,仅仅是只案例所需要的所有内容都具备了。当后续写CSS时,如若需要空白的div,仍然需要修改HTML的,但那时,仅仅是多了一些包裹层,大体结构是不变的。

思考 : 我们一开始说,写HTML不需要考虑CSS。但后来添加滚动轴部分代码时,又考虑了CSS布局结构,确定了层级关系才写的HTML部分。请大家好好体会其中差别,什么时候考虑,什么时候不考虑。

CSS :

我们首先完成滚动轴部分的CSS。前面说了,白色垂线作为定位元素,因此需要将其position属性设置为relative。

#axis{
position:relative;
width:1px;
height:590px;
background-color:white;
}
#axis ul,#WHITE,#gray{
position
d6af
:absolute;
top:50%;
left:50%;
}
#axis ul{
width:300px;
margin-left:-83px;
}
#axis ul li{
display:inline;
padding-right:50px;
color:white;
}
#WHITE{
width:20px;
height:20px;
border-radius:20px;
background-color:white;
margin-top:-10px;
margin-left:-10px;
z-index:20;
}
#gray{
width:28px;
height:28px;
border-radius:28px;
background-color:gray;
margin-top:-14px;
margin-left:-14px;
z-index:10;
}


说明 : 一口气写了这么多,大家一定有些问题。我将个人认为需要讲解的问题在此一一为大家解答。

#axis
设置width:1px可以理解,为什么设置590px呢?这个590是从哪来的?

答:590px是图片的高度,因此设置为590。另外,大家需要注意的是,我们一般不定义元素的高度,因为如果把高度写死了,就不容易拓展新内容了。但这里,显然是需要设置高度的,大家要有此意识。

#axis ul
中宽度300与左外边距-83是如何确定的?

答:是试出来的。300完全可以换成其他数值。至于margin-left,大家可以通过调试工具,看偏移量是多少时文字能在轴两侧对称分布。同理,
#axis ul li
中padding-right的数值也是可以改变的,只要实现文字两边对称显示即可。

#WHITE与#gray中都设置了margin-top和margin-left为负值,什么意思?


答:这个比较简单,是居中对其。我们设置了left和top为50%,是指元素的左上角距离父元素左、上的距离为父元素宽、高的50%,而没有考虑元素本身的宽高。因此通过margin-left设置为元素自身宽度的一半、margin-top设置为元素自身高度的一半来实现元素中心点处于父元素的中心点位置。

④设置z-index是什么意思?

答:所有绝对定位的元素,都会有该属性,用来决定z轴的高低关系。白色小球将灰色小球覆盖,因此白色小球的z-index较高,至于具体数值,大家随便取即可。

注意 : 设置了absolute后,一定要养成良好习惯,写left和top的值,即使有时你不写好像也没任何问题。

盒子模型

这里不是要讲解什么内外边距,啥东西。而是说,实现该案例,我们先建立一个盒模型演示一下。

前面也说了,浏览器窗口较大时,图片居中显示。而当浏览器宽度变小时,图片左右两侧渐渐消失,且图片始终居中。当宽度小于一定值时,图片位置不再变动,右侧图片被截掉。大家想想这样的效果是如何实现的。

我们这样思考。

首先,图片的位置是随着浏览器窗口大小改变而发生变化的,且图片左右外边距为0时其位置仍然随着窗口大小发生变化(也就是说,并不是设置margin:0 auto实现的图片位置随窗口大小改变而变化。)因此,图片一定是设置了绝对定位,始终定位在浏览器窗口的中心处。

img{
position:absolute;
left:50%;
top:0;
margin-left:-900px;
}


然后,图片是相对谁定位的,是相对于body(即浏览器窗口)吗?实际上,这里真可以相对于body进行定位。当body宽度大于图片宽度(1800px)时,图片居中显示,左右两侧距离浏览器窗口有一定距离。当body宽度小于图片宽度时,图片仍然居中显示,且由于居中显示,图片左右两侧处于浏览器窗口外的部分自然就消失了。示意如图:



为了让超出浏览器窗口两侧的图片内容消失,需要使用
overflow
属性。注意,对浏览器窗口写该属性时,正确的写法是:

html,body{overflow-x:hidden;}


而不是只写
body{overflow-x:hidden;}


最后,当窗口再小时,图片位置不发生改变。这说明,虽然窗口通过光标拉窄了,但body元素的宽度并没有发生变化,因此图片位置也不会发生变化(图片始终居中body元素,body元素的大小没有发生变化,图片的位置自然也不会改变。)

所以,需要给body元素设置一个宽度。直接设置width可以吗?显然是不可以的,因为如果设置了width固定值,那么图片从一开始就不会发生位置变化。那怎样才能一开始body元素宽度能变,后来又不能变呢?很简单,使用min-width属性。也就是说,body元素宽度小到一定程度时,将不再发生变化。这就解决了我们的问题了。

body{
min-width:1200px;
}


现在还有一个问题,目前,两张图片是完全重叠的。而我们希望的是非高清图片只显示一半宽度。可是,当我们设置非高清图片的width属性为一半即900px时,却发现图片的高度也随之缩小了,这显然不是我们要的。如果我们设置height:590px,并不能实现图片裁剪,实际上会造成图片拉伸变形。

该怎么解决这个问题呢?实际上很简单,我们只需要为非高清图像加一个容器,通过控制容器的宽度,来实现裁剪图片的功能。图片仍然是完整显示,但由于容器宽度只有900px,所以超出容器部分的图片自然就不能显示了。因此需要在非高清图外加一个容器。

添加容器后的HTML :

<img src="xxxxxx" alt="4k" class="firstImg"/><!-- 4k高清图 -->
<div id="wrap">
<div id="inner">
<img src="xxxxxx" alt="no-4k" class="secondImg"/><!-- 非高清图 -->
</div>
</div>
<div id="axis"><!-- 滚动轴 -->
<ul>
<li>优化前</li>
<li>优化后</li>
</ul>
<div id="WHITE"></div><!-- 白色小球 -->
<div id="gray"></div><!-- 灰色小球 -->
</div>


需要将容器设置为图片大小,并且也绝对定位始终在浏览器窗口居中显示。此时,原先对img元素设置的绝对定位,就可改成只对第一张图片绝对定位即可,第二张非高清图就不需要绝对定位了。

#wrap{
width:1800px;
height:590px;
position:absolute;
left:50%;
top:0;
margin-left:-900px;
}
#inner{
width:900px;
overflow:hidden;
}


此时,当改变
#inner
的width值时,就能控制非高清图覆盖的区域了。

将滚轴定位到图片中间

目前,图片部分已经完成。滚动轴模块已经实现,但还未进行定位。显然,滚动轴需要始终在图片中间,需要以图片作为定位元素。而图片img元素本身是行级inline元素,不能作为父级。可是,刚刚我们写的
#warp
元素,它完全和图片是重叠的,因此以
#wrap
元素定位,和以图片元素定位是完全一样的,因此我们需要将滚动轴部分HTML结构放在
#wrap
下面。

将滚动轴放在
#wrap
元素下面的HTML :

<img src="xxxxxx" alt="4k" class="firstImg"/><!-- 4k高清图 -->
<div id="wrap">
<div id="inner">
<img src="xxxxxx" alt="no-4k" class="secondImg"/><!-- 非高清图 -->
<div id="axis"><!-- 滚动轴 -->
<ul>
<li>优化前</li>
<li>优化后</li>
</ul>
<div id="WHITE"></div><!-- 白色小球 -->
<div id="gray"></div><!-- 灰色小球 -->
</div>
</div>
</div>


注意,原本我们为
#axis
设置为相对定位,现在也需要修改成绝对定位。
#axis
修改成绝对定位,完全不会对其子元素定位结果造成任何影响。

#axis{
position:absolute;
width:1px;
height:590px;
background-color:white;
left: 50%;
top:0;
}


好了,到目前位置所有HTML和CSS部分代码就实现了,下面就是实现JS拖拽滚动轴改变
#inner
的width值了。

未完待续….明天继续
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  CSS max-width overflow