- CSS用以描述HTML文档的样式,让页面更加美观
- 如何引入CSS代码
- CSS的基本语法
- 如何使用CSS的选择器
这里我们来理解一下CSS的基本原理。先想象一下如果自己来开发一个CSS的渲染引擎,我们会怎么来做?得到了HTML元素构成的一个树状结构,首先要做的事情是不是就要在一个页面上把各个HTML元素按照一定的顺序排列出来?所以我们就先从如何排列HTML元素开始了解吧。
盒模型
如果不写任何CSS代码,HTML文档中的元素是按照出现顺序显示的,从上到下,从左到右。这是很自然的处理方式,我们在纸上或者在电脑上写文章也都是按照这种顺序。
具体到一个特定HTML元素的显示,它会被呈现为一个矩形,CSS标准中称之为Box。一个HTML元素占据空间的大小由盒模型决定。在盒模型中,一个盒子由内容、内边距、边框和外边距共同构成,其尺寸也是这四部分的尺寸之和。
看下面的代码:
<style>
.box {
width: 100px;
height: 100px;
border: 10px solid blue;
padding: 30px;
margin: 40px;
background: yellow;
}
</style>
<div class="box"></div>
这段代码的效果如下:
在Chrome的开发者工具中我们可以直观地看到class为box的div元素的盒模型,如下图所示:
在上面这个例子中:
- 内容区域是最内部的浅蓝色方框部分,是由width: 100px; height: 100px;定义的,即高为100px,宽为100px
- 内边距区域由padding属性定义
- 边框区域由border属性定义
- 外边距区域由margin属性定义
margin和padding都有上、右、下、左四个方向的宽度,四个方向的宽度大小可以分别设置。比如对于padding对应有padding-top, padding-right, padding-bottom, padding-left,margin同理。
注意,例子中width属性定义的是内容的宽度,不包含边距、边框。然而在IE中width定义的是内容+内边距+边框的宽度。 IE的做法相对更加符合直观的感觉。width的计算方式是由box-sizing属性来定义的,如果设置一个元素为box-sizing: border-box; ,元素的内边距和边框就会包含在width宽度内。
如果想要页面上所有的元素都以相同的方式定义高度和宽度,可以使用如下代码:
* {
box-sizing: border-box;
}
HTML元素类型
HTML元素占据一个矩形区域,接下来你可能会问一个问题,相同层次的两个HTML元素,它们是在同一行左右排列,还是分布在不同的行上下排列呢?这时我们需要了解一下HTML元素的两种类型了。
HTML中的标签元素分为两种类型:
- 块(block)元素
- 行内(inline)元素
块元素的特点有:
- 每个块元素都从新的一行开始,独占一行
- 元素的高度、宽度、行高以及顶和底边距等属性都可设置
- 默认的高度与父元素的宽度一致,即width默认为100%
- 可以容纳行内元素和其他块元素
比如<div>、<p>、<ol>、<ul>、<table>、<form>等元素都是块元素。
行内元素具有如下特点:
- 和其他行内元素都在一行上
- 元素的高度、宽度、行高及顶部和底部边距等属性不可设置
- 元素不能设置高度,宽度就是它包含的文字或图片的宽度
- 行内元素只能容纳文本或者其他行内元素
比如<a>、<span>、<br>、<em>、<strong>等元素都是行内元素。
来看一个简单的例子,如下代码,在class为parent的<div>下分别有四个元素,一个<span>,一个<a>和两个<div>:
<style>
.box {
width: 50px;
height: 50px;
border: 20px solid blue;
padding: 30px;
margin: 40px auto;
background: yellow;
}
.parent {
padding: 10px;
border:1px solid green;
text-align:center;
}
</style>
<div class="parent">
<span>天码营</span>
<a href="https://course.tianmaying.com/spring-mvc">Spring MVC实战训练</a>
<div class="box"></div>
<div class="box"></div>
</div>
这段代码的显示效果如下:
<span>和<a>元素是行内元素,因此它们在同一行。而<div>元素是块元素,两个<div>各自独占一行。
所以浏览器渲染页面时,碰到行内元素就会向右排列,处理块元素就会向下排列。但是这样简单的排列方式是很难做出复杂的布局的,所以这时候我们需要display属性了。
设置元素的显示方式:display属性
行内元素与块元素也可以相互转化,在CSS中将行内元素可以通过display: block设置为以块元素的方式显示,我们还可以继续设置该元素的长宽等原本不能设置的属性。同样,我们也可以设置块元素的display属性为display: inline,这样块元素就可以再同一行显示了。
比如如下代码:
<style>
.box {
border: 2px solid blue;
background: yellow;
padding: 5px;
display: inline; /*将div设置为inline*/
}
.parent {
padding: 10px;
border:1px solid green;
text-align:center;
}
.parent a, .parent span {
display: block; /*设置为block*/
margin: 50px;
}
</style>
<div class="parent">
<span>天码营</span>
<a href="https://course.tianmaying.com/spring-mvc">Spring MVC实战训练</a>
<div class="box">12345</div>
<div class="box">67890</div>
</div>
显示效果如下:
通过把<span>和<a>元素设置为display: block可以让它们各自占据一行;而把<div>元素设置为display:inline可以让它们在一行内排列。对于大部分HTML元素来说,如果设置display:inline,它的高、宽、行高、上下边距就无法设置了。
display还有其它取值,除了block和inline,其中另外两种很常见的取值为:
- none: 隐藏元素;
- inline-block:以block的方式渲染,以inline的方式放置;
none是最容易理解的取值。当一个元素的display属性被设为none时,该元素不会被渲染,也不会占位,就像不存在一样。对布局不会产生任何影响。它和visibility属性不一样。把display设置成none不会保留元素本该显示的空间,但是visibility: hidden;还会保留。
display: inline-block修饰的元素称之为行内块元素,它们会像行内元素一样在同一行显示,又可以像块元素一样设置高、宽、行高、边距。
比如在上面的例子中,如果将<div>设置为display: inline-block,我们就可以设置高度和宽度了,如下代码:
<style>
.box {
border: 2px solid blue;
background: yellow;
padding: 5px;
width: 200px; /*div设置为inline-block时,可以设置宽度*/
height: 50px; /*div设置为inline-block时,可以设置高度*/
display: inline-block; /*将div设置为inline-block*/
}
.parent {
padding: 10px;
border:1px solid green;
text-align:center;
}
.parent a, .parent span {
display: block; /*设置为block*/
margin: 50px;
}
</style>
<div class="parent">
<span>天码营</span>
<a href="http://course.tianmaying.com/spring-mvc">Spring MVC实战训练</a>
<div class="box">12345</div>
<div class="box">67890</div>
</div>
设置元素位置:postion属性
目前为止我们已经了解了块元素、行内元素和行内块元素默认的显示方式,它们会按照流的方式从上往下从左往右进行布局,每一个元素都会获得自己的显示位置。如果你希望修改元素默认的定位行为,那就需要position属性了。
postion属性具有如下取值:
-
inhert:规定应该从父元素继承 position 属性的值
-
static:默认值。没有定位,元素出现在正常的流中,会忽略top, bottom, left, right 或者 z-index等移动元素位置的声明
-
relative:相对于元素本身正常位置(即static方式下的位置)进行定位,比如right:10px 会让元素的向右侧移动20 像素
-
absolute:绝对定位,相对于第一个非static的祖先元素进行定位,元素的位置通过 left, top, right 以及bottom 属性进行设置。
-
fixed:生成绝对定位的元素,相对于浏览器窗口进行定位。元素的位置通过 left, top, right 以及 bottom 属性进行规定。
一个HTML网页都可以看成是由一层一层页面元素堆叠起来的,如下图所示:
这里X轴和Y轴定义的是在页面上的位置,而Z轴则定义的是层叠的层次,对应于z-index的值,如果两个元素在XY平面上有重叠,则z-index值大的元素会覆盖值更小的元素。
position: relative 的元素依然在普通流中,位置是正常位置,只不过可以通过设置left、right等属性移动元素,这种移动是会影响其他元素的位置的。
但是对于postion: absolute和position: fixed的元素,具有以下特性:
- 该元素往 Z 轴方向上移了一层,元素脱离了普通流,所以不再占据原来那层的空间,还会覆盖下层的元素。如果不想覆盖下层的元素,可以减少z-index的值以达到效果。
- 该元素将变为块级元素,相当于给该元素设置了 display: block;,比如给一个内联元素,如 <span> ,设置 absolute之后发现它可以设置宽高了。
- 如果该元素是块级元素,元素的宽度由原来的 width: 100%(占据一行),变为了 auto。
如下代码:
<style>
.box1 {
width: 100px;
height: 100px;
margin: 40px auto;
background: blue;
}
.box2 {
width: 100px;
height: 100px;
margin: 40px auto;
background: red;
position: relative;
left: 50px;
}
.box3 {
width: 30px;
height: 30px;
background: yellow;
position: fixed;
right: 50px;
bottom: 50px;
}
.parent {
padding: 10px;
border:1px solid green;
text-align:center;
}
</style>
<div class="parent">
<div class="box1"></div>
<div class="box2"></div>
<div class="box3"></div>
</div>
会显示如下效果
- 蓝色方块为默认定位
- 红色方块为relative相对定位,相对于默认定位的位置,向右侧移动了50px
- 黄色方块的fixed定位,始终会出现在页面的右下角(之前你是不是一直奇怪右下角一直有个黄色方块?)。
更复杂的浮动布局:float属性
除了absolute和fixed定位,还有一种方法可以使得元素脱离普通文档流,那就是float属性了。顾名思义,你可以让一个元素在页面流中浮起来,不占据原来元素的空间。
float的取值一共有四个:
- left:向左浮动
- right:向右浮动
- none:不浮动
- inherit:继承父元素值
设置了float属性的元素具有以下一些特点:
- 浮动元素的下一个兄弟元素会紧贴到该元素之前的非浮动元素之后;如果下一个兄弟元素如果也设置了同一浮动方向,则会紧随该元素之后显示。
- 如果该元素的下一个兄弟元素中有内联元素(通常是文字),则会围绕该元素显示,形成类似"文字围绕图片"的效果。
- 该元素将变为块级元素,相当于给该元素设置了display: block;。
浮动效果
下面我们通过几个例子来看看float会带来什么效果。
我们先来展示三个平铺的<div>:
<style>
.box1 {
width: 100px;
height: 100px;
background: blue;
}
.box2 {
width: 100px;
height: 100px;
background: green;
}
.box3 {
width: 100px;
height: 100px;
background: red;
}
.parent {
padding: 10px;
border:1px solid green;
text-align:center;
}
</style>
<div class="parent">
<div class="box1"></div>
<div class="box2"></div>
<div class="box3"></div>
</div>
可以看到蓝色、绿色和红色方块从上往下排列,典型的块元素排列方式。
现在让我们把蓝色方块设置为float:right,效果如下:
如果将蓝色方块设置为float:left,则蓝色方块会遮挡绿色方块,效果如下:
如果三个方块都向左浮动,设置float:left,效果如下:
注意此时三个方块的父<div>元素是没有高度的,因为三个脱离了普通文档流,父<div>元素此时并没有包含这三个方块。
如果父<div>的宽度不够容纳三个方块,出出现什么情况呢? 我们将parent的width改为250:
<style>
.box1 {
width: 100px;
height: 100px;
background: blue;
float:left;
}
.box2 {
width: 100px;
height: 100px;
background: green;
float:left;
}
.box3 {
width: 100px;
height: 100px;
background: red;
float:left;
}
.parent {
padding: 10px;
border:1px solid green;
text-align:center;
width: 250px; /*这里设置宽度为250px,无法容下3个100px宽度的方块*/
}
</style>
<div class="parent">
<div class="box1"></div>
<div class="box2"></div>
<div class="box3"></div>
</div>
如果将蓝色方块的高度改为150px,则蓝色方块会挡住红色方块向最左侧浮动,效果如下:
文字环绕效果
如果该元素的下一个兄弟元素中有内联元素(通常是文字),则会围绕该元素显示,形成类似"文字围绕图片"的效果。即虽然浮动会让元素脱离文档流,但是文本内容会受到浮动元素的影响。
<style>
.box1 {
width: 100px;
height: 100px;
background: blue;
float:left;
}
.box2 {
width: 200px;
height: 200px;
background: green;
}
.parent {
padding: 10px;
border:1px solid green;
text-align:center;
width: 250px;
}
</style>
<div class="parent">
<div class="box1"></div>
<div class="box2">天码营秉承让技术学习更加高效和便捷的使命,致力于打造新一代的技术学习服务平台,提供创新并且专业的内容、工具与服务,帮助学习者与从业者实现个人价值。</div>
</div>
虽然蓝色方块浮动起来覆盖了绿色方块,在绿色方块中的文字并不会被覆盖。
清除浮动
clear属性用以清除浮动带来的影响。比如上一个示例中,为了让绿色方块不被蓝色方块遮挡,可以给绿色方块设置clear: left,即清除向左浮动带来的影响。你还可以用right或both来清除向右浮动或同时清除向左向右浮动,表示元素的哪些边不挨着浮动元素。
<style>
.box1 {
width: 100px;
height: 100px;
background: blue;
float:left;
}
.box2 {
width: 200px;
height: 200px;
background: green;
clear: left;
}
.parent {
padding: 10px;
border:1px solid green;
text-align:center;
width: 250px;
}
</style>
<div class="parent">
<div class="box1"></div>
<div class="box2">天码营秉承让技术学习更加高效和便捷的使命,致力于打造新一代的技术学习服务平台,提供创新并且专业的内容、工具与服务,帮助学习者与从业者实现个人价值。</div>
</div>
天码营秉承让技术学习更加高效和便捷的使命,致力于打造新一代的技术学习服务平台,提供创新并且专业的内容、工具与服务,帮助学习者与从业者实现个人价值。
对元素清理实际上为前面的浮动元素留出了垂直空间,这可以解决我们之前的一个问题。三个float:left的<div>因为不会占据空间,因此它们的父<div>高度为0。为了让父<div>包裹住三个方块,可以增加一个空的<div>并设置clear: both;。
<style>
.box1 {
width: 100px;
height: 100px;
background: blue;
float:left;
}
.box2 {
width: 100px;
height: 100px;
background: green;
float:left;
}
.box3 {
width: 100px;
height: 100px;
background: red;
float:left;
}
.parent {
padding: 10px;
border:1px solid green;
text-align:center;
}
</style>
<div class="parent">
<div class="box1"></div>
<div class="box2"></div>
<div class="box3"></div>
<div style="clear:both;"></div>
</div>
从效果中可以看到,三个色块都包含在父<div>中了。
总结
介绍了CSS中的盒模型,display、postion和float几个用于布局的关键属性,并且理解其基本原理,你已经了解CSS部分最关键的知识了,接下来你可以深入到各个CSS属性的细节中去了,在实践过程中可以逐渐增强自己CSS的功力,积累更多经验。