the data:url protocol

所谓"data"类型的Url格式,是在RFC2397中 提出的,目的对于一些“小”的数据,可以在网页中直接嵌入,而不是从外部文件载入。例如对于img这个Tag,哪怕这个图片非常非常的小,小到只有一个 点,也是要从另外一个外部的图片文件例如gif文件中读入的,如果浏览器实现了data类型的Url格式,这个文件就可以直接从页面文件内部读入了。

data类型的Url格式早在1998年就提出了,时至今日,Firfox、Opera、Safari和Konqueror这些浏览器都已经支持,但是IE直到7.0版本都还没有支持,IE不支持的东西太多了,也不差这一个。:(

小例子

下面这个html代码可以在支持data类型Url的浏览器中运行,例如Firefox。运行后会看到一条蓝色渐变底色的标题。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<style type="text/css">
.title {
  background-image:url(data:image/gif;base64,R0lGODlhAQAcALMAAMXh96HR97XZ98Hf98Xg97DX97nb98Lf97vc98Tg973d96rU97ba97%2Fe96XS9wAAACH5BAAAAAAALAAAAAABABwAAAQVMLhVBDNItXESAURyDI2CGIxQLE4EADs%3D);
  background-repeat:repeat-x;
  height:28px;
  line-height: 28px;
  text-align:center;
}
</style>
</head>
<body>
<div class="title">Hello, world!</div>
</body>
</html>

这个渐变的蓝色底色实际上是用一个1x28的小图片通过横行重复(repeat-x)形成的。这个图片很小,不过104个字节,直接嵌入到html或css文件还是很合适的。

data格式的Url最直接的好处是,这些Url原本会引起一个新的网络访问,因为那里是一个网页的地址,现在不会有新的网络访问了,因为现在这里是网页的内容。这样做,会减少服务器的负载,当然同时也增加了当前网页的大小。所以对“小”数据特别有好处。

data类型Url的形式

既然是Url,当然也可以直接在浏览器的地址栏中输入。

data:text/html,<html><body><p><b>Hello, world!</b></p></body></html>

在浏览器中输入以上的Url,会得到一个加粗的"Hello, world!"。也就是说,data:后面的数据直接用做网页的内容,而不是网页的地址。

简单的说,data类型的Url大致有下面几种形式。

data:,<文本数据>
data:text/plain,<文本数据>
data:text/html,<HTML代码>
data:text/html;base64,<base64编码的HTML代码>
data:text/css,<CSS代码>
data:text/css;base64,<base64编码的CSS代码>
data:text/javascript,<Javascript代码>
data:text/javascript;base64,<base64编码的Javascript代码>
data:image/gif;base64,base64编码的gif图片数据
data:image/png;base64,base64编码的png图片数据
data:image/jpeg;base64,base64编码的jpeg图片数据
data:image/x-icon;base64,base64编码的icon图片数据

因为Url是一种基于文本的协议,所以gif/png/jpeg这种二进制属于需要用base64进行编码。换句话说,引入base64以后,就可以支持任意形式的数据格式。下面是个png图片的例子,会在浏览器中显示一个Mozilla的图标。

data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHWSURBVHjaYvz//z8DJQAggJiQOe/fv2fv7Oz8rays/N+VkfG/iYnJfyD/1+rVq7ffu3dPFpsBAAHEAHIBCJ85c8bN2Nj4vwsDw/8zQLwKiO8CcRoQu0DxqlWrdsHUwzBAAIGJmTNnPgYa9j8UqhFElwPxf2MIDeIrKSn9FwSJoRkAEEAM0DD4DzMAyPi/G+QKY4hh5WAXGf8PDQ0FGwJ22d27CjADAAIIrLmjo+MXA9R2kAHvGBA2wwx6B8W7od6CeQcggKCmCEL8bgwxYCbUIGTDVkHDBia+CuotgACCueD3TDQN75D4xmAvCoK9ARMHBzAw0AECiBHkAlC0Mdy7x9ABNA3obAZXIAa6iKEcGlMVQHwWyjYuL2d4v2cPg8vZswx7gHyAAAK7AOif7SAbOqCmn4Ha3AHFsIDtgPq/vLz8P4MSkJ2W9h8ggBjevXvHDo4FQUQg/kdypqCg4H8lUIACnQ/SOBMYI8bAsAJFPcj1AAEEjwVQqLpAbXmH5BJjqI0gi9DTAAgDBBCcAVLkgmQ7yKCZxpCQxqUZhAECCJ4XgMl493ug21ZD+aDAXH0WLM4A9MZPXJkJIIAwTAR5pQMalaCABQUULttBGCCAGCnNzgABBgAMJ5THwGvJLAAAAABJRU5ErkJggg==

data格式Url的种种应用举例

可以在Html的Img对象中使用,例如

<img src="data:image/x-icon;base64,AAABAAEAEBAAAAAAAABoBQAAF..." />

可以在Css的background-image属性中使用,例如

div.image {
  width:100px;
  height:100px;
  background-image:url(data:image/x-icon;base64,AAABAAEAEBAAAAAAAABoBQAAF...);
}

可以在Html的Css链接处使用,例如

<link rel="stylesheet" type="text/css"
  href="data:text/css;base64,LyogKioqKiogVGVtcGxhdGUgKioq..." />

可以在Html的Javascript链接处使用,例如

<script type="text/javascript"
  href="data:text/javascript;base64,dmFyIHNjT2JqMSA9IG5ldyBzY3Jv..."></script>

完整的语法定义

在RFC中,完整的语法定义如下。

dataurl    := "data:" [ mediatype ] [ ";base64" ] "," data
mediatype  := [ type "/" subtype ] *( ";" parameter )
data       := *urlchar
parameter  := attribute "=" value]]

urlchar指的就是一般url中允许的字符,有些字符需要转义,例如"="要转义为"%3D",不过我测试下来,至少在Firefox里面,不转义也是可以的。

parameter可以对mediatype进行属性的扩展,常见的是charset,用来定义编码格式,在多语言情况下需要用到。例如下面的例子。

data:text/plain;charset=UTF-8;base64,5L2g5aW977yM5Lit5paH77yB

这个例子会显示出"你好,中文!"。如果吧charset部分去掉,就会显示乱码,因为我用的是UTF-8编码。

Firefox有一个data类型Url的测试页面,列出了各种格式的data类型Url的测试Url,和测试结果说明。

base64编码和内容的隐秘

把二进制数据转换成为Base64不是什么难事,比如Total Commander就有这样的功能。还有一些在线资源,

有些在线转换把base64里面的“=”转换成为%3D,这个在Url中和“=”是一样的,不转换也没什么问题。

当然,这种Url还有一种隐秘的好处,就是将一些道貌岸然者不喜欢的东西,堂而皇之的放在页面上,例如下面这个数据。你可以Copy下来贴到地址栏里面去瞅瞅,呵呵呵:o)

data:image/jpeg;base64,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


ref:www.bobopo.com/article/code/data_url.htm

编写跨浏览器兼容的 CSS 代码的金科玉律

作为 Web 设计师,你的网站在各种浏览器中有完全一样的表现是很多人的目标,然而这是一个永远无法真正实现的目标,很多人认为,完美的跨浏览器兼容并不必要,这样说虽然没错,但在很多情形,一种近似的兼容还是很容易实现的,本文讲的是各种跨浏览器兼容的 CSS 编码准则和技巧。

Browsers-css in The Principles Of Cross-Browser CSS Coding

理解 CSS 盒子模型

如果你想实现不需要很多奇巧淫技的跨浏览器兼容的 CSS 代码,透彻地理解 CSS 盒子模型是首要事情,CSS 盒子模型并不难,且基本支持所有浏览器,除了某些特定条件下的 IE 浏览器。

CSS 盒子模型负责处理以下事情:

  • 一个 blcok (区块)级对象占据多大的空间
  • 该对象的边界,留白
  • 盒子的尺寸
  • 盒子与页面其它元素的相对位置

CSS 盒子模型有以下准则:

  • Block (区块)对象都是矩形 (事实上所有对象都如此)
  • 其尺寸由 width, height, padding, borders, 以及 margins 决定
  • 如果不设置高度,该盒子的高度将自动适应其包含的内容,加上留白等(除非使用了 float)
  • 如果不设置宽度,一个非 float 型盒子水平上将充满其父容器(扣除父容器的留白)

处理 block 级对象时,必须注意以下事项:

  • 如果一个盒子的宽度设置为 100%,它就不能再设置 margins, padding, 和 borders,否则会撑破其父容器
  • 垂直毗邻的 margin 会引起复杂的坍塌问题,导致布局问题(比如两个垂直毗邻的 Block 对象,上面的对象的 bottom-margin 为 40,下面的对象的 top-margin 为 20,则两个对象的间距将是 40,而不是 60 - 译者)
  • 拥有相对位置和绝对位置的对象,拥有不同的行为

Css-box-model in The Principles Of Cross-Browser CSS Coding
在 Firefox 的 Firebug 中显示的盒子模型

理解 block 级和 inline 级 对象的区别

这个看似简单的问题事如果能透彻地理解,会受益匪浅

下图讲解了 block 级对象和 inline 级对象的区别:

Block-inline in The Principles Of Cross-Browser CSS Coding

下面是 block 级对象和 inline 级对象的基本区别:

  • Block 级对象会自然地水平充满其父容器,因此没有必要为之设置 100% 宽度属性
  • Block 级对象的起始摆放位置是其父容器的左上边界,并顺排在其前面的兄弟 Block 对象的下方(除非设置 float 或绝对位置)
  • Inline 级对象会忽略其宽度和高度设置
  • Inline 级对象会随着文字排版,并受排版属性的影响(如 white-space, font-size, letter-spacing)
  • Inline 级对象可以使用 vertical-align 属性控制其垂直对齐,block 级对象不可以
  • Inline 级对象的下方会保留一些自然的空间,以适应字母 g 一类的会向下探出的笔画
  • 一个设置为 float 的 inline 对象将变成 block 对象

理解 Floating 和 Clearing 属性

实现多栏排版的最好方法是使用 float 属性,float 也是一个将使你受益匪浅的属性。一个 float 对象可以居左或居右,一个设置为 float 的对象,将根据设置的方向,左移或右移到其父容器的边界,或其前面的 float 对象的边界,而紧随其后的非 float 对象或内容,则包围在其相反的方向。

Float-css in The Principles Of Cross-Browser CSS Coding

以下是使用 float 和 clear 属性的一些重要准则:

  • 一个 float 对象,将从其置身的 block 级非 float 内容流中跳出,换句话说,如果你要将一个 box 向左边 float,它后面的 block 级非 float 对象会显示到下方,inline 级内容会在旁边包围
  • 要让一段内容从一侧包围一个 float 对象,这段内容必须要么是 inline 级的,要么也设置为相同方向的 float
  • 一个 float 对象,如果没有设置宽度,则会自动缩成其包含的内容的宽度,因此最好为 float 对象明确设置宽度
  • 如果一个 block 对象包含 float 子对象,会出现本文中阐述的问题
  • 一个设置了 clear 属性的对象,将不会包围其前面的 float 对象
  • 一个既设置了 clear 又设置了 float 属性的对象,只有 clear:left 属性生效,clear:right 不起作用

首先使用 IE 进行测试

虽然我们都痛恨 IE6 和 IE7,但当你开始一个新项目的时候,最好还是首先针对这两种浏览器进行测试,否则,如果你在设计在后期才想起针对 IE6 和 IE7 进行测试,将出现以下问题:

  • 你将不得不使用一些奇巧淫技,甚至使用独立的 IE6/7 CSS,导致 CSS 文件臃肿。
  • 某些地方的布局将不得不重新设计
  • 会增加测试的时间
  • 你的布局在 IE/6/7 中和其它浏览器中不一样

如果你设计的是个人项目,Web 程序等,则不建议你针对旧版本 IE 做太多工作,而对一些公司类站点,它的用户群中有大量 IE 用户,这些技巧会让你避免大量的头痛。如果将 IE 的问题归类为 IE 的 BUG 而不去处理,会带来很多负面的影响,和 IE 和平共处是 Web 开发与设计者不可逃避的现实。

译者注:在 IE6/7 仍有大量用户基础的国内(感谢中行,建行,农行,工行,以及各级政府网站),忽视这两种浏览器是极不明智的,首先针对 IE6/7 进行设计是一种很好的方法,一般来说,在IE6/7 通过测试的站点,在 Firefox,Chrome,Safari,Opera 等标准浏览器面前基本不会出现问题,前提是,你的 CSS 设计是基于 W3C 标准的。

IE 浏览器最常见的问题

  • IE6 中不可滥用 float,否则会带来内容消失以及文字重复等稀奇古怪的问题
  • IE6 中,float 对象,在 float 方向的那边,会出现双倍 margin,将 display 设置为 inline 会解决这个问题
  • IE6/7 中,一个没有直接或间接设置 hasLayout 的对象,会发生各种稀奇古怪的问题 (译者注:对这类问题,zoom 这个 css 属性可以帮很大的忙,将 zoom 设置为除了 normal 之外的其它值,可以迫使一个对象 hasLayout 同时不影响这个对象的任何视觉外观)
  • IE6 不支持 min-width, max-width, min-height, max-height 一类的属性
  • IE6 不支持固定位置背景图
  • IE6/7 不支持很多 display 属性值(如 inline-table, table-cell, table-row
  • IE6 中,只有 a 这个对象才可以使用 :hover 这个伪类
  • IE 的某些版本对某些 CSS 选择器支持很少(如属性选择器,子对象选择器)
  • IE6~8 对 CSS3 的支持很有限 (不过有一些变通方法)

永远不要指望在所有浏览器中都一模一样

在不同浏览器实现相同的体验个功能是可能的,实现近似像素级的一致外观也是可能的,但永远不要指望一模一样。

Form 控件在不同浏览器显示总是不同

以下是 Facebook 首页中的 select 控件,在5种不同浏览器的显示差异(基于 Adobe’s Browserlab 截图)

某些 Form 控件,如果要求必须跨浏览器一致,可以找到变通办法,如,可以使用图片 替代 submit 按钮,但有一些控件,比如 radio,select, textarea,文件选择框,是永远都不可能一模一样的。

字体的表现都有差异

先不谈有的字体在有的系统中根本不存在,即时存在,它们在不同系统的渲染效果也不完全一样,比如,Windows ClearType 支持 IE7,但不支持 IE6,导致同一个字体在 IE7 和 IE6 有不同的样子。

Cleartype-ie in The Principles Of Cross-Browser CSS Coding
A List Apart’s 文章字体在 IE6 and IE7 中的区别

使用 CSS 清零

使用 CSS 清零(CSS Reset)是实现跨浏览器兼容的灵丹妙药,CSS 清零可以消除不同浏览器对 margin,padding 这些属性的默认表现,你可以更容易控制诸如对齐,间隙等等问题。推荐使用 Eric Meyer’s CSS 清零代码

Reset-wd in The Principles Of Cross-Browser CSS Coding

 

参考 SitePoint’s CSS 兼容表

SitePoint CSS Reference 是一个非常好的资源(下载离线版),可以用来检查某些 CSS 属性的跨浏览器兼容问题

Sitepoint-chart in The Principles Of Cross-Browser CSS Coding

结语

跨浏览器兼容是个永恒的话题,本文介绍的跨浏览器兼容 CSS 准则只是帮助 Web 开发设计者尽可能实现这一目标,除了这些,基于 CSS3 的渐进式增强设计也是一种趋势,Web 开发与设计者可以针对某些浏览器提供增强功能,而在不支持这些增强功能的浏览器中降级使用基本功能。

延伸阅读

本文国际来源:Smashing Magazine The Principles Of Cross-Browser CSS Coding

原文作者:Louis Lazaris

Louis Lazaris 是一位自由职业 Web 开发者,住在多伦多,他创办了 Impressive Webs, 以及 Interviews by Design,后者主要是一些著名 Web 设计师访谈,他的 Twitter 地址是 http://twitter.com/ImpressiveWebs