anjia / blog

博客,积累与沉淀
106 stars 4 forks source link

image type #33

Open anjia opened 5 years ago

anjia commented 5 years ago

CSS Images Module Level 3

https://drafts.csswg.org/css-images-3

此模块定义了 CSS3 里与<image>type 和一些 replaced elements 相关的特性。

在 CSS1/CSS2 里,image values 只能是 url value

<image> type 的值,可以用在 background-image, cursor, list-style-image, content 等属性上

此模块里定义的属性,只有 image-rendering 能用在 ::first-line::first-letter

目录:

  1. <image> Type: 2D Image Values
  2. Gradients
  3. Sizing Images and Objects in CSS
  4. Image Processing
anjia commented 5 years ago

<image> Type: 2D Image Values

<image> value type 表示 2D 图像。它可以是 url 也可以是 color gradient。

语法:<image> = <url> | <cross-fade()> | <gradient>

cross-fade() = cross-fade( <cf-image># )
<cf-image> = <percentage>? && [ <image> | <color> ]

<image>无效的时候,会渲染一个没有 intrinsic dimensions 的纯色透明的 invalid image。然后 invalid images 在有些上下文里会触发 error-handling,比如 list-style-image 里如果设置了 invalid image 那么就会用 list-style-type 替补上来。

anjia commented 5 years ago

Gradients

gradient 是从一种颜色平滑过渡到另一种颜色的 image。这通常用于背景图片、按钮、边框等的细微着色。本节描述的 gradient 允许 author 用简洁的语法指定这样的 image,然后 UA 就能在渲染页面的时候自动生成 image 了。

<gradient> 的语法是:

<gradient> = <linear-gradient()> | <repeating-linear-gradient()> |
             <radial-gradient()> | <repeating-radial-gradient()>

gradient 会绘制到 gradient box(渐变框)里,gradient box 是一个有 concrete object size 尺寸的 box。但是,gradient 本身是没有 intrinsic dimensions 的。

关于 concrete object size 和 intrinsic dimensions 的定义,见 #32

比如,你将 gradient 用在 background 上,默认情况,gradient box 会是元素的 padding box。如果 background-size 被设置成了 100px 200px,那么 gradient box 就变成了宽 100px 高 200px。类似的,若给 list-style-image 用 gradient,那么 gradient box 会是 1em 的正方形,这是该 property 的 default object size。

指定 gradients,通过定义 gradient line 上的 starting point 和 ending point,然后再指定那两个 points 上的 colors。这样 colors 就会平滑的填充线的其余部分,每种 gradient 的类型会定义如何使用 gradient line 上的 color 来生成实际的 gradient。

gradient line 取决于 gradient 的类型,在几何上可以是 line(线段), ray(射线), spiral(螺旋)

anjia commented 5 years ago

linear-gradient()

linear gradient 就是指定一个 straight gradient line,然后再在那条线上放置几种 colors。 创建一个 infinite canvas,用垂直于 gradient line 的 lines 来绘制它,画 lines 的颜色就取它和 gradient line 相交的那个颜色,这样就构造了一个 image。它会在指定的方向上产生从每个 color 到它的下一个 color 的 smooth fade(平滑淡入淡出)。

linear gradient 的语法是:

linear-gradient() = linear-gradient(
    [ <angle> | to <side-or-corner> ]?,
    <color-stop-list>
)

<side-or-corner> = [left | right]] || [top || bottom]

函数的第一个参数,定义了 gradient line,它给出了 gradient 的 direction,进而确定了如何放置 color-stops。当未指定时,默认是 to bottom。

gradient line 的 direction 可以用两种方式来指定:

如果 argument 指向 box 的 corner,比如 to top left,那么 gradient line 必须转特定的角度,以让它指向和指定角度相同的象限,且垂直于另外两个相邻角的的连线。

例子+图例:渐变的中间色,一定和另外两个相邻角的连线重叠

从 gradient box 的中心开始,沿两个方向以特定的角度延伸。ending point 是 gradient line 在指定方向上和 gradient box 的 corner 相交的点。starting point 也类似,只不过是相反的一个方向。

此 module 的下一个 level 将会提供相对于 current text direction 和 writing-mode 来定义 gradient 的 direction。

例子+图例:上面的规则是如何确定 gradient line: direction + (ending point, starting point) 的。

虽然 starting point 和 ending point 会落在 box 的外面,但它两定义的方向绝对正确。渐变在角落处是纯白,在对角处是纯黑。对于 linear gradients 总是如此

anjia commented 5 years ago

gradient line 是 starting point 和 ending point 定义的线段 它的长度是 abs(W * sin(A)) + abs(H * cos(A))

  • A 代表 gradient line 的 direction 的 angle。0 指向 upward, 正数则顺时针
  • W 代表 gradient box 的 width
  • H 代表 gradient box 的 height

gradient 的 color stops 通常是在 gradient line 上的 starting point 和 ending point 之间。但这并不是必需的,因为 gradient line 是在两个方向上无限延伸的。starting point 和 ending point 只是任意的两个位置标识罢了:starting point 定义了 0%, 0px 的位置;ending point 定义了 100% 的位置。color-stops 允许在 0% 之前和 100% 之后有位置。

linear gradient 在任意点上的 color 值确定,是从它作一条垂直于 gradient line 的线,取垂点处的颜色,即可。

anjia commented 5 years ago

<color-stop-list>

<color-stop-list> = <color-stop>#{2,}
<color-stop> = <color> <length-percentage>?

list 上的 color stop 个数必须 >=2 才有效。color stop 是 color 和 position 的组合。

color stops 是在 gradient line 上。gradient line 定义了 gradient 每个 point 的 color 。gradient function 定义了 gradient line 的 shape 和 length,以及 starting point 和 ending point。

percentages 是相对于 gradient line 的 length 而言的。0% 是在 starting point,100% 是在 ending point。position 也可以不写,将由浏览器计算自动得出(具体的算法策略,详见 spec)。

anjia commented 5 years ago

基于以上,整理成文:深入理解 CSS linear-gradient #35

anjia commented 5 years ago

3. Sizing Images and Objects in CSS

调整 CSS 中图像和对象的大小

CSS 中的 images 可能有多种来源:

除此之外,document 也可能包含许多其他类型的 objects,eg. video, plugins, or nested documents

这些 images 和 objects(以下简称 objects)可以向 CSS 提供许多 sizing 信息,也可以没有提供。这部分定义了 object 和 CSS layout algorithms 之间的 size negotiation model。

negotiation 谈判/协商

为了定义这个处理过程,定义了一些术语。Object-Sizing Terminology #32

CSS⇋Object Negotiation

object size negotiation 算法 size 和 render 了 CSS 中的 objects。步骤是:

  1. 当 document 里指定了一个 object,CSS 先查 object 的 intrinsic dimensions(固有尺寸)
    • 指定 object 可以是 background-image: url()<img src="">
  2. 使用 intrinsic dimensions、specified size 和 object 使用的上下文的 default object size,CSS 计算出 concrete object size。这就确定了 object 要渲染的区域的 size 和 position
  3. CSS 告诉 object 把自己渲染在 concrete object size。但是 CSS 并没有定义,当 concrete object size 和 intrinsic dimensions 不同时,object 应该如何渲染自己。所以,object 就以某种方式来调整自己,以匹配 concrete object size,有时也会因为要满足它自身的 sizing constraints 而渲染的比 concrete object size 更大/更小。
  4. 除非 CSS 另有指定,否则 object 会被 clipped(裁剪)到 concrete object size。

Concrete Object Size Resolution

resolution 决议/分辨率/解析/分解

目前,sizing objects 的规则在每一个使用它的上下文里有描述。这部分定义了一些 common sizing constraints(限制)以及如何解决它们,以便未来的规范可以引用,而不是在每一个示例里都重新定义 size resolution。

1. Default Sizing Algorithm

Default Sizing Algorithm 是一组规则集合,用它可以确定 object 的 concrete object size。它解决 simultaneous constraints(同时约束),由 object 的 intrinsic dimensions 和不受约束的 specified size 或仅指定了 width/height。

一些对象的 sizing rules(eg.list-style-image)与 default sizing algorithm 的完全一致。其它的对象(eg.border-image)调用 default sizing algorithm,但之后也会应用其它的 sizing rules,最后才会得到 concrete object size。

default sizing algorithm 的定义如下:

  1. 如果 specified size 是确定的 width 和 height,那么 concrete object size 就是给出的 width 和 height
  2. 如何 specified size 只指定了 width 或者只指定了 height,那么 concrete object size 计算另一个尺寸的方法是:
    • 如果对象有 intrinsic aspect ratio,那么就用它和给出的值计算出另外一个
    • 否则,如果对象的 intrinsic dimensions 里有那个 missing dimension,那么就从 intrinsic dimensions 里取
    • 否则,就从 default object size 里取那个 missing dimension
  3. 如果没有 specified size
    • 如果 object 有 intrinsic width 或 height,它的 size 被解析,就好像 intrinsic dimensions 被指定成如 specified size 一样
    • 否则同 default object size

2. Cover and Contain Constraint Sizing

另外两个常见的 specified sizes(指定大小/尺寸)是 contain constraint 和 cover constraint。两者都是针对指定的 constraint rectangle,使用 object 的 intrinsic aspect ratio。

在这两种情况下,如果 object 没有 intrinsic aspect ratio,那 concrete object size 就是指定的 constraint rectangle。

CSS Object Sizing(CSS 对象大小)的例子

  1. background-image
    • 计算 background 的 concrete object size 的规则,定义在 [CSS2.1]() 和 [CSS3]()
    • CSS2.1 使用 default sizing algorithm,没有指定大小,background positioning area 作为 the default object size
    • CSS3 里,background-size 属性可以提供 sizing constraint,调用 default sizing algorithm 或者 contain/cover constraints。如果background-repeat有一个 round 值,在后面的步骤中进一步调整 concrete object size
  2. list-style-image
    • 计算 list-style image 的 concrete object size 的规则,定义在 [CSS2.1]()
    • 使用 default sizing algorithm,没有 specified size,1em 正方形的 default object size
  3. border-image
    • border images 会两次 sizing:首先调整 entire image 以确定 slice points,然后调整 slices 来装饰 border。
    • 第一次 sizing 操作定义在 [CSS3](),使用没有 specified size 的 default sizing algorithm,并将 border image area 作为 default object size
    • 第二次操作定义在 [CSS3](): default sizing algorithm 用于确定每个 slice 的 initial size,border image area part 作为 default object size。默认情况,specified size 和 default object size 是匹配的,然而border-image-repeat属性可以在一个或多个方向上删除 specified size,也可能会应用额外的 rounding 步骤 [CSS3]()。
  4. cursor
    • 计算 cursor 的 concrete object size 的规则,定义在 [CSS2.1]()
    • default object size 是 UA-defined size,是基于 UA 操作系统上的典型游标的大小
  5. content
    • 通过 [CSS2.1]() content 属性插入的 objects 是 anonymous replaced elements(匿名替换元素),并且以相同的方式确定大小。
    • [CSS2]() 说这样的 anonymous elements 将它们所有的 non-inherited properties(包括 width,height 等)设置成 initial values
  6. replaced elements
    • [CSS2.1]() 定义了 replaced elements 的 sizing(大小),包括通过content生成的插入内容,在 [10.3.2](),[10.4](),[10.6.2](), [10.7]()
    • 下面定义的 object-fit property 定义了 concrete object size 如何与元素的使用的 width 和 height 相对应,默认情况,它们是重合的

以上链接都是空的 完整的详见 https://drafts.csswg.org/css-images-3/#object-sizing-examples

anjia commented 5 years ago

接下来看两个

Sizing Objects: the object-fit property

replaced elements

object-fit属性决定了 replaced element 的内容如何放到由它的 width 和 height 建立的 box 里。

none 和 contain 都尊重 content 的 intrinsic aspect ratio,所以 smaller 的概念是明确的

如果 content 没有完全 fill 到 replaced element 的 content box,则 unfilled 区域显示 replaced element 的 background。因为 replaced elements 一直会剪裁它们的 contents 以适应 content box,所以 content 从来不会 overflow。

object-position 属性可以在 content box 之内 positioning the object(定位对象)。

object size negotiation 算法, concrete object size(在这个案例中,是 content 的 size)不会直接 scale object 本身,它只是作为 the size of the visible canvas 的信息传递给 object。如何绘制到这个 size 取决于 image format。特别是,raster images 总是缩放到给定大小,而 SVG 使用给定大小作为 SVG Viewport 的大小,然后使用根<svg>元素上的几个属性的值来确定如何绘制自身。

Positioning Objects: the object-position property

决定了 replaced element 在它的 box 里的 alignment。使用 concrete object size 作为 object area,使用 content box 作为 positioning area。

anjia commented 5 years ago

基于以上,整理成文:CSS 是怎样确定图像大小的? #44