现在我们已经熟悉了HTML和CSS。了解了它的基础。现在我们来更深入的了解元素在页面中的呈现和大小。
在这节课中,我们将会讨论什么是盒子模型,它的工作模式是怎样的。我们也会在课程中学习一些新的CSS属性,并且将介绍三种长度单位。
元素是如何显示的
在了解盒子模型之前,我们先来了解一下元素是如何显示的。在第二节课中,我们学习了块状元素和内联元素的差异。快速回顾一下,块状元素会另起一行,并占据所有可用的宽度,不管内容有没有。而内联元素会并排显示,宽度紧随内容变化而变化。块状元素通常用在大块的内容上,例如标题,结构元素。内联元素用在小块的内容上,比如将几句话加粗或斜体显示。
display属性
元素如何显示——例如块状元素,内联元素和其他元素——都由显示属性display
决定。每个元素都有一个默认的display
属性值。和其他属性值一样,这个属性值是可以被覆盖的。display
值有很多,其中最常用的是block
,inline
,line-block
和none
。
我们可以通过CSS选中元素并改变和重新声明元素的display
属性值。 若值为block
可以使元素成为块状元素显示。
p {
display: block;
}
将值设置为inline
,可以将元素转化为内联元素。
p {
display: inline;
}
inline-block
比较有意思,它可以使元素的所有块状元素的属性生效。但元素又按照内联元素显示,不会另起一行。
p {
display: inline-block;
}
inline-block
内嵌块元素有个重要的点,就是它们并非是首尾相接的。两个内嵌块元素之间存在小空隙。这个空隙虽然很恼人,但这是正常现象。我们会讨论为什么这个空隙存在,以及怎么消除。
最后是none
属性值,会完全隐藏元素,页面渲染的时候会当它不存在。任何被包裹在这个属性值元素内的元素都会被隐藏。
div {
display: none;
}
了解元素如何显示,以及怎么修改display
属性非常重要,因为它会影响盒子模型的呈现效果。讨论盒子模型的时候,我们会知道他们之间的差别,意义和影响。
什么是盒子模型?
根据盒子模型的概念,每个在页面上的元素都是一个拥有宽,高,内边距,边框和外边距的长方形盒子。
页面上每个元素都符合盒子模型的定义,所以它非常重要。我们使用一些新的CSS属性来来熟悉它。
使用盒子模型
每个元素都是一个长方形盒子,有几个属性能确定这个盒子的大小。盒子的核心属性是元素的宽高,这两个值可能是由元素的display
属性、元素的内容或具体的width
,height
属性值生成的。内边距padding
和边框border
拓展了元素的高宽。最后是我们定义的在边框外的外边距margin
。
盒子模型对应的CSS属性为:width
,height
,padding
,border
,margin
。
我们来看例子:
div {
border: 6px solid #949599;
height: 100px;
margin: 20px;
padding: 20px;
width: 400px;
}
根据盒子模型,元素的总宽度计算如下:
margin-right + border-right + padding-right + width + padding-left + border-left + margin-left
使用上述公式,就能算出示例中的高宽值
- Width:492px = 20px + 6px + 20px + 400px + 20px + 6px + 20px
- Height:192px = 20px + 6px + 20px + 100px + 20px + 6px + 20px
毫无疑问盒子模型是HTML和CSS很容易混淆的部分之一。
我们将width
的值设置为400
像素,但元素的实际宽度为492
像素。默认情况下,盒子模型是加法。因此想要确定盒子的实际大小,我们需要考虑将四面的内边距,边框,外边距都考虑进去。宽度不仅仅是width
属性的值,也要加上左右两侧的内边距,边框和外边距。
到目前为止,上述属性看着没什么实际意义。因为这只是为了澄清所有形成盒子模型的属性:width
,height
,padding
,border
和 margin
。
宽度和高度
每个元素都有默认的高度和宽度。虽然宽度和高度都有可能是0
像素,但默认情况下,浏览器会渲染每个元素的大小。元素的默认宽度和高度依赖于元素是怎么显示的。如果元素是页面布局的关键元素。那么它就需要设置具体的width
和height
属性值。这种情况下,只能指定非内联元素的属性值。
宽度
元素的默认宽度依赖于它display
属性的值。块状元素的默认宽度为100%
,占据整行空间。内联元素和内嵌块元素的宽度都随着元素的内容变化而变化。内联元素不具备固定的大小,所以width
和height
属性只有在非内联元素上才能生效。如下是为非内联元素设置宽度的例子:
div {
width: 400px;
}
高度
元素的默认高度取决于它的内容。元素根据内容需要进行垂直扩展或收缩。我们可以使用height
属性为非内联元素设置高度:
div {
height: 100px;
}
调整内联元素
请记住内联元素不支持width
和height
属性和与其相关的值。块状元素和内嵌块元素支持width
和height
属性和与其对应的值。
外边距和内边距
浏览器会根据元素设置其默认的外边距和内边距,使其更清晰易读。我们使用基于文本的元素来看一下这个现象。不同浏览器和不同元素之间的默认外边距和内边距可能存在差异。我们在第一课中有讨论过CSS重置,将这些差别调低,或使其为零。这样我们就可以从头开始定义我们需要的样式。
外边距
margin
属性设置一个元素的周围空间大小。外边距在元素边框外并且是完全透明的。外边距可以帮助我们将元素定位在页面的特定位置,并且可以与其他元素保持距离。 示例如下:
div {
margin: 20px;
}
margin
有一个特殊的现象,就是在内联元素中垂直外边距margin-top
和margin-bottom
不生效,在块状元素和内嵌块元素中有效。
内边距
padding
属性和margin
属性相似,只不过它在边框内部,padding
是为元素提供内部空间。示例如下:
div {
padding: 20px;
}
padding
属性和margin
属性不一致的地方是垂直内边距在内联元素中同样有效;虽然垂直内边距显示在元素基准线之上或之下,但是它确实是存在的。
内联元素的外边距和内边距
内联元素对内边距和外边距的实现和块状元素与内嵌块元素不同。外边距只有横向margin-left
和margin-right
有效。内边距在内联元素中完全生效,但是垂直内边距padding-top
和padding-bottom
在元素基准线上面或下面显示(译者注:内联元素加上垂直内边距之后,元素内部的内容部分在视觉上没有产生偏移)。
块状元素和内嵌块元素的外边距和内边距的显示是正常的。
外边距和内边距的声明方式
在CSS中,很多属性都有多种声明方法。普通的写法,就是一个属性一个值,一个个地列出来。但我们也可以使用简写,一个属性包含多个值。不是所有的属性都有简写,所以我们必须确保写出的属性和值的结构是正确的。
margin
和padding
有普通和简写两种书写方式。当元素四面设置相同的外边距时,可以使用margin
属性,并只指定一个值:
div {
margin: 20px;
}
如果上下外边距的值一致,左右外边距的值一致,我们可以输入两个值。 设置上下外边距的值在前面。以下例子将上下外边距设置为10
像素,将左右外边距设置为20
像素:
div {
margin: 10px 20px;
}
如果四个值都不一致,那么我们按照 上右下左 的顺序输入值。例如,我们为div
设置10
像素的顶部外边距,20
像素的右侧外边距,0
像素的底部外边距,以及15
像素的左侧外边距:
div {
margin: 10px 20px 0 15px;
}
若我们要设置多个值,优先考虑用margin
和padding
。但我们也可以用普通写法,输入一一对应的属性和值。每个属性名(该例子中是外边距和内边距)后跟随一个破折号-
以及要设置值的盒子的方向:top
,bottom
,right
和left
。
例如,padding-left
属性只接受一个值,设置元素的左侧内边距;margin-top
只接受一个值,设置元素的顶部外边距。
div {
margin-top: 10px;
padding-left: 6px;
}
当我们只想设置单边的margin
和padding
值时,这种普通写法是最好的选择。保持代码的精确性可以防止出现混淆。例如,我们是否只想将元素的上右左三侧的外边距设为0
,是否只想将底部外边距设为10
像素?
普通写法输入属性和值可以让目标更明确。当处理三个或以上的值时,缩写更有帮助。
外边距和内边距的颜色margin
和padding
属性是完全透明的,不可以设置颜色。但因为是透明的,所以透出了相关元素的背景色。元素外边距部分看到的颜色为它父级元素的背景色。元素内边距部分看到的颜色为该元素的背景色。
边框
边框在内边距和外边距之间,画出了元素轮廓。border
属性要求三个值:宽度,样式,颜色。边框属性简写时值的顺序为:宽度,样式,颜色。普通书写方式下,边框的三个属性名为:border-width
,border-style
和border-color
。普通书写方式因为是单个值,更容易修改和复写。
边框的宽度和颜色能分别使用第三节课中讨论过的长度单位和色值。
边框有很多不同样式。最常用的样式值为solid
,dashed
,dotted
和none
,但你可以在列表中看到很多其他的样式。
以下是边框设置示例:
div {
border: 6px solid #949599;
}
单侧边框
和margin
,padding
属性一样,也可以一次只设置元素一个方向的边框。使用属性名:border-top
, border-right
,border-bottom
和border-left
。它们的属性值和border
的属性值一样有三个:宽度,样式和颜色。如下所示:
div {
border-bottom: 6px solid #949599;
}
另外,单侧边框的样式也可以被细分,如下所示:
div {
border-bottom-width: 12px;
}
这些高度细分的边框属性名都由连字符分隔,由border单词开头,随后是边框的方向:top
,right
,bottom
,left
,最后是要设置的样式:width
,style
,color
。
border-radius
border-radius
可以使元素的边角变圆。
border-radius
接受多种长度单位,如百分比,像素,确定元素边角变圆的半径。单个值表示四个角的弧度一直,两个值按分别表示top-left
/bottom-right
和top-right
/bottom-left
,输入四个值按顺序分别表示:top-left
,top-right
,bottom-right
和bottom-left
。
思考border-radius
多个值的顺序时(包括margin
和padding
),记住它们是从左上角开始(margin
和padding
从上侧开始)按顺时针方向排序的。
div {
border-radius: 5px;
}
border-radius
属性也允许我们使用普通方法书写单个属性值。这些普通的属性以border
单词开通,跟着是边角的垂直位置(top
或bottom
),再是边角的横向位置(left
或right
),最后是半径radius
。例如,要设置<div>
右上角的边角半径,可以使用border-top-right-radius
属性:
div {
border-top-right-radius: 5px;
}
box-sizing
现在,在盒子模型中有一个附加属性。如果你设置了元素的width
为400
像素,并将padding
设置为20
像素,将border
设置为10
像素,那么实际的盒子宽度为460
像素。记住,盒子的宽度是width
,padding
和border
相加获得的。
但是在CSS3中,盒子模型有了一个不一样的计算方式。CSS3推出了box-sizing
属性,完全改变了盒子模型的运作模式和元素大小的计算方式。这个属性有三个主要值——content-box
,padding-box
和 border-box
——每个值对盒子模型大小的计算稍微有些不一样。
content-box
content-box
这个属性值是默认值。这个默认值和元素不加box-sizing
属性时的效果是一致的。元素从width
和height
属性的值开始计算,加上padding
,border
和margin
属性值获得盒子的实际尺寸。
div {
-webkit-box-sizing: content-box;
-moz-box-sizing: content-box;
box-sizing: content-box;
}
上例中box-sizing
属性前的连字符和字母是什么?
CSS3的推出后,浏览器逐步开始以加前缀的方式支持新属性和值,包括box-sizing
属性。随着部分CSS规范被浏览器广泛支持以及浏览器版本的更新,前缀的作用也越来越小,随着时间的发展将不再是一个问题。但在老版本浏览器中还是不可或缺的。
属性名和属性值都可以添加前缀。例如,上例中的box-sizing
属性名加了前缀。浏览器可以选择什么时候加前缀什么时候不加前缀,因此有些属性需要带有某浏览器的前缀,有些属性不需要。
接下来的课程中,若某个属性或值需要前缀,只会在介绍那个属性时添加使用(这有利于保持代码的简洁)。不过你们在实际写代码的时候不要忘记添加前缀。
最常见的几个浏览器前缀概括如下:
- Mozilla的火狐浏览器:
-moz-
- 微软的IE浏览器:
-ms-
- Webkit(谷歌的Chrome浏览器和苹果的Safari浏览器):
-webkit-
padding-box
属性值padding-box
时,元素将padding
属性值计算入width
和height
属性值内,改变了盒子模型计算模式。例如,元素的width
设置为400
像素,padding
值设为20
像素,最终元素实际的宽度还是400
像素。随着内边距的扩大,元素的内容区域会随着缩小,但是盒子实际大小并未发生改变。
如果我们增加border
或margin
,那么盒子的大小就是这些属性值加上width
和height
的值。例如,我们将元素的的width
设置为400
像素,每个方向的border
都设置为10
像素,padding
设置为20
像素,那么元素的实际宽度就为420
像素。
div {
box-sizing: padding-box;
}
随着CSS规范的更新,box-sizing
的值padding-box
已被弃用,我们不应再使用它。
Border Box
最后一个属性值是border-box
,它将border
和padding
都算在元素的width
和height
属性值内。例如,一个元素的width
为400
像素,每边的padding
为20
像素,border
为10
像素,最终元素的实际宽度仍然为400
像素。
若我们还增加了margin
属性,在获取盒子总大小时它的值需要做加法计算。不管box-sizing
的属性值是什么, 计算盒子总大小时任何margin
的值都需要做加法计入。
div {
box-sizing: border-box;
}
使用box-sizing属性
通常来说,box-sizing
最佳属性值为border-box
,这个属性值更易计算。如果我们将一个元素的width
为400
像素,那么不管你增加了边框还是内边距,它的大小都还是400
像素。
另外,我们也可以轻松的相对值。如果我们设置一个元素的宽度为40%
,元素每边的padding
值为20
像素,border
值为10
像素。那么尽管有地方设置了像素值,元素盒子的实际大小仍然为40%
。
唯一遗憾的是box-sizing
是CSS3的属性,并不是所有浏览器都支持,尤其是老版本浏览器。所幸随着浏览器版本更新,影响会越来越小。我们使用box-sizing
的时候,需要留意哪些浏览器会出现兼容问题。
开发者工具
大多数浏览器都有开发者工具。我们可以使用这些工具查看页面上的元素、这些元素的HTML结构
和CSS属性及它们值。它们大部分都有盒子模型图解。
在Chrome浏览器中打开菜单栏,找到“更多工具”选项中的“开发者工具”选项并点击它,浏览器窗口的底部会显示出一个视窗,其中提供了一些代码检查工具。
悬停或点击视窗中的元素节点,可以查看这个元素的信息。
选中一个元素后,在视窗右侧选中“Computed”选项,我们就可以看到我们选中的元素的盒子模型。
Chrome, Firefox,Safari以及其他浏览器中都有开发者工具。查看源代码可以学到很多东西。我在编写HTML和CSS的时候通常都会打开开发者工具,也常常用它查看分析其他网站的源代码。
练习
现在我们回到之前做的“样式讨论会”网站,并未它添加更多的内容。
- 首先,在
main.css
文件中添加一个box-sizing
属性,值设置为border-box
,这样可以使我们的元素更容易控制。在文件的页面重置样式下,添加一条注释,有助于网站布局。把它放在样式重置代码之下,是使其放在正确的层叠关系上。
在这里,我们可以使用通配符选择器*
,后面跟随带伪元素的选择器*:before
和*:after
,这样就可以选中页面中所有的元素,将其box-sizing
值设置为border-box
。请记住,box-sizing
是有前缀的,因为它是一个较新的属性。
/*
========================================
Grid
========================================
*/
*,
*:before,
*:after {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
- 接下来我们要创建一个可以作为我们元素容器的class属性。用它在不同的元素上设置共同的
width
,padding
属性,并将元素居中。 在我们通配符选择器下,创建一个新的class选择器名为container
。在选择器中将width
设置为960
像素,padding-left
和padding-right
设置为30
像素,上下外边距设置为0
,左右外边距设为auto
。container
告诉浏览器所有使用了这选择器的元素的宽度。左右外边距值设为auto
,再加之设好的宽度值,可以让浏览器自动计算出左右相等的外边距,元素就相对于页面居中了。最后设置左右内边距,使内容不紧贴元于素的边缘,为内容提供一点喘息的空间。
.container {
margin: 0 auto;
padding-left: 30px;
padding-right: 30px;
width: 960px;
}
- 现在
container
已经可以使用,我们把它添加到所有页面的<header>
和<footer>
元素上,所有页面包括index.html
,speakers.html
,schedule.html
,venue.html
以及register.html
页面。
<header class="container">...</header>
<footer class="container">...</footer>
- 接下来,我们将
container
添加到介绍会议的<session>
元素和包含<section>
作为子元素的`<section>元素上。
<section class="container">...</section>
- 另外,也将
container
添加到其他页面中包含有<h1>
元素的<section>
元素上。
<section class="container">
<h1>...</h1>
</section>
- 稍后我们还会再回来调整这些元素和class属性。现在我们先做另一件事。
- 现在我们的内容已经居中显示,接下来为元素创建纵向的间隔。我们先把标题和段落的底部外边距设置为
22
像素。我们将这个排版样式以及它的注释放在之前的容器样式之下。
/*
========================================
Typography
========================================
*/
h1, h3, h4, h5, p {
margin-bottom: 22px;
}
- 我们在此跳过了
<h2>
和<h6>
元素,因为设计中<h2>
不需要外边距,<h6>
这次我们不会用到。 - 现在我们在页面第一个
<section>
的底部放置一个按钮,并为其设置边框和圆角。
我们先添加一个<a>
元素,并将其的class属性值设为btn
和btn-alt
.
<a class="btn btn-alt">...</a>
- 接下来我们在排版样式之下为这两个属性值添加样式。
- 首先创建一个能被所有按钮共享的样式的class选择器
btn
。我们希望所有的按钮的border-radius
为5
像素,display
为inline-block
,并移除所有外边距。
/*
========================================
Buttons
========================================
*/
.btn {
border-radius: 5px;
display: inline-block;
margin: 0;
}
- 我们使用
btn-alt
为当前按钮设置特殊的样式。我们增加1像素的灰色边框,并且设置上下内边距为10
像素,左右内边距为30
像素
.btn-alt {
border: 1px solid #dfe2e5;
padding: 10px 30px;
}
- 我们在同一
<a>
元素中使用了btn
和btn-alt
,那么相应的样式都会渲染上去。 - 在主页上,我们为包含上述
<a>
元素的<section>
元素设置padding
样式。我们通过在其上添加一个class属性值hero
来实现。
<section class="hero container">
...
</section>
- 最后,我们在CSS文件分隔出一块专门设置主页的样式,然后
hero
添加padding
属性。
/*
========================================
Home
========================================
*/
.hero {
padding: 22px 80px 66px 80px;
}
现在我们的网站更加完整了,尤其是主页。
在此练习的第一步,我们提到了通配符选择器*
,它会选中所有的元素。相比于一一列出所有能想到的单个元素,不如使用它来选中所有的元素。
我们也在第一步中提到了伪元素:before
和:before
,它们可以在CSS中动态生成元素。我们不会当前项目中使用它。不过在通配符选择器中使用伪元素是很常用的做法。
演示源代码
这是练习的源代码。点击下载
总结
休息一下我们再继续。
将盒子模型所有内容学完并不容易。这些概念虽然只是简单介绍,却花了很多时间来掌握它。
这节课所学内容概括如下:
- 元素是如何显示的
- 什么是盒子模型,它为什么很重要
- 怎么修改元素的大小,包括宽度和高度
- 怎么添加元素的外边距,内边距和边框
- 怎么修改元素box-sizing及其对盒子模型的影响
现在我们对如何显示元素和设置尺寸有了更好的了解,接下来我们深入了解一下元素的定位。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。