Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

响应式图片 #25

Open
yvesluo opened this issue Oct 25, 2015 · 0 comments
Open

响应式图片 #25

yvesluo opened this issue Oct 25, 2015 · 0 comments

Comments

@yvesluo
Copy link

yvesluo commented Oct 25, 2015

什么是响应式图片?

响应式图片关键之一就是让浏览器能够自动调节图片尺寸。
 
为了能自动调节图片尺寸,就需要准备大尺寸图片。一些网站为了适应高清屏设备的要求,都需要准备超大大尺寸图片,例如:
 
http://www.w3cplus.com/sites/default/files/blogs/2015/1509/hero_ygold_edition_large_2x.jpg


 
此图尺寸:5144px x 1698px,体积是398K。
 
问题:把这样一张尺寸过大的图片传送到一些低分辨率设备上,会造成资源浪费。

什么情况下需要使用到响应式图片?

 
一般情况下,需要使用到响应式图片的情况有两种:分辨率切换和艺术指导,以下分别详细说明:
 

分辨率切换:硬式切换

 
最常见的情况,不改变图片高宽比的情况下显示不同尺寸,这个很好理解
 

艺术切换:软式切换

很多情况下,设计师和产品会要求在尺寸改变的同时,改变图片的高宽比,以达到修改图片的内容,聚焦点等等。这种情况主要是为了迎合人类主观视感受的要求。我们把这种情况称为艺术指导,或相对于分辨率切换:硬式切换,也可以称之为软式切换。

当照片以大尺寸显示时,显示出背景里的汽车工厂是有意义的。背景可以在图像上说明这个事件发生的地点。然而试想如果我们把图片缩小来适应小屏幕的时候呢?
照片被缩放到宽度为100px。


 
在这个尺寸上,你无法辨认出人物的脸部,背景更是一片模糊。因此,我们不应该简单得缩放图片,而应该合理裁切图片, 去掉一些背景从而把焦点放到奥巴马身上。最终结果这张图片在小尺寸上的表现变得更好。

来看一下更加复杂的例子:
 
最常见的场景是图文并茂的设计
 

这个图像包含了三个照片,两个带有文字的logo,一个描边邮戳和文本。如果我们只是简单粗暴地把这个图像调整到320px宽,文本将会变得太小而无法辨认。
 

更理想的结果是这样的:

响应式图片解决方案

响应式图片解决方案,最经典的有元素,其它比较新近的例如和srcset,等,不管采用哪种方案,元素必不可少。 

img 的currentsrc属性

方法:用JavaScript来监控img元素上currentSrc的变化

来看一个例子
 

(function() {
  var currentSrc, oldSrc, imgEl;
  var showPicSrc = function() {
    oldSrc     = currentSrc;
    imgEl      = document.getElementById('picimg');
    currentSrc = imgEl.currentSrc || imgEl.src;
    if (typeof oldSrc === 'undefined' || oldSrc !== currentSrc) {
      document.getElementById('logger').innerHTML = currentSrc;
    }
  };
  // You may wish to debounce resize if you have performance concerns
  window.addEventListener('resize', showPicSrc);
  window.addEventListener('load', showPicSrc);
})(window);

 
示例中,你可以改变浏览器尺寸来观察currentsrc的变化。将你的浏览器慢慢的缩小,你将看到如下图的一个变化效果:

其它更强大的方法,比如说想要支持高分辨率屏幕,我们需要扩展元素。

SRCSET

 
自从苹果发布带retina显示屏的iPhone 4,网页设计人员一直在找一个处理高分屏的方案。于是引入了srcset和它的显示密度。
 

srcset密度描述

语法:在元素上添加srcset属性。srcset的值是一个用逗号分隔的列表。列表中的每个项包含一张图片的路径并且按倍数(例如,1x,2x,3x...)提供多张分辨率的图片

image

问题:
1x,1.5x,2x,3x !!!! 我们需要为多种像素密度提供相应的设置吗?好难维护!!!

 

Srcset宽度描述

语法与屏幕密度描述符类似。srcset属性值是逗号分隔的图片源和描述列表。区别是我们在这边列出了图片源宽度。

image

问题:当图片开始下载时浏览器知道的只有视窗尺寸
 

SRCSET密度描述和宽度描述结合

也有人提到混合SRCSETSRCSET结合显示密度描述和宽度描述的方法,在CHROME模拟器上测试失效
 

智能的srcset和sizes属性

以上写法都会有各种问题,最新的建议SRCSET写法是这样子的:
 
image

非常方便:只需要提供图片资源、以及断点,其他都交给浏览器智能解决,什么响应宽度啊、设备像素比啊,都不要关心了,浏览器会自动匹配最佳显示图片。
 
例:

<img src="kebile-s.jpg" srcset="kebile-s.jpg 320w, kebile-m.jpg 640w, kebile.jpg 1280w"
         sizes="(max-width: 480px) 100vw, (max-width: 900px) 50vw, 900px">

 
上面的例子提供了三种尺寸的图片源,SIZES设置的意思是:指定三种BREAKPOINT,屏幕小于480时图片WIDTH=100%, 481-900时图片WIDTH=50%,然后是901之后图片永远是显示900PX。
 
100vw是指图片的宽度值设置,1vw等于 1%,33vw就是33%,当然也可以使用其它的单位,em, px, cm, vw, 等等,甚至可以用CSS3的calc计算,例如:sizes="(max-width: 360px) calc(100vw - 20px), 128px"。

PICTURE标签

之前的内容都是针对“分辨率切换”的使用情况来进行的讨论。下面来讨论一下怎么应对“艺术指导”的情况。这就需要用到元素。 image

元素包含一系列子元素后跟着需要的元素。source元素和video元素的子源类似。每个源必须有一个srcset属性,可选属性包括media,sizes和type。元素上的sizes和srcset的使用和上完全一样。 MEDIA:media属性的值就是我们熟悉的媒体查询。如果没有匹配媒体查询时,浏览器则使用元素。SRCSET:与的srcset不同,的srcset,前者不是建议,而是指令。此时浏览器必须使用srcset指定的图片。 

来个实战的例子:http://www.shopify.com/


 
注意人物部分的图片切换。
 
以下是简化后图片部分的代码

<picture>
  <source srcset="homepage-person@desktop.png, homepage-person@desktop-2x.png 2x"       
          media="(min-width: 990px)">
  <source srcset="homepage-person@tablet.png, homepage-person@tablet-2x.png 2x" 
          media="(min-width: 750px)">
  <img srcset="homepage-person@mobile.png, homepage-person@mobile-2x.png 2x" 
       alt="Shopify Merchant, Corrine Anestopoulos">
</picture>

 

Type属性

给大家带来的另一个好处就是,提供了浏览器对图片格式进行自由选择的机制。

通过type属性,我们不仅可以使用经典的gif, jpg, png图片格式,还可以指定使用比较新潮的svg或webp。如:

<picture>
  <source type="image/svg+xml" srcset="logo.xml">
  <source type="image/webp" srcset="logo.webp"> 
  <img src="logo.png" alt="ACME Corp">
</picture>

在这个例子中,如果浏览器能够识别SVG,则使用SVG,如果不行,就往下类推,最后旧版本的浏览器使用logo.png。
 
到这里我们可以发现,我们在这边实现了在图片格式使用上的渐进增强的功能,在使用SVG文件的同时,我们又兼顾了旧版本浏览器用户的体验,从而防止的用户流失。
 
另外一点需要注意的是,TYPE,SIZES和 SCRSET是可以自由组合来完成不同的功能。
 

CSS实现响应式图片

 
上面我们讨论的是使用内联图片来实现响应式图片,接着我们来看使用CSS实现响应式图片的方法。说到CSS,响应式,有的同学会马上想到媒体查询。在和srcset的解决方案出现之前,我们一直都用CSS媒体查询实现响应式功能,现在来看一下,在CSS方面,内联图片响应式为我们带来什么新的启发。

image-set()语法

我们会注意到image-set()和srcset之间的一些联系。需要注意的是image-set不支持宽度描述。
 
Image-set可以用在任何可以使用图片的CSS属性上。
 

分辨率媒体查询

首先会注意到的是我们加入了包含-webkit前缀的媒体查询。这是为了支持老device-pixel-ratio语法的机器。只有一台机器支持这个带-webkit前缀的语法所以只列出了一台。
 
现在的设备都支持min-resolution和max-resolution, 可以使用以下单位
 
dpi:点每英尺
dpcm:点每厘米
dppx:点每像素, 这个单位可以基本理解为等于x, 1dppx = 1x, 2 dppx = 2x

兼容性

 
响应式图片标准的浏览器支持在快速发展。到2015年8月,Chrome,Opera和Firefox都支持了 picture, srcset, sizes, 和type.
 
Microsoft Edge和Safari支持带有显示描述符(x)的srcset,但不支持宽度描述符。Microsoft已经开始了支持所有响应式图片标准的开发。
 
image-set()相对落后。
 

SCRSET

http://caniuse.com/#search=srcset

PICTURE

http://caniuse.com/#search=picture

PictureFill

 
PictureFill插件让你现在就可以使用新响应式图片语法。
https://scottjehl.github.io/picturefill/

响应式图片断点

 
响应式图片的断点设置是个很复杂的问题。要比较完美的设置断点需要考虑多方面的因素,我们这边就不做过多详解。但是我们设置断点时需要永远记住,响应式图片断点要解决的问题是:
 
需要提供多少个图片源来包含此图片需要使用的场景?
在哪里以及什么时候应该使用这些图片?

以这两个问题为出发点来思考解决方案,这样一切问题应该可以迎刃而解。

由于文章篇幅限制,关于响应式图片我们就讨论到这里,需要做更多了解的同学可以参考以下文章。
 
参考:
http://blog.cloudfour.com/responsive-images-101-definitions/
译文:http://www.w3cplus.com/responsive/responsive-images-101-definitions.html
 
http://www.zhangxinxu.com/wordpress/2014/10/responsive-images-srcset-size-w-descriptor/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants