到目前为止,我们已经学习了CSS的一些基本语法。但是,对于页面布局来说,还是不够的。本章我们来学习一下布局,说白了,就是确定标签的位置和尺寸。在我们日常开发中,经常使用两种布局方式:一种定位布局,另一种是浮动布局。首先,我们先介绍定位布局,它涉及到的CSS属性就是position,它的常用属性值如下:
static 默认位置,即没有定位,按照标签顺序和类型(是否换行)展示
absolute 绝对定位,标签的位置相对于最近的已定位父标签
relative 相对定位,标签的定位是相对其默认位置。
fixed 固定定位,标签的位置相对于浏览器窗口是固定位置
首先是static默认方式,类似于“搭积木”方式,有的积木占据一行,有的平列一行。absolute、relative、fixed 这三种定位方式都是相对于某个基点的定位,不同之处仅仅在于这个基点是不同的,然后三种方式还要搭配 top、bottom、left、right这四个方向属性一起使用,最终确定标签的页面位置。接下来,我们来说一说绝对定位absolute,它是相对于上级标签(一般是父标签)进行偏移定位的,也就是说,它的定位基点是父标签。当然,这个父标签必须也有明确的定位方式。我们创建一个“05_pos.html”文件,代码如下:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>position</title>
</head>
<body>
<div style="width:200px;height:200px;background:#cdcdcd;"></div>
<div style="height:200px;background-color:#ff0000;"></div>
</body>
</html>
我们定义了两个div标签。第一个尺寸是200像素的灰色正方形,第二个只定义了高度200像素的红色长方形(div是行级标签,默认占据整个一行)。我们还是直接看效果吧。
这就是默认的static布局方式。我们在代码中写的先后顺序,就是网页中显式的先后顺序。当我们给这个行级标签<div>赋予指定宽度的时候,它就不在占据整个一行的位置了。但是这并不代表后面的新的<div>标签会填补空白的空间,因为<div>属于块级标签,后面新的<div>标签仍然会在下方显示出来,空白的空间依然存在。即使我们将红色的<div>换成一个行级标签(例如span),它也不会填充那个空白的空间。这就是为什么我们之前总是提到<div>标签总是“霸占”一行的意思了。
接下来,我们使用绝对定位absolute,代码如下:
<style type="text/css">
.box { position:absolute;left:0px;top:0px;width:300px;height:100px;background:#0000ff; }
</style>
<div style="width:200px;height:200px;background:#cdcdcd;"></div>
<div style="height:200px;background-color:#ff0000;"></div>
<div class="box"></div>
我们新增加了一个.box的样式,然后将其应用到一个新的<div>标签上面。我们定义了一个绝对定位absolute,然后左和上偏移都是0像素,也就是说,它是紧贴着父标签(<body>)的左上角,然后定义了其宽度和高度,而且为了更好的观察,我们让其背景为蓝色。接下来,我们就在浏览器中查看它的效果。
我们可以看到,这个蓝色的<div>紧贴着它的父标签<body>,并且覆盖在灰色<div>的上面。需要大家注意的是,这个位置以及覆盖灰色<div>的效果,跟“<div class="box"></div>”这句代码位置没有关系,即使我们放到之前两个div标签代码的上面,效果依然如此。
<div class="box"></div>
<div style="width:200px;height:200px;background:#cdcdcd;"></div>
<div style="height:200px;background-color:#ff0000;"></div>
我们刷新浏览器,发现页面效果没有任何变动。因为绝地定位是相对于父标签(这里就是<body>标签)而已的。只要父标签没有改变,那么当前<div>在网页中显式的位置就不会改变的(跟代码中的位置没有太大关系)。并且,使用绝地定位的<div>会覆盖默认方式的<div>。另外,还有一个问题,就是绝对定位的方向属性top和left是考虑盒式结构的内外边距空间的。因为我们之前提到过,<body>标签默认是8像素的margin外边距。默认方式布局的标签不会占据这一点点空间,但是绝对定位会占据。为了不被干扰,我们将body的外边距清零,增加如下代码即可:
<style type="text/css">
body { margin:0; }
.box { position:absolute;left:0px;top:0px;width:300px;height:100px;background:#0000ff; }
</style>
<div class="box"></div>
<div style="width:200px;height:200px;background:#cdcdcd;"></div>
<div style="height:200px;background-color:#ff0000;"></div>
我们直接看效果
这个效果就非常满意了。
接下来,我们继续定义另一个新的<div>标签,代码如下
<style type="text/css">
body { margin:0; }
.box { position:absolute;left:0px;top:0px;width:300px;height:100px;background:#0000ff; }
.box2 { position:absolute;left:0px;top:0px;width:300px;height:100px;background:#00ff00; }
</style>
<div style="width:200px;height:200px;background:#cdcdcd;"></div>
<div style="height:200px;background-color:#ff0000;"></div>
<div class="box"></div>
<div class="box2"></div>
我们又定义了一个新的 .box2 样式,同样也使是绝对定位,左上偏移0像素,尺寸是300*100像素,背景色是绿色。我们按照绝对定位absolute的定义理解,这两个标签div是相对于父标签<body>的基点的,因为父标签没有改变,所以他们应该重叠在一起。
我们发现,新的绿色的div确实与之前蓝色的div重叠,并且覆盖了上面。如果我们颠倒两个div的话,如下所示:
<div class="box2"></div>
<div class="box"></div>
我们就会发现,他们的位置是不变的,只是蓝色div覆盖了绿色的div。由此可见,相同绝对定位的标签内容,后面的会覆盖前面的(这个就取决于两者在代码中的位置了),这个应该很容易理解。那么,如果不让他们覆盖在一起,而是蓝色在上面,绿色在下面呢?非常简单,只需要修改绿色<div>中的top属性值。
<style type="text/css">
body { margin:0; }
.box { position:absolute;left:0px;top:0px;width:300px;height:100px;background:#0000ff; }
.box2 { position:absolute;left:0px;top:100px;width:300px;height:100px;background:#00ff00; }
</style>
<div style="width:200px;height:200px;background:#cdcdcd;"></div>
<div style="height:200px;background-color:#ff0000;"></div>
<div class="box"></div>
<div class="box2"></div>
注意到,我们将绿色div的样式“.box2”中的top值由0修改为了100像素,这个数值正好是上面蓝色div的高度。那么,他们两个就应该都可以显示出来了。
这种情况下,即使我们再次颠倒两个<div>的代码位置,他们也不会存在覆盖的情况了。
接下来,我们继续添加另一个新的<div>标签。
<style type="text/css">
body { margin:0; }
.box { position:absolute;left:0px;top:0px;width:300px;height:100px;background:#0000ff; }
.box2 { position:absolute;left:0px;top:100px;width:300px;height:100px;background:#00ff00; }
.box3 {position:absolute;left:0px;top:0px;width:50px;height:50px;background:#ff0000;}
</style>
<div style="width:200px;height:200px;background:#cdcdcd;"></div>
<div style="height:200px;background-color:#ff0000;"></div>
<div class="box"></div>
<div class="box2"><div class="box3"></div></div>
我们新增加了一个“.box3”的样式,是一个尺寸为50像素的红色正方形。我们将它应用到绿色div的子标签上面。也就是说。红色小<div>的父标签是绿色的<div>标签。
我们发现,新的红色小<div>确实在父标签绿色<div>的左上角位置。此时,我们移动一个父标签绿色<div>的位置,代码如下:
.box2 { position:absolute;left:50px;top:100px;width:300px;height:100px;background:#00ff00; }
我们修改绿色<div>的样式“.box2”的左边距离left的数值为50像素,也就是让绿色<div>向右移动50像素。我们直接查看效果:
我们发现绿色的<div>确实移动了,露出了下面的灰色<div>,同时子标签红色小<div>也跟随移动了。但是,我们注意的是,红色小<div>与父标签绿色<div>的相对位置不变。这个案例就说明了,绝对定位的使用,以及它与父标签的关系。这里还需要大家注意的一个条件就是,这个父标签也必须有明确的定位方式,比如 absolute 或者 relative,肯定不能是默认的static没有定位。我们如何证明呢?我们将父标签绿色<div>的“.box2”样式中的定位属性注释掉,如下所示:
.box2 { /*position:absolute;left:50px;top:100px;*/width:300px;height:100px;background:#00ff00; }
我们刷新浏览器查看效果
首先,红色小<div>的参考父标签不在是绿色的<div>,即使它名义上还是父标签。但是因为没有定位,所以红色小<div>就会继续向上寻找父级,最终就是<body>标签了。因此红色小<div>就跑到了整个页面<body>的左上方了。由于绿色父标签没有了绝对定位,改成了默认定位,所以它就显示在了最下方了。在我们日常开发中,我们尽量避免上面的问题发生,如果我们想要使用绝对定位的话,最好看看它的父标签是否有明确的定位属性。
接下来,我们来说一说 relative 相对定位,它是相对于默认位置(即static时的位置)进行偏移,即定位基点是标签的默认位置。我们创建“05_pos2.html”新文档,以下代码:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>position2</title>
</head>
<body>
<style type="text/css">
body { margin:0; }
.box { width:200px; height:200px; background:#cdcdcd; }
</style>
<div class="box"></div>
</body>
</html>
我们没有进行定位的设置(即static时的位置),就是一个普通的宽度和背景浅灰色的设置。
我们可以看到,正常情况下,这个浅灰色的<div>就按照顺序排列页面中,这就是默认位置。接下来,我们将红色<div>的定位设置为 relative 相对定位的话,那么我们在使用top或者left进行偏移设置的时候,就是相对于上面的默认位置而言的。
.box { position:relative;top:20px;left:0; width:200px; height:200px; background:#cdcdcd; }
我们只设置了top方向偏离20像素,我们来查看它的效果:
我们发现,浅灰色的<div>确实偏移了原来位置,向下移动了20像素的距离。有些人可能就会产生疑问,使用绝对定位也是这种效果啊,凭什么说相对定位的参考点是自己默认位置,而不是父标签<body>呢?从目前来看,好像相对定位与绝对定位没有任何区别。那么接下来,我们就继续添加代码。
<style type="text/css">
body { margin:0; }
.box { position:relative;top:20px;left:0; width:200px; height:200px; background:#cdcdcd; }
.box2 { position:relative;top:0px;left:0px;width:300px;height:200px;background:#0000ff;}
</style>
<div class="box"></div>
<div class="box2"></div>
我们添加了一个新的box2的样式。我们按照上面学习绝对定位的方式来验证以下,两者的区别。在绝对定位中,上面的两个<div>应该会重合,那么相对定位是什么效果呢?
我们发现,两者并没有重合,说明相对定位和绝对定位是不一样的。为什么蓝色的<div>显示在浅灰色的<div>下方呢?首先,我们还有知道蓝色的默认位置在哪里?我们注释掉蓝色的相对定位代码,如下代码:
.box2 { /*position:relative;top:0px;left:0px;*/width:300px;height:200px;background:#0000ff;}
我们刷新浏览器查看
我们发现两个<div>的位置没有发生变化,只是灰色的覆盖了蓝色一部分区域。请注意,上图中蓝色显示的位置就是其默认位置,就是在灰色的默认位置的下面。请大家注意的是,是在灰色默认位置的下面。由于我们灰色向下移动了20像素,因此蓝色就向上跟他重合了20像素的部分。我们之前讲过,绝对定位的优先级大于默认定位,其实相对定位也是如此。所以,灰色的<div>在重复部分是覆盖掉了蓝色的<div>。因为灰色<div>是相对定位,而蓝色<div>是默认定位。如果我们解开注释,恢复蓝色<div>的相对定位,那么两者就是平级关系,但由于蓝色<div>位于灰色<div>的代码下面,所以蓝色会覆盖灰色。也就是说,如果两个<div>发生重合的话,那么重合的部分,就按照代码书写位置,后面的覆盖前面的。这个法则适用于相对定位,也适用于绝对定位。
我们给蓝色<div>指定相对定位,并且top=0,left=0的时候(没有偏移),那么它就仍然在它原来的默认位置。假如,我们修改top值为20像素的话,那么蓝色<div>就应该向下偏移20像素,也就是相对于现在的位置向下偏移。
.box2 { position:relative;top:20px;left:0px;width:300px;height:200px;background:#0000ff;}
我们修改top数值为20像素,然后查看效果
这样,两者不在重叠了,蓝色<div>刚好位于灰色<div>的下方。也就是说,两个<div>都全部基于自己默认位置向下移动20像素。
接下来,我们给浅灰色<div>添加一个子标签,我们先看看这个子标签的默认位置在哪里
<style type="text/css">
body { margin:0; }
.box { position:relative;top:20px;left:0; width:200px; height:200px; background:#cdcdcd; }
.box2 { position:relative;top:20px;left:0px;width:300px;height:200px;background:#0000ff;}
.box3 { width:100px; height:100px; background:#ff0000; }
</style>
<div class="box"><div class="box3"></div></div>
<div class="box2"></div>
我们刷新浏览器
默认情况下,子标签会从上到下,从左到右的排列在父标签里面,这与父<div>默认排列于<body>中是一回事。接下来,我们给红色的子标签添加相对定位,代码入下
.box3 { position:relative;top:20px;left:0;width:100px; height:100px; background:#ff0000;}
我们发现红色的子标签向下移动了20像素。那么,如果我们移动父标签,会有什么效果呢?
.box { position:relative;top:20px;left:20px; width:200px; height:200px; background:#cdcdcd; }
我们修改父标签浅灰色的样式“.box”中的left值为20像素。
我们发现浅灰色父标签确实向右移动了20像素,而且红色子标签也跟随移动了,但是父子标签之间的间距没有改变。这与我们之前的绝对定位中的父子关系是一样的。也就是说,不管是相对定位,还是绝对定位,父标签的移动会将所有子标签同步移动,但是父子标签的相对间距是不变的。这也是一条重要的法则。
在日常的布局中,我们经常搭配绝对定位和相对定位一起使用。如果我们定义个<div>使用了relative相对定位,但是其top,left,right,bottom都是0(或者干脆不写),那么这个<div>标签的位置根本没有任何变化。这样的好处在于,我们使用了定位,但是仍然保持标签的自然摆放方式,简单又灵活。重要的一点是,当我们使用绝对定位的时候,我们最后给父标签给定一个明确的定位(比如说relative相对定位)。
接下来,我们说说 fixed 固定定位方式,它是相对于浏览器窗口进行偏移,即定位基点是浏览器窗口。这会导致标签的位置不随页面滚动而变化,好像固定在网页上一样。我们在浏览一些网页的时候,经常会遇到左右两边的广告内容,他们会一直停留在浏览器的固定位置,这就是通过fixed固定定位方式实现的。我们看看如下代码:
<style type="text/css">
.box4 { position:fixed;top:20px;left:0px;width:100%;height:50px;background:#00ff00; }
</style>
<div class="box4"></div>
注意,当我们使用定位以后,<div>标签的默认宽度不在是一整行,此时我们可以使用“width:100%”的方式让它的宽度重新占据一整行。请注意,这里我们只是说<div>的宽度值不在是一整行,而不是说它“不霸占”一整行了。我们将这个绿色的<div>标签固定在了距离网页顶部20像素的位置,那么当网页长度超过屏幕的时候,我们需要滚动才能看到屏幕下面的内容的时候,我们发现这个绿色的<div>始终会在那个位置不变。为了能让网页长度超过屏幕高度,我们在“<div class="box4"></div>”增加一堆<br/>标签来增加网页长度。
当我们移动滚动条的时候,绿色的div始终在网页内容最上面20像素的位置。
总结:通过上面的三种常用的定位方式,我们基本上可以做到,让一个<div>随心所欲的放置到页面中的任何一个位置上。在我们日常的开发过程中,建议优先使用相对定位,然后是绝对定位,如果想要实现固定位置的话,就使用固定定位。 同时,我们还可以借助 margin 和 padding 也可以达到一定的布局效果。例如,我们想让上下两张图片间隔20像素,我们可以使用相对定位来实现,也可以设置上图片的下边距,或者下图片的上边距。实际上,在日常开发中,我们也经常这样使用内外边距。
本课程的内容可以通过CSDN免费下载:https://download.csdn.net/download/richieandndsc/88962032