天津渔网价格虚拟社区

Tony学前端(十):盒子模型,国王如何建城堡?

我的天空2018-09-15 12:39:40

(点击上方公众号,可快速关注)

本文共有5100字,预计阅读时间:25分钟

本系列累计34800

在文章末尾可以观看本课的视频



首先照例我们先复习一下上次都讲了哪些:


上节我们学习了文本相关的样式,包括:


  • 水平对齐:text-align

  • 文本缩进:text-indent

  • 字间距与词间距:letter-spacing、word-spacing

  • 大小写:text-transform

  • 划线装饰:text-decoration

  • 空白处理:white-spacing



我们已经学习完了常用的HTML,CSS也学习了一部分了,但是我们一直关注点是单个的页面元素。而对于一个网页来说,其总是由多个页面元素构成的,而此时,我们就必须要考虑元素间的位置关系,甚至于元素自身不同部分之间的位置关系(这句话现在不懂不要紧,本节正是来解决这个问题的)。


这节我们要学习CSS中一个非常非常重要的概念:盒子模型(Box Model,又称框模型)。如今,我们习惯于用DIV来进行页面布局,之前学习HTML的时候已经接触了一些,而使用DIV布局,则是离不开盒子模型。我们先看一个非常典型的页面:



该页面的结构很简单,我们一般用一个大的DIV来呈现背景图片,随后嵌套一个小的DIV来显示左上角的文字,因此基本上就是这个结构:


虽然结构简单,但是以我们已经学过的知识,却还是无法处理那个左上角的小DIV,因为很明显该DIV相对于大DIV的上侧及左侧均有距离要求,这个就是元素间的位置关系控制了。


另外再举个很平常的例子。我们已经学习过了按钮,那么请看以下两个按钮的区别:



左侧的按钮是默认按钮,而右侧的按钮我们发现“确定”两个字离边框的边距与默认的不同,特别是离下边框更远。而这个控制便是元素自身不同部分之间的控制了(按钮内容区与按钮边框之间的位置)。


接下来我们先来讲一个故事,随后引申出盒子模型。


从前有个国王,准备建立自己的城堡,他找到一块很不错的地方,此地依山傍水,北边是山脉,而南边是河流:


国王开始规划城堡,首先是宫殿,宫殿长、宽各三里


国王自己的宫殿位于城堡的中心位置,为了显示气派恢弘,国王声明:除了距城墙二里以内的范围为平民居住,其他都是宫殿的范围!


城墙当然要高大威猛,厚达二十丈


北面距山脉十里,南边离河流两里


东西两侧二十里都是自己的势力范围:


城堡建完了,从此国王过上了幸福的生活!


国王的宫殿已经建好了,我们看看宫殿的位置与哪些因素有关系,而这些因素在盒子模型中的相关术语又是哪些:


宫殿长、宽各三里,这就是元素的高度宽度


距城墙二里以内的范围为平民居住,这实际上是元素的内边距


城墙厚达二十丈,这是元素的边框宽度


北面距山脉十里、南边离河流两里、东西两侧二十里都是自己的势力范围,这是元素的外边距


因此在盒子模型中,元素尺寸及位置涉及到的因素包括:长度、宽度内边距边框以及外边距,其由内而外的结构就是:


我们首先来学习内边距(padding)。


元素的内边距位于边框与内容区之间,控制内边距的属性是padding


在之前的按钮示例中,正因为我们调整了按钮的内边距,才使得按钮内的文字与边框之间的距离显得与默认的不同。


以上三个按钮分别是默认状态、左侧内边距加大、上侧内边距加大的效果。


内边距分为上、下、左、右四个方向,我们可以单独控制,也可以统一控制:


四个方向内边距的属性名分别是:


因此,如果是这样的的CSS样式:


{
    padding-top:20px;
    padding-right:40px;
    padding-bottom:60px;
    padding-left:25px;
}


呈现的内边距效果就是:


当然这样的写法会觉得很繁琐,通常我们是使用padding属性,按照上、右、下、左顺时针的顺序来设置各内边距的值,各个内边距的值用空格隔开,因此以上示例如果用padding写的话,那就是:

{padding:20px 40px 60px 25px}


如果四个方向的内边距都一样,譬如都是20px,那就可以直接写成:

{padding:20px}


padding属性可以使用长度值或百分比,但是不能设置为负值,如果使用百分比,则是相对于父元素的宽度来计算内边距的值。


内边距我们就学习到这里,接下来讲边框:


元素的的边框是围绕元素内容及内边距的一条或多条线,我们用border属性来控制边框。我们可以控制边框的颜色与线条样式(实线或虚线等等)。


以上三个按钮的边框分别是:

  1. 默认样式。

  2. 宽度为2px的红颜色实线。

  3. 上左右边框为宽度1px的红色实线、下边框为宽度1px的蓝颜色虚线。


与内边距一样,边框也有四个部分:上、下、左、右。


边框也有三个方面可以设置:样式、宽度、颜色。


因此,设置边框的样式名就是这些部分的组合,例如:


border-top-style:solid

上边框样式为实线。


border-bottom-color:red

下边框颜色为红色。


border-width:10px

边框宽度为10px


border-width:10px 5px 12px 20px

上边框宽度为10px,右边框5px,下边框12px,左边框20px。


border:1px solid red

边框宽度为1px,样式为实线,颜色为红色。注意由于通常来说边框的四个方向的设置都是相同的,所以这种写法是边框最常用的写法。


对于边框颜色,如果设置为transparent的话,那么边框颜色为透明,即边框是看不到的,既然边框看不到,那还有什么作用呢?感觉多此一举。稍后我们会讲到透明边框的用途。


边框样式的种类比较多,我们来集中演示一下:


边框样式其实就是边框的线型,由属性border-style设置,取值比较多,我们来演示一下效果:


dotted:点状边框


dashed:虚线边框


solid:实线边框


double:双线边框


groove:3D凹槽边框


ridge:3D垄状边框


inset:inset边框


outset:outset边框


none:无边框


演示完了边框样式,我们再看两个边框需要注意的地方。


1、边框是绘制在背景之上的:


边框绘制在“元素的背景”之上,这意味着如果边框是“间断“的,譬如虚线边框,那么在边框的可见部分之间应显示出背景。


以上这个虚线边框,在虚线的间隔是可以看到背景图片的。


2、必须设置边框样式:


边框的设置必须要设置样式,并没有什么默认样式。否则即使设置了边框的宽度,也不会显示边框。


border-width:10px

border-color:red


仅仅这样设置是不行的,依然无法显示边框。


接下来我们要学习的是外边距(margin)。


围绕在元素边框的空白区域就是外边距,控制外边距的属性是margin


在之前的页面示例中,我们调整了内部文字所在的<div>的外边距,使得文字可以处于指定的位置。


另外,元素间的间隔也是由外边距控制,如以下四个元素A、B、C、D在页面上的相互位置:


那么实际上就是由元素不同方向上的外边距来控制相互间隔的。就像国王的城堡,东西二十里都是自己的势力范围,其他的城堡(这里就是元素)不能建立在这个范围之内。


与内边距一样,外边距也有四个方向,分别是上、下、左、右。


与内边距类似,外边距四个方向的属性名分别是:


因此参照内边距,一个元素的外边距样式可以这样写:

{
    margin-top:20px;
    margin-right:40px;
    margin-bottom:60px;
    margin-left:25px;
}


当然,聪明的小朋友马上就知道,实际上可以使用margin属性:

{margin:20px 40px 60px 25px}


如果四个方向的外边距都相同,譬如都是20px,则可以写成:

{margin:20px}


margin属性可以使用长度值或百分比,与内边距不同的是,外边距可以设置为负值,如果是负值,就会出现一个元素叠加在另一个元素之上的效果;如果使用百分比,则是相对于父元素的宽度来计算内边距的值。



如图,红颜色方框的margin-top设置为负值,所以就会向上移动而覆盖在黄颜色方框之上。


内边距、边框、外边距都说完了,接下来我们要学习一些相关的知识,首先谈谈值复制。


之前我们写padding或margin属性时,如果四个方向都是同值的情况下,只要写一个就可以了,这种写法叫做值复制,譬如:

{padding:10px}


实际上值复制的规则要更复杂一些,我们可以写一个、两个、甚至三个值,CSS会根据以下的规则来解析:


首先CSS是按照上、右、下、左的顺时针顺序来解析四个值。

{20px 15px 30px 10px}

上20px、右15px、下30px、左10px


如果缺少左侧的值,也就是说缺少第四个值,那么就会用右侧的值来代替左侧的值,此时左右两侧的值相同:

{20px 15px 30px}

上20px、右15px、下30px、左15px


如果缺少下侧的值,也就是说缺少第三个值,那么就会用上侧的值来代替下侧的值,此时上下侧的值相同,左右两侧的值也相同:

{20px 15px}

上20px、右15px、下20px左15px


如果继续缺少右侧的值,也就是只剩一个值了,那么上下左右均采用此值。

{20px}

上20px、右20px下20px左20px


用示意图表示:


接下来要讨论的是元素究竟有多大?


在之前的学习知识里,我们总是理解为块级元素的大小由width和height两个属性决定。但是在学习了盒子模型后,这个问题就变得复杂了,根据盒子模型,块级元素的可视大小由一下几个属性来决定。


下面我们演示一下宽度(width)的计算,而高度(height)的方法是一样的。


首先是元素的width


随后加上元素的padding


再加上元素的border


因此最后该元素的可视宽度是110px


以上显示的是元素的可视大小,如果要计算元素的占地大小,那还得把margin给计算进去。就像国王的城堡约定东西二十里都是自己的势力范围一样。margin将影响到元素在页面的定位,这个我们将在下一讲中详细学习。


接下来我们学习的是一个难点,也是实际开发中很容易被忽视的一个概念:外边距合并。


之前我们学习的都是单个元素,如果两个元素相邻的话,则这两个元素的间距计算就会变的复杂了。


当两个元素的外边距相遇时,将发生外边距合并,合并后的外边距等于发生合并的两个外边距中的较大者。


譬如以下两个元素,位于上侧的元素设置了下边距为30px;而位于下侧的元素设置了上边距为20px:


那么通常我们会认为这两个元素在垂直方向会相隔50px(30px+20px):


但是实际上,此时两个相邻的元素会发生垂直方向的外边距合并,实际上的外边距将取两个外边距中的较大者,那么这两个元素将相距30px。

要注意的是,元素的外边距合并只会发生在块级元素的垂直方向上


当一个元素包含另一个元素时,如果父元素没有边框也没有内边距的情况下,也会发生外边距合并。


譬如以下两个元素,父元素设置了上边距为20px,且没有边框与内边距;而子元素也设置了上边距为20px,那么这两个元素并不会像以下图示显示:



此时将发生外边距合并,两个元素的显示就像子元素没有设置上边距一样:


包含元素间的外边距合并尤其要注意,否则很容易会中招,回到我们最早的示例:


这就是一个典型的元素包含,子元素由于要在父元素区域内有一定的偏移,因此我们自然而然的会来设置子元素的外边距。譬如是这样:

child{margin:20px 0 0 20px}


由于父元素是显示一张图片,我们通常就不会设置边框与内边距,那么此时就会发生外边距合并了,页面的显示就不是我们的预期了:


我们发现图片内的文字顶格了,这就是外边距合并后,导致子元素的外边距设置无效了。


要解决这个问题,那我们可以有两种方法:

1、给父元素加上一个很窄的内边距,譬如设置为1px。


2、给父元素加上边框,并且把边框设置为透明(transparent),这样虽然存在边框,但是却不会显示出来,因此不会影响页面效果。


3、也可以通过定位或者浮动来调整子元素的位置,而定位将是我们下一讲将学习的内容。


后面暂时没有了,我们来总结一下,今天我们主要学习了:


盒子模型:

盒子模型的组成,内边距、边框、外边距。

内边距:

元素内容与边框间的空白、样式的值复制写法。

边框:

围绕元素内容与内边距的一条或多条线、边框样式。

外边距:

边框外围的空白、外边距合并。



今天我们讲述了一个非常重要的概念:盒子模型,又称为框模型。在HTML中,一切元素均为框。下一节我们将会学习元素的定位,通过掌握盒子模型与定位,我们就拥有的页面布局的能力,可以向页面实战迈出重要一步了。娃娃们加油,我们的目标是星辰大海!


点击观看本课视频,也可以在腾讯视频上搜索“Tony学前端”


 

本系列相关阅读:

Tony学前端(一):超文本是超人的文本吗?

Tony学前端(二):居然有懒人专用写法?

Tony学前端(三):专用收纳箱是指什么?

Tony学前端(四):说走就走?

Tony学前端(五):进了表格请整齐排列!

Tony学前端(六):更大的收纳箱!

Tony学前端(七):HTML终章,框架与表单!

Tony学前端(八):CSS起步,樱桃小丸子家的故事!

Tony学前端(九):文本到底有多少秘密?



针对ISO的打赏二维码,感谢大家对老潘的支持!