[译]响应式图像

自从2010年Ethan Marcotte开始讨论响应式网页设计,开发者和设计师们竞相寻求处理响应式图片的方法。这的确是一个棘手的问题 ,因为我们对同一个网站在众多设备宽度下,使用同一图像源。你愿意在一个大显示屏上显示模糊地、马赛克状的图像?你愿意在你的手机上加载一个巨大的(虽然更漂亮的)图像?这个问题令人左右为难。

一群来自响应式问题社区组(RICG)的聪明家伙致力于解决这个难题,他们使picture元素和srcsetsizes属性纳入HTML 5.1规范草案 。因为我们无法预测用户在何地以及如何访问我们的网站,所以我们需要浏览器自身根据情况选择最好的图像。新规范将解决以下问题:

  • 基于设备象素比(device-pixel-radio)选择
  • 基于viewport选择
  • 基于美术设计(Art direction)选择
  • 基于图像格式选择

该规范中,img元素增加了两个新属性:srcsetsizessrcset用来声明一组图像源,浏览器根据我们使用描述符指定的条件来选择图像。描述符x表示图像的像素密度,描述符w表示图像的宽度;浏览器使用这些信息从列表中选择合适的图像。sizes属性为浏览器提供将要显示图像的尺寸信息,srcset使用w描述符时必须包含此属性。这种方法尤其适用于可变宽度的图像,我将在后面详细讨论。

我们现在可以根据用户的viewport,提供不同质量或art direction的图像,无需借助复杂的服务器端设置。响应式图像将成为HTML规范的重要组成部分,所有浏览器终将都会支持此解决方案。

固定宽度图像:基于设备像素比选择

视网膜屏幕的广泛应用,使我们不仅需要考虑屏幕分辨率,而且也需要考虑像素密度。视网膜屏幕,4K显示器,UltraHD-它们都比相同尺寸的标准分辨率显示器填充了更多的像素。更多的像素=更清晰的图像。

有些图片不管屏幕尺寸,始终以固定宽度显示-如站点logo或人物简介图像,也就是说需要根据设备像素比来选择。浏览器将根据设备像素比来选择加载哪张图像。

srcset属性列出了浏览器可以选择加载的源图像池,是一个由逗号分隔的列表。x描述符表示图像的设备像素比。浏览器根据运行环境,利用这些信息来选择适当的图像。不理解srcset的浏览器会直接加载src属性中声明的图像。

<img srcset="crest-383.jpg 1.5x, crest-510.jpg 2x" src="crest-255.jpg" alt="USWNT crest" />
USWNT crest

网站logo就是固定宽度图像的一个例子,不管viewport的宽度如何,始终保持相同的宽度。不过,与内容相关的图片,通常也需要响应式,它们的大小往往随viewport改变。对于这类图像,还有更好的处理方法。

可变宽度的图像:基于viewport选择

对于可变宽度的图像,我们使用srcset搭配w描述符以及sizes属性 。w描述符告诉浏览器列表中的每个图象的宽度。sizes属性是一个包含两个值的,由逗号分隔的列表。根据最新规范,如果srcset中任何图像使用了w描述符,那么必须要设置sizes属性。

sizes属性有两个值:第一个是媒体条件;第二个是源图尺寸值,在特定媒体条件下,此值决定了图片的宽度。需要注意是,源图尺寸值不能使用百分比,vw是唯一可用的CSS单位。

<img srcset="uswnt-480.jpg 480w, 
             uswnt-640.jpg 640w, 
             uswnt-960.jpg 960w,
             uswnt-1280.jpg 1280w" 
     sizes="(max-width: 400px) 100vw, 
            (max-width: 960px) 75vw, 
            640px" 
     src="uswnt-640.jpg" alt="USWNT World Cup victory">
USWNT World Cup victory

上列中,我们告诉浏览器在viewport宽度小于400像素时,使图像的宽度与viewport等宽。在viewport宽度小于960像素时,使图像的宽度为viewport宽度的75%。当viewport大于960像素时,使图像的宽度为640像素。如果你不熟悉vw ,可以看看Tim Severien的大文viewport单位详解 。

浏览器利用srcsetsizes信息来选择最符合规定条件的图像。如果浏览器的viewport是600像素,图像最可能以75vw的宽度显示。浏览器将尝试加载第一张大于450像素(600*0.75)的图像,也就是uswnt-480.jpg。如果我的是dpr为2的Retina显示屏,那么浏览器就会尝试加载第一张大于900像素(600*0.75*2)的图像,也就是uswnt-960.jpg。我们无法确定究竟显示哪张图像,因为每个浏览器根据我们提供的信息挑选适当图像的算法是有差异的。(译者注:srcset和size列表是对浏览器的一个建议(hint),而非指令。例如,设备像素比(dpr)为1.5的设备,亦可用1x也可用2x的图像,由浏览器根据其能力、网络等因素来决定。)

前两个例子都是以不同质量显示相同的图像,仅用srcset属性就足够了。不必担心老旧浏览器,老旧浏览器会把它看作为一个普通的图像并从src中加载。如果你想在不同宽度下显示稍微不同的图像,比如在较窄屏幕下仅显示图像的关键部分,那么要使用picture元素。

picture:基于美术设计(Art direction)选择

picture元素就像是图像和其源的容器。浏览器仍然需要img元素,用来表明需要加载图片,如果没有img,那么什么都不会渲染。source为浏览器提供了要显示图像的供选版本。基于art direction选择的适用场景为:在一个特定的转效点(breakpoint)需要显示一个特定的图像时。使用picture元素选择图像,不会有歧义。

<picture>
  <source media="(min-width: 960px)" srcset="ticker-tape-large.jpg">
  <source media="(min-width: 575px)" srcset="ticker-tape-medium.jpg">
  <img src="ticker-tape-small.jpg" alt="USWNT ticker-tape parade">
</picture>
USWNT ticker-tape parade

在本例中,当viewport大于960像素时,会加载图像的风景模式版本(ticker-tape-large.jpg)。当viewport宽度大于575像素时,浏览器会加载图像的裁剪过的肖像模式版本(ticker-tape-medium.jpg)。而当宽度小于575像素时,加载的图像( ticker-tape-small.jpg)已经被裁剪成焦点仅在一个球员上了。

picture元素是向后兼容的;不支持picture元素的浏览器将显示img。图像的所有标准属性(如alt),应该作用在img上而不是picture上。

source:基于图片格式选择

最近几年出现了一些新的图片格式,这些新图像格式在较小的文件大小情况下保证了较好的图片质量。听起来还不错,但残酷的事实是没有一个新格式被所有浏览器支持。谷歌的WebP表现不错,但只有Chrome和Opera原声支持。JPEG-XR,最初被称为高清照片,是微软发布的一个专有图像格式,仅Internet Explorer支持。如果你想了解更多信息,可以查看Zoltan Hawryluk对这些新格式的深入研究

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

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

现在可以使用这些东东吗?

在写这篇文章的时候, Firefox,Chrome和Opera的最新稳定版本均支持picture。Safari和IE本身均不支持picturesrcset的情况稍微好一点,Firefox、Chrome和Opera的最新稳定版本完全支持,Safari8和Internet Explorer Edge部分支持,可以使用x描述符用于根据分辨率切换,但不支持w描述符。Safari9已经完全支持srcset了(译者注)。

现有不少polyfills解决支持性问题,最知名的恐怕是Scott Jehl的picturefill。目前我(原作者)在我自己的网站上使用Alexander Farkas的respimage。目前的状况是,我们已对响应式图像的处理方案达成一致,并且这些解决方案逐渐被所有的主流浏览器实现。尽管该规范仍在不断完善之中,但原生的响应式解决方案离我们越来越近了。

 

原文地址:Using Responsive Images (Now)

async vs defer 属性

<script>元素的async和defer属性支持度已经不错了,是时候详细了解它们了。

图例

719530

<script>

<script>脚本不设置任何属性。HTML文档解析过程中,遇到script文档时,会停止解析HTML文档,发送请求获取script文档(如果是外部文档的话)。脚本执行后,才恢复HTMl文档解析。

936468

<script async>

设置async属性后,在HTML解析的同时,下载script文档。script文档下载完成后,HTMl解析会暂停,来执行script文档。

712163

<script defer>

设置defer属性后,在HTML解析的同时,下载script脚本。但只有在HTML解析完成后,才执行script文档。同时,defer属性保证脚本按照其在文档中出现的顺序执行。

460821

如何选用?

通常情况下,尽可能的使用async属性,然后考虑defer,都不适用时才不设置任何属性。选用规则:

  • 如果脚本是模块化的,并且不依赖其他脚本,那么使用async。
  • 如果脚本依赖其他脚本或被其他脚本依赖,那么使用defer。
  • 如果脚本比较小,并且被一个async脚本依赖,那么使用行内脚本,并放置在async脚本之前。

支持情况

IE9及以下浏览器在实现defer属性上存在糟糕的bug,比如无法保证脚本的执行顺序。如果需要支持<=IE9,不建议使用defer,如果执行顺序非常重要的话,不要使用任何属性。查看规范

后记

Chrome为了更快的页面加载,引入了两项JavaScript新技术:script streaming 和 code caching。简而言之,前者优化脚本文档的解析(Chrome 41),后者缓存编译后的代码(Chrome 42)。

streaming

ref:

  1. async vs defer attributes
  2. New JavaScript techniques for rapid page loads

可视化格式模型( Visual formatting model)再学习

“理论不懂就实践,实践不会就学理论”,非常赞同bluedavy的这句话。实践过程中经常会遇到某个属性的使用,浏览器渲染效果与预期效果不符,虽然通过死记硬背能避免或巧妙应用这种效果,但总感心虚发慌、毫无自信,因为不知晓背后的原理。这时就不要再用“就是这样的”的借口来搪塞自己,我们需要重新认识它。

场景:DEMO

  • 元素A,C绝对定位,不设置top,bottom值;
  • 元素B处于常规流中;

问题:为什么元素C的位置受元素B的影响,跟随在元素B的下方?
abs-top-bottom-auto

为了解决这个问题,我重新学习了CSS 2.1规范中的9 Visual formatting model10 Visual formatting model details

这两章讲解了可视化格式模型:用户代理在视觉媒体上如何处理文档树。在可视化格式模型中,文档树中的每个元素根据框模型(box modal)生成0或多个框。这些框的布局由以下因素决定:

  • 框尺寸和类型
  • 定位方案(常规流、浮动和绝对定位)
  • 文档树中元素之间的关系
  • 外部信息(比如viewport尺寸、图像的固有尺寸等)

9.1.2 Containing blocks(包含块)

CSS 2.1中,许多框的位置和尺寸的计算是相对于一个矩形框的边缘,这个矩形框称为包含块。通常情况下,生成框是后代框的包含块(generated boxes act as containing blocks for descendant boxes;),称之为一个框为其后代创建了包含块。短语“一个框的包含块”指的是“这个框存在其中的包含块”,而非它生成的框。

每个框会相对于其包含块赋予位置,但它并不囿于包含块,可能会溢出(overflow)。包含块的尺寸计算细节在第10章有详细介绍。

9.2 Controlling box generation(控制框生成)

本节描述了CSS 2.1中可生成的框类型。一个框的类型部分地影响其在可视化格式模型中的行为。

9.2.1 Block-level elements and block boxes

处在块格式化环境(BFC,block formatting context)中的框称之为块级框(block-level box)每个块级元素生成一个包含后代框和生成的内容的主体块级框,同时这个框与定位方案密切相关。有些块级元素除了生成主体框外,还会生成一个附加框,如’list-item’元素。附加框相对于主体框定位。

表框(table boxes)和替换元素(replaced elements)外,块级框同时也是块容器框(block container box)。块容器框要么仅包含块级框,要么建立一个行内格式化环境(IFC,inline formatting context),即仅包含行内级框。并非所有的块容器框都是块级框:非替换行内块(inline blocks)和非替换表格单元格都是块容器,但不是块级框。既是块级框也是块容器的框称为块框(block box)

“块级框”、“块容器框”和“块框”这三个术语有时被简称为块(block)

9.2.3 Run-in boxes(插入型框)

CSS Level 3的CSS basic box model中定义。

run-in框的行为如下:

  1. 如果run-in框包含一个块框,那么run-in框变为块框。
  2. 如果run-in框的后继兄弟元素为块框(非浮动,非绝对定位),那么run-in框变为该块框的第一个行内框。run-in不能插入本身为run-in的块中,也不能插入块中已有run-in的块中。
  3. 否则,run-in框变为块框。

浏览器支持:IE8+,chrome(不支持,难道是太鸡肋?)

DEMO(IE下查看)

run-in-box

9.3.2 Box offsets: ‘top’, ‘right’, ‘bottom’, ‘left’

  • (绝对、固定)定位元素会生成一个定位框(positioned box),根据top,right,bottom,left布局。
  • 初始值为auto,非0。(文章开头的问题中未设置四值,等同设置为auto
  • 对于绝对定位元素,四值指定的是元素margin边与包含块的边之间的偏移量。对于相对定位元素,四值指定的是相对于自身框边的偏移量。

9.6 Absolute positioning

  • 从常规流中完全抽离,对其后继兄弟元素无影响。
  • 固定定位是绝对定位的特例,它的包含块是viewport。

9.7 Relationships between ‘display’, ‘position’, and ‘float’

这三个属性影响了框的生成和布局,相互影响如下:

  1. 如果’display’值为’none’,同时不设置’position’和’float’,那么该元素不生成框。
  2. 否则,如果’positon’值为’absolute’或’fixed’,即框为绝对定位,’float’的计算值为’none’,并且’display’根据下表设置。那么该框的位置由’top’,’right’,’bottom’,’left’和框的包含块决定。
  3. 否则,如果’float’的值不为’none’,那么该框会浮动,’display’根据下表设置。
  4. 否则,如果该元素为根元素,’display’根据下表设置。
  5. 否则,剩余的’display’属性值与指定值相同。
指定值 计算值
inline-table table
inline, table-row-group, table-column, table-column-group, table-header-group, table-footer-group, table-row, table-cell, table-caption, inline-block block
others same as specified

10.6 Calculating heights and margins(高度和margin值计算)

10.6.4 Absolutely positioned, non-replaced elements(绝对定位的非替换元素)

静态位置(static position),粗略地讲是指一个元素在常规流中的位置。精确地讲,一个元素的静态top值,是指包含块顶部边沿与该元素的假想框的顶部margin边沿之间的距离。假想框是指如果该元素的’position’值为’static’,以及’float’值为’non’且’clear’值为’none’时,该元素的第一个框。

对于绝对定位的元素,垂直尺寸的使用值必须满足下面约束:

‘top’ + ‘margin-top’ + ‘border-top-width’ + ‘padding-top’ + ‘height’ + ‘padding-bottom’ + ‘border-bottom-width’ + ‘margin-bottom’ + ‘bottom’ = height of containing block

如果’top’,’bottom’,’height’值均为auto,那么’top’值为元素的静态位置。(这也就回答了文章开头的问题

如果三个值均不为auto,那么:

  • 如果’margin-top’和’margin-bottom’值均为’auto’,那么假定margin-top和margin-bottom两值相等,然后再解上面方程式。(可以利用这点实现垂直居中的效果,查看DEMO 
  • 如果’margin-top’和’margin-bottom’值中其一为’auto’,解上面方程式获取该margin值。
  • 如果数值超过限制,忽略’bottom’值,解方程式获取该值。

否则,从以下六种规则中挑选适用情况:

  1.  ‘top’和’height’为’auto’,’bottom’不为’auto’,那么’height’基于其内容根据10.6.7规则计算,’margin-top’值设为’auto’,’margin-bottom’值设为0,解方程式得’top’值。
  2.  ‘top’和’bottom’为’auto’,’height’不为’auto’,那么设置’top’值为其静态位置,’margin-top’值设为’auto’,’margin-bottom’值设为0,解方程式得’bottom’值。
  3.  ‘bottom’和’height’为’auto’,’top’不为’auto’,那么’height’基于其内容根据10.6.7规则计算,’margin-top’值设为’auto’,’margin-bottom’值设为0,解方程式得’bottom’值。
  4.  ‘top’值为’auto’,’bottom’和’height’不为’auto’,那么’margin-top’值设为’auto’,’margin-bottom’值设为0,解方程式得’top’值。
  5.  ‘height’值为’auto’,’bottom’和’top’不为’auto’,那么’margin-top’值设为’auto’,’margin-bottom’值设为0,解方程式得’height’值。
  6.  ‘bottom’值为’auto’,’height’和’top’不为’auto’,那么’margin-top’值设为’auto’,’margin-bottom’值设为0,解方程式得’bottom’值。

box-sizing最佳实践

/* apply a natural box layout model to all elements, but allowing components to change */
html{
    box-sizing:border-box;
}
*, 
*:before, 
*:after{
    box-sizing:inherit;
}

组件需要重置时,只需在组件容器上重置即可:

.component {
    /* designed to work in default box-sizing */
    /* in your page, you could reset it to normal */
    box-sizing: content-box;
}

参考资料

  1. * { Box-sizing: Border-box } FTW
  2. Inheriting box-sizing Probably Slightly Better Best-Practice

创建高效media queries的七个好习惯

1. 内容决定转效点(Let content determine breakpoints)

从最小屏幕开始,逐渐扩大窗口,当效果丑陋不堪(like shit)时,此处就是breakpoint。

2. 把布局看作为增强行为(Treat layout as an enhancement)

作为移动优先的响应式设计策略的一部分,以移动优先的方式书写样式是非常重要的。样式代码更少、更简洁、更易维护。

/* Desktop-first styles: Avoid */
.column {
    float: left;
    width: 50%;
}

@media all and (max-width: 50em) {
    .column {
        float: none;
        width: auto;
    }
}
/* Mobile-first styles FTW */
@media all and (min-width: 50em) {
    .column {
        float: left;
        width: 50%;
    }
}

3. 使用主、次转效点(Use major and minor breakpoints)

  • 主转效点:效果显著变化,如一列变两列、三列。
  • 次转效点:某些特定元素的调整,或称为tweakpoint

使用Sass管理转效点

$bp-small : 24em;
$bp-small-2 : 29.75em;
$bp-small-3 : 39.8em;
$bp-med : 46.8em;
$bp-med-2 : 48em;
$bp-large : 50em;
$bp-large-2 : 54.5em;
$bp-xl : 60em;
$bp-xl-2 : 67em;

4. 使用相对单位(Use relative units)

media queries中使用相对单位,浏览器可以根据用户的缩放等级调整设计效果,避免出现横向滚动条,提供一个更加舒适和易于阅读的体验。

ems

5. 超越宽度(Go beyond width)

检测viewport width不是media queries的全部,可检测的媒体特性非常多,包括color, color index, aspect ratio, device aspect ratio, width, device width, height, device height, orientation, monochrome, resolution, scan, pixel-density等。

  • 使用pixel-density可以为视网膜屏或其他高分辨率屏幕有条件的提供大背景图片或icon sprites。
  • 使用height检测可用的屏幕高度,并相应的调整样式。
  • 使用orientation检测屏幕是处在横向还是竖向模式。

6. 条件装载(Use media queries for conditional loading)

7. 过犹不及(Don’t Go Overboard)

参考文献:

纯CSS实现响应式表格

先看DEMO

自从转岗至腾讯云后,项目中接触到大量的数据表格。多列数据表格在空间有限的手机屏幕下,难以完美呈现,需要做响应式处理。本文介绍一种使用纯CSS实现响应式表格的方法。

通常表格中的一行代表一条项目,每列代表项目的一个属性方面(即字段)。在屏幕空间充足的情况下,我们可以将表格的每列都完全显式在屏幕上,但在手机下,每列内容会拥挤不堪,甚至出现横向滚动条,用户快速了解每条项目基本情况的效率会大打折扣。

Snip20150407_5

Snip20150407_6

一种优化方法是:使用media queries监测屏幕viewport小于568px时,让单元格(td)独占一行,每行(tr)相互隔离,如同每条项目为一独立的表格,如下图:

Snip20150407_7

现在每条项目便于阅读了,但表头(th)与对应的单元格(td)隔离开了,单元格的具体意义难以理解。那么,隐藏掉表格的thead,单元格内容右对齐,在每个单元格前面插入对应的表头(th)即可解决这个问题,如下图:

Snip20150407_9

伪元素(:before)结合att()表达式(获取伪元素所依附元素的HTML属性值)可完成此任务。当然,我们首先要对每个单元格(td)元素改造:

Snip20150407_10

样式如下:

table {
    border: 1px solid #ccc;
    width: 100%;
    margin: 0;
    padding: 0;
    border-collapse: collapse;
    border-spacing: 0;
}

table tr {
    border: 1px solid #ddd;
    padding: 5px;
}

table th,
table td {
    padding: 10px;
    text-align: center;
}

table th {
    text-transform: uppercase;
    font-size: 14px;
    letter-spacing: 1px;
}

/* <= 568px */
@media screen and (max-width: 35.5em) {
    table {
        border: 0;
    }
    table thead {
        display: none;
    }
    table tr {
        margin-bottom: 10px;
        display: block;
        border-bottom: 2px solid #ddd;
    }
    table td {
        display: block;
        text-align: right;
        font-size: 13px;
        border-bottom: 1px dotted #ccc;
    }
    table td:last-child {
        border-bottom: 0;
    }
    table td:before {
        content: attr(data-label);
        float: left;
        text-transform: uppercase;
        font-weight: bold;
    }
}

大功告成了吗?某些屏幕阅读器(如OSX 和iOS下voiceOver)可朗读伪类插入的内容,这 是否造成了过度提示,会不会影响屏幕阅读器用户的访问效率。而某些屏幕阅读器与浏览器的组合又不会朗读,如何优化呢?

参考资料:
Responsive Tables in Pure CSS

[温故知新] Text-level semantics

em

The em element represents stress emphasis of its contents.

突出强调其内容(重读),重音位置不同语句的含义也会改变。

em不是一个通用的italics元素。如果想在语句中突出一段文字,以不同的感情和语调朗读,i元素更适用这种情况。

em元素也没有传递重要性。如果想表达重要性,strong元素更合适。

strong

The strong element represents strong importance, seriousness, or urgency for its contents.

表示其内容有强烈的重要性、严重(肃)性、紧迫性。

重要性:strong元素可以用在结构性标题(heading)、说明性标题(caption)或段落中,用来将真正关键(really matter)部分与其他部分区别开来,比如详细解释文字、模式化文字(如:图片1)。

严重(肃)性:可以用在警告或提示上。

紧迫性:表示此部分内容要先于文档中的其他部分查看。

通过strong元素改变文字片断的重要程度,并不会改变语句的意义。

<h1>Chapter 1: <strong>The Praxis</strong></h1>

<figcaption>Figure 1. <strong>Ant colony dynamics</strong>. The ants in this colony are
affected by the heat source (upper left) and the food source (lower right).</figcaption>

small

The small element represents side comments such as small print.

表示旁注,如附属细则(small print)。

注:附属细则一般表现为免责说明、警告、法律限制或版权说明,有时也用于归属、许可要求。

注:对于由em元素强调过的或由strong元素标记为重要的文本,small元素不会取消对文本的强调,也不会降低这些文本的重要性。

<dl>
<dt>Single room
<dd>199 € <small>breakfast included, VAT not included</small>
<dt>Double room
<dd>239 € <small>breakfast included, VAT not included</small>
</dl>

s

The s element represents contents that are no longer accurate or no longer relevant.

表示内容已不准确或不再相关。

注:s元素不适用于文档编辑。如要表示一段文字已从文档中删除,请使用del元素。

<p>Buy our Iced Tea and Lemonade!</p>
<p><s>Recommended retail price: $3.99 per bottle</s></p>
<p><strong>Now selling for just $2.99 a bottle!</strong></p>

cite

The cite element represents a reference to a creative work. It must include the title of the work or the name of the author(person, people or organization) or an URL reference, which may be in an abbreviated form as per the conventions used for the addition of citation metadata.

引述,表示对于一个作品的引用。必须包括作品的标题或作者名称(个人、民族或组织)或URL地址。

<p>In the words of <cite>Charles Bukowski</cite> -
<q>An intellectual says a simple thing in a hard way. An artist says a hard thing in a simple way.</q></p>

q

The q element represents some phrasing content quoted from another source.

引文,引用自其他源的措辞内容。如果存在引用源,则用cite属性标识。引文如果放在引号内,则无需使用q元素。

<p>The W3C page <cite>About W3C</cite> says the W3C's
mission is <q cite="http://www.w3.org/Consortium/">To lead the
World Wide Web to its full potential by developing protocols and
guidelines that ensure long-term growth for the Web</q>. I
disagree with this mission.</p>

dfn

The dfn element represents the defining instance of a term.

表示一个术语定义实例,必须包括术语的释义。

The term <dfn>organic food</dfn> refers to food produced without synthetic chemicals.

i

The i element represents a span of text in an alternate voice or mood, or otherwise offset from the normal prose in a manner indicating a different quality of text, such as a taxonomic designation, a technical term, an idiomatic phrase from another language, transliteration, a thought, or a ship name in Western texts.

使用另外一种语气和情感的文字片断,或者使用有别于正常的讲述方式来表明文字的不同质量,如分类名称、技术术语、另一种语言的惯用语、音译、西文船舶名等。

鼓励开发者考虑是否有比i元素更恰当的元素使用,比如em表明突出强调,dfn表示一个术语的定义。

Lemonade consists primarily of <i>Citrus limon</i>.

b

The b element represents a span of text to which attention is being drawn for utilitarian purposes without conveying any extra importance and with no implication of an alternate voice or mood, such as key words in a document abstract, product names in a review, actionable words in interactive text-driven software, or an article lede.

仅为吸引注意力,并不传达额外的重要性也不暗含语气和情感的变化。比如文档摘要中的关键词、综述中的产品名称、交互式文本驱动软件中的可操作词语、一篇文章的首段。

实在无其他元素可用时,再考虑使用b元素吧。(这样看来,bi更适合用来标记icon?)

Take a <b>lemon</b> and squeeze it with a <b>juicer</b>.

u

The u element represents a span of text with an unarticulated, though explicitly rendered, non-textual annotation, such as labeling the text as being a proper name in Chinese text (a Chinese proper name mark), or labeling the text as being misspelt.

简单理解为中文的专名号。生拼硬凑词语,非文本解释,中文专有名词,或拼写错误文字。

The mixture of apple juice and <u class="spelling">eldeflower</u> juice is very pleasant.

mark

The mark element represents a run of text in one document marked or highlighted for reference purposes, due to its relevance in another context.

标记和高亮显式与用户当前行为相关的内容。最常用的场景是用户搜索文档,将与搜索关键字相匹配的文字高亮显式。语法高亮,span更合适。

Elderflower cordial, with one <mark>part</mark> cordial to ten <mark>part</mark>s water, stands a<mark>part</mark> from the rest.

参考资料:

text-level-semantics

Retina显示屏下ICON优化方法

便于理解,先来了解几个名词:

  • dpi(dots per inch),每英寸的点数,用来测量任何设备的硬件分辨率。一个21”的屏幕可以拥有1680 X 1050 的分辨率,27”的屏幕也可以拥有相同的分辨率,那么大屏幕比小屏幕的dpi小。
  • dip(device independent pixels),设备独立像素,与160 dpi显示屏上的1px相等, 又称dp。
  • dppx(dots per ‘px’),每px单位上的点数。由于CSS英寸与CSS像素的固定比是1:96,那么1dppx=96dpi。
  • Device pixel ratio (DPR)是物理像素与CSS像素的比率。

方法一:media queries & background-size

查看demo

/*
** 注意:background-size的值是sprite.png的尺寸,而不是每个icon的尺寸
*/
.sprite-icon{
    background-image:url(sprite.png);
    background-size:98px 65px;       
}

/*
** 每个icon的background-positon只需写一次,即icon相对与1x图片的位置,在@2x图片中的位置也是这个
*/
.icon-1{
    background-position:0 0;
}
.icon-2{
    background-position:-33px 0;
}
.icon-3{
    background-position:-66px 0;
}
.icon-4{
    background-position:0 -33px;
}
.icon-5{
    background-position:-33px -33px;
}
.icon-6{
    background-position:-66px -33px;
}

/* 
** 2x图片要是1x图片的准确2倍
** sprite中图标之间的间隙,也应是2倍
** 每个图标无需重新写background-position
*/
@media (min-resolution:2dppx), /* Standard syntax */
(-webkit-min-device-pixel-ratio:2)  /* Safari & Android Browser */
{
    .sprite-icon{
        background-image:url(sprite@2x.png); 
    }  
}

方法二:background-image:img-set( url(a.png) 1x, url(a@2x.png) 2x )

媒体查询(media queries)已经可以解决高密度显示问题,为什么还需要image-set? 问的好。 使用image-set的两个主要好处:

  • 与媒体查询不同的是,image-set没有告诉浏览器使用哪个图片,而是提供了一些选项。我希望将来在低网速下使用高密度设备,能够告诉浏览器使用低分辨率图片。如果浏览器能够根据当前的网络状况智能地选择使用的图片,那就更好了。 媒体查询的问题是没有给浏览器任何自由裁决权,它明确的指明,如果像素密度大于1或者2,浏览器就使用特定的图片。 我知道,这只是理论上(更是“意淫“出来)的好处。如今支持“image-set”的浏览器只是简单将图片源与显示密度相匹配,并没有提供额外的功能。但我坚信,同一张图片需要不同分辨率时,让浏览器去选择合适的图片是方向。
  • CSS编码好处:将不同分辨率的图片源集中在一起。

查看demo

/* ** 注意: ** 图片要求:2x图片要是1x图片的准确2倍,sprite中图标之间的间隙也应是2倍 ** 无需写background-size,浏览器自动处理 ** */ 
.sprite-icon{ 
    background-image:url(sprite.png); 
    background-image: -webkit-image-set( url('sprite.png') 1x, url('sprite@2x.png') 2x ); 
}

/* ** 每个icon的background-positon只需写一次,即icon相对与1x图片的位置,在@2x图片中的位置也是这个 */ 
.icon-1{
     background-position:0 0; 
} 
.icon-2{ 
    background-position:-33px 0; 
} 
.icon-3{ 
    background-position:-66px 0; 
} 
.icon-4{ 
    background-position:0 -33px; 
} 
.icon-5{ 
    background-position:-33px -33px; 
} 
.icon-6{ 
    background-position:-66px -33px; 
}

方法三: media queries & background-size,适用于仅部分图标提供了2x图,且icon位置不对应,可能是由工具生成的sprite。

查看demo

.sprite-icon{
    background-image:url(more.png);
}
.icon-1{
    background-position:0 0;
}
.icon-2{
    background-position:-33px 0;
}
.icon-3{
    background-position:-66px 0;
}
.icon-4{
    background-position:0 -33px;
}
.icon-5{
    background-position:-33px -33px;
}
.icon-6{
    background-position:-66px -33px;
}
.icon-7{
    background-position:0 -66px;
}

/* 
** 每个icon的backgroud-size是2x图片的一半
** 每个icon的backgroud-position是相对与2x图片的位置除以2
*/
@media (min-resolution:2dppx), /* Standard syntax */
(-webkit-min-device-pixel-ratio:2)  /* Safari & Android Browser */
{
    .icon-1{
        background-image:url(portion@2x.png); 
        background-size:197px 65px;
        background-position:0 0;
    }
    .icon-2{
        background-image:url(portion@2x.png); 
        background-size:197px 65px;
        background-position:-33px 0;
    }
    .icon-3{
        background-image:url(portion@2x.png); 
        background-size:197px 65px;
        background-position:-66px 0;
    }
    .icon-4{
        background-image:url(portion@2x.png);
        background-size:197px 65px;
        background-position:-99px -33px;
    }
    .icon-5{
        background-image:url(portion@2x.png); 
        background-size:197px 65px;
        background-position:-132px -33px;
    }
    .icon-6{
        background-image:url(portion@2x.png);
        background-size:197px 65px;
        background-position:-165px -33px;
    }

}