分类目录归档:css

响应式SPRITES图片实现方法探究

腾讯云正在走向全面支持响应式和Retina屏的道路上,我们广泛使用了SVG Sprites技术。在实践过程出现了“某些元素的背景图片来自于一张SVG Sprites,同时该元素也需要支持响应式”的情况,就需要解决“在元素尺寸发生变化时,来自Sprites的这张背景图片如何同步等比缩放?“的问题。

我曾经探讨过“响应式图像”的实现方法,当然这些方法都不适用背景图。我们来分解下这个问题,具体要完成哪些任务?

HTML元素在缩放时,如何保持宽高比不变?

对于这个问题,我在“使用PADDING-TOP:(PERCENTAGE)实现响应式背景图片”这篇文章中给出了解决方法,不再赘述。

See the Pen responsive image sprites 1 by wenjul (@wenjul) on CodePen.

Sprites中的背景图片如何跟随容器尺寸的变化而等比缩放?

background-size正是用来解决这个问题的。大家应该比较熟悉关键字“cover“(缩放背景图片以完全覆盖背景定位区,可能背景图片部分看不见)和”contain“(缩放背景图片以完全装入背景定位区,可能背景定位区部分空白)的效果,这两个关键字主要解决整张背景图如何适应容器,比较适用于单张图片,不适用于Sprites图。

如何计算background-size: <percentage>?

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

demo-1

先看下100%的效果,也就是说Sprites图和容器是1:1的比例,显然不是我们要的效果。

demo-2

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

background-size : ( Sprites width / image width) (Sprites height / image height)

demo-3

上面这个公式比较容易理解,但是如何在容器元素显示其他的头像呢?

当然是通过background-position来改变背景图片的初始位置。我们通常使用<length>(如px)控制背景图片相对于容器元素的偏移量,显然不适用我们这种情况,因为整张Sprites图片是可以等比缩放的,那么单张图片的左上角相对于Sprites图片的左上角的距离也是变化的,所以使用<length>是会出错的,如下例。

demo-4

如何计算background-position: <percentage>?

background-position值还可以使用 <percentage>和关键词(top, bottom, left, right, center),可以把关键词理解为<percentage>特殊形式,两者的计算方式是相同的。但是,<percentage>和<length>的计算方式是不同的:<length>的参照点是图片的左上角,<percentage>的参照点是随着取值变化的。

background-position:30px 40px; 为例,计算方法为:Sprites图的左上角相对于容器元素的左上角向右偏移30px,向下偏移40px。

demo-5

background-position:<percentage>就大不同了:如background-position:0% 0%(或top left)是将图片的左上角与容器元素的左上角对齐,background-position:100% 100%(或bottom right)是将图片的右下角与容器元素的右下角对齐,background-position:50% 50%(或center center)是将图片的中心点与容器元素的中心点对齐,background-position:33% 15%是将图片的横向33%和纵向15%的交汇点放置在容器元素的横向33%与15%的交汇点上。

demo-6

理解 <percentage>和<length>之间计算方式的差异是至关重要的。那么如果要在容器元素内显示第二张图片,怎么计算<percentage>的具体值呢?

demo-7

我们已知的信息如下:

  • 容器元素的尺寸: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)

把我们上面例子的信息代入方程式:

  • x = w / (4w -w) = 1/3
  • y = 0 / (h – h ) = 0

查看效果

手动计算累死人?Maxim来解救你!

Maxim是我们团队开发的可视化的构建工具,支持windows和Mac,开发时无需考虑background-sizebackground-position,发布时将文件拖入Maxim内,自动完成Sprites拼合,并补全background-sizebackground-position值,轻松实现响应式Sprites图。Maxim的更多功能也等你发现,赶快下载一个试试吧!!!

——
我的博客即将搬运同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=ed2bo5axvfm8

深入理解视觉格式化模型( VISUAL FORMATTING MODEL)

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

实践与现象

绝对定位是一种常用的定位方式,也经常会看到一些使用技巧,轻松搞定一些不太容易实现的效果。现介绍两个绝对定位的使用技巧:

1. 绝对定位元素,水平方向(top和bottom)或和垂直方向(left和right)的定位值不设置时,其位置受其前面的兄弟元素影响,如同其在常规流中的位置。如下例所示:

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

结果是:元素C的位置受元素B的影响,跟随在元素B的下方。

这种看似毫无用处的技巧,却能帮助我们解决一些项目实际问题。我们总希望我们的布局是自适应的,即不依赖与所处环境,当环境改变时,仍能完美工作。下面这个实例要求蓝色购买按钮水平居中,其后跟随一个链接。为了达到自适应布局,我们不能假设父级容器宽度固定,也不能假设蓝色按钮的文案固定,所以链接元素的位置也是根据上下文环境改变的。这种情况下,我们就可以对链接设置绝对定位,并且不用设置left 和right 值,两者的间距通过margin值实现,即可轻松达到预期效果。(当然,通过嵌套的方式也可实现,但不是最优解)

另一个案例是用以实现下拉菜单,下拉菜单通常由触发按钮和下拉列表组成,下拉列表的位置位于触发按钮的下方。同样,由于触发按钮的高度是可能变化的,那么下拉列表与触发按钮顶端的绝对距离是不固定的,使用单位px是无法达到自适应的,通常的技巧是设置top:100%,其实利用我们上面提到的技巧,对top和bottom不设置值也是可以实现的。

2. 绝对定位结合margin实现垂直居中

很多设计都可以抽象为“一个元素相对于父级(或包含块)在垂直方向或水平方向上居中对齐”的模式,根据实际情况又可分为该元素的尺寸未知和已知两种情况。这是个经久不衰的话题,实现方式也多种多样,这里我们讨论的是“尺寸已知元素在垂直方向上的居中对齐”问题。你可能看到过下面这种实现方式,绝对定位元素的4个值均为0,margin在垂直方向上也设置为了auto(支持IE8+)。一般为了水平居中会在水平方向上设置auto,为什么这种情况下,在垂直方向上设置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不支持,难道是太鸡肋?) 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两值相等,然后再解上面方程式。(上述的第二个垂直居中案例就是利用了这一点 
  • 如果’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’值。

CSS表格布局实践

{D8A8EAC8-0326-4736-83B1-81AF692C45FA}

如何实现上图所示效果:左右两列的列宽由列内最宽单元格的宽度决定,进度条列占据剩余空间。(兼容到IE8就好了)

经分析需要处理一列的宽度,只有table布局才有列的概念,故采用display:table | table-row | table-cell来布局。

CSS属性table-layout定义了表格单元格、行和列的布局算法。默认值为auto,表格及其单元格的宽度由其内部的内容决定。而值为fixed时,表格的宽度取决于tabe元素的宽度值,列宽由对应col元素的宽度决定,或者由首行单元格的宽度决定,后续行内单元格不会影响列宽。使用fixed布局方法时,一旦表格的首行下载和解析完成,整个表格即可被渲染。相对于自动布局方法,这种方法可加速表格渲染,但可能会造成后续单元格的内容与列宽不适合。如果单元格的内容溢出,使用overflow属性来决定是否截断溢出内容。

一直强烈建议使用fixed布局方式,但从上文看,是无法实现我们所需效果。而auto布局,默认为各列平分表格的宽度。如果我们对左右两列设置一个看似合适的固定宽度(如10em),进度条列是可以占据表格的剩余空间,但无法实现列宽根据内容自适应改变(so sad)。

怎么办?怎么办?怎么办?

猜想:我们可否为单元格设置一个最小宽度,当单元格的内容超过最小宽度时自动撑开?

经分析和尝试,将左右两列的内容设置不换行white-space:nowrap,并将宽度设置为一个很小的值(如width:1px | 1%),即可实现我们期待的效果

再猜想:如果让需要占据剩余空间的列的宽度尽可能的大,大到100%,那么浏览器是否会为其他列按照其内容宽度来分配空间呢?经尝试,居然也可以达到我们期待的效果

哈哈哈……

但是 why? why? why?

[未完待续]

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;
    }

}