你的位置:首页 > 网页设计

[网页设计]聊聊css盒子模型


css盒子模型原理:

在网页设计中常听的属性名:内容(content)、填充/内边距(padding)、边框(border)、外边距(margin), CSS盒子模式都具备这些属性。
这些属性我们可以把它转移到我们日常生活中的盒子(箱子)上来理解,日常生活中所见的盒子也就是能装东西的一种箱子,也具有这些属性,所以叫它盒子模式。

CSS中, Box Model叫盒子模型(或框模型),Box Model规定了元素内容(element content)、内边距(padding)、边框(border) 和 外边距(margin) 的方式。在HTML文档中,每个元素都有盒子模型,所以说在Web世界里(特别是页面布局),Box Model无处不在。下面是Box Model的图示:

 

理解css盒子模型:

可以把它当成日常中的一个盒子去理解。content就是盒子里装的东西,它有高度(height)和宽度(width),可以是图片,可以是文字或者小盒子嵌套,在现实中,内容不能大于盒子,内容大于盒子就会撑破盒子,但在css中,盒子有弹性的,顶多内容太大就会撑大盒子,但是不会损害盒子。padding即是填充,就好像我们为了保证盒子里的东西不损坏,填充了一些东西,比如泡沫或者塑料薄膜,填充物有大有小,有软有硬,反应在网页中就是padding的大小了。而再外一层就是border边框,因为边框有大小和颜色的属性,相当于盒子的厚度和它的颜色或者材料。margin外边距,就是我们的盒子与其他的盒子或者其他东西的距离。假如有很多盒子,margin就是盒子堆码直接的距离,可以通风,也美观同时方便取出。

我们理解了盒子模型,有助于我们了解一个元素的最终尺寸是怎么样决定的,同时也帮助我们理解元素在网页上是如何定位的,而盒子模型主要适用于块级元素。

css盒子尺寸的计算:

我们通过给高宽赋值,来定义content(内容)的高度和宽度。如果没有做任何声明,那么高度和宽度的默认值将是自动(auto)。即在css中给一个块级元素的width和height属性赋值时比如div{width :200px; height: 200px}时,其中的width 和height只是对content部分设置的,即上图中content区域的长和宽。而不是内容,内边距,边框的总和(但在IE的早期版本包括IE6中,盒子模型的width和height却是内容+内边距+边框的总和,尽管符合人们思考的逻辑习惯,但是不符合规范,造成了很多兼容性问题。)

包含块注释

包含块(Containing Block)是视觉格式化模型的一个重要概念,它与框模型类似,也可以理解为一个矩形,而这个矩形的作用是为它里面包含的元素提供一个参考,元素的尺寸和位置的计算往往是由该元素所在的包含块决定的。

包含块简单说就是定位参考框,或者定位坐标参考系,元素一旦定义了定位显示(相对、绝对、固定)都具有包含块性质,它所包含的定位元素都将以该包含块为坐标系进行定位和调整。



如代码所示,div和table都是包含块,可以说div是table的包含块,也可以说table是div的包含块,这不是绝对的。

其定义如下:
  1. 用户代理(比如浏览器)选择根元素作为 containing block(称之为初始 containing block)。
  2. 对于其它元素,除非元素使用的是绝对位置,containing block 由最近的块级祖先元素盒子的内容边界组成。
  3. 如果元素有属性 'position:fixed',containing block 由视口建立。
  4. 如果元素有属性 'position:absolute',containing block 由最近的 position 不是 static 的祖先建立,按下面的步骤:
    1. 如果祖先是块级元素,containing block 由祖先的 padding edge 形成。
    2. 如果祖先是内联元素,containing block 取决于祖先的 direction 属性。
      1. 如果 direction 是 ltr(左到右),祖先产生的第一个盒子的上、左内容边界是 containing block 的上方和左方,祖先的最后一个盒子的下、右内容边界是 containing block 的下方和右方。
      2. 如果 direction 是 rtl(右到左),祖先产生的第一个盒子的上、右内容边界是 containing block 的上方和右方,祖先的最后一个盒子的下、左内容边界是 containing block 的下方和左方。

如果没有祖先,根元素盒子的内容边界确定为 containing block。今天主要讲解css盒子模型,包含块另外写贴咯。

对宽度为自动状态的静态定位元素(即无定位),和相对定位元素来说,计算宽度的方法是,将他们包含块(containing block)的宽度减去此元素的横向的所有外边距,内边距,边框,滚动条。也就是说,从包含块的宽度中除去元素的横向外边距,内边距,边框,滚动条(如果存在的话)的宽度,所剩的值就是content了。

在 CSS 中,width 和 height 指的是内容区域的宽度和高度。增加内边距、边框和外边距不会影响内容区域的尺寸,但是会增加元素框的总尺寸。假设框的每个边上有 10 个像素的外边距和10个像素的内边距和5个像素的边框。如果希望这个元素框达到 100 个像素,就需要将内容的宽度设置为 50像素,以下是CSS代码:

 

以上事例即可以明白css盒子模型的计算了。

对于浮动和绝对定位元素(包括固定定位元素)来说, 自动状态的宽度会使盒子收缩到紧贴它内容大小。

以下代码和盒子示意图即可以理解:



当我们放置一个块级元素于页面上时,并且不设置它的定位属性(relative,absolute,fixed),即position:static,或者设置了position:relative的情况下,块的宽度是延伸自动填充满它的父元素的宽度区域。

 

以下代码及盒子示意图可知:

留意外边距叠加效应

尽管在上面的计算元素所需区域大小的例子中外边距已经在计算中包括在内了,但是需要注意的是纵向的无定位(static)元素的相邻外边距会叠加合成为其中一个较大宽度的外外边距的值,并非两者之和。这就意味当计算实际上需要存放一个元素的区域大小时,并不是从外边距的边缘开始算起,只有最宽的外边距会生效,并且较窄的外边距会与较大的叠加在一起。

由上图可知,两个盒子的纵向margin,不是两个margin相加,而是最宽的外边距为准,假如相等的外边距就是取之一就ok。

 

注意,当一个元素的宽度被设置为100%时(也就是说父元素的内容宽度是100%),它不应该有任何的外边距,内边距,或者是边框,这只会使它放置的区域需要更大的面积。这通常会被忽略且扰乱了页面的布局,这样的话内容要么溢出要么使元素比他们应该的样式更宽。

以上代码以及效果图可见,布局破坏,父元素独占一行,影响布局。

如果可用区域是固定宽度的,你能简单的把每一个属性元素(margin,padding等)的宽度都相加起来以匹配可用的那个固定宽度。举个例子,如果可用的区域宽度是100px,并且你需要一个元素有20px的内边距,简单的把这个元素的宽度设置为60px,内边距为20px(20+60+20=100)。这个办法中先决条件是宽度值和元素盒子属性使用的都是同一测量单位,因为你不希望把混合单位相加起来(100px + 10%,只是举个例子而已,在内容中这样的写法是没有意义的)。

当可用内容区域的宽度是未知的时候——比如在流式布局(fluid layout)中——这个方法是行不通的,因为百分比和像素不能一起相加。在这种情况下,解决方法应该是为需要的元素声明一个100%的宽度值,并且把内边距,边框,外边距的值都设置到一个嵌套其中的元素中去。这个嵌套元素没有任何的宽度值声明,并且可以在没有干扰父元素的情况下展示需要的内边距,边框,外边距。

例如自适应效果,具体代码和图片如下:

 

这就是根据屏幕大小,调整适合的宽度。这个嵌套元素没有任何的宽度值声明,并且可以在没有干扰父元素的情况下展示需要的内边距,边框,外边距。

css盒子的延伸:div+css布局的思路
  传统的前台网页设计是这样进行的:根据要求,先考虑好主色调,要用什么类型的图片,用什么字体、颜色等等,然后再用Photoshop这类软件自由的画出来,最后再切成小图,再不自由的通过设计HTML生成页面,改用CSS排版后,我们要转变这个思想,此时我们主要考虑的是页面内容的语义和结构,因为一个强CSS控制的网页,等做好网页后,你还可以轻松的调你想要的网页风格,况且CSS排版的另外一个目的是让代码易读,区块分明,强化代码重用,所以结构很重要。假如你想说我的网页设计的很复杂,到后来能不能实现那样的效果?我要告诉你的是,假如用CSS实现不了的效果,一般用表格也是很难实现的,因为CSS的控制能力实在是太强大了,顺便说一点的是用CSS排版有一个很实用的好处是,假如你是接单做网站的,假如你用了CSS排版网页,做到后来客户有什么不满足,非凡是色调的话,那么改起来就相当轻易,甚至你还可以定制几种风格的CSS文件供客户选择,又或者写一个程序实现动态调用,让网站具有动态改变风格的功能。

关键点:实现结构与表现分离

  在真正开始布局实践之前,再来熟悉一件事——结构和表现相分离,这也用CSS布局的特色所在,结构与表现分离后,代码才简洁,更新才方便,这不正是我们学习CSS的目的所在吗?举个例来说P是结构化标签,有P标签的地方表示这是一个段落区块,margin是表现属性,我要让一个段落右缩进2字高,有些人会想到加空格,然后不断地加空格,但现在可以给P标签指定一个CSS样式:P {text-indent: 2em;},这样结果body内容部分就如下,这没有外加任何表现控制的标签:

很高兴跟大家分享到这里,今天就聊到这了,假如有需要指正与补充的地方,欢迎给我留言哟!谢谢!