对新CSS规范草案的解读_html/css_WEB-ITnose
CSS是一种描述文档样式的语言,它不依赖于HTML,可以用于许多其他标记语言。它也不只是用于视觉媒介,还用于听觉媒介。
在CSS的世界里只有线框,用CSS思考就是用线框去思考,它给文档上所有可视或可读的东西都画了线框。这些线框的嵌套关系和文档结构上元素嵌套关系是不一样的,特定的排版方式都会改变它们的嵌套关系。首先确认线框的嵌套关系,再确认这个线框里所有线框的互相影响,记住关于尺寸,摆放位置,材质皮肤的计算规则。
我觉得把box翻译成盒子是欠妥的,还不如线框。在中文里盒子是个立体实物的概念,如果用盒子去理解CSS box会带来不必要的副作用,CSS更适合用传统印刷排版术语来理解。比如子box溢出父box的情况,如果用盒子去理解就会很怪,但用线框去理解就简单多了,类似出版术语bleed。在印刷排版领域大量使用的框术语,和CSS的box极其类似,为什么不直接用,非要生造个盒子出来。其实不光是box,还有很多地方的翻译都能套用排版术语。
最新的草案描述和老规范的术语定义区别大。而且现在CSS规范划分成独立的子模块形式发布,一些基础模块的术语定义没有确定,造成依赖这些模块的其他模块术语定义也很混乱。阅读不同模块规范能发现互相用到了相同术语,但是定义却不一样。他们换了不同的说法描述这些规则,他们想建立更好的术语体系。规范是对现实中厂商的具体实现方案和开发者的具体开发方案的标准化。其实就是让不同方案的主导者互相妥协,通过谈判达成一致意见,用来规范和要求不同的厂商和开发者必须按统一的方案执行。
Use tomorrow’s CSS syntax, today.
http://cssnext.io/
这个类似JS的babel。让我们提前使用CSS新规范的内容,而不用等到浏览器支持。但是因为CSS的特殊性,cssnext和babel比起来,还太low了。在CSS这块,估计在很长时间里都只能使用老旧但安全的方案。
理解CSS规范: 就算你不是一名计算机科学系的学生,甚至不用满十八岁或拿到学士学位,都可以读懂 W3C 的 CSS 文档,前提是你得乐于钻研,能耐下心,以及注重细节。
http://www.chinaw3c.org/archives/369/
最新CSS规范草案
https://drafts.csswg.org/
相关内容汇总:
CSS Device Adaptation Module
The viewport在老规范里面,viewport术语只适用于continuous media,@viewport applies to continuous media, and @page to paged media。现在viewport适用于所有media。
这个规范介绍了一种通过the user agent (UA)重写viewport尺寸的方法。 因此我们需要提出初始视窗the initial viewport和实际视窗the actual viewport的不同。
initial viewport
初始视窗是指在任何UA或作者的样式把UA的屏幕窗口或可视区域的视窗覆盖前的那个视窗。注意初始视窗的尺寸将随着UA的窗口或视区的尺寸而变化。
actual viewport
实际视窗是指通过串联所有样式表的视窗描述符viewport descriptors,并且按CSS规则应用后的视窗。
当实际视窗不能全部显示于当前UA的窗口或视区时,如果不是因为实际视窗大于初始视窗,那就是因为缩放导致实际视窗只能显示部分。UA应该提供滚动条或者拖拽机制。
也就是初始视窗是最终显示媒介的可视区域尺寸,而实际视窗则是样式表指定的尺寸,可以设置得和初始一样,也可以比它大,如果大了就会有部分内容看不到,需要滚动或拖拽才能看到。比如window.innerWidth/Height就是initial viewport的尺寸。document.documentElement.clientWidth/Height就是actual viewport的尺寸。
如果文档根元素的方向direction属性值是ltr,推荐实际视窗的左上角和UA窗口或视区的左上角是对齐的,同理,direction属性值是rtl则右上角对齐。
Media Queries
由于渲染文档的媒介有很多,初始包围区的尺寸和设备方向都会影响一个媒介查询计算的结果,意思是在media queries上要特别注意@viewport rules的影响。Media Queries Level
媒介查询允许作者检测和查询UA或显示设备的值或者特征,据此把文档渲染成独有的样式。通过CSS @media rule按条件给文档应用不同的样式。
Media Queries Level 4叙述了媒介查询 Media Queries,媒介类型Media Type,媒介特征Media Features的句法和机制。
一个媒介查询是一个逻辑运算表达式,它的值是true或false。由media type和media condition两部分组成,如果都为真,那么这个表达式的值为真,否则为假。
多个媒介查询可以合并成一个用逗号分隔媒介查询列表。
媒介类型是指UA的宽泛类别。最初媒介类型集合的定义是在HTML4规范中,用于link元素的media属性。
从以往情况看,Media Types不能很好的区分日益复杂的UA情况。所以放弃了扩展媒介类型来解决问题,而是采用更精细的Media Features。句法上,media features看起来像CSS属性。每个媒介特性分两大类,范围range类或者单独discrete类。范围类特性的名字通常带有min-或max-这样的前缀。单独类特性值通常是规范指定关键字或者布尔数字0或1之类。
多个媒介特性可以使用逻辑运算符(not and or)组成一个媒介条件判断语句。CSS Display Module
这个模块描述如何从文档元素树the document element tree生成CSS编排线框树CSS formatting box tree,并且定义了display和box-suppress属性,用来控制线框boxex。
The viewport and the canvas 视窗和画布 视窗是浏览文档的Media的可视区域。对于所有媒体来说,术语画布用来描述格式化结构体渲染后的显示空间。这个画布的尺寸是无限的。
CSS是一种描述结构化文档(比如HTML和XML)在显示屏,印刷品,语音流等媒介上如何渲染的语言。
CSS把一个组织成元素树的源文档渲染在画布canvas上(比如显示屏,一张纸,一段语音流)。要做到这点,它生成一个中介结构,线框树box tree,它表示已渲染文档的编排结构。
每个线框表示它对应的元素或伪元素在画布上出现的空间或时间。
创建线框树box tree的过程。
CSS首先使用级联cascading和继承inheritance规则给源节点树上的每个元素的每个CSS属性赋一个值。
然后按每个元素的display和box-suppress属性设置来为其生成零个或多个线框boxes,通常一个元素生成一个单独的线框box。然而一些display属性值 (e.g. display: list-item)会生成多个线框 (e.g. a principal block box and a marker box),并且一些属性值(比如display:none, display: contents, and box-suppress: discard) 会造成这个元素或者其后代根本不生成任何线框boex。
除非另有说明,线框boxes的样式和生成它们的元素一样。它们通常被叫成它们的显示类型display type,比如一个display属性是block的元素生成的线框box叫做块状线框“block box”或者块“block”。
一个匿名线框anonymous box是一个不与任何元素相关的线框box。
匿名线框Anonymous boxes是在需要特殊组织线框树the box tree的情况下生成,这种情况是需要一个特殊的嵌套结构,这个结构中的线框boxes不是从元素树生成的。
例如,当一个table cell box需要一个特殊类型的父box (the table row box)的时候,如果它的父box不是一个table row box,将生成一个anonymous table row box来嵌套它. (See [CSS2] § 17.2.1.) 不同于元素生成的box,元素生成的box样式是严格通过元素树继承的,只存在于box tree中的匿名boxes样式继承自它们的box tree。
在排版的过程中,一个box线框可能拆成多个片段. 是这么发生,例如, 当一个inline box分拆穿过多行的时候, 或者当一个block box分拆穿过一页或一列的时候,因此一个box由一个或多个box片段组成. See [CSS3-BREAK] for more information on fragmentation.CSS basic box model
CSS假定文档的呈现是以元素树为模型。每个元素是一个拥有零个以上子元素的有序列表,和一个可选的文本字符串,在这个列表前后以及子元素之间。每个子元素都有一个父元素,除了唯一一个元素没有父元素,它叫做根元素。
CSS描述每个元素element和每个文本字符串string of text如何从文档树模型转换为一组矩形框rectangular boxes来排版,其在画布上的尺寸,位置,堆叠层级都依赖于boxes的属性。
我们说一个元素生成一个或多个线框boxes。它们是许多不同类型的线框boxes。
The flow 流,有时也叫做normal flow正常流,是CSS中排版的两个基本类型之一,另一个是line layout [CSS3LINE]。其他CSS模块, 比如tables [CSS3TBL], positioning [CSS3POS], flex boxes [CSS3-FLEXBOX] and grid templates [CSS3LAYOUT]都是基于流模型flow model实现的,通过把一个文档分拆成不止一个流,在画布上通过这些不同的流来进行定位和校准。
一个flow是从一个box开始构建,当一个box满足以下规则时,它叫做flow root:
The value of ‘float’ is not ‘none’.
The used value of ‘overflow’ is not ‘visible’.
The value of ‘display’ is ‘table-cell’, ‘table-caption’ (see [CSS3TBL]), ‘inline-block’ or ‘inline-table’.
The value of ‘position’ is neither ‘static’ nor ‘relative’ (see [CSS3POS]).
The value of ‘block-progression’ is ‘lr’ or ‘rl’ and the value of ‘block-progression’ of its parent box is ‘tb’
The value of ‘block-progression’ is ‘tb’ and the value of ‘block-progression’ of its parent box is ‘lr’ or ‘rl’.
flow root术语在CSS level 2 规范中定义是不同的. 在老规范中一个flow root定义为 “an element that establishes a new formatting context.”
我们说flow从flow root引出。注意flow root本身不是它引出的流flow的一部分,每个flow root最多引出一个flow。
一个flow root的flow是一组boxes。当一个元素的box是flow root,而且它的子元素的box满足以下规则时,则属于这个flow:
The used value of its ‘display’ is ‘block’, ‘list-item’, ‘table’ or .
The used value of its ‘float’ is ‘none’.
The used value of its ‘position’ is ‘static’ or ‘relative’.
It is either a child of the flow root or a child of a box that belong to the flow.
注意元素树element tree和框树box tree不见得一样,比如在DOM树中的某个元素的框,通过position属性的改变,它的框的父框,可能不是父元素的框,而是某个祖先元素的框。
如果需要一个box忽略前后的floating box影响时,则可以把它的clear属性值设为和前后box的float一样的值,或者both。
注意由于一个浮动元素是一个flow root,对这样一个元素设置‘clear-after’,仅去掉了这个元素自己flow里子孙的浮动。
补充说明:
当元素box的float属性值不为none默认值时,它会从父box的flow中分离出来,生成一个新flow,并且会浮动在原来父box内的左边或者右边。如果前面的兄弟box也是相同的浮动属性值,则会浮动在其旁边。前面的兄弟块级元素box的float值是none,则会浮动在它下面。后面的其他普通兄弟块级元素box会忽略浮动元素的box尺寸,但是后面元素包括后代在内所有行内元素环绕会在前面第一个浮动元素box旁,如果float是left,则在box右边,如果float是right,则在box左边。direction属性值不同会改变规则。
一个简单的float hack 解决原父box无视浮动box的高度问题:
.clearfix {
overflow: auto;
zoom: 1;
}
CSS Positioned Layout Module
这个模块包含关于定位元素和叠加元素的CSS level 3特性。
CSS Positioned Layout Module最新草案的术语定义还是老的,它依赖CSS basic box model,可还没用CSS basic box model新草案的相关术语定义。CSS basic box model新草案定义‘position’ is neither ‘static’ nor ‘relative’则生成新的flow。而且flow也和formatting context术语没有关系了。
本模块描述了如何安排元素树中任何元素的位置,而不依赖于其在文档结构中的顺序。(即从“流”中取出)
Containing Blocks 包围区
在CSS中,许多线框boxex的位置和尺寸是相对于一个矩形框的边缘计算的,这个矩形框叫做包围区containing block。在一般情况下,生成的框就是其包含的子框的包围区; 我们说一个框为包含的子框“建立”了一个包围区。短语“一个框的包围区”的意思是“这个框存在于这个包围区内”,而不是说这个框生成的包围区。
每个框安排的位置都是相对于它们的包围区,但它们不受包围区限制 它们可能溢出。也就是说包围区只是提供了一个参考坐标体系。
根元素的顶层box的包围区是一个视窗尺寸的矩形,这个包围区叫做initial containing block 初始包围区,The containing block of the root element根元素的包围区。
一个元素的线框box的位置和尺寸往往是相对于一个确定的矩形计算出来的,这个矩形叫做元素的包围区。
元素box的position属性,默认值是static,The top, right, bottom, left and z-index properties 无效。
当元素box的position属性值是relative时,保留了box占位空间。设置box位置坐标时,用的是原始containing block左上角为原点的坐标体系。
当元素box的position属性值是absolute时,生成新的flow,不再影响原flow中box排版,设置box坐标时,用的是最近的position属性不是static的祖先box的containing block 左上角为原点的坐标体系,如果没有这样的祖先box,则是以根box的containing block左上角为原点。
当元素box的position属性值是fixed时,生成新的flow,不再影响原flow中box排版,设置box坐标时,用的是以视窗左上角为原点的坐标体系,无视滚动条。它的containing block is the viewport。
当元素box的position属性值是sticky时,就是relative和fixed的结合,它通过一个临界点sticky offset设置把box的position切换成relative或fixed。
当元素box的position属性值不是static时,可能会出现box重叠的情况,这时候可以设置它们的z-index属性来调整它们的Z轴顺序,大的在上面。
补充说明:
当根元素到父元素高度或宽度是100%,当前元素position属性值是absolute时,位置属性是top:0px; bottom:0px;或left:0px; right:0px时, 可以达到其高度或宽度是100%效果。当配合其他固定宽高元素时,通过修改位置属性,可以实现自动填满剩余空间,实现类似FlexBox的伸缩排版。CSS Multi-column Layout Module
一个多列元素是指一个元素的’column-width’或’column-count’属性值不是’auto’,因此作为一个多列排版的容器。
在传统CSS线框模型CSS box model中,元素内容是直接属于元素内容线框box。多列排版在内容box和内容之间引入了新的类型容器,叫做列box。一个多列元素的内容是属于它的列box。(应该就是CSS Display Module规范中所说的匿名线框anonymous box)。
在多列元素中,列线框column boxes排列成行。就像表格单元格,列框在行内是按多列元素的横线方向有序排列。列的宽度是这个列框在横线里占的长度。列的高度是这个列框在竖线里占的长度。在一行里面所有列框的宽度是相等的,高度也是相等的。也就是把横线均分为相等长度的线段。在多列元素的每一行里面,相邻的列框有列间隙隔开,也可以有列界线。如果它们出现在同一行内,所有间隔都是相等的,所有列界线也是相等的。列界线仅出现在两个有内容的列之间。
在最简单的情况下,一个多列元素一列只有一行,并且每一列的高度值和这个多列元素的内容线框box的高度值是相等的。如果多列元素跨页了,那么它每行的高度受制于页面,结构上连续的内容跨页后,另一页的部分属于新行的新列框。一个列框是不会分到不同页面的。
同样的结果出现在一个spanning element分割多列元素时,当多列元素内一个元素的column-span属性为none时,是适用于正常分列规则,当column-span属性为all时,它将建立一个新行的列框。
不可能去设置列线框column boxes的属性值,例如,设置一个列框的background,padding,margin,border属性。将来可能会支持。。。
列框Column boxes充当它们内容的包围区containing block。就是说列框column boxes的表现就像CSS21规范里的block-level, table cell和inline-block boxes。不管怎样,column boxes不会为它所属的多列元素建立用于定位属性‘position: fixed’ or ‘position: absolute’的包围区containing blocks。
column box内容的样式值是基于column box计算的。
‘columns’属性是一个速写属性,用于设置’column-width’ 和 ‘column-count’属性.
实际column box的宽度可能会和设置的column-width属性值不一样,它受到多列元素的width值影响,可能大于或小于设置的值,如果把元素按column-width均分后,小于元素宽则会自动加宽,大于元素宽,则会自动变窄,最终实际的column-width乘以column-count,再加上column-gap的宽度后等于元素的width。
列间距gaps和界线rules存在一个多列元素的列之间。它们的长度等于列的长度,是说竖线方向的长度,也就是高度是相等的。列距是占空间的。就是说,列距会推开同一个多列元素里相邻列的内容。
列界线是画在列间距中间,并且终点在元素上下边上。列界线是不占空间的。就是说,列界线的存在不会影响任何排版相关的属性值。如果线的宽度超过了间距,则看起来是叠在列框上面,甚至可以超出整个框。界线刚好在元素的背景上面。多列元素的后代元素可以用z-index属性值来叠到它上面。界线仅画在有内容的两列之间。
多列元素的后代元素,有很多属性可以改变默认的内容分割规则。比如break-,column-span之类的。
当一个多列元素的后代元素的column-span属性值为all时,可以独占一行,自成一列,而且列宽就是多列元素的宽度。
注意那种超过列宽的连续字母,无法对其实现分栏。CSS Flexible Box Layout Module
伸缩线框排版
CSS 2.1定义了四种排版模式 – 决定线框boxes的尺寸和位置的规则系统,基于它和它的兄弟祖先线框boxes的关系:
1 block layout 区块排版,设计用于编排文档
2 inline layout 行内排版,设计用于编排文本
3 table layout 表格排版,设计用于编排表格形式的数据
4 positioned layout 定位排版,设计用于在文档中非常明确的定位,不用过多考虑其他元素
这个模块介绍一种新的排版模式,flex layout伸缩排版,设计用于更多复杂的应用和页面。
伸缩排版flex layout表面上看类似区块排版block layout。它缺乏许多在区块排版中用于更复杂的以文本或文档为中心的特性,比如浮动floats和多列columns。
作为交换,它获得了纯粹又强大的手段,用于空间分布和对齐内容,这常常是复杂web应用和页面需要的。
一个伸缩容器flex container的内容contents:
内容能往任何流方向flow direction排列(向左,向右,向下,甚至向上!)
内容的显示顺序能在样式层上反转或者重新排列(也就是说,看见的内容顺序可以和源码或语音流顺序无关)
内容能顺着单一主轴线排列或者把内容包入多行顺着十字交叉穿过主轴线的次轴线排列
内容的尺寸能伸缩响应可用空间的变化
内容能相对于所属容器对齐或者它们彼此相对次轴线对齐
内容能顺着主轴线折叠或不折叠,同时保留容器的次轴线长度
Flex Layout Box Model and Terminology伸缩排版线框模式和术语
一个伸缩容器是由一个元素生成的线框,它的dsplay属性值是flex或者inline-flex。一个伸缩容器的流的孩子叫做伸缩项,它们的排版是采用伸缩排版模式。
不同于基于区块和行内流方向计算排版数值的区块和行内排版,伸缩排版是基于伸缩方向。为了让关于伸缩排版的讨论变得不费劲,这节定义了一组伸缩流相关flex flow–relative术语的集合。flex-flow属性值和书写方式决定了这些术语如何映射到物理方向 (top/right/bottom/left), 轴线 (vertical/horizontal), 和尺寸。
二维空间
main axis 第一维轴线
main dimension 第一维度
伸缩容器的第一维轴线是伸缩项排版采用的主要坐标轴线。它在第一维维度上延伸。
main-start 第一维开始
main-end 第一维结束
伸缩项被这样摆放在容器里,从第一维开始的一侧延伸到结束的一侧。
main size 第一维长度
main size property 第一维长度属性
一个伸缩项的宽或者高,哪个在第一维度上,它就是项目的第一维长度。项目的第一维长度属性就是项目的宽或者高属性,哪个在第一维度上就是哪个。
cross axis 第二维轴线 (和第一维轴线十字交叉)
cross dimension 第二维度
这条垂直于第一维轴线的轴线叫做第二维轴线。它在第二维度上延伸。
cross-start 第二维开始
cross-end 第二维结束
放满伸缩项的伸缩行被这样摆放在容器里,从第二维开始的一侧到结束的一侧。
cross size 第二维长度
cross size property 第二维长度属性
一个伸缩项的宽或者高,哪个在第二维度上,它就是项目的第二维长度。项目的第二维长度属性就是项目的宽或者高属性,哪个在第二维度上就是哪个。
一个元素的display属性值为flex,则生成一个区块级别的伸缩容器box。
一个元素的display属性值为inline-flex,则生成一个行内级别的伸缩容器box。
在伸缩box里面浮动box无效,伸缩box的margin不会和它内容的margin发生折叠。和区块容器一样,伸缩容器box就是它内容box的包围区。overflow属性在伸缩容器上也适用。多列相关属性无效,浮动相关属性float和clear无效,vertical-align属性无效, ::first-line and ::first-letter 伪元素无效,
宽泛的说,伸缩容器的伸缩项是表示它的流内容的线框。每个伸缩容器流的孩子都会变成伸缩项,没有子元素嵌套的文本,则会自动创建一个匿名线框把文本包起来,作为匿名伸缩项。匿名线框是没法独立应用样式,只能继承父元素的样式。
伸缩容器和其伸缩项的boxes也叫做flex-level boxes。和block-level boxes没关系。
相邻的伸缩项的margin不折叠。伸缩项的order属性可以设置其在所有伸缩项中显示顺序,而且它们是可以叠加的,z-index属性自动生效,默认值是auto。
伸缩项的visibility属性设置成collapse,这个不同UA实现不一样。看起来和visibility:hidden一样。有的隐藏但保留占位,有的隐藏不保留占位。
Display Order: the order property
Reordering and Accessibility
默认情况下,伸缩项的显示顺序和文档结构中内容顺序一样,可以通过order属性改变顺序。值小的在前面,可以用负数。
CSS一再强调,在组织文档结构时,不要考虑样式,一定要语义优先,语义为大。在具体显示的时候,完全可以用CSS实现和语义结构不同排版。CSS一般不会去改变文档的语义结构,它是通过为内容建立对应的box,用box去做重新的排版。
Flex Lines
伸缩项在伸缩容器中的排版,是排成一条线(横线或竖线)放在伸缩行(横行或竖行即列)里,假设容器用分组对齐的排版算法。一个伸缩容器可以是单行或者多行,取决于flex-wrap属性值:
一个单行的伸缩容器,比如flex-wrap: nowrap,它的内容都排版成一行,即使会溢出。
一个多行的伸缩容器,比如flex-wrap: wrap or flex-wrap: wrap-reverse,它的内容会分成多行,当一行满了就会把超出的内容分入新行。当追加的行创建时,它们是根据flex-wrap属性值沿着交叉轴线堆放。每一行至少有一个伸缩项,除非伸缩容器是空的。
Flexibility伸缩排版的一个特点是,它可以让伸缩项伸缩。在第一维度上修改它们的宽或高去充满可用空间。这是用flex属性做到的。伸缩容器把空闲的空间分给伸缩项去充满容器,按伸展系数flex-grow的比例伸展,剩余空间的情况,或者按收缩系数flex-shrink的比例去收缩,溢出空间的情况。
如果flex-grow和flex-shrink的值是0,则伸缩项没有伸缩特性,值不是0,才可以伸缩。
flex属性是伸缩相关属性的速写属性,可以同时指定计算伸缩长度的属性值:flex-grow,flex-shrink,flex-basis。当一个box是flex item时,flex属性会征求取代main size属性来决定box的第一维长度。如果box不是一个flex item,那么flex属性无效。
flex-grow的值是数字,指定伸缩的伸展系数,它决定了一个伸缩项如何相对于同一容器中其他伸缩项来伸展长度,当确定有空闲空间分配的时候。如果在flex属性中没有指定,默认值是1。负值无效。
flex-shrink的值是数字,指定伸缩的收缩系数,它决定了一个伸缩项如何相对于同一容器中其他伸缩项来收缩长度,当空闲空间不够分配的时候。如果在flex属性中没有指定,默认值是1。负值无效。注意:当分配有限空间的时候,收缩系数要乘以伸缩项长度。按百分比确定如何收缩,比如在特别长的项目大幅收缩前,短的项目不会收缩为0。
flex-basis是关键字或数字,指定伸缩项的初始长度采用哪种规则获得,然后用于和伸缩系数的运算。
当flex-basis值为auto时,检索flex item的main size属性的值用于flex-basis。
当flex-basis值是content时,表明为自动计算长度,基于伸缩项的内容。注意:这个关键字是新加的,有些老的解析器可能不支持。它等同于flex-basis值为auto和main size为auto的情况。
其他情况值和伸缩项的宽或高的值规则一样。
如果在flex属性中没有指定,则默认值是0。
在flex属性中flex-grow,flex-shrink,flex-basis的默认值,和flex-grow,flex-shrink,flex-basis独立时的默认值不同。
flex属性常用配置:
flex: initial; 等同于 flex: 0 1 auto;这就是默认值。基于伸缩项的宽或高属性确定伸缩项的长度。如果项目的main size属性计算为auto,那么项目的长度计算基于它的内容。当空间足够的时候,项目是固定长度。当空间不够,则项目的长度会收缩。
flex: auto; 等同于 flex: 1 1 auto;基于伸缩项的宽或高属性确定伸缩项的长度。项目的长度会根据容器第一维长度情况,沿着第一维轴线按系数1来自动变长或短。如果多个项目中,同时有flex: auto, flex: initial, or flex: none的项目,则flex: auto的项目为自适应剩余空间。
flex: none; 等同于 flex: 0 0 auto;基于伸缩项的宽或高属性确定伸缩项的长度。不能伸缩,可能会出现内容溢出容器的情况。
flex: 等同于 flex: 1 0;伸缩项可以伸缩,并且基准数是0。按系数百分比分配空间。如果所有项都是这个属性配置,它们都会按指定系数的百分比来分配空间。
默认情况,flex item不能缩短到比内容长度还短,最小内容长度是最长的单词或固定长度的元素决定的。可以通过min-width或者min-height属性改变它。
规范鼓励作者使用速写法的属性,因为对于未指定值的属性组件,提供了常用的默认值。
Alignment当完成了display属性值为flex或inline-flex的伸缩容器的flex-flow属性,内容的order属性值和flex属性配置,确定了伸缩的定向,排序,长度计算规则后,可以开始搞对齐校准了。
伸缩项的对齐校准,是通过margin属性和CSS Box Alignment类型属性。
margin值为auto的伸缩项表现和block流中的margin值为auto的box类似:
在计算伸缩基准值和伸缩长度时,自动外边距相当于「0」。
在使用「justify-content」和「align-self」控制分布对齐前,在对应维度上的所有正值空闲空间会分配给自动外边距使用。
溢出的boxes忽略自动外边距,在对应维度的结束方向溢出。
注意:如果空闲空间分配给了自动外边距,则对齐相关的属性在这一维度上将不起作用,因为外边距偷走了伸缩后所有的可用空间。
Axis Alignment: the justify-content property
justify-content属性沿着容器的行的第一维轴线分布行内所有伸缩项的位置。这个属性在伸缩长度和所有自动外边距的计算都已解决后才生效。当一行中所有伸缩项都是不可伸缩,或者伸到最大后,还额外剩下的空闲空间,用这个属性决定如何分配。就算项目溢出,这个属性依然生效。
justify-content: flex-start; 行内的伸缩项都靠向行的开始一侧。行内第一个项目在第一维度上的开始外边缘和这行在第一维度上的开始外边缘完全齐平摆放,它之后的项目依次紧跟着前面的项目,后面项目的开始边缘和前面项目的结束边缘完全齐平摆放。
justify-content: flex-end;和flex-start相反。行内最后一个项目的结束边缘和这行的结束边缘完全齐平摆放,它之前的项目依次紧跟着后面项目,前面项目的结束边缘和后面项目的开始边缘完全齐平摆放。
justify-content: center;行内的伸缩项都靠向行的中间。在行内所有伸缩项目彼此边缘完全齐平摆放,并且整体对齐于行的中间,还有这行的开始边缘和第一个项目的开始边缘之间的空间长度与这行的结束边缘和最后一个项目的结束边缘之间的空间长度是相等的。如果剩余空闲空间是负的,则这些项目整体在两个相反方向的溢出空间是相等的。
justify-content: space-between;
如果剩余空闲空间是负的,或者行内仅有单个项目,这种情况表现和justify-content: flex-start; 一样。
其他情况下,所有伸缩项目平均分布在行内,行内第一个项目的开始边缘和这行的开始边缘完全齐平摆放,行内最后一个项目的结束边缘和这行的结束边缘完全齐平摆放,剩下的项目平均分布在行内剩下的空闲空间,保证任何两个项目的相对的边缘之间的空间长度是相等的。
justify-content: space-around;
如果剩余空闲空间是负的,或者行内仅有单个项目,这种情况表现和justify-content: center; 一样。
其他情况下,行内的伸缩项目平均分布在行内,并且在行内任何两个项目的相对的边缘之间的空间长度是相等的,并且第一个项目的开始边缘到容器的开始边缘的空间长度和最后一个项目的结束边缘到容器的结束边缘的空间长度是两个项目的相对的边缘之间的空间长度的一半。
Cross-axis Alignment: the align-items and align-self properties
伸缩项可以在其所属容器的所属行的第二维轴线上对齐。作为一个整体来说,类似于justify-content,但是是在justify-content垂直的方向上对齐于行的边。
align-items设置flex容器内所有项目的默认对齐方式,包括匿名flex items。
align-self允许为单个flex items重写默认对齐方式。
对于匿名flex items来说,它的align-self永远和它所属的容器的align-items的值一样。
如果flex item的第二维度上的margin属性值是auto,那么align-self无效。
如果「align-self」的值为「auto」,则其计算值为元素的父元素的「align-items」值,如果该元素没有父元素,则计算值为「stretch」。
对齐属性值的定义如下:
flex-start
行内伸缩项目在第二维度上的开始外边缘和这行在第二维度上的开始外边缘完全齐平摆放。
flex-end行内伸缩项目在第二维度上的结束外边缘和这行在第二维度上的结束外边缘完全齐平摆放。
center行内伸缩项目在第二维度上的中间和这行在第二维度上的中间对齐在一条线上。如果行在第二维度上的长度小于项目在第二维度上的长度,那么项目会溢出,并且在两个相反方向的溢出空间是相等的。
baseline行内伸缩项目根据基线对齐,然后算出基线到项目在第二维度上的开始外边缘的长度最大的项目,将它的第二维度上的开始外边缘和这行在第二维度上的开始外边缘紧靠齐平摆放。如果行内项目外边缘到基线的长度一样,则看起来和flex-start一样。
stretch
如果flex item的cross size属性值求出为auto,并且第二维轴线的margins不是auto,那么这个项目在第二维度上的长度是会伸展的。
使用这个值,行内的项目在第二维度上的长度会尽可能接近这行在第二维度上的长度,同时仍然接受min-height/min-width/max-height/max-width属性值对于项目长度的限制。
注意,如果容器指定了具体高度,可能会造成伸缩项目的内容溢出。
Packing Flex Lines: the align-content property
align-content属性和justify-content属性类似。和justify-content属性一样值的我就不翻译了,看后面补充说明。
注意,这个属性在单行的伸缩容器上无效。
align-content: stretch;
多行box会占据剩余空间。如果剩余空闲空间为负,它的表现和flex-start一样。
其他情况,空闲空间会等分给所有行,增加每行在第二维度上的长度。
Flex Container Baselines
为了一个伸缩容器本身参与到基线对齐。例如,当一个伸缩容器本身就是一个外层伸缩容器的伸缩项目时。它必须提交基线的位置,它将最能表示它的内容。
first/last main-axis baseline set
如果伸缩容器的第一或最后一行中的任何一个伸缩项目参与了基线对齐,伸缩容器的第一或最后的主轴基线设置是生成自这些伸缩项共用的基线。这种情况对应容器设置align-items: baseline;
其他情况,如果伸缩容器至少有一个项目,并且它的第一个或最后一个项目有一条基线平行于容器的主轴,这个容器的第一或最后的主轴基线设置生成自它的对齐基线。这种情况对应容器某个项目设置align-self:baseline;
其他情况,容器的第一或最后主轴基线设置是合成自第一个或最后一个项目内容box,或者,直接来自容器内容box。这种对应容器和项目都没有设置align-items: baseline;和align-self:baseline;的情况。
官方翻译版本 https://www.w3.org/html/ig/zh/wiki/Css3-flexbox/zh-hans
A Complete Guide to Flexbox
A Complete Guide to Flexbox
补充说明:
关于flex flow,它是flex排版的基础。
首先确定writing-mode的值是horizontal-tb还是vertical-rl,flex-direction的值是row还是column,只有这个确定了,后面所有的术语才有了确定的意义。main是二维空间中的哪个维度,main axis是XY轴中的哪个轴,reverse是反往哪个方向,line是横行还是竖行等等。
第一大类:writing-mode: horizontal-tb;
第一大类的第一小类:
第1种属性配置,也是默认情况 flex-direction: row; flex-wrap: nowrap; 或速写 flex-flow: row nowrap;
main axis 可理解为XY坐标系的X轴,伸缩项的宽度就是它在X轴上的长度。伸缩项从X轴的原点往正值方向摆放,即从左往右沿着main axis摆放。
cross axis 可理解为XY坐标系的Y轴,伸缩项的高度就是它在Y轴上的长度。
原点是伸缩容器box的左上角。可以把容器box理解为XY坐标系的第四象限。第2种属性配置,flex-direction: row; flex-wrap: wrap; 或速写 flex-flow: row wrap;
main axis 可理解为XY坐标系的X轴,伸缩项的宽度就是它在X轴上的长度。伸缩项从X轴的原点往正值方向摆放,即从左往右沿着main axis摆放。
cross axis 可理解为XY坐标系的Y轴,伸缩项的高度就是它在Y轴上的长度。当伸缩项触发换行时,伸缩行从Y轴的原点往负值方向摆放,即从上到下沿着cross axis摆放。
原点是伸缩容器box的左上角。可以把容器box理解为XY坐标系的第四象限。第3种属性配置,flex-direction: row; flex-wrap: wrap-reverse; 或速写 flex-flow: row wrap-reverse;
main axis 可理解为XY坐标系的X轴,伸缩项的宽度就是它在X轴上的长度。伸缩项从X轴的原点往正值方向摆放,即从左往右沿着main axis摆放。
cross axis 可理解为XY坐标系的Y轴,伸缩项的高度就是它在Y轴上的长度。当伸缩项触发换行时,伸缩行从Y轴的原点往正值方向摆放,即从下到上沿着cross axis摆放。
原点是伸缩容器box的左下角。可以把容器box理解为XY坐标系的第一象限。第4种属性配置,flex-direction: row-reverse; flex-wrap: nowrap; 或速写 flex-flow: row-reverse nowrap;
main axis 可理解为XY坐标系的X轴,伸缩项的宽度就是它在X轴上的长度。伸缩项从X轴的原点往负值方向摆放,即从右往左沿着main axis摆放。
cross axis 可理解为XY坐标系的Y轴,伸缩项的高度就是它在Y轴上的长度。
原点是伸缩容器box的右上角。可以把容器box理解为XY坐标系的第三象限。第5种属性配置,flex-direction: row-reverse; flex-wrap: wrap; 或速写 flex-flow: row-reverse wrap;
main axis 可理解为XY坐标系的X轴,伸缩项的宽度就是它在X轴上的长度。伸缩项从X轴的原点往负值方向摆放,即从右往左沿着main axis摆放。
cross axis 可理解为XY坐标系的Y轴,伸缩项的高度就是它在Y轴上的长度。当伸缩项触发换行时,伸缩行从Y轴的原点往负值方向摆放,即从上到下沿着cross axis摆放。
原点是伸缩容器box的右上角。可以把容器box理解为XY坐标系的第三象限。第6种属性配置,flex-direction: row-reverse; flex-wrap: wrap-reverse; 或速写 flex-flow: row-reverse wrap-reverse;
main axis 可理解为XY坐标系的X轴,伸缩项的宽度就是它在X轴上的长度。伸缩项从X轴的原点往负值方向摆放,即从右往左沿着main axis摆放。
cross axis 可理解为XY坐标系的Y轴,伸缩项的高度就是它在Y轴上的长度。当伸缩项触发换行时,伸缩行从Y轴的原点往正值方向摆放,即从下到上沿着cross axis摆放。
原点是伸缩容器box的右下角。可以把容器box理解为XY坐标系的第二象限。
第一大类的第二小类:
第1种属性配置, flex-direction: column; flex-wrap: nowrap;
第2种属性配置, flex-direction: column; flex-wrap: wrap;
第3种属性配置, flex-direction: column; flex-wrap: wrap-reverse;
第4种属性配置,flex-direction: column-reverse; flex-wrap: nowrap;
第5种属性配置,flex-direction: column-reverse; flex-wrap: wrap;
第6种属性配置,flex-direction: column-reverse; flex-wrap: wrap-reverse;
和前面6种一一对应,区别就是,main axis从X轴变成了Y轴,cross axis从Y轴变成了X轴。row对应的是inline,是行,或叫横行。column对应的是block,是列,或叫竖行。
第二大类writing-mode: vertical-rl;的属性配置情况就不细说了。初始属性配置就类似第一大类的第二小类的第3种配置的表现。
关于flex属性
它是flex排版的标志,它决定了box能不能flex,怎么改变长度。从flex的默认值flex: 0 1 auto;,可以看出它默认是为了适应窄屏的情况,当空间足够时,它是没有flex特性的,只有空间不够的时候才触发flex。关于分布和对齐
justify-content,从字面意思也能看出,它强调的是行的内容怎么相对于行的空间来分布它们的位置,整体是靠行的哪边或中间,确定整体大方向后,它们相对的位置间隔怎么分配。
align-content和justify-content规则一样,但是作用对象不同,它是作用于容器内所有行的分布。如果说justify-content是相对行box,怎么分配行内的item box的位置,那么align-content则是相对于容器box,怎么分配行box的位置。注意只有一行的情况无效。
align-items 和 align-self,它强调的是项目们如何对齐,项目上的一条线怎么对齐在行的一条线上。align-items是容器的属性,它同时作用于行内所有项目,align-self是项目的属性,作用于单个项目自身。
一定要注意,虽然规范大量使用line的术语,但是因为main axis和cross axis所代表的二维空间上的维度是可以互换的,也就是说可以指定二维空间的那个维度作为主维,所以行,有可能是横行,也可能是竖行。如果用中文一个字理解,就是行和列的意思。
HTML5规范中关于元素样式渲染的描述。
UA不是必须以一个特定的方式去呈现HTML文档。
一个元素已渲染如果它有关联到CSS排版线框,SVG排版线框,或者其他同类的样式语言。
一个元素只是出了屏幕不意味着没有渲染。可以通过重写样式表让元素的显示属性为隐藏才不会被渲染。
没有什么元素的display必须是block或者inline,可以重写UA提供的默认样式。
W3C正在大力推进默认值:在浏览器默认样式和作者样式起作用之前,所有所有元素的所有CSS声明都有规范定义的默认值。例如,所有元素的display属性默认值都是inline,因为这是规范定义的默认值。随后,浏览器样式表设置块级元素的display属性为block。web开发者可以写样式表再次改变display的属性值。
https://html.spec.whatwg.org/multipage/rendering.html
https://www.w3.org/TR/html5/rendering.html
http://www.quirksmode.org/blog/archives/2015/09/a_new_device_ad.html规范给出的一些默认样式建议
14.3.2 The pagehtml, body { display: block; }
14.3.3 Flow content
address, blockquote, center, div, figure, figcaption, footer, form, header, hr,
legend, listing, main, p, plaintext, pre, xmp {
display: block;
}
14.3.7 Sections and headings
article, aside, h1, h2, h3, h4, h5, h6, hgroup, nav, section {
display: block;
}
14.3.8 Listsdir, dd, dl, dt, menu, ol, ul { display: block; }
14.3.9 Tables
table { display: table; }
caption { display: table-caption; }
colgroup, colgroup[hidden] { display: table-column-group; }
col, col[hidden] { display: table-column; }
thead, thead[hidden] { display: table-header-group; }
tbody, tbody[hidden] { display: table-row-group; }
tfoot, tfoot[hidden] { display: table-footer-group; }
tr, tr[hidden] { display: table-row; }
td, th, td[hidden], th[hidden] { display: table-cell; }
14.3.13 The fieldset and legend elements
fieldset {
display: block;
}
css-tricks almanac
CSS Almanac
推荐阅读
-
css 规范的 code review_html/css_WEB-ITnose
-
怎么对HTML 5的特性做检测?_html/css_WEB-ITnose
-
帮我看一下我的网站字符编码设置的对吗_html/css_WEB-ITnose
-
帮我看一下我的网站字符编码设置的对吗_html/css_WEB-ITnose
-
你对position的了解到底有多少?_html/css_WEB-ITnose
-
position:fixed对元素影响的疑问?_html/css_WEB-ITnose
-
新手,新写的INPUT函数的VALUE值显示不了。_html/css_WEB-ITnose
-
CSS3中transition-duration参数对hover前后两种过渡时间的影响_html/css_WEB-ITnose
-
对原生TextView解析Html格式文本的增强:TextViewForFullHtml_html/css_WEB-ITnose
-
请教div层浮动的做法:例如 登陆对话div层跟随页面上下浮动的做法_html/css_WEB-ITnose