欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

通俗易懂CSS(一)-相对定位和绝对定位position和float

程序员文章站 2022-04-25 19:54:46
...

一、简述:

CSS中有三种基本的定位机制:普通流、浮动和绝对定位。我们先看看他们的解释和描述:

普通流:默认情况下,所有框都在普通流中定位。按照你所写的html,顺序的排列,块级元素从上到下一个接一个地排列;块级元素之间的垂直距离由其定义的margin-top,margin-bottom决定。行内元素则在一行中水平布置。利用margin-left/right,padding-left/right,来调整它们之间的水平距离。

相对定位:position:relative;如果一个元素的设置该属性为relative,那么就**了该元素left和top属性,利用这两个属性,该元素就相对于它自身原本在普通文档流中的位置进行偏移,但无论如何进行移动,元素仍然占据原来的空间,仍然属于普通流。

绝对定位:position:absolute;绝对定位使元素的位置与文档流无关,因此不占据空间。普通文档流中的其他元素在布局的时候就像绝对定位的元素不存在时一样,绝对定位的元素的位置是相对于最近的已定位祖先元素(position:relative/absolute)。如果元素没有已定位的祖先元素,那么它的位置相对于最初的包含块.同时因为绝对定位的框与文档流无关,所以它们可以覆盖页面上的其他元素。可以通过设置z-index属性来控制这些框的堆放次序。z-index值越高,框在堆中的位置就越高

浮动模型。浮动的元素脱离普通文档流,向左或者向右移动,直到它的边缘碰到包含框或者另一个浮动框的边缘。因为浮动框不在文档的普通流中,所以文档的普通流中的块框表现得就像浮动框不存在一样。

二、分析

我们来建一个简易的模型来帮助我们理解和记住他们之间的关系:

通俗易懂CSS(一)-相对定位和绝对定位position和float

如图,static(包含static+非float、static+float)、absolute、relative(包含relative+非float、relative+float)的层叠效果,像是一个三明治,我们就站在面包的上面看这个面包。

想象下:static+非float比作一条可以注水成冰的河流,static+float是冰上浮动的木头盒;absolute是夹心层,可以插入很多层的彩色激光层,无形且可以穿透的光层;relative是static基于激光层的对称的倒影层(relative+float是static+float的投影层,ralative+非float是static+非float的投影层),投影层可以通过left、top等产生位置偏移。不过因为是投影,就算设置了left、top等产生偏移,跟其他的relative也只会出现重叠,而不是相互挤压。

下面我们来详细阐述下(下述示例见“四、示例代码”):

(一)、先理解清楚static+非float、static+float定位规则(先忽略上面的absolute和relative层来看问题);

1、static+非float区域(如果div没有设置position、或者标注为position:static)是像一条河流,里面可以按块分区域注水结成冰块。我们知道div是块级元素,所以注入水结成冰的时候,都是按整行设置围栏注入水的(即使div设置了宽度,未注入的地方也会被占据位置)。如下图:虽然我们看到的红色和绿色只有左边小块,但是占据了整行。

通俗易懂CSS(一)-相对定位和绝对定位position和float

如果先布局的float和absolute的对象,因为下面对应的static+非float区域是空的,再添加static+非float区域时会在float对象下面开始填充;如果先布局static+非float,则会成了一个隔离栏带,之后的需要重新换新行排列。如上图中的黑色就算是absolute也要新行里面布局,如果float对象也是如此。

换言之:但是当static+非float有空的区域才可能有上面的float对象、absolute。

2、static+float,我们把这个比作一块一块颗漂浮的方形木头盒。设置了float的div不再占据整行,而是按照实际的宽度漂浮在static区域的上面。

如1所述,如果static+非float区域如果有冰柱,上面不能漂浮其他东西。但是相反,如果先有了static+float的木头盒,因为下面static区域是空置的可以填充,但是是从float区域的下一行填充。如下图black占据2行高度,其中第一行位置是在float的下面,被遮挡了。

通俗易懂CSS(一)-相对定位和绝对定位position和float

(二)、relative的定位跟static对应区域一样,只是位置上基于absolute层对称投影到上面去了。

1、relative+float的位置可以先按照static+float是在哪个位置?然后偏移浮起到relative+float层,但是static+float中的位置继续保留。所以relative+float跟static+float类似,也是漂浮的,relative+float跟static+float不会出现重叠,而是紧挨着排列。如下图,float的对象相互紧挨着漂浮。

通俗易懂CSS(一)-相对定位和绝对定位position和float

再看下图,对relative+float设置了left产生了偏移,但是不会影响后面float的位置,并且偏移导致了投影重叠,但是不会出现相互挤压。

通俗易懂CSS(一)-相对定位和绝对定位position和float

2、relative+非float的位置同上类似,也是会形成一个隔离带。可以先看看static+非float时排在哪个位置,然后投影上去relative+非float区域。

如下图设置了red的top,只是本身位置产生了偏移和下面的green重叠了,但是并不会挤压green导致位移。

通俗易懂CSS(一)-相对定位和绝对定位position和float

 

(三)、absolute不影响其他区域的布局。

absolute比较简单,是夹在中间的激光层,可以像纸张一样多个相互重叠;float对应不会影响他的位置、static+非float和relative+非float是个隔离带,如果之后出现absolute需要换行布局;但是如果先有的absolute,再出现“static+非float和relative+非float”,则不会影响“static+非float和relative+非float”的布局。

 

三、其他

(一)、只有非static的对象(absolute、relative+float、relative+非float)设置left、top、right、bottom才有作用。

(二)、absolute加上float是没有意义的

(三)、父div需要靠子div支撑宽度、高度。但是只能依赖文档流,即static+非float区域(relative+非float也是特殊的static+非float)。如果想要float区域也支撑父div。有2种办法:

1、父级设置overflow: hidden(overflow:hidden要有宽度或者高度才会溢出部分隐藏,如果外部盒子没有宽度或者高度,里面又是浮动元素,就会被撑开)

2、在float后面加 <div style=”clear:both”></div>,相当于加了一个隔离支撑板,这样也会撑开父级

四、示例代码

<html>
<head>
</head>
<body>
<!--
rel是static类似的普通流,只是rel**了left和top等属性,可以位移,位移后原来的位置还保留了。并且位移后不会影响其他的位置
-->
<!--abs和float都是在res和static隔离后新行创建-->
<div style="background:yellow;padding:2px;position:relative;width:800px;margin-top:100px;">
	<div style="background:red;width:300px;">1</div>
	<div style="background:green;width:300px;">2</div>
	<div style="background:black;width:200px;position:absolute">4</div>
</div>

<!--black在red和green下一行开始填充,并占据red和green下面的位置。black占据2行位置,并且float的漂浮在static上面
-->
<div style="background:yellow;padding:2px;position:relative;width:800px;margin-top:100px;">
	<div style="background:red;width:300px;float:left;">1</div>
	<div style="background:green;width:300px;float:left;">2</div>
	<div style="background:black;width:200px;">4</div>
</div>

<!--float不会重现重叠,都是按顺序漂浮
去掉relateive的float,因为static虽然有浮动,但是下面可以有文档流,所以在static的float下面开始文档流,只是这个rel的div需要独占一行,所以下面一行也会占据。
-->
<div style="background:yellow;padding:2px;position:relative;width:800px;margin-top:100px;">
	<div style="background:red;width:100px;float:left;">1</div>
	<div style="background:green;width:100px;float:left;">2</div>
	<div style="background:blue;width:200px;position:relative;float:left;">4</div>
	<div style="background:black;width:200px;position:relative;float:left;">4</div>
</div>

<!--relative层是个可重叠的,设置top、left等不会出现相互挤压,而是会重叠
-->
<div style="background:yellow;padding:2px;position:relative;width:800px;margin-top:100px;">
	<div style="background:red;width:300px;position:relative;top: 5px;">1</div>
	<div style="background:green;width:300px;position:relative;">2</div>
</div>


<!--其他示例------>

<!--static的float对象设置left、top、right、bottom没有作用--->
<div style="background:yellow;padding:2px;position:relative;width:800px;margin-top:100px;">
	<div style="background:blue;width:100px;position:absolute">3</div>
	<div style="background:black;width:200px;position:relative">4</div>
	<div style="background:red;width:300px;float:left;">1</div>
	<div style="background:green;width:300px;float:left;">2</div>
</div>

<!--将red;width:300px改成变成700px后,black占据了3行-->
<div style="background:yellow;padding:2px;position:relative;width:800px;margin-top:100px;">
	<div style="background:blue;width:100px;position:absolute">3</div>
	<div style="background:red;width:300px;float:left;">1</div>
	<div style="background:green;width:300px;float:left;">2</div>
	<div style="background:black;width:200px;position:relative">4</div>
</div>

<!--将position: absolute;加上float:left。float加了没有作用-->
<div style="background:yellow;padding:2px;position:relative;width:800px;margin-top:100px;">
	<div style="background:black;width:200px;position:relative">4</div>
	<div style="background:blue;width:100px;position:absolute">3</div>
	<div style="background:red;width:300px;float:left;">1</div>
	<div style="background:blue;width:200px;position:absolute">3</div>
	<div style="background:green;width:300px;float:left;">2</div>
</div>
<!---
relative的black紧挨着static的green进行排列;float没有影响absolute、relative的布局;absolute也没有影响relative的布局
--->
<div style="background:yellow;padding:2px;position:relative;width:800px;margin-top:100px;">
	<div style="background:red;width:300px;">1</div>
	<div style="background:green;width:300px;">2</div>
	<div style="background:red;width:300px;float:left;">1</div>
	<div style="background:green;width:300px;float:left;">2</div>
	<div style="background:black;width:200px;position:absolute">4</div>
	<div style="background:black;width:200px;position:relative">4</div>
</div>
<!-- 去掉 4的 position:relative,即变成static看看效果? -->
<!-- 4里面加上float=left会出现什么效果,在relative层浮动,没有了独占一行的特性,并且跟float层相互影响,按顺序浮动 -->
<div style="background:yellow;padding:2px;position:relative;width:800px;margin-top:100px;">
	<div style="background:red;width:300px;float:left;">1</div>
	<div style="background:green;width:300px;float:left;">2</div>
	<div style="background:blue;width:100px;position:absolute">3</div>
	<div style="background:black;width:200px;position:relative">4</div>
</div>
<!--
absolute和float不会影响父级div大小,static是文档流才会影响(relative也是特殊的static)
可以设置下面的撑开下级:
1、父级设置overflow: hidden(overflow:hidden要有宽度或者高度才会溢出部分隐藏,如果外部盒子没有宽度或者高度,里面又是浮动元素,就会被撑开)
2、在float后面加 <div style="clear:both"></div>,相当于加了一个隔离支撑板
-->
<div style="background:yellow;padding:2px;position:relative;width:800px;margin-top:100px;">
	<div style="background:blue;width:100px;position:absolute">3</div>
	<div style="background:red;width:300px;float:left;">1</div>
	<div style="background:green;width:300px;float:left;">2</div>
	<div style="clear:both"></div>
	<div style="background:green;width:300px;float:left;">2</div>
	<div style="background:blue;width:100px;position:absolute">3</div>
	<div style="background:black;width:200px;position:relative">4</div>
</div>

</body>
</html>