web图像的常见应用策略与技巧

标签: 体验设计 | 发表时间:2017-04-28 16:50 | 作者:练小习
出处:https://isux.tencent.com

本文介绍一些关于响应式图像的适配应用策略,回退原理,SVG的换色技巧,雪碧图的百分比定位计算公式等相关的一些小知识点,目的在于帮助一部分同学快速的理清图像应用思路,以及一些web图像的应用技巧。

1.响应式图像的应用与回退

特点:应用简单,上手容易,性能表现良好
难点:lazyload实现

根据不同设备,不同分辨率,不同像素比使用的响应式图像,常用的有两种场景:

1.1固定尺寸图像

基于设备像素比选择,很多网站logo就是固定宽度图像的一个例子,不管viewport的宽度如何,始终保持相同的宽度。

在dom里图像与在css里的图像写法如下面的例子

<img srcset="test.jpg 1.5x, test2.jpg 2x" src="test.jpg" alt="" />
background-image: image-set(url(test.jpg) 1x,url(test2.jpg) 2x);

1.2不固定尺寸图像

与内容相关的图片,在需要响应式的时候,它们的大小往往并不是不变的,会随viewport改变,对于这类图像,也有两种常用的处理方式

1.2.1 我们使用srcset搭配w描述符以及sizes属性 。

w描述符告诉浏览器列表中的每个图象的质量。sizes属性是一个包含两个值的,由逗号分隔的列表。根据最新规范,如果srcset中任何图像使用了w描述符,那么必须要设置sizes属性。

sizes属性有两个值:第一个是媒体条件;第二个是源图尺寸值,在特定媒体条件下,此值决定了图片的宽度。

比如:

<img srcset="360.jpg 360w,
            768.jpg 768w,
            1200.jpg 1200w,
            1920.jpg 1920w"
     sizes="
     (max-width: 360px) 100vw,
     (max-width: 768px) 90vw,
     (max-width: 1980px) 80vw,
     768px"
     src="360.jpg" alt="">

我们来逐条读这一个img标签的信息

srcset,我们给浏览器准备了四个质量的图像,分别为360 768 1200 1920
sizes,我们来告诉浏览器,在不同的环境下图像的宽度
当视口不大于360的时候,图像显示宽度为100vw,当视口不大于768的时候,图像显示宽度为90vw,以此类推。
最后一个src作为默认图像url引入,并且是天然的回退方案,当浏览器不认识以上属性的时候,直接读取src渲染。

这样说不够直观,我们看个demo

在iphone4(320)下,图像宽度和我们设置的100vw一致,但是为什么浏览器选择了768的图像而没有选择360的?因为4的dpr是2呀^_^,浏览器很智能的选择了质量最合适的768.

再看一下6p(414),很听话的按照我们的设置,显示了90vw。因为他的dpr更高,浏览器聪明的选择了1200质量的图像。

这里我们可以欺骗一下浏览器:

360.jpg 1200w,
1200.jpg 9999w

我们把360的图像,骗浏览器说这是1200的,然后把原本1200的扔天上去

浏览器果然上当了,他把360的图当成1200的来用了。这里可能有些疑问,图像的宽度为什么不是90vw了哪?因为浏览器被骗了但是自己却不知道,他依然按照1200的图像,去适配dpr。414*90%*(360/1200)约等于111.7。这种方式很智能,浏览器去根据你的sizes,从w列表里选择最适合的图像来调用显示。正因为他太智能了,在实际操作中可控性较差,有些我们想精确控制的图像显示,有时候并不能如意。而且在做lazyload的时候要处理的东西也比较复杂。

这个时候可以考虑另外一种方式。

1.2.2.picture元素,可精确把控

picture元素就像是图像和其源的容器。浏览器仍然需要img元素,用来表明需要加载图片,如果没有img,那么什么都不会渲染。source为浏览器提供了要显示图像的供选版本。

适用场景为:在一个精确特定的转效点(breakpoint)需要显示一个特定的图像时。使用picture元素选择图像,不会有歧义,理解起来也更直观。

<picture>
  <source media="(min-width: 960px)" srcset=960.jpg">
  <source media="(min-width: 768px)" srcset="768.jpg">
  <img src="360.jpg" alt="">
</picture>

在本例中,当viewport大于960像素时,会加载图像960的图像。当viewport宽度大于768像素时,浏览器会加载768的。而当宽度小于768像素时,加载默认图像360。

而且这个写法的懒加载非常好处理,只需要在传统的lazyload策略上稍加改进

data-src
data-srcset
在加载到的时候更换为
src
srcset

就轻松解决了。

http://snghr.tencent.com  里面使用较多

他也不需要去特意做回退处理,当浏览器不支持的时候就直接读取img标签。对于懒加载的回退......我选择判断IE 7-8...直接塞url给他.....。

2.特殊格式的图像应用与回退

特点:体积优化效果显著
难点:兼容性掌控

上面picture元素还可以提供  基于图片格式选择。

有一些图像格式在较小的文件大小情况下保证了较好的图片质量。听起来还不错,但残酷的事实是没有一个新格式被所有浏览器支持。谷歌的WebP表现不错,但只有Chrome和Opera原声支持 JPEG-XR,最初被称为高清照片,是微软发布的一个专有图像格式,仅Internet Explorer支持

<picture>
  <source type="image/vnd.ms-photo" src="test.jxr">
  <source type="image/jp2" src="test.jp2">
  <source type="image/webp" src="test.webp">
  <img src="test.png" alt="test">
</picture>

source的type属性用来指定每个图像的MIME类型,浏览器会选择第一个含有其支持的MIME类型的源。源的顺序是至关重要的,如果浏览器无法识别所有的图象类型,它会回退至原来的img元素。

但是目前这些格式的支持多数不会直接这么做,因为代码会有些冗余难看,有判断浏览器ua输出不同dom或者样式的,也有服务端直接输出的。服务端直接输出,或者CDN做特殊处理,进行无感知格式切换,同时预留url和拒绝的接口,处理起来更灵活,省时省力,例如我们的:

 

服务端根据浏览器的请求头,返回不同的图像格式,对于X5内核还可以支持sharpP。

3.SVG应用

难点:变色方案,响应式定位计算

上面这个source的type属性 还支持另一种我们更常用的图像格式,SVG。

说起SVG,这是个出现频率比webp更高的图像格式了,他有着比iconfont更多的优点,所以现在web上正在大量的应用。

优点:

1.SVG提供的功能集涵盖了嵌套转换、裁剪路径、Alpha通道、滤镜效果等能力,它还具备了传统图片没有的矢量功能,可适配任何高清屏。

2.可读性好,有利于SEO与无障碍

与iconfont对比

1.渲染方式不同

关于渲染方式,之前欧文同学的文章已经讲述的很清楚,这里不多做叙述( https://isux.tencent.com/svg-icon-part-one.html),无论 黑白渲染, 灰度渲染, 次像素渲染,还是 DirectWrite 或  GDI 渲染, 既然iconfont他是一个字体,就难逃出现锯齿的命运,特别是在一倍屏幕下的渲染。

2.icon font只能支持单色

icon font做为字体无法支持多色图形,这就对设计造成了许多限制,因此这也成为了icon font的一个瓶颈。

3.icon font可读性不好

icon font主要在页面用Unicode符号调用对应的图标,这种方式不管是浏览器,搜索引擎和对无障碍方面的能力都没有SVG好

在对比完之前,可能有同学就会问,SVG和iconfont对比有个致命的缺点,就是换色.

比如hover换色,iconfont只要写个颜色就好了,SVG是不是需要做两个颜色的图?这也是SVG图像应用我们解决的一个难点之一

SVG换色,最初我试过三个方案

一是mask-image属性,他的优点是简单粗暴,直接用css来mask这个svg图形来进行换色,缺点很明显就是兼容性了,除去兼容性,还是很好用的。

demo:

background: #ff6600;
-webkit-mask:center no-repeat;
-webkit-mask-image: url(qq-logo.svg);

查看demo

二是通过SVG滤镜来实现,优点是效果更好,缺点除了兼容性,还需要额外的脚本配合。关于滤镜换色的详细说明在我上一篇文章里有详细介绍以及demo

查看文章

三是我们最终选择的底层无感知换色的方案,把修改颜色的脚本集成到了我们的工作流里,我们在写css的时候,遇到svg需要换色的地方,只需要

background-image: url(test.svg?fill=#ffffff)

加一句换色参数,工作流在底层会自动生成你所需要的svg图片并合并到雪碧图里。

SVG应用的另一个难点,就是作为背景图响应式渲染,雪碧图的background-position和background-size 的计算,这个其实也是其他图像都会存在的一个难点。

我的导师 wenju 之前发过这个计算公式相关的文章:

百分比值()是背景图相对于背景定位区(background positioning area)的百分比,可以控制在容器元素内仅显示Sprites图的部分内容。比如下图中,Sprites图是由四张图像拼成的,要想在容器内仅显示第一张图像,background-size的值应该多少呢?

我们仅需要Sprites图的1/4显示在容器内,那么Sprites图与容器的比例应该是4:1,计算公式为: background-size : ( Sprites width / image width) (Sprites height / image height)

如何计算background-position

我们已知的信息如下:

容器元素的尺寸:elW * elH
单张图片的尺寸:imgW * imgH
Sprites图片的尺寸:spritesW * spritesH
单张图片在Sprites图上的位置:imgPosX, imgPosY

我们假设:

点的位置为 (x, y)
容器上的(x, y)点与容器左上角的距离为 cX, cY
Sprites图上的(x, y)点与本张图片左上角的距离为 sX, sY

如果要把某张图片完全显示在容器元素内,我们可以推导出:

elW = imgW, elH = imgH
cX = sX, cY = sY

根据上面的信息,我就可以计算出具体的(x, y)值了,下面以 x% 为例:

cX = elW * x
sX = spritesW * x - imgPosX
elW * x = spritesW * x - imgPosX

解方程后就得到计算公式了:

x = imgPosX / (spritesW - elW) = imgPosX / (spritesW - imgW)
y = imgPosY / (spritesH - elH) = imgPosY / (spritesH - imgH)

如果你每次都手动计算的话会被累死吧?所以这一步我们还是集成到了工作流里,在所有合并雪碧图的地方用这个公式自动计算出位置。

而关于SVG的回退方案,已经是老生常谈

比如

<svg width="200" height="200">
        <image xlink:href="svg.svg" src="svg.png" width="200" height="200" />
</svg>

svg标签方式,缺点必须指定宽高,没有图片的保持款高比例特性,优点兼容性好,兼容所有主流浏览器

或者

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

在支持的浏览器里使用SVG,在不支持的浏览器里显示PNG,优点是type灵活,可用于SVG,WEBP等,而且保持了img标签的特性,方便做布局操作。缺点兼容性要求高,ios9+,安卓5+,微软Edge+
当然这个兼容性说的是source type的兼容,并不是SVG本身的兼容。

对于css里的SVG 的应用与回退策略,比较简单,也已经成熟,一般情况下都是这种用法

 background-image: url(fallback.png);
 background-image: url(image.svg), none;

利用的技术是CSS3多背景,浏览器只要支持了多背景,几乎无一例外支持SVG

再或者

background-image: url(fallback.png);
background-image: image-set( "test.png" 1x, "test-2x.png" 2x,
"test-print.png" 600dpi );

通过image-set来筛选和回退。

相关 [web 图像 常见] 推荐:

web图像的常见应用策略与技巧

- - 腾讯ISUX – 社交用户体验设计
本文介绍一些关于响应式图像的适配应用策略,回退原理,SVG的换色技巧,雪碧图的百分比定位计算公式等相关的一些小知识点,目的在于帮助一部分同学快速的理清图像应用思路,以及一些web图像的应用技巧. 1.响应式图像的应用与回退. 特点:应用简单,上手容易,性能表现良好. 根据不同设备,不同分辨率,不同像素比使用的响应式图像,常用的有两种场景:.

web页面相关的一些常见可用字符介绍

- 红茶 - 张鑫旭-鑫空间-鑫生活
本文地址:http://www.zhangxinxu.com/wordpress/?p=1623. 正文开始之前先分享两个与字符相关的东西. 首先是一张图片,是一张一些字符以及想对应的HTML实体表示的对照图片. 然后是一个页面,是我收集的些杂七杂八字符页面,地址如下:http://www.zhangxinxu.com/sp/character.html.

常见Web技术之间的关系,你了解多少?

- - 博客园_首页
如果你是一个Web开发初学者,那么你难免会在网上搜索HTML,CSS,XML,JS(Javascript),DOM,XSL等等这些词的意思,然而,随着学习的深入. 当你把他们搅在一起,你又糊涂了,你会不停的问,HTML是什么. 无论是网络百科,还是一些IT专题网站,又或者一些牛人博客,他们都会告诉你,某个单一的东西是什么,这类文章很多,但很少有涉及,它们组合起来是什么,有什么用.

Web开发常见的几个漏洞解决方法

- - 博客园_知识库
本文主要根据本人项目的一些第三方安全测试结果,以及本人针对这些漏洞问题的修复方案,介绍在这方面的一些经验,希望对大家有帮助.   基本上,参加的安全测试(渗透测试)的网站,可能或多或少存在下面几个漏洞:SQL注入漏洞、跨站脚本攻击漏洞、登陆后台管理页面、IIS短文件/文件夹漏洞、系统敏感信息泄露.   1、测试的步骤及内容.

Web项目性能问题常见定位方法梳理

- - 互联网 - ITeye博客
第一类:请求无响应,浏览器始终处于等待状态. 定位方法:kill -3或者jstack先分析线程堆栈,找到当前block的线程. 常见于:外部接口调用无返回或者网络IO阻塞无响应;死锁;死循环;……. 定位方法(这一类问题普遍比较难定位):.     (1)寻找hs_err_pidxxx.log这样的JVM日志.

常见六大Web 安全攻防解析

- - SegmentFault 最新的文章
在互联网时代,数据安全与个人隐私受到了前所未有的挑战,各种新奇的攻击技术层出不穷. 本文主要侧重于分析几种常见的攻击的类型以及防御的方法. 想阅读更多优质原创文章请猛戳 GitHub博客. XSS (Cross-Site Scripting),跨站脚本攻击,因为缩写和 CSS重叠,所以只能叫 XSS.

Web设计师如何制作Retina图像

- - 博客 - 伯乐在线
英文原文: how to create retina graphics for your web designs,编译: w3cplus – 大漠. 苹果公司发布了更多的产品适应Retina屏幕. 到目前为止,我们知道苹果设备中支持Retina屏幕技术的有“iPhone”、“iPod”、“iPad”和“Macbook Pro”,这些设备能为用户呈现更细腻、平滑和高质量的图片效果,提高了用户的视觉体验.

列举web应用程序设计中常见的10种错误

- - GamerBoom.com 游戏邦
作者:Jakob Nielsen. 撰写有关应用程序设计错误的文章是件很困难的事情,因为最糟糕的错误往往具有领域专门性和特殊性. 通常情况下,应用程序的失败有以下3种原因:解决了错误的问题;目标问题正确,但使用的是错误的功能;功能设计正确,但过于复杂使得用户难以理解. 这3个错误都可能导致应用的失败,而我却还无法告诉你怎么做才是正确的.

图像处理之常见二值化方法汇总

- - CSDN博客推荐文章
图像处理之常见二值化方法汇总. 图像二值化是图像分析与处理中最常见最重要的处理手段,二值处理方法也非常多. 本文主要介绍四种常见的二值处理方法,通常情况下可以满. 主要本文讨论的方法仅针对RGB色彩空间. 该方法非常简单,对RGB彩色图像灰度化以后,扫描图像的每个像素值,值小于127的. 将像素值设为0(黑色),值大于等于127的像素值设为255(白色).

如果你不知道这11款常见的Web应用程序框架,就说明你out了

- - 外刊IT评论
本文推荐了11款常见的Web应用程序框架,并列出了相关的学习资料和下载文档. 如果对这些项目还不熟悉,就赶紧学起来吧~. Rails是Ruby on Rails的简称,是一款开源的Web应用框架,采用Ruby语言,其设计原则是“不做重复的事”和“惯例优于设置”,是一款更符合实际需要而且更加高效的Web开发框架.