CSS样式规则的学习是很繁琐和枯燥的,因为它不像物理、数学或者其他编程语言一样有一些基本概念、有一些基本公理或者规则,其他所有的表现都是概念在这些公里或者规则之下的逻辑游戏,CSS是有一些基本概念,但它没有说给你几条规则然后所有的表现都是在这些规则之下的任意自由组合,你要推测一个样式声明块的在页面中具体是怎样表现的,你几乎靠非常少逻辑推理去推测出来,绝大多数是你知道并记住了这种写法的声名块是具有怎样的表现的。之所以为这样也是因为样式的组合太繁琐组合情况特别多,像同样的概念margin在块级中的表现和在行内元素中的表现是不一样的,即便是同样在块级元素中不同方向上的margin表现也是不一样的,再进一步就算是同样在块级元素中同样的方向上,父元素的某些属性不同其表现也是不一样的,再加上浮动定位又是另一种情况,要是再考虑到各种不同浏览器的兼容性的话那就更令人烦躁了,这样的特性是不可能存在一个或几个规则让你逻辑推理样式表现的,掌握CSS样式规则只有穷举各种各样的组合并且记住它们的表现(虽然可能会有一小点的逻辑推理),因此前端这个职业感觉工作经验比其他的编程语言更加重要一些。
掌握一门语言的结果是在头脑中可以形成一个清晰的知识系统脉络图,而CSS的学习很难有一个清晰的逻辑线路去循环渐进的学习,因为它的概念关联性太弱了,所以在没有很清晰的逻辑帮助理解概念时,很好的理解现有概念是非常有必要的,比如说盒模型。
盒模型以及相关知识点在CSS中占有非常重要而核心的地位,而大家常常听到的非常经典的对盒模型的理解就是一个盒子的类比,盒子本身是border,里面货物就是内容,填充就是padding,盒子在摆放的时候要分开一定的距离就是margin。这种类比有它的好处,但是仍然感觉像是和没说一样(至少我这么觉得)。而且这种类比无形中把padding和内容这个整体视为标签元素的内容,把margin视为内容以外的东西,感觉这对理解css布局的相关本质会造成一定的偏差,最明显的一个例子就是初学人员会完全没有意识到width和height指定的宽和高是内容的宽和高(css3加了新的属性可以更改宽高的指定范围),并不是把padding和border还有margin算在一起的。所以现在我并不想把内容、padding、border、margin放到一个盒子相关中去理解,以一个不是盒模型的角度去理解也同样可能(只是可能因人而异)有利于避开在盒模型类比下形成想当然的认识。
在起初接触前端的时候都会看到这样的话:html标记页面内容,css表现页面样式,javascript控制页面行为。这是说页面的内容都是用html标签标记出来的,一个内容一定有一个相关html标签去标记它;css做到的是表现与内容分离,也就是说css是为页面的内容添加各种各样的样式,它的操作目标是内容,所以关于CSS的概念以内容为起点讨论,而不以盒子为起点。
打开网页可以发现页面的内容范围是文字、表单相关(输入框、按钮、单选框、复选框、下拉框)、图片、音频、视频。内容在页面中会放到一个矩形区域中即内容区,控制该区域的宽高属性为width和height,在内容区外部分则是标签元素形成的用于布局用的额外的空间。
标记这些内容的html标签分为两种:替换元素与非替换元素。
替换元素:以上除了文字都是替换元素,替换元素是指这个标签元素为某个内容的占一个位子,在原始html代码中看不出来实际具体表现。像图像、音频、视频标签它们就是指向某个图片文件、音频文件、视频文件。起占位作用的标签就是一种替换元素。
非替换元素:标签元素标记的内容在原始html代码中可以看出来,就不如说用span标签标记的文本。标记文本的span标签就是一种非替换元素。
因为内容总是有一个标签来标记它,而标签在浏览器中的渲染结果就是在内容周围变成一个矩形区域(在CSS3中可以设置为非矩形区域),这种矩形区域会在内容周围生成额外的空间,而产生的额外空间的种类一共有三种:padding(内边距)、border(边框)、margin(外边距)。在正常文档流中css对内容的样式布局实现大部分就是通过设置padding、border、margin来实现的。
padding空间是在边框和内容区域之间的无色透明的一块区域,该区域可以看到元素的背景色并且在没有border和margin的情况下该区域是不能合并的。
border空间是在内边距和外边距之间的一块有内置样式有颜色的一块区域,该区域也是绘制在背景色之上的,因此如果边框有镂空是可以看到背景颜色的。
margin空间是在边框外面的一块无色透明区域,该区域可以看到父元素的背景色并且在正常流中垂直方向上该区域是可以合并的,水平方向上是不存在合并规则的。
以上三个空间区域在在默认情况下都是不存在的。
虽然每个元素都会在内容周围渲染成矩形区域,但不同元素默认渲染成的矩形区域类型可能是不同的。通过设置display可以在不同类型的矩形区域之间进行切换。对矩形区域分类的一个标准就是看矩形区域前后是否有换行符:前后都有换行符的矩形区域为块级矩形区域;前后没有换行符的矩形区域为行内矩形区域。相应的不同类别的矩形区域所对应的元素也就叫做块级元素或者行内元素。换行符只是块级和行内与否的一条区分标识,并不是区别的全部,他俩在默认状态和变化行为上也有些许差别。
在文档流中默认状态下,多个块级元素是垂直排列的,并且它的宽为父元素的内容区域宽,高为自己内容区域高,可以自由改变自己内容区的宽和高。而多个行内元素是横向排列的,它的宽和高都为内容区域的宽和高,并且不能设置内容区的宽和高。
这样,一块标签标记的内容在页面中的表现从里到外就是内容区、内边距、边框、外边距四部分,这四部分是紧密相连的,并作为一个整体放在一个布局上下文中,并基于这个布局上下文摆放。布局上下文是父元素的内容区,这个内容区可能在块级元素中也可能在行内元素中。一般情况下,各个标签内容能按照从左到右的顺序摆放的就按照从左到右的顺序摆放,从左到右摆放不下的(像超出或者有换行符)就按照从上到下的顺序摆放,如果一个元素标签处在这样一个摆放顺序中,就说这个标签在文档流中。只有浮动和定位会摆脱这种束缚,这时就说元素脱离了文档流。