据互联网分析公司StatCounter公布的2月份数据显示,数据显示:
谷歌的Android默认浏览器成为了最流行的手机浏览器,
欧朋浏览器占到了22.67%的市场份额,
苹果的Safari浏览器占到了21.7%的市场份额。
诺基亚的Symbian浏览器占到了11.24%的市场份额,
黑莓浏览器占到了6.53%的市场份额。
iPhone默认浏览器为Safari;
Android默认浏览器webkit内核;
诺基亚Symbian S60智能机默认浏览器为OSS(OpenSourceSoftware)浏览器;
诺基亚window phone7手机浏览器默认是IE9浏览器。
以上所有手机都可以安装最新的手机Opera浏览器。
Chrome浏览器可以在iPhone/iPad以及Android设备中安装。
UC浏览器可以在上述所有手机上安装.
iPhone4+以及Android2.3+自然,CSS3中各类选择器都是支持的,无论是默认浏览器,还是在该设备上安装最新的Chrome/Opera/UC浏览器等。
Symbian OSS浏览器的选择器也很强大,支持桌面设备中用来区分现代浏览器和IE6~8浏览器的:root,支持:before以及:after以及其他很多CSS伪类。不过,并不支持body:nth-of-type(1) {}。因此,body:nth-of-type(1) .samrtphone{}是区分塞班OSS浏览器和其他HTML5支持完备浏览器的Hack。
WP7默认浏览器是IE9,因此,我们可以使用\9或\0等Hack和其他浏览器进行区分。
三、浏览器与CSS属性支持① CSS2.1
OSS浏览器虽然给人感觉低级了点,但是,对于常规CSS的支持还是很不错的,与Chrome浏览器等都相差无几。如display:table-cell等都是支持的。
基本上,手机浏览器对于background-position:fixed属性都不怎么感冒,iPhone Safari浏览器以及WP7上的IE9浏览器都是如此。因此,我们要想在页面上实现效果较好的background-position:fixed效果,基本上只能这样:
html, body { height: 100%; overflow: hidden; }
② CSS3
如果不考虑OSS浏览器,我们使用CSS3基本上都是很从容以及安心的,不过因为要兼顾OSS浏览器,需要注意的就多了。
box-shadow/text-shadow等不影响布局,可以渐进增强的CSS3属性我们不讨论。
background-size
OSS浏览器不支持background-size, 因此,使用该属性实现视网膜屏幕与普通屏幕的背景图片兼容实现出现了障碍(下面会提及)。但是,如果是小尺寸图片,如星星,我们也是可以使用上面的body:nth-of-type(1) hack进行特别处理。
border-radius
为了让iPhone3默认Safari浏览器支持圆角效果,我们可以通过添加-webkit-前缀方法。但是,OSS浏览器本身有部分webkit内核的东西,其对-webkit-border-radius也是敏感的;如果效果不错那还好,但该死的是,OSS浏览器上,对元素使用-webkit-border-radius,就像是在豆腐的四个角上用毛笔画了四个黑色的圈圈,而不是把豆腐边角削圆了!!相当的丑!
因此,我的建议是,圆角实现直接border-radius, 而非-webkit-border-radius,iPhone3也作为优雅降级的对象。当然,如果你无视OSS浏览器,后者也是可以的。
font-face
font-face与SVG是让图形兼容视网膜屏幕的两个利器。
大小颜色可控,资源占用小。相比普通png/jpg图片,视网膜显示屏下不会拉伸模糊。
首先,OSS浏览器不支持font-face.
然后,让人意想不到的是wp7上的IE9浏览器也是不支持font-face,据说这是IE9的安全还是什么的策略(真是坑爹!),IE9桌面浏览器是支持font-face的。
后来,测试发现,Android设备上安装的UC浏览器也不支持font-face。
老版本iPhone上,貌似只对SVG格式的字体文件支持良好,因此,我们写CSS代码的时候,一定要注意字体文件调用的顺序,如下:
@font-face { font-family: ico; src: url(/b/pad/font/icomoon.eot); src: url(/b/pad/font/icomoon/.eot) format('embedded-opentype'), url(/b/pad/font/icomoon.woff) format('woff'), url(/b/pad/font/icomoon.ttf) format('truetype'), url(/b/pad/font/icomoon.svg) format('svg'); }
SVG格式文件需要放在最后。
为了即使浏览器不支持也不影响功能(一些装饰性的图形可以不用管),使用IcoMoon生成自定义字体的时候,其中的字符我们不应该使用其默认生成的,我们需要根据自己图形的模样,寻找接近的字符。
甚至我们可以使用中文:
我收集了下乱七八糟的字符,具体可以参见我站点左下角这里:
由于OSS浏览器不支持content: attr(*),所以,对于装饰性的字符图形,我们可以将需要显示的字符写在自定义属性上,如:
<span data-icon="!" aria-hidden="true"><span>
可以避免显示上的干扰。
四、浏览器与图片显示竖着状态,如iPhone4, 宽度像素640,而一般Symbian S60宽度320. 由于为了阅读体验,iPhone4和Symbian默认浏览器的布局视区宽度都是320像素,因此iphone4的设备像素比devicePixelRatio为2, Symbian为1.
这所导致的问题就是实际320像素宽的图片在Symbian上是正常比例宽度满屏显示;而在iPhone4上,也是宽度满屏,但图片实际两倍拉伸了,因此,如果图片本身质量不高,就会有模糊的拉伸——视网膜屏幕的iPhone反而效果不好。
如果您不计成本,可以制作两套图片,分别使用语高清屏幕以及普通屏幕。不过,上文“设备像素比devicePixelRatio”也提到过,有些设备的像素比是2.25, 以后可能还会出现像素比3, 因此,这种多尺寸图片,开发维护成本高,且不一定长寿的方法是否值得推广值得商榷。
.icon { background-image: url(/blog_article/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(/blog_article/example@2x.png); /* 2倍尺寸图片 */ } }
如果你想省事,可以使用高清版本的图片,对于320像素宽度,设备像素比为1的设备,使用1/2尺寸压缩限制,或者使用background-size进行一般尺寸显示。举例而言,我们使用640像素宽度的图片,使用CSS(eg. img { width: 320px; })限死成300像素宽。类似Nokia塞班机子有浪费,但是,iPhone以及最近的Android设备上图像显示很OK.
如果想兼容OSS浏览器,background-size慎用。
当然,最好的方法就是避免使用图片,尤其底纹,装饰性图标,边边角角的图形等。我们可以使用CSS3 font-face图形生成,或者SVG矢量图片,或者Canvas绘图。如果值考虑智能机,上面的技术都是很OK的。
五、浏览器与HTML5表单元素iPhone4与iPhone4S相比只少了一个"S", 但是在对HTML5元素的支持上差异较大。
例如:
<input type="date" />
在iPhone4上就是个普通的框框,但是,iPhone4S上就可以很华丽丽地选择日期,如下图:
其他差异还体现在对required, pattern等验证属性的支持上。以及表单元素间的对齐,奇怪的间距bug等!
塞班默认浏览器自然不支持HTML5,但是,塞班机子上安装最新Opera浏览器,各类HTML5表单元素的特性,UI等均支持。
iPhone3 默认浏览器的文本框似乎默认有个很蛋疼的内阴影效果,因此,当我们想要div等标签模拟边框或无边框效果时候,这玩意让人伤神!
iPhone浏览器文本框上面是不能覆盖其他元素的,如下图所示的叉叉效果:
iPhone的Safari浏览器上点击这个叉叉,永远都是文本框选中,而不是清空其中的内容。解决之道只能,边框模拟,叉叉覆盖在普通元素之上。
不得不说,OSS浏览器对JavaScript的支持不是一般的弱,例如不支持document.querySelectorAll(),因此,为了这个该死的浏览器,不得不自己写个简单基本的选择器。不支持ES5,因此,如数组的forEach方法就不可以使用等。
因此,如果想支持OSS浏览器的话,JS一定要慎用,复杂的JS交互直接忽略,使用最简单的方式呈现即可。
其他手机浏览器对JS的支持都是可以的。HTML5的本地存储、地理位置;以及上面提到的document.querySelector()以及ES5都是支持。
不过,iPhone上似乎有个坑爹的问题,其默认浏览器下,页面滚动的时候,上面的标题栏也一起滚动了;结果在计算其滚动高度的时候,最上面的60像素(实际页面已经下去了),但是滚动高度似乎都是0. 这使得使用JavaScript实现元素的底部浮动变成了很头疼的问题。其他浏览器都没有这个问题。
我在getview 里面 写了类似与 qq 聊天 界面左右显示 使用到 四个 view 界 面,使用缓存就null报错,不使用都正常,最好可以远程看看 qq:815107057,
public class MessageAdapter extends BaseAdapter { Context context; private List<Mes> MessageLists; private LayoutInflater inflater; public MessageAdapter(Context context, List<Mes> MessageLists) { this.context = context; this.MessageLists = MessageLists; inflater = LayoutInflater.from(context); } @Override public int getCount() { // TODO Auto-generated method stub return MessageLists.size(); } @Override public Object getItem(int position) { // TODO Auto-generated method stub return MessageLists.get(position); } static final int LEFT_TEXT =100; static final int RIGHT_TEXT = 1; static final int RIGHT_VI = 2; static final int RIGHT_POTO = 3; @Override public int getItemViewType(int position) { Mes message = (Mes) getItem(position); if (message.getBelong().equals("1")) { //判断左边 还是 右边 return LEFT_TEXT; } else{ int s = Integer.valueOf(message.getClas()); switch(s){ case RIGHT_TEXT: return RIGHT_TEXT; case RIGHT_VI: return RIGHT_VI; case RIGHT_POTO: return RIGHT_POTO; } } return 1000000000; } @Override public long getItemId(int position) { // TODO Auto-generated method stub return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { Holder holder = null; // if (convertView == null) { holder = new Holder(); switch (getItemViewType(position)) { case LEFT_TEXT: convertView = inflater.inflate(R.layout.left_message_font, null); holder.left_tv_mescon = (TextView) convertView.findViewById(R.id.left_txt_message); break; case RIGHT_TEXT: convertView = inflater.inflate(R.layout.right_message_item_font, null); holder.right_tv_mescon = (TextView) convertView.findViewById(R.id.right_txt_message); break; case RIGHT_VI: convertView = inflater.inflate(R.layout.right_message_item_vi,null); break; case RIGHT_POTO: convertView = inflater.inflate(R.layout.right_message_item_poto, null); break; } // convertView.setTag(holder); // } else { // holder = (Holder) convertView.getTag(); // } final Mes message = (Mes) getItem(position); switch (getItemViewType(position)) { case LEFT_TEXT: holder.left_tv_mescon.setText(message.getMes()); /* 去掉添加数据代码 */ break; case RIGHT_TEXT: holder.right_tv_mescon.setText(message.getMes()); /* /* 去掉添加数据代码 */ break; case RIGHT_VI: /* /* 去掉添加数据代码 */ break; case RIGHT_POTO: /* 去掉添加数据代码 */ break; } return convertView; } class Holder { // left font public TextView left_tv_mescon; // right font public TextView right_tv_mescon; // right vi public TextView right_tv_chatcontent; // right poto } }
就算不是果粉也应该知道,iPad2与new iPad的重大区别之一就是显示屏的分辨率。new iPad显示屏被称之为“视网膜显示屏”,其设备分辨比(之前有详细介绍,点击这里查看)是iPad2的两倍。 – iPad mini也是普通分辨比。
iPad2与new iPad同时显示一个页面,宽度都是1024像素的,那差别在什么地方呢?——就在于new iPad每个像素点实际上有4倍的普通像素点,如下示意(© smashingmagazine):
我们使用CSS设置的像素值(px)属于普通像素点,或者称之为标准像素点。
因此,一张200×200尺寸的图片,我们设置如下CSS:
img { width: 200px; height: 200px; }
在iPad2或Mini iPad中就是很正常显示的图片;但是,在New iPad中,1个CSS像素点实际上有4个位图像素点,1个分成4个,显然不够分啊,只能颜色近似选取,于是,图片感觉就是模糊的(© smashingmagazine)!
因此,要想让视网膜屏幕下的图片高清晰显示,我们需要的图片的原始大小不能是200×200像素,而需要2倍高宽,即400×400像素,CSS像素限制依然是:
img { width: 200px; height: 200px; }
此时,视网膜屏幕下图片就显示OK了(非视网膜屏幕图片被压缩-减少像素取样——资源浪费!)(© smashingmagazine):
因此,这种不同iPad上不同的像素分辨比是兼容处理的大头!
近期折腾的一个pad相关项目基本上进入尾声,产品嘛就那样,跟点评的比差距很大,差距不在于技术实现……毕竟不是优秀方驱动的……(没忍住还是吐槽下吧~)比方说,建铁路,线路急急忙忙规划好,结果造路的时候发现花岗岩地质,此时最大权衡的方法是修改设计路线,结果是一声口号:工人们,我对你们的技术信得过,大家不畏艰难险阻,一起上吧……结果大家都懂的——通过技术弥补设计缺陷是很傻逼的!
镜花水月,飘渺浮云,很多事情不是一人能左右的。还是做点实在的事情:钓钓鱼,分享些技术心得,可能价值更大些,哈哈!
二、关于设计图设计图一定要是针对高清设计的,即宽度为2048像素。为什么呢?历史是向前的,向下兼容才是王道与趋势。
在定元素的CSS像素尺寸的时候,设计图size除以2就是准确值。例如,设计图上这个:
显然,一些圆角,以及渐变之类,使用CSS3实现,这样,无论是高清屏还是普通屏,都显示很赞,尤其在New iPad上,显示效果真的很赞的!
例如上面的那个券字图标,里面的文字就是文字,后面的渐变以及圆角都是CSS实现,代码如下:
.priv_icon_coupon { display: inline-block; width: 70px; height: 70px; border-radius: 0.1em; background-image: -webkit-gradient(linear, 0 0, 0 bottom, from(#EF137A), to(#9C117A)); font: bold 50px/64px "微软雅黑"; color: #fff; text-align: center; text-shadow: 0 1px rgba(0,0,0,.5); }
<span >券</span>
如下Chrome浏览器下的效果,New iPad显示效果很细腻(恕我弄不到截图,我就想啊,总不能用我的诺基亚手机拍下来展示吧~~)
或者下面的图形效果等等(Chrome浏览器下截图),都可以使用CSS实现——无需担心IE之类的兼容问题!
并不是所有的图形都可以使用CSS生成的,例如很多的纯色小图标。此时,我们可以借助另一项技术:自定义图标字体!
我是利用IcoMoon的免费开源图标字体进行制作的,根据设计图选择合适的小图标们,生成自定义字体,之前有详细介绍,点击这里查看详情!
有人曾像我抱怨,该网站更新太快,不能用。其实完全不用担心,首先,在同一现代浏览器上,您选择的字体其会本地存储下来,下次打开的时候会自动显示您之前的选择;再者,就算本地信息被remove掉,您也可以通过导入之前生成的SVG字体文件进行新的编辑与生成!
下图为我在项目中使用到的所有图标字体:
相关CSS如下:
/* custom fonts */ @font-face { font-family: ico; src: url(/b/pad/font/icomoon.eot); src: url(/b/pad/font/icomoon/.eot) format('embedded-opentype'), url(/b/pad/font/icomoon.woff) format('woff'), url(/b/pad/font/icomoon.ttf) format('truetype'), url(/b/pad/font/icomoon.svg) format('svg'); }
当然,传统web开发的@font-face相关代码与上面还是有差异的(这里无需关心低版本IE浏览器),具体可以查看我之前的“CSS3 @font-face实现颜色大小可控的三角效果”一文。
使用自定义字体图形的好处就是,无论你屏幕的像素比多高,我的图形都是细腻的平滑的,越高像素比效果越好!因此,iPad2与iPad3之间屏幕分辨率差异问题就无需担心!
例如,在Chrome浏览器下,我用鼠标把页面比例搞得蛮大的,效果也是平滑的:
本项目中,我并没有使用过SVG背景,不过之前的手机项目到时使用过,与之类似的,可以解决高清iPhone与普通iPhone的兼容性问题,具体可查看前文“SVG特征、支持以及一些实际使用问题”。
其中,举例了实现下图的波波效果:
该SVG文件可以点击这里查看:circle.svg
该SVG文件是自己绘制的,如果您也想自己绘制创建SVG文件,可以参见这里。
六、background-size下的向下兼容有些小图标,设计师把它弄成渐变的,带边框的,不规则的,这时候,自定义字体搞不定(文字渐变仅部分支持),SVG也搞不定(自己画图功力有限,55555555),不得已,还是使用传统的图片。
这时候,偶的策略是这样子的,高清图片上原始大小抠出这些小图标,使用background-size进行尺寸限制,优先高清设备;因为都属于小图标,所浪费的尺寸大小有限,权衡来看,是最佳策略。
例如下面这个设计效果:
弄出来的图片信息如下:
可见,高度仅为设计图上的原始高度。在实际CSS处理的时候,尺寸1/2限制,代码如下:
star, .star_in { background: url(/blog_article/star.png) repeat-x; background-size: 14px 30px; /* 原始大小28x60 */ } ...
于是,最终,高清new iPad下高清显示,效果杠杠的;普通pad上图片1/2压缩,效果也还好,也算清楚!
当然,如果你精力够多,追求完美,也可以使用CSS进行精确控制,例如:
@media only screen and (-Webkit-min-device-pixel-ratio: 1.5) { /* 当设备像素比不小于1.5的时候... */ }
展示性的图片是最难处理的。
例如,一个餐厅图片,CSS限制的像素宽度是480×320, 如果我们直接显示480*320像素的图片,则在高清设备下,图片相当于2倍拉伸的效果 – 模糊!如果限制高清的960*640图片,Oh, my gaga! 这增加的图片尺寸大小估计有4倍之多,也就是说,普通iPad上,3/4的图片流量是多余的,浪费的,关键显示的效果还不如480*320像素的好!如何权衡,如何博弈!?
理论上讲,最佳的做法是,不同的屏幕设备显示不同的大小图片。具体做法如下:
/1/a.jpg /1.5/a.jpg /2/a.jpg
<img src="/2/a.jpg" />
<img src="/blog_article/%E5%8D%A0%E4%BD%8D.jpg" data-url="/1/a.jpg" data-url2="/2/a.jpg" width="240" height="180" />
var eleImg = $("img"), ratio = window.devicePixelRatio; eleImg.attr("src", eleImg.attr(ratio > 1.5? "data-url2": ""data-url"));
但是,上面的做法只是理论的做法。实际上,如果完全按照上面的实践,会遇到很多阻碍——资源、配合、实施以及最终效果等!说白了,就是非常的折腾,工作量大;最后说不定还吃力不讨好——老板拿着个高清iPad在咆哮:怎么这个瀑布流页面的图片加载这么慢啊!!
还是那句话,一切在于权衡!
大众点评iPad高清版,餐厅详情页面的特色菜图片都是模糊的(图在我眼中,弄不下来~);可以看到,大众点评可能选择了速度,而不是图片的显示质量(因为这里的特色菜图片可能上百之多——虽然使用了动态加载)!
但是,对于某些特殊图片,到时可以做一些兼容处理。
例如,餐厅位置的Google静态图片(截图有缩放):
如果不考虑new iPad等视网膜屏幕设备,直接下面的Code就可以搞定了:
<img src="http://maps.google.com/maps/api/staticmap?center=31.230393,121.473704&zoom=12&size=300x210&sensor=false" height="210" width="300" />
如下效果(非截图):
但是,上面这个图在最新的iMac上或者new iPad上就是模糊的,跟旁边细腻的文字,图标混在一起,显得十分的不和谐;我们有必要进行特殊处理。
很简单,new iPad上图片两倍大小就可以了,因此,上面的size=300x210我们改成size=600x420,然后,把缩放比例zoom=12再提高一点就可以了,比如说zoom=16.
因此,new iPad下HTML代码为:
<img src="http://maps.google.com/maps/api/staticmap?center=31.230393,121.473704&zoom=16&size=600x420&sensor=false" height="210" width="300" />
如下效果(非截图):
至于如何让不同屏幕显示不同图片,那就是你的事情了,方法多多,情况不同使用方法不一样。
例如,我这里餐厅的信息(包括静态地图位置)都是Ajax load HTML载入的,因此,我只需要在Ajax请求的时候,将iPad的设备像素比devicePixelRatio值发给后台,其他的事情,就交给后台他们去判断、去输出了!
我对静态地图研究不是很深,这里可能有处理不当的地方,欢迎同行指正,不甚感谢!