一、retina视网膜时代的页面
随着iphone4与new ipad的推出,retina(视网膜)屏在移动设备中被越来越广泛的应用,retina屏给画面带来了前所未有的清晰平滑效果,却给开发人员带来了一些小小麻烦……
高分辨率屏幕与高像素密度屏幕
在 Retina 视网膜屏幕面世之前人们很少关注像素密度,尤其在 Windows 系统下,提高屏幕分辨率一般都是通过提高屏幕尺寸。而随着屏幕分辨率的提升,图像和文字显示目标会相应缩小,造成观看极其不便。因为系统并不会自动根据屏幕尺寸和分辨率关系相应的调整文字和图标的大小。(即使手动调整也会因为微软一直采用的点阵字体和大多数位图在提高分辨率后,因为多于出的像素点没有填充渲染会出现拉伸,进而会产生锯齿,这也是系统不会自动适配的原因之一)
这也就给我们造成一种假象:显示器尺寸越大,分辨率就会越大。
所以当最近苹果的 Retina 视网膜屏幕令很多人困惑不已,为什么那么小的屏幕会有那么大的分辨率。为什么那么大的分辨率,非但没有使得文字和图像变小,反而更加清晰了呢?
高像素密度屏幕(高 ppi)
严格来说,高像素密度屏幕也是属于高分辨率屏幕,不同的是高像素密度屏幕在提升了分辨率的同时也提高了其像素密度,即相同的尺寸有着更大的分辨率。以评估的 Retina 视网膜屏幕为例,它并不是像普通显示器那样通过增大尺寸来增加分辨率,而是靠提升单位面积屏幕的像素数量,即像素密度来提升分辨率,这样就有了高像素密度屏幕。
同时操作系统也会自动采取相应的模式(如 Mac 下的 HiDPI)进行适配,将缩小后的字体(苹果一直采用矢量字体)和图标重新放大,这样苹果用了更多的像素数来显示同样的内容,显示尺寸仍然不变,但是多了更多细节,因此会有非常明显的视觉效果提升。
那么应当如何整合系统和高分辨率屏幕呢? 我们以 Retina 为例看看实例。对于苹果来说要想适配 Retina 屏,除了系统默认支持外,苹果无论在 iOS 还是 Mac 设备上都是采用将分辨率提高 2 倍,即对应 UI 尺寸分别扩大为原来的 2 倍的方式来进行 Retina 适配的。
- iPhone/iPod Touch
普屏分辨率 320像素 x 480像素 Retina分辨率 640像素 x 960像素
- iPad,iPad2/New iPad
普屏 768像素 x 1024像素 Retina屏 1536像素 x 2048像素
- 换算关系
普屏 1点 = 1像素 Retina屏 1点 = 2像素
Retina设备
Retina是由苹果提出来的,根据苹果发布产品的定义:PPI高于210(笔记本电脑)、260(平板电脑)、300(手机)的屏幕都称为Retina屏幕
win8 与 Ivy Bridge
微软也对未来windows平台做了规划,将借助 Windows 8 的 Metro UI 和其在平板上的手势来解决因为屏幕分辨率增大造成的缩放,采用 100%、140% 和 180% 三种不同的缩放比例来解决缩放图形和视觉效果在类似 Retina 高像素屏幕上用户界面元素面积太小的问题。并同时表示未来将放弃传统的点阵字体,开放供开发者利用矢量字型和图文件(SVG)进行架构,来协助开发者为未来各种分辨率的适配做准备,助力 Windows 8平板电脑加入到视网膜行列。
如何做网站才能适应视网膜时代的产品呢
mir.aculo.us的信息图会告诉你如何让网站适应视网膜分辨率
二、HTML和CSS的方法实现
如何使用Retina来优化Web图形的方法还是如雨后春笋涌现,而且还有更多的人在关注和分享
最直截了当的方法就是通过手动制图或以编程的方式制作两种不同的图形,一张是普通屏幕的图片,另外一种是Retina屏幕的图形,而且Retina屏幕下的图片是普通屏幕的两倍像素。看个实例,有一张200x300像素的图片(CSS像素),然后将一个位图的像素400x600上传到你的服务器上,通过CSS样式或HTML属性将其压缩50%,这个时候,在一个标签分辨率的显示器上,其呈现的图像是位图的四分之一像素。简单点理解,普通屏幕下的图像被压缩,减少像素取样(只是位图含像素的四分之一),这样就造成了资源浪费。同时把这个过程称为"Downsampled"。
但在Retina屏幕下,相同的图像会使用四倍的物理像素显示,这样一来,每个物理像素最终完全匹配一位图像素,使用图像得到完全的呈现。
有几种方法可以实现这样的效果。
1、使用width、height和两套图片实现
1)HTML
最简单的方法就是通过“img”标签,设置“width”和“height”属性——准备一张400x400像素的图片
<img src="example@2x.png" width="200" height="300" />
此时,视网膜屏幕下图片就显示OK了(非视网膜屏幕图片被压缩-减少像素取样——资源浪费!)
这里注意了,即使指定的图片高度是可选的,但是在加载图片前,浏览器已经预留了所需的空间。这样就可以防址页面布局更改图片时,在加载一次。
2)使用JavaScript
同样的效果,我们可以通过JavaScript脚本对图像(为Retina屏幕准备的图像)进行减半。
$(window).load(function() { var images = $('img'); images.each(function(i) { $(this).width($(this).width() / 2); }); });
3)使用CSS
另外一种方法就是通过CSS来实现。那么常见的方法就是给元素设置一个背景图像,比如说给“div”元素设置一个背景图像,最关键的是给这个背景图像设置"background-size",来指定背景图像的大小,你也可以给元素设置一个大小,然后给"background-size"设置一个“contain”属性值。不过可惜的是IE78不支持这个属性的运用。
.image { background-image: url(example@2x.png); background-size: 200px 300px; /*或者设置background-size: contain; */ height: 300px; width: 200px; }
你还可以使用元素的伪元素来代替
.image-container:before { background-image: url(example@2x.png); background-size: 200px 300px; content:''; display: block; height: 300px; width: 200px; }
HTML和CSS方法的优点
- 很容易实现
- 能跨浏览器兼容
HTML和CSS方法的缺点
- 非Retina屏幕下必须下载更大的图片资源
- Downsampled图像在不同的分辨下可能会失去一定的清晰度
- background-size在IE9以下浏览器不能得到友好支持
注明:图片命名:
切图的时候,可以以下列方式进行分类
640x960/pic@2x.png
320x480/pic.png
UI:图标参考:
图标会自动添加高亮效果,如果不需要,可以在plist中明确指定UIPrerenderedIcon的键值去掉
57像素的普屏的iPhone图标,图标圆角的半径为10像素
114像素Retina屏的iPhone图标,图标圆角的半径为20像素
512像素的用于iTunes/App Store的图标,在实际显示是会被缩放到175像素进行显示(但提交是不可以提交175像素)
72像素的普屏iPad图标,图标圆角的半径为13像素
144像素Retina屏iPad图标,图标圆角的半径为26像素
50像素iPad的Spotlight搜索图标的最终视觉大小是48像素,原因是iOS会对图标的每个边去掉1个像素,添加阴影效果
100像素Retina屏的Spotlight搜索图标的最终视觉大小是96像素,原因同上,这次是每边减2个像素
2、使用CSS Media Queries和两套图片实现
可以通过“device-pixel-ratio”属性或者其扩展属性“min-device-pixel-ratio”和“max-device-pixel-ratio”。这几个Media Queries可以使用background-image为Retina准备高精密度像素的图片。
.icon { background-image: url(example.png); background-size: 200px 300px; height: 300px; width: 200px; } @media only screen and (-Webkit-min-device-pixel-ratio: 1.5), only screen and (-moz-min-device-pixel-ratio: 1.5), only screen and (-o-min-device-pixel-ratio: 3/2), only screen and (min-device-pixel-ratio: 1.5) { .icon { background-image: url(example@2x.png); } }
通过“window.devicePixelRatio”的比例“1.5”或"2"为不同的苹果设备做相对应的查询。
@media only screen and (-webkit-min-device-pixel-ratio : 1.5),only screen and (min-device-pixel-ratio : 1.5) { /* Styles */ //iPhone 4 } @media only screen and (min- 320px) { /* Small screen, non-retina */ } @media only screen and (-webkit-min-device-pixel-ratio: 2) and (min- 320px), only screen and ( min--moz-device-pixel-ratio: 2) and (min- 320px), only screen and ( -o-min-device-pixel-ratio: 2/1) and (min- 320px), only screen and ( min-device-pixel-ratio: 2) and (min- 320px), only screen and ( min-resolution: 192dpi) and (min- 320px), only screen and ( min-resolution: 2dppx) and (min- 320px) { /* Small screen, retina, stuff to override above media query */ } @media only screen and (min- 700px) { /* Medium screen, non-retina */ } @media only screen and (-webkit-min-device-pixel-ratio: 2) and (min- 700px), only screen and ( min--moz-device-pixel-ratio: 2) and (min- 700px), only screen and ( -o-min-device-pixel-ratio: 2/1) and (min- 700px), only screen and ( min-device-pixel-ratio: 2) and (min- 700px), only screen and ( min-resolution: 192dpi) and (min- 700px), only screen and ( min-resolution: 2dppx) and (min- 700px) { /* Medium screen, retina, stuff to override above media query */ } @media only screen and (min- 1300px) { /* Large screen, non-retina */ } @media only screen and (-webkit-min-device-pixel-ratio: 2) and (min- 1300px), only screen and ( min--moz-device-pixel-ratio: 2) and (min- 1300px), only screen and ( -o-min-device-pixel-ratio: 2/1) and (min- 1300px), only screen and ( min-device-pixel-ratio: 2) and (min- 1300px), only screen and ( min-resolution: 192dpi) and (min- 1300px), only screen and ( min-resolution: 2dppx) and (min- 1300px) { /* Large screen, retina, stuff to override above media query */ }
CSS Media Queries的优点
- 只有对应的目标元素才会下载图片资源
- 跨浏览器兼容
- 像素可以精确控制
CSS Media Queries的缺点
- 单调无味的实现过程,特别是大型项目中
- 只能通过HTML元素的背景图片来实现,无任何语义化可言
也可使用JavaScript
使用js对“window.devicePixelRatio”进行判断,然后根据对应的值给Retina屏幕选择图像。
$(document).ready(function(){ if (window.devicePixelRatio > 1) { var lowresImages = $('img'); images.each(function(i) { var lowres = $(this).attr('src'); var highres = lowres.replace(".", "@2x."); $(this).attr('src', highres); }); } });
简单的javascript方法
<script src="js/retina.js"></script>
其中Retina.js是为Retina而生的,基本上实现了上面的所有功能。使用retina.js脚本来控制调用Retina图像。简单点说,retina.js会自动检查你图片目录中的”@2x“图像,然后在Retina设备下替换普通的图片。
前面也说过了,devicePixelRatio目前支持的浏览器并不多,但将来会有更多的浏览器支持这一技术。
Javascript查询的优点
- 易于实施
- 非Retina屏幕不用下载过大的资源
- 像素精确控制
Javascript查询的缺点
- Retina屏幕下必须下载标准备和高精密度的两个资源
- Retina屏幕下图像交互可见
- 浏览器兼容性不强
3. 可缩放矢量图形来实现
不管使用什么方法,光栅衅像仍然有自己固定的位图分辨率,也就是其缩放始终受限于其像素,也绝对无法无限制的伸缩。但是矢量图就不一样,他可以随意的进行伸缩,而无任何影响。这就是在Retina屏幕下的Web图形,矢量图形具有无法可比的优势。
到目前为止,基于XML的svg格式制作的矢量图得到了70&以上的浏览器支持,可以使用svg绘制各种图形,并且可以在Retina下任意的伸缩。
做为web设计人员,使用SVG最简单的方法是通过HTML的img标签、CSS的background属性或者伪元素的content中的url()。
HTML的img标签调用svg
<img src="example.svg" width="200" height="300" />
在这里一个svg图像可以做为普通显屏和Retina显屏的通用图像,可以做任何的伸缩,而不会像光栅位图一样失真,而且资源统一,节省带宽,方便维护。
CSS中调用svg图像
svg图像可以像普通图像一样,当作元素的背景图片来应用
.image { background-image: url(example.svg); background-size: 200px 300px; height: 200px; width: 300px; }
了当成元素的背景图片使用之外,还可以通过伪元素的“content”来调用
.image-container:before { content: url(example.svg); }
如果你想在IE7-8和Android2.x上运用,那么使用使用png图片来代替svg图像
.image { background-image: url(example.png); background-size: 200px 300px; } .svg { .image { background-image: url(example.svg); } }
在HTML标签中,给img标签自定义一个属性,给这个自定义属性设置一个png图片,以做备用,不过这种方法需要一定的脚本配合使用。
<img src="example.svg" data-png-fallback="example.png" />
需要的脚本
$(document).ready(function(){ if(!Modernizr.svg) { var images = $('img[data-png-fallback]'); images.each(function(i) { $(this).attr('src', $(this).data('png-fallback')); }); } });
SVG矢量图的优点
- 一个资源适合所有设备
- 易于维护
- 面向未来的:可伸缩向量图形
SVG矢量图的缺点
- 没有像素那样有精度
- 由于文件大小,不适合复杂的图形
- 不支持IE7-8和早期的安卓版本
3. 使用css sprites来优化你的网站在Retina屏幕下显示
http://miekd.com/articles/using-css-sprites-to-optimize-your-website-for-retina-displays/
优化高分辨率下的屏幕下效果,你需要通过“media queries”准备一张大的图片。所以在正常分辨率下加载的是“@1x”图像,在高分辨率下加载的是@2像素下的效果。这就意味着,你的图片数要增加两倍,而且CSS样式中也需要增加两倍。
是的,我们通过javascript可以解决,但是我们没有找到通过代码真正解决的方法。但是通过css sprites技术,我们只需要通过CSS的选择器来覆盖@1x的图片。
接下来的例子中,我们只通地四个选择器来控制不同的图片资源。首先会使用Retina技术,你可以为独立的元素使用不同的代码。然后在非视网膜屏幕下使用200x200px的的CSS Sprites图片。
span.location { background: url(location.png) no-repeat 0 0; } span.success { background: url(success.png) no-repeat 0 0; } a.delete { background: url(delete.png) no-repeat 0 -100px; } .content a.fav-link { background: url(favorite.png) no-repeat 0 0; } @media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min-device-pixel-ratio: 2) { span.location { background-image: url(location@2x.png); background-size: 16px 14px; } span.success { background-image: url(success@2x.png); background-size: 13px 14px; } a.delete { background: url(delete@2x.png) no-repeat 0 -100px; } .content a.fav-link { background-image: url(favorite@2x.png); background-size: 11px 13px; } }
span.location { background: url(sprite.png) no-repeat 0 0; } span.success { background: url(sprite.png) no-repeat -100px 0; } a.delete { background: url(sprite.png) no-repeat -100px -100px; } .content a.fav-link { background: url(sprite.png) no-repeat 0 -100px; } @media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min-device-pixel-ratio: 2) { span.location, span.success, a.delete, .content a.fav-link { /* Reference the @2x Sprite */ background-image: url(sprite@2x.png); /* Translate the @2x sprite's dimensions back to 1x */ background-size: 200px 200px; } }
注:记住上面的这个例子仅适用于Retina屏幕下的设备,目前仅在IOS的移动设备iPhone4s、iPhone5、iPad、iPod和Mackbook Pro。对于Android系统下,要取决于你的系统,采用不同的“min-device-pixel-ratio”。
总结
- 不应该将所有的资源引入一个文件中,应该使用CSS sprite来集成图片。
- 创建@2x的sprites图,这个图刚好是普通图的两倍,而且具有双向扩展
- 在Retina屏幕下,对应的元素上使用相同的Scripts图片
- 使用background-size属性来确保你的@2x Sprites图正确定位
注意,这只是一个简单的例子,里面对三个元素设置了背景图,你可以根据需要在你的站点上使用更多的图片,按这种方式。在Retina屏幕下,使用这种方法,不仅节约了http的请求,还让你的代码简洁易于维护,同时在Retina下也更高效。
注明:刚刚发现一个CSS4的属性:image-set也可以用在Retina的网页上,具体可以参考:http://www.w3cplus.com/css/safari-6-and-chrome-21-add-image-set-to-support-retina-images.html