《CSS权威指南》读书笔记

刚学前端的时候总是觉得页面啊样式表啊这些东西,没有什么技术含量,刷一刷W3C School就够了。现在工作了一段时间,才发现页面结构和页面样式的坑是多么的大,之前学到的东西都是知其然而不知其所以然,刚好看见论坛上有推荐《CSS权威指南》这本书,赶紧补一补。

<!--more-->

1. CSS和文档

CSS的特性表现在两个规则上面:

  • 能够向文档中的一组元素应用某些表现规则
  • CSS层叠样式表中的“层叠”,即指定了样式的冲突规则。

1.1. 元素

替换元素和非替换元素 书中将CSS的元素分为了替换元素和非替换元素,这是一个之前没有接触过的概念:

  • 替换元素指该元素表示的内容由其内部的属性直接表示,而并非该元素标签包围的文档内容,比如img需要显示的指定其src属性,(PS:作者应该说的是非闭合标签);
  • 非替换元素指该元素的内容由浏览器在元素本身的框(元素框)中生成并显示(即闭合标签)

行内元素和块级元素 根据元素在浏览器重的显示形式,也可以将元素分为块级元素和行内元素:

  • 块级元素生成一个元素框,默认填充其父元素的内容区,旁边不能有其他的元素
  • 行内元素在文本行内生成元素框,而不会打断这行文本
  • XHTML层次结构要求行内元素可以包含在块元素中,反之则不行。但是CSS没有这种限制,可以通过display属性改变元素的显示形式

1.2. 样式表

将页面样式统一放在一个样式表中有很多好处,比如易于使用,便于维护和管理等。在HTML文档使用link标签来链接样式表和文档。

书中提到:为了成功的加载一个样式表,link标签必须位于head标签内部。但是经过测试,貌似这种限制已经消失了,即使是在body中使用了link链接外部样式表,样式表依旧会加载成功。

CSS样式表中不能出现任何文档标记,否则会导致部分或者全部样式无法被解析(表示今天刚遇到的一个报错,一个未闭合的大括号导致其后面所有的样式都无法正确显示,所幸使用了HBuilder的CSS语法检测才能快速定位错误。)

首选样式表 如果为一个rel为stylesheet的link标签指定了title属性,也就指定了该样式表作为首选样式表;如果没有为样式表指定title,则该样式表将作为一个永久样式表,始终用于文档的显示。

候选样式表 将link标签的rel属性值设置为alternate stylesheet即可定义候选样式表,即只有在用户选择这个样式表时才会生效,需要为不同的样式表指定不同的title属性值。(然而找了半天都没找到开启候选样式表的地方,最后终于在IE的“页面-样式-样式文件名”中发现了)

1.3. CSS规则

CSS的一个核心特性就是能够向文档中的一组元素应用某些规则。

h1 /* 选择器有多种写法和对应的匹配规则 */
{
    /* 一个大括号围成一个声明块,声明块由一条或数条声明组成*/
    color: red; /* 一条声明 */
    font-size: 20px;
}

可见样式规则由选择器和声明块组成共同组成的

  • 选择器指定浏览器对不用的选择器应用不同的样式规则。
  • 一条声明语句由属性名和属性值组成,而属性名和属性值都由某些关键字组成,掌握这些关键字是学习CSS必不可少的一步,详细的信息可以参考CSS手册

接下来就开始介绍选择器的部分了。

2. 选择器

选择器在定义了将影响文档中的哪些部分,而选择器的书写方式决定了对应的匹配规则。这里并不有按照书上的顺序来整理,而是从语义,结构和属性这三方面来进行归纳选择器的相关知识。

2.1. 语义选择器

选择器从语义上可以分为元素选择器,类选择器和ID选择器这三大类,每一类选择器又可以细分。

2.1.1. 元素和伪元素

元素选择器 最常见的选择器是HTML元素,如a,h1,li之类的,换句话说,文档的元素就是最基本的选择器。 但是单纯使用元素选择器有很多缺点,一个最明显的是页面上所有的元素都会应用声明样式,在某些时候这并不是我们希望的。在某些CSS书写规范中,甚至建议不要使用元素选择器。

伪元素选择器 伪元素能够在文档中插入假想的元素,通过为这些假想的元素指定样式,得到某种效果。常见的伪元素有:before:after等。

通配选择器 如果要为页面上的所有元素声明统一样式,可以使用*来进行匹配(但是大多数时候这并不是一个很好的主意)。

2.1.2. 类和伪类

在某些时候需要使用一种独立于文档元素的方式来指定样式,可以使用类选择器完成我们的需求。

类选择器 在样式表中,使用.标记一个类名选择器。为了将一个类选择器的样式与元素关联,必须为元素的class属性指定相关的属性值,该值可以包含多个类名,多个类名之间使用空格分隔。

伪类选择器 伪类选择器的实质是将某个“幻象类”关联到与伪类相关的元素,这样就不必添加具体的类就选择到对应的元素,比如:"first-child"的含义是选择某个作为某元素的第一个子元素的那个元素,而不是某元素下的第一个子元素!最经典的伪类莫过于a标签的:link,:visited,:hover,:active这四个了。

2.1.3. ID

ID选择器类似于类选择器。在样式表中,使用#来标记一个ID选择器,为了将一个ID选择器的样式与元素关联,必须为元素的id属性指定相关的属性值,该值是唯一的,不允许有以空格分隔的词列表,也就是说一个元素只可以使用一个ID进行标记。

点号加类名的方法在HTML、SVG和MathML中可以正常工作,在其他标记语言中则不一定正常;而加#号ID选择器可以在任何文档语言中使用。

通常情况下,浏览器其实并不会检验ID的唯一性,也就是说,其实在页面使用了所有同名的ID也可能使用相同的样式规则,然而这种做法是不正确的,此外对于JS获取DOM来讲是很坑的,可能只会获取到第一个ID,因此,任何时候都不要在页面中使用相同的ID名称。

2.2. 属性选择器

HTML文档中的元素都拥有通用或特有的属性值(包括前面的class和id属性),或者是HTML5新增的自定义属性值,如果希望根据属性来进行匹配(有的标记语言中甚至不支持class),则可以使用属性选择器。 属性选择器又可分为简单属性选择器,具体属性选择器和部分属性选择器三种:

2.2.1. 简单属性

简单属性选择器只关注用于某属性的元素,而并不关注其属性值,比如a[title]匹配带有标题属性的a标签,而那些没有title属性的a标签则不会应用相应的样式。

2.2.2. 具体属性

具体属性选择器选择拥有该属性且其属性值也一一对应的元素,比如a[href="http:www.google.com"]为包含谷歌官网的a标签应用相关样式

2.2.3. 部分属性

部分属性选择器类似于正则语法,通过属性值的某部分来筛选元素:

  • [att~="val"],选择具有att属性且属性值为一用空格分隔的字词列表,其中一个等于val的元素(包含只有一个值且该值等于val的情况)。
  • [att^="val"],选择具有att属性且属性值为以val开头的字符串的元素。
  • [att$="val"],选择具有att属性且属性值为以val结尾的字符串的元素。
  • [att*="val"],选择具有att属性且属性值为包含val的字符串的元素。
  • [att|="val"],选择具有att属性且属性值为以val开头并用连接符"-"分隔的字符串的元素(包含只有一个值且该值等于val的情况)。

部分属性选择器一个非常强大的选择器,可以在某些样式库中看见他们的身影。

2.3. 结构选择器

选择器的从结构上可以分为:分组选择器,多类选择器和后代选择器

2.3.1. 分组选择器

分组选择器表示多个选择器应用相同的样式规则,多个选择器之间使用,进行分隔;

2.3.2. 多类选择器

如果需要限定只有同时包含这些类名的元素(与类名顺序无关)才能应用对应的声明规则,则可以使用多类选择器(表示&&

需要注意的是,在IE7及之前的浏览器版本无法正确识别多类选择器。

2.3.3. 后代选择器

后代选择器基于HTML文档结构,而后代选择器的书写依赖于结合符

空格结合符 ,空格结合符,解释为"在...中找到...","...作为...的一部分...",要求从右向左读选择器(实际上浏览器的解析后代选择器也是从右向左进行的)。 空格结合符组成的后代选择器之间的层次可以是无限的,并不仅限于某代元素。

子结合符 >,子结合符,表示选取父元素下的第一代子元素,缩小了子元素的匹配范围。 子结合符两边可以有空白符,这是可选的,即p > ap>a是相同的

相邻兄弟结合符 +,相邻兄弟结合符,表示选取指定元素的后一个兄弟元素 ~,兄弟结合符,会选择所有符合条件的兄弟元素,而不强制是紧邻的元素。 与子选择符一样,兄弟结合符两边也可以带有可选的空白符

2.4. 小结

要想正确地理解选择器以及如何组合选择器,需要深入地掌握选择器与文档结构的关系。

3. 层叠与权重值

确认向某一个元素应用某些样式时,应当考虑的因素有:

  • 来自父元素的样式继承,继承是一个元素向其后代元素传递属性值所采用的机制
  • 样式的来源,某些样式可能被用户,浏览器或者开发人员共同指定
  • 样式声明的权重值,即优先程度

浏览器考虑并处理这些因素的过程就称为层叠,即解决样式冲突的本质都是依靠“层叠”进行的。

3.1. 权重值计算规则

一个元素可能被多个选择器所匹配,对于每个选择器所声明的规则,都可能存在样式冲突,浏览器会计算其特殊性(即权重值),并根据权重值的大小解决样式冲突,也就是说,

  • 依照 0,0,0,0 的规则计算权重值,
    • 行内样式千位+1,
    • ID选择器百位+1,
    • 类、伪类和属性选择器十位+1,
    • 元素、伪元素选择器个位+1,
    • 通配选择器权重值为0(并非没有权重值),而结合符没有任何权重值,
  • 权重值计算不会出现进位的情况(即0,1,0,0始终优先于0,0,13,0)
  • 浏览器会将元素的样式规则“解组”为单独声明,并对每一条单独声明计算其权重值。

3.2. 冲突的解决方案

如果有多条规则应用在同一元素上,则使用层叠解决:

important 使用!important进行声明的元素并没有权重值,而是归属与“重要声明”,而其他未使用!important进行声明的规则归属与“非重要声明”,重要声明的规则总是优先于非重要声明(包括行内样式),而不是权重值之间的比较。 此外,用户的重要声明优先于开发人员的重要声明(不过大多数用户应该都不会为某个页面去指定样式吧)。

权重值 如果冲突的样式规则均不是“重要声明”,则使用权重值进行比较,权重值高的规则声明优先于权重值低的规则。

样式来源 尽管大多数时候权重值决定样式规则就够了,但在权重值相同的情况下,就根据样式的来源进行取舍。

  • 开发人员的规则声明优先于用户的规则声明
  • 出现在样式表后面的声明优先于前面的声明(因此出现了关于a标签的4个伪类LVHA的书写方式)
  • 主样式表的声明优先于@import引入的样式表声明

默认样式 浏览器的默认规则声明优先级最低,只要用户或开发人员声明了对应的样式,浏览器的默认样式就会被覆盖。

继承样式 继承只能自上向下传递(body背景样式传递到html元素是一个例外),大多数盒子模型属性都不能被继承。

继承的值没有任何的权重值(连0都没有,甚至低于浏览器的默认样式),因此需要慎重使用通配选择符。此外需要注意浏览器的一些默认标签样式,只有在该规则没有显式指定任何声明的情况下才会使用继承属性! 初学时一个常见的问题就是:为什么已经指定了段落的字体颜色,而a标签的样式却没有改变?这正是由于继承属性没有任何权重值而浏览器为a标签指定了默认样式所引起的。

4. 单位

在利用CSS能做的所有工作中,最基础的就是单位了,这是影响所有属性的颜色,距离和大小的一种属性。

4.1. 数字

CSS中有两类数字:整数和实数(小数和百分数)。

4.2. 颜色

颜色有多种表示方法:命名颜色,RGB颜色,十六进制颜色。

  • 命名颜色指浏览器预留的颜色名词如red,pink等,不同的浏览器所支持的命名颜色可能不同
  • rgb颜色,如rgb(255,255,0),其中既可以使用百分数,也可以使用0-255之间的正式,分别代表该颜色重红、绿、蓝三种颜色分量
  • 十六进制颜色,如#aabbcc,如果其三组数十成组出现的,可以进行简写(比如示例简写成#abc);

WEB安全色指的是在256色计算机上总能避免抖动的颜色。在rgb()百分数表示法中的三色分量要么为0,要么能被20%整除;在rgb()整数表示法中的三色分量能被0或51整除;在十六进制表示法中三色的简写为0,3,6,9,c和f。

4.3. 长度

很多CSS属性都依赖于长度单位来使当地显示各种页面元素(论切图的意义~~)。

绝对长度 绝对长度有英寸,厘米,毫米,点(标准印刷单位)和派卡(印刷术语);除了在定义打印文档的样式表时(从来没弄过),最好不要使用绝对长度(总之就是写页面不要用绝对长度)。

相对长度 相对长度单位是根据与其他事物的关系来度量的,因此相对长度单位具有不确定性。常用的相对长度单位有em,expx:

  • 1em的定义为该元素字体的font-size大小,因此不同字体大小的元素上的em是不同的。如果em长度单位本身就是用来指定该元素上的字体大小,那么该元素的font-size就是其父元素的em(也就是父元素的font-size)乘以指定乘积因子
  • 1ex的定义为该元素所用字体小写x的高度,一般来说,可以假设为1ex = 0.5em,该单位实际情况中用的很少
  • 1px即组成显示器显示区域网格的方形单元格(简称为显示器元素)的长度,在不同的显示器下(比如PC和打印机),可能会被像素长度(1px)重新缩放为更合理的度量,因此,像素也是一个相对长度单位。

在控制字体大小的时候,最好不要使用像素,这会导致在ie7之前的某些BUG(但是貌似之前字体一直用的是像素啊);而在控制图像大小方面,最好使用像素(因为图片的尺寸本身就是像素,除非是SVG矢量图)

4.4. 其他单位

书中把URL和一些关键字如inheirt,none等都归为了单位。

5. 字体与文本

字体和文本是HTML文档的重要组成部分,而设置字体和文本属性也就成了样式表最常见的用途之一,因此单独整理了一篇文章:CSS文本样式

5.1. 字体

字体系列 指定font-family时最好提供一个通用字体系列,以备在用户系统中部存在指定字体的情况下选择备用的字体系列,多个字体之间使用逗号隔开,字体名称中含有空格或"#""&"之类的符号时需要使用引号将字体名称包围起来

字体粗度 虽然字体粗度关键字有100-900,对应字体的9级加粗度,但是这些关键字并没有固定的加粗度,比如100,200,300,400可能映射到同样的较细变形程度;而使用bolder和lighter时浏览器会首先计算其父容器的font-weight数值,再乘以对应的乘积因子

字体大小 使用百分数或者em指定字体大小时,是由浏览器先获取其父元素的font-size再乘以对应的乘积因子,并且浏览器很有可能会将该结果取整为最接近的整数像素,因此在连续使用百分数或者em指定字体大小时,误差可能会累积。

复合属性 使用font组合属性时需要注意下面几点:

  • 必须指定font-size和font-family,且font-size属性位于font-family属性之前
  • 如果某个属性对应的关键字是normal则可以省略
  • 可以加入line-height,但是必须使用font-size/line-height的格式

5.2. 文本

文本是内容,而字体用来显示这些内容。 文本缩进 text-indent继承的也是计算值而非声明值,也就是说子元素继承的缩进是与父元素宽度的尺寸,下面两个情景测试,均先按照父元素的尺寸进行计算,然后将计算结果传递给子元素:

  • 使用百分数指定缩进大小,且子元素与父元素宽度不同
  • 使用em指定缩进大小,且子元素与父元素字体大小不同

水平对齐 text-align指定文本的水平对齐方式(那个jsutify的属性我至今没有弄明白)。

行高 行高指文本行基线之间的距离,行间距实际上是(line-height - font-size)的值,因此可能为负。 实际上,文本行每行的行内元素都会生成一个内容区,而每个内容区又会生成对应的行内框,在默认情况下,行内框的大小即为字体大小,而使用line-height则是显式地重新指定了文本行中各个行内框的大小,只需要将行间距均分成两半且应用到每个内容的顶部和底部,就可以得到对应的重新生成的行内框的大小

  • 如果使用em,ex和百分数指定行高,都是相对于元素的font-size进行计算
  • 如果是从父元素继承行高,则情况会变得复杂:
    • 如果使用百分数来设置行高,浏览器会首先计算其父元素的字体大小与对应百分数的乘积,得到对应的结果再传递给对应元素(当子元素的字体大小大于该值就会出现文本行重叠的情况);
    • 如果使用乘积因子来指定行高,浏览器会计算该元素的字体大小(如果没有则计算该元素从其父元素继承得到的字体大小),然后乘以对应的乘积因子,并将结果应用在行高之上。

上面两点的总结:继承也是有优先级顺序的,当属性值之间存在依赖关系的时候,这种优先级十分重要(不知道这种理解是否正确)。

垂直对齐 默认的文本对齐方式是baseline,这会导致在某些浏览器下,基线下面的空间会导致图像出现一段空白,这种方法是文本对齐的正确实现,但有时候并不是我们想要的,有多种解决办法,在之前关于img两个小问题的那篇文章中提到过,最简单的方法大概就是指定父容器的font-size:0了。

6. 基本视觉格式格式化

CSS包含了一个开放且强大的模型用于自定义视觉显示。 目前读到这里,感觉这一章是整本书的精华,将之前学习到的零散的知识点真正整合起来了。

6.1. 包含块

每个元素都生成一个或多个矩形框,称为元素框;各元素框中心有一个内容区,内容区周围有可选的内边距、边框和外边距。但是,对于不同类型的元素格式化时存在着差别:块元素与行内元素不同,浮动元素与非浮动元素也不同。

在文档树中,每个元素都相对于其包含块摆放。包含块就是一个元素的布局上下文,包含块由最近的块级祖先元素,表格单元或者行内块祖先框的内容边界构成。CSS定义了一系列规则来确认元素的包含块。

6.2. 水平格式化

正常流中的块级元素框的水平部分总和(即左右外边距+左右边框宽度+左右内边距+元素内容区),这七个属性的值之和必定为该元素包含块的内容区大小,

  • 如果使用负的marigin值也是如此(在这种情况下子元素的宽度可能大于包含块的宽度)
  • width,margin-leftmargin-right可以设置为auto(其他四个值只能为非负数值),浏览器会自动计算其大小
  • 如果这三个属性都设置为非auto的某个值(这种情况叫做过分受限),且所有值之和不等于其包含块的内容区大小,那么浏览器会强制重置margin-right为计算值
  • 水平方向上的外边距不会合并

6.3. 竖直格式化

如果为margin-top或者margin-bottom设置auto会自动计算为0而不是一个智能的大小。 如果将元素的高度设置为auto,那么计算得到的值是最高的元素子元素的外边框边界到最低子元素的外边框边界(而不是外边距边界)之间的距离,这种情况会导致出现“外边距渗透的现象”,这可以归结于是子元素与其包含块之间发生的外边距折叠; 外边距折叠在竖直格式化中是十分常见的情形,相邻的外边距会沿着竖直轴合并,需要注意的是如果元素有内边距或内边框,就不会发生外边距折叠的现象了

6.4. 外边距/边框/内边距

所有的文档元素都会生成一个矩形框,这被称作“元素框”,描述了一个元素在文档布局中所占的空间大小。可以为所有元素应用外边距,边框和内边距。

6.4.1. 宽度和高度

width被定义为从左内边界到右内边界的距离,height被定义为从上内边界到下内边界之间的距离,即元素内容区的大小。

  • 这两个属性不能应用在内联元素上,内联元素的宽度和高度由其内容决定;
  • 由于默认外边距,边框,内边距均为0,由于子元素元素框大小等于父元素内容区宽度的规则,块级子元素的默认宽度为父元素的100%;
  • 在IE6及之前的怪异渲染模式中,width和height被用来定义元素框的尺寸而非元素内容区的大小,CSS3指定的box-sizing则允许我们自由的选择盒子模型。

6.4.2. 外边距

外边距指定了正常文档流中个元素之间的空白,所谓“空白”指的是不能放置其他元素的区域(这里只讨论了正常的文档流)。

  • 可以为margin设置为百分数,百分数是相当于父元素的width来计算的,而不论是左右margin和上下margin。这是由于如果上下外边距根据其父元素的height来设定可能会出现无限循环的情况(子元素的margin增加适应父元素的height,而父元素的height也必须增加来完全包含子元素...)
  • 元素的margin-top/margin-left被赋予负值时,元素将被拉进指定的方向,覆盖之前的元素;
  • 设置margin-bottom/right为负数,元素并不会向下/右移动,而是将后续的元素拖拉进来,覆盖本来的元素
  • 在只设置了元素外边距的情况下(无边框或内边距),垂直方向上的外边距会发生折叠。

外边距也可以应用在内联元素上(之前的认识完全错误),只是由于上面外边距并无法影响行高(内联元素的定位是由行框决定的,而影响行间距离的属性只有line-height,font-size和vertical-algin这三个),且外边距本身是透明的(背景色不会延伸至外边距),所以上下外边距不会有任何视觉效果。而在水平方向上,水平外边距会使该行内元素与其前后元素隔开指定的距离

6.4.3. 边框

  • 边框的默认样式是none,即没有任何边框,如果希望边框出现,必须显式地声明一个边框样式
  • 边框的默认颜色是元素的字体颜色
  • 元素的背景颜色会延伸到边框,即如果指定为dotted等样式的时候,元素的背景颜色在边框的可见区域也能够看到。
  • 边框也不法影响到行内元素的行高

6.4.4. 内边距

  • 跟外边距类似,指定内边距的大小为百分数,是相对于其父元素的width进行计算的
  • 为行内元素指定内边距也是规范完全允许的,同理,内边距也是无法影响行高的,但是由于背景颜色会覆盖内边距,因此会出现行内元素的背景颜色超过其行高的情况(之前关于为内联元素指定边距的疑惑豁然开朗)

7. 颜色和背景

  • 边框画在背景之上;
  • 所有的背景属性都不能被继承,默认背景为transparent;
  • 背景颜色与背景图像可以同时存在,且建议指定背景图像的时候同时指定元素的背景颜色
  • 背景图形的定位是相当于元素的内边距边界进行的(虽然背景可以延伸至元素边框),可以通过关键字,百分数和数值的方式指定background-position:
    • 关键字的顺序可以是任意的,且只指定一个关键字的情况下,另一个关键字的默认值为center
    • 百分数指定的定位有非常智能的效果,会导致背景图像的左上角或中心或右下脚等等对应元素不同的位置;如果使用百分值设置位置,第一个出现的数值将应用在水平方向,而第二个数值的默认值为50%
    • 使用具体数值指定背景图片定位,会将这些数值解释为背景图像从元素内边距左上角的偏移,偏移点是原图像的左上角。
    • 在CSS2.1之后,可以混合使用这三种方式指定背景图像定位
  • 背景图像的滚动关联如果指定为fixed,则该背景图像会相对于可视区定位

8. 浮动和定位

8.1. 浮动

浮动的元素会以某种形式从文档的正常流中移除,但还是会影响布局:

  • 浮动元素在竖直方向上的外边距并不会合并(触发了BFC);
  • 浮动元素的包含块是距离其最近的块级祖先元素;
  • 浮动元素都会产生一个块级浮动框,而不论该元素本身是什么类型(要记住,所有元素都可以浮动),因此对浮动的元素显式声明display:block是多此一举;
  • 有一系列的规则控制着浮动元素的摆放,比如:
    • 浮动元素彼此无法覆盖;
    • 浮动元素的外边界无法超过其包含块的内边界(当然使用负边界可以达到这样的效果);
    • 浮动元素在竖直方向上会尽可能高地摆放,但是其顶端不能比之前的浮动元素或者块级元素的顶端更高;
    • 浮动元素在水平方向上会尽可能向左或者向右摆放,且位置越高,漂浮的更远;
  • 行内框与一个浮动元素重叠时,其边框,背景和内容都在该浮动元素之上显示(只有在浮动元素具有负边框的情况下才会看见这个情况);
  • 块级元素与一个浮动元素重叠时,其边框和背景都在该浮动元素之下显示,而内容在浮动元素之上显示;
  • 使用clear进行清浮动,可以指定该元素的对应方向上不存在浮动元素,在CSS2.1中,使用clear的本质是引入了一个“清除区域”,清除区域是在元素上外边距之上额外增加了一个间距,且不允许任何浮动元素进入这个范围。这样造成的结果是设置了清浮动的元素的上边框边界推到了刚好越过浮动元素下边界的情况,出现“设置了上边距却没有出现间隔”的情况,解决这种情况的一个办法是设置浮动元素的下边距,相当于延长了浮动元素的下边界,从而达到预期的效果,具体的原理只有一句话:浮动元素的外边距边界定义了浮动框的边界

8.2. 定位

不同类型的定位会影响对应元素框的生成:

  • static,块级元素生成矩形元素框,并作为文档流的一部分,内联元素生成行内框,置于其父元素中;
  • relative,元素偏移某个距离,其原本所占据的文档流位置仍然保留,其包含块由最近的块级框,表格单元格或者行内块祖先框的内容边界构成,
  • absolute,元素框从文档流中完全删除,并相当于其包含块定位,其包含块由最近的position属性值部位static的祖先元素的内容边界构成

偏移量top,right,bottom,left描述了距离包含块对应边的偏移

  • 其值可正可负,正值会导致元素向内偏移,使边界朝着包含块的中心移动,负值会导致元素向外偏移。
  • 所有偏移量的计算都是使用外边距边界来进行的,而静态位置都是相对于包含块的内容区来进行的,偏移所移动的是元素框所有属性,包括外边距,边框,内边距和内容区。
  • 当同时声明了left和right会自动计算width的大小;当同时声明了top和bottom会自动计算height的大小;

可以为偏移量设置为auto,这在不同的定位形式下的不同元素的表现上是不一样的:

  • 绝对定位:将left设置为auto,元素的左边界会相对于其定位钱本来的左侧位置对齐;将top设置为auto,元素的上边界相对于其未定位前本来的顶端位置对齐;将right设置为auto,元素的右边界会相对其未定位前本来的右侧位置对齐。
  • 在上述情况中,浏览器会自动计算元素的width和height;但是需要注意的是,在水平布局中如果left或者right设置为auto,在水平方向上元素都会相对于其静态位置(即未定位时的本来位置)摆放;在竖直方向中,只有top值为auto时元素会相对于其静态位置摆放,而bottom无法达到这种效果。
  • 在过度受限的情况下(这里指margin为auto),浏览器会忽略对应方向上的偏移并重新计算其偏移,甚至是竖直范行方向上的外边距(在正常流中,margin-top: auto的计算值为0),这样就可以使用margin: auto 0达到竖直居中,比如下面的代码,可以使元素达到完全居中的效果;
    .box {
      background: red;
      position: absolute;
      width: 100px;
      height: 100px;
      left: 0;
      right: 0;
      top: 0;
      bottom: 0;
      margin: auto 0 ;
    }
    //不要被四个0给唬住了,像下面这样,只要是过分受限,浏览器都会忽略并重新计算,这里可以理解为浏览器处理margin: auto的优先级更大...
    .box {
      background: red;
      position: absolute;
      width: 100px;
      height: 100px;
      left: 10px;
      right: 100px;
      top: 30px;
      bottom: 15px;
      margin: auto ;
    }

9. 最后

本书后面的内容介绍了表布局,列表生成内容以及用户样式界面和非屏幕媒体。前面两章内容过于晦涩,后两章内容过于偏门,加之最近一直在忙着工作的事,因此这篇笔记草草结尾。《CSS权威指南》是一本非常难得的好书,值得反复阅读,细细琢磨,来日方长,定会多刷几次,第一次阅读完毕(好吧其实后面的内容还没有看完),最大的收获便是“CSS的复杂程度远超过它表面上看起来的那样,仍需不断地努力”。