盒模型的二次理解。
1. 定义
所谓盒模型,就是浏览器为页面中的每个HTML元素生成的矩形盒子。
1.1排布
这些盒子们都要按照可见版式模型在页面上排布,版式模型由position,display,float这三个属性来控制,position属性控制页面上元素间的位置关系,用于定位;display属性控制元素显示的本质(inline:默认值,显示为内联元素;block:块级元素;inline-block:行内块级;table:作为块级表格来显示;none:不会被显示......)这些值可以令元素轻松拥有其他属性的特点~比如span是行内元素,拥有inline属性,但是我们也有需要span纵向排列的时候,这就需要给span设置display:block了,设置后span会像div,p等块级元素一样自动换行。float属性也是作用于元素的位置关系,不过和position相比貌似调皮了一些,浮动是完全脱离文档流(不再占用文档中的位置,就像小天使飞在天上不再占用地面的位置一样~),定位的值中只有absolute,fixed完全脱离了文档流,默认值static即在常规文档流中(失去了法力的小天使需要在地上走路,和我们一样),相对定位relative是相对于它原来在文档流中的位置(或者默认位置)定位的。静态定位的元素不会受到top, bottom, left, right,z-index的影响。非静态定位根据不同定位目标产生由top, bottom, left, right影响的定位。
举个栗子:
1 static 即没有定位,元素出现在正常的流中
<body> <p>111111111111</p> <p>111111111111</p> <p>111111111111</p> <p>111111111111</p> <p>111111111111</p> </body>
2 relative 相对定位元素的定位是相对其正常位置。
<body> <p>111111111111</p> <p>111111111111</p> <p>111111111111</p> <p style="position: relative; top: 10px;left: 10px;">111111111111</p>//相对于其原来位置偏移 <p>111111111111</p> </body>
3 absolute 绝对定位的元素的位置相对于最近的已定位父元素,如果元素没有已定位的父元素,那么它的位置相对于<html>。因为不占空间,所以和其他元素重叠。z-index属性指定了一个元素的堆叠顺序(z-index的值越高,层次越高,层次低的会被其覆盖,并且允许负值)
<body> <p>111111111111</p> <p>111111111111</p> <p>111111111111</p> <p style="position: absolute;left: 10px;top: 10px; color: red;">111111111111</p>//相对与body偏移,其原来在文档刘 <p>111111111111</p> </body>
4 fixed 元素的位置相对于浏览器窗口是固定位置。(老版IE不支持)
<body> <p>111111111111</p> <p>111111111111</p> <p>111111111111</p> <p style="position: fixed;left: 10px;top: 10px; color: red;">111111111111</p> <p>111111111111</p> </body>
图和absolute的看起来一样,其实他们是不同的,absolute中的元素会随着鼠标的滚动在页面的位置发生变化,而fixed则不会。
1.2 属性
默认情况下每个盒子的边框不可见,背景也是透明的,属性可分为三组:边框(border),内边框(padding),外边框(margin)。
CSS为边框,内边框和外边框分别规定了简写属性,这样对不同边框样式相同的就可以一条声明设定了。但是不同样式的最好单独声明,利于后期的单独更改和语义化表达,如{margin:1px 2px 3px 4px;}(表示上,右,下,左的外边距,顺时针排列~)最好用{margin-top:1px;margin-right:2px;margin-bottom:3px;margin-left:4px;},也可以将两者混合使用,这样只需要把不同的那一个属性单独拿出来写就可以了,可以很大程度上减小工作量,但是要注意css文件的读取顺序,后读取的属性值会覆盖先读取的。所以单独写的属性要放在后面,比如:
div { margin:2px; margin-top:3px; }
2. 盒子边距
2.1 基本
盒子的内边距(padding)指盒子内容区与盒子边框之间的距离,盒子的外边距相对来说就复杂一些了,因为盒子之间的距离会出现“垂直方向上叠加”的情况,eg:有3个段落我们设置 p{margin-top:10px;margin-bottom:20px;},那么第一个段落和第二段落,以及第二个和第三段落之间的距离是多少?(10+20=30)吗?实际距离是20px,也就是说值较大的外边距决定两个元素最终的距离,垂直外边距叠加,直到一个元素的外边距碰到令一个元素的边框为止。不过要注意的是叠加只是用于垂直方向的哦,水平的相邻的元素他们之间的距离是相邻外边距之和。
2.2 扩展
为文本元素设置外边距时通常需要混合使用不同的单位,eg:一个段落的左右外边距可以使用像素,这样该段文本始终与包含元素边界保持固定间距,不受字号变化的影响。然而对于上下边距,以em,rem(rem是相对与body字体的相对字体,em是相对与父级字体的相对字体,所以使用rem更好控制一些)当字体变大时,段间距也会相应变大,就比较和谐了。
3. 盒子有多大
3.1 不同盒子模型
盒子模型有两种,分别是 IE 盒子模型和标准 W3C盒子模型。他们对盒子模型的解释各不相同。标准盒子模型的宽度只是内容的宽度,IE的盒子模型宽度包括内容,内边距(padding),边框(border)。所以在占据位置相同的情况下,盒子的大小是不同的。
so~我们需要在网页的顶部加上doctype声明,这样就能避免不同浏览器按自己想法理解盒子模型进而出现不同浏览效果的情况了。<!DOCTYPE> 声明必须是 HTML 文档的第一行,位于 <html> 标签之前。它不是 HTML 标签;它是指示 web 浏览器关于页面使用哪个 HTML 版本进行编写的指令。在 HTML 4.01 中有三种 <!DOCTYPE> 声明。在 HTML5 中只有一种(在 HTML 4.01 中,<!DOCTYPE> 声明引用 DTD,因为 HTML 4.01 基于 SGML。DTD 规定了标记语言的规则,这样浏览器才能正确地呈现内容。HTML5 不基于 SGML,所以不需要引用 DTD。):
HTML5
<!DOCTYPE html>
HTML4
HTML 4.01 Strict
该 DTD 包含所有 HTML 元素和属性,但不包括展示性的和弃用的元素(比如 font)。不允许框架集(Framesets)。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
HTML 4.01 Transitional
该 DTD 包含所有 HTML 元素和属性,包括展示性的和弃用的元素(比如 font)。不允许框架集(Framesets)。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
HTML 4.01 Frameset
该 DTD 等同于 HTML 4.01 Transitional,但允许框架集内容。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN""http://www.w3.org/TR/html4/frameset.dtd">
XHTML 1.0 Strict
该 DTD 包含所有 HTML 元素和属性,但不包括展示性的和弃用的元素(比如 font)。不允许框架集(Framesets)。必须以格式正确的 XML 来编写标记。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
XHTML 1.0 Transitional
该 DTD 包含所有 HTML 元素和属性,包括展示性的和弃用的元素(比如 font)。不允许框架集(Framesets)。必须以格式正确的 XML 来编写标记。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
XHTML 1.0 Frameset
该 DTD 等同于 XHTML 1.0 Transitional,但允许框架集内容。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
XHTML 1.1
该 DTD 等同于 XHTML 1.0 Strict,但允许添加模型(例如提供对东亚语系的 ruby 支持)。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML .1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
一定要向 HTML 文档添加 <!DOCTYPE> 声明,这样浏览器才能获知文档类型。
另一种解决方法来自CSS3的box-sizing属性,当我们设置box-sizing:border-box;时,border和padding就被包含在了宽高之内,就和IE的标准一样了。为了避免同一份css样式在不同浏览器表现不同,最好加上:
*,*:before,*:after { -moz-box-sizing:border-box; -webkit-box-sizing:border-box; box-sizing:border-box; }
3.2 盒子的宽度
如果不设置块级元素的width属性,那么这个属性的默认值就是auto,结果会让元素的宽度扩展到与父元素同宽。添加水平边框,内边距和外边距,会导致内容宽度减少,减少的量为添加的水平边框,内边距和外边距的和。设定宽度值后,添加内边距元素的width值不变,但是元素占的地方比之前宽了2倍内边距。说明width属性只是盒子内容区的宽度,而非盒子所占的宽度。