css布局模型
css布局模型:清楚了CSS 盒模型的基本概念、 盒模型类型, 我们就可以深入探讨网页布局的基本模型了。布局模型与盒模型一样都是 CSS 最基本、 最核心的概念。 但布局模型是建立在盒模型基础之上,又不同于我们常说的 CSS 布局样式或 CSS 布局模板。如果说布局模型是本,那么 CSS 布局模板就是末了,是外在的表现形式。 CSS包含3种基本的布局模型,用英文概括为:
1、flow(正常流)
2、浮动模型 (Float)。脱离文档流,但是仍然能其他元素在同一层级,即还是显示在普通文档流中,虽然其他元素会视其不存在一样。
3、层模型(Layer).完全脱离文档流,和普通文档流都不在一个层级,相当于变成两个永无交集的平行面了(CSS 定位 (Positioning) 属性允许你对元素进行定位。)
CSS 定位和浮动
CSS 为定位和浮动提供了一些属性,利用这些属性,可以建立列式布局,将布局的一部分与另一部分重叠,还可以完成多年来通常需要使用多个表格才能完成的任务。
定位的基本思想很简单,它允许你定义元素框相对于其正常位置应该出现的位置,或者相对于父元素、另一个元素甚至浏览器窗口本身的位置。显然,这个功能非常强大,也很让人吃惊。要知道,用户代理对 CSS2 中定位的支持远胜于对其它方面的支持,对此不应感到奇怪。
一切皆为框
div、h1 或 p 元素常常被称为块级元素。这意味着这些元素显示为一块内容,即“块框”。与之相反,span 和 strong 等元素称为“行内元素”,这是因为它们的内容显示在行中,即“行内框”。
您可以使用 display 属性改变生成的框的类型。这意味着,通过将 display 属性设置为 block,可以让行内元素(比如 <a> 元素)表现得像块级元素一样。还可以通过把 display 设置为 none,让生成的元素根本没有框。这样的话,该框及其所有内容就不再显示,不占用文档中的空间。(不被渲染)
CSS 定位机制
CSS 有三种基本的定位机制:普通流、浮动和定位。
(一)普通流
除非专门指定,否则所有框都在普通流中定位。也就是说,普通流中的元素的位置由元素在 (X)HTML 中的位置决定。
块级框从上到下一个接一个地排列。
行内框在一行中水平布置。
流动模型(一)
先来说一说流动模型,流动(Flow)是默认的网页布局模式。也就是说网页在默认状态下的 HTML 网页元素都是根据流动模型来分布网页内容的。
流动布局模型具有2个比较典型的特征:
第一点,块状元素都会在所处的包含元素内自上而下按顺序垂直延伸分布,因为在默认状态下,块状元素的宽度都为100%。实际上,块状元素都会以行的形式占据位置。如右侧代码编辑器中三个块状元素标签(div,h1,p)宽度显示为10
流动模型(二)
第二点,在流动模型下,内联元素都会在所处的包含元素内从左到右水平分布显示。(内联元素可不像块状元素这么霸道独占一行)
右侧代码编辑器中内联元素标签a、span、em、strong都是内联元素。
应用:一列布局
(二)浮动模型(浮动不完全定位,浮动后的元素虽然脱离普通流,但是该元素和其他元素普通流中的元素仍然在同一层级,因而该元素仍然在文档中显示)
float的设计初衷:实现文字环绕效果
当一个元素设置了float之后: 首先,该元素自身的表现和inline-block水平元素一样;可以设置宽高、和其他元素浮动元素显示在一行等。【注意,浮动元素虽然类似于inline-block,但是又不同于普通的inline-block元素,因为普通的inline-block元素当做一个整体作为行内元素在一行中布局。而,浮动元素不是行内元素。再一点,浮动元素不像行内元素之间有空隙间隔。故而,浮动可以去空格话】
其次,该元素按照inline-block水平元素在其应该出现的行中左浮动或者有浮动,浮动的规则为:
浮动的框可以向左(left)或向右(right)移动,直到它的外边缘碰到包含框或另一个浮动框的边框为止。即其无视该行中其他所有元素,一直向左或者向右移动,直到碰到包含框的边缘或者另一个浮动框为之。
请看下图,当把框 1 向右浮动时,它脱离文档流并且向右移动,直到它的右边缘碰到包含框的右边缘:
再请看下图,当框 1 向左浮动时,它脱离文档流并且向左移动,直到它的左边缘碰到包含框的左边缘。因为它不再处于文档流中,所以它不占据空间,实际上覆盖住了框 2,使框 2 从视图中消失。
如果把所有三个框都向左移动,那么框 1 向左浮动直到碰到包含框,另外两个框向左浮动直到碰到前一个浮动框。
如下图所示,如果包含框太窄,无法容纳水平排列的三个浮动元素,那么其它浮动块向下移动,直到有足够的空间。如果浮动元素的高度不同,那么当它们向下移动时可能被其它浮动元素“卡住”:
最后,浮动元素在浮动到其对应的位置之后,该元素就从普通文档流中脱离,不再属于任何一个框,而是就在其所在位置独立存在于文档流中,即文档流中的其他元素表现得就像浮动元素不存在一样在页面中布局,这些元素在布局的时候都会给该浮动元素留位置。浮动元素占据的位置相当于是遮盖了文档流中的一块区域,普通文档流都是由元素挨个紧密组成的,因此,浮动元素所遮盖的文档流中的一块区域一定是些元素组成的区域【普通文档流的宽度=文档流的宽度,只不过浮动元素存在文档流中即遮盖普通文档流的一部分位置。(注意,块状元素仍然独占一行,即最大宽度仍然是文档流的宽度,典型的例子:文字环绕效果。)】【这就会有一个问题,即父容器塌陷。因为当一个父容器的一个子元素设置浮动之后,该子元素脱离普通文档流即不再属于任何一元素,父容器的实际高度以正常子元素的占据的高度为其高度】
浮动元素的布局规则:内联元素不会独占一行,而每个非浮动块级元素都独有一行, 浮动元素则按规则浮在行的一端. 若当时行容不下, 则另起新行再浮动。浮动元素不占任何正常文档流空间,然而浮动元素的定位照样基于正常的文档流,当一个元素脱离正常文档流后,依然在文档流中的其他元素将忽略该元素并填补其原先的空间。即浮动框旁边的行框被缩短,从而给浮动框留出空间,行框围绕浮动框。
因此,创建浮动框可以使文本围绕图像:
例:
结果为
再例:
这里,由于h1游离于文档,因此,p元素就当其不存在,但是还会给其留相应的位置,自己填充剩余的空间
浮动的特性:1》包裹性
-a.元素在float之后,就块状化,display:block;
a.虽然浮动可以块状化,但是元素的表现又类似内联块状化。即内联元素在用了float属性后,可以设置宽高等;宽度变为实际占用的宽度(针对原来是普通块状元素并且没有设置宽度)。但是只是类似内联块状元素,因为其在文字环绕的时候,并没有像内联块状元素一样当做整体和行内的其他元素显示在一样,而是文字环绕。
b.BFC化
元素float之后,元素可设置宽高。相当于内联块状元素,可以和其他浮动元素显示在一行。对于本来就是块状的元素,浮动之后,宽度缩小为实际需要的大小。故而有收缩的特点。
一个元素设置了float之后,就实现了BFC效果,即里面的内容无论怎么变,都不会影响到外面的元素。
元素浮动后与原来一些特性的变化:
例如<span>等行内元素不能设置宽高等,。但是float之后,就成为块状元素,可以设置宽高等。
2》破坏性:让父元素内容塌陷【一个元素浮动之后,在页面布局中,其不在属于原来的父元素了,而是成为文档流的一部分,就遮盖页面的一部分区域。】
块状元素这么霸道都是独占一行,如果现在我们想让两个块状元素并排显示,怎么办呢?不要着急,设置元素浮动就可以实现这一愿望。
任何元素在默认情况下是不能浮动的,但可以用 CSS 定义为浮动,如 div、p、table、img 等元素都可以被定义为浮动。如下代码可以实现两个 div 元素一行显示。
div{ width:200px; height:200px; border:2px red solid; float:left; } <div id="div1"></div> <div id="div2"></div>
效果图
当然你也可以同时设置两个元素右浮动也可以实现一行显示。
div{ width:200px; height:200px; border:2px red solid; float:right; }
又有小伙伴问了,设置两个元素一左一右可以实现一行显示吗?当然可以:
div{
width:200px;
height:200px;
border:2px red solid;
}
#div1{float:left;}
#div2{float:right;}
浮动的最初目的是为了实现文字环绕效果,这个效果有时候不是我们想要的效果或者这会让父元素高度塌陷。那么我们应该如何处理这些问题呢?
即清除浮动/防止父容器塌陷
I.清除浮动
清除(clear)
Clear清除浮动
要想阻止元素围绕浮动框,需要对该框应用 clear 属性。clear属性就是定义元素的那些边不挨着浮动框(也就是水平方向)。即clear 属性的值可以是 left、right、both 或 none,它表示框的哪些边不应该挨着浮动框,也就是所说的清除浮动。
定义和用法
clear 属性规定元素的哪一侧不允许有浮动元素。
在清除浮动的时候,应该对清除与浮动相匹配:如果某个元素浮动到左侧,则应清除左侧。您的浮动元素会继续浮动,但是清除浮动的元素将显示在浮动元素的下方。
clear适用的范围:只适用于普通块状元素或者浮动元素。[对于普通块状元素,因此其本来就应该独占一行,由于浮动元素占据了其应有的位置,因此可以使用clear来让实现自己的本来宽度,维护自己的权益。对于行内元素无效,因为浮动元素已经脱离文档流了,没办法当做平级原来来处理。]
例如:清除向左的浮动,表示在div的左侧不允许出现浮动元素;
<head>
<style>
.div1 {
float: left;
width: 100px;
height: 50px;
margin: 10px;
border: 3px solid #73AD21;
}
.div2 {
border: 1px solid red;
}
.div3 {
float: left;
width: 100px;
height: 50px;
margin: 10px;
border: 3px solid #73AD21;
}
.div4 {
border: 1px solid red;
clear: left;
}
</style>
</head>
<body>
<h1>不使用 clear</h1>
<div class="div1">div1</div>
<div class="div2">div2 - 请注意,在 HTML 代码中 div2 在 div1 之后。不过,由于 div1 向左浮动,div2 中的文本会流动到 div1 周围。</div>
<br><br>
<h1>使用 clear</h1>
<div class="div3">div3</div>
<div class="div4">div4 - 在此处,clear: left; 把 div4 移动到浮动的 div3 下方。值 "left" 会清除向左浮动的元素。您也可以清除 "right" 和 "both"。</div>
显示结果:
例如:浮动元素清除浮动
利用clear 清除
总结:父类元素有浮动元素和一般元素,那么要使一般元素(块状元素)能够按照理想的情况展现,需要给因浮动产生影响的元素添加属性clear。
II.防止父容器塌陷的方法(父容器没有设置高度才会塌陷):
(一)BFC
一个元素BFC之后,无论其里面的元素怎么翻云覆雨都不会影响外面的元素。而浮动会导致父元素塌陷,因此会影响父元素之外的其他元素,故而我们给包含浮动元素的父元素BFC,这样其里面的子元素无论怎么设置都不会影响到外面的元素。【position:absolute呢?】
例如:如果一个元素比包含它的元素高,并且它是浮动的,它将“”溢出到其容器外,这种我们可以通过给容器添加属性overflow:auto来解决此问题
<head> <style> div { border: 3px solid #4CAF50; padding: 5px; } .img1 { float: right; } .clearfix { overflow: auto; } .img2 { float: right; } </style> </head> <body> <h1>Clearfix</h1> <p>在本例中,图像高于包含它的元素,然而它被浮动了,所以它会在容器之外溢出:</p> <div> <img class="img1" src="/i/logo/w3logo-3.png" alt="W3School" width="180" height="167"> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus imperdiet, nulla et dictum interdum... </div> <p style="clear:right">请为包含元素添加一个带有 overflow: auto; 的 clearfix 类,以解决此问题:</p> <div class="clearfix"> <img class="img2" src="/i/logo/w3logo-3.png" alt="W3School" width="180" height="167"> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus imperdiet, nulla et dictum interdum... </div>
显示结果如下:
(二)利用子元素清除浮动
我们可以在父类元素中增加一个空的块级子元素,然后给设置clear属性。【原理:给父元素增加一个块级子元素,该元素就和浮动原型形成文字环绕效果,然后我们给该块级子元素清除浮动,该子元素就在浮动元素的下面显示,而又因为父元素一定包含子元素,因此就实现了父元素既包含浮动元素又包含空的块级子元素,从而解决了父容器塌陷的问题。】
让我们更详细地看看浮动和清理。假设希望让一个图片浮动到文本块的左边,并且希望这幅图片和文本包含在另一个具有背景颜色和边框的元素中。您可能编写下面的代码:
这种情况下,出现了一个问题。因为浮动元素脱离了文档流,所以包围图片和文本的 div 不占据空间。
如何让包围元素在视觉上包围浮动元素呢?需要在这个元素中的某个地方应用 clear:
这样可以实现我们希望的效果,但是需要添加多余的代码。常常有元素可以应用 clear,但是有时候不得不为了进行布局而添加无意义的标记。
不过我们还有另一种办法,那就是对容器 div 进行浮动:
这样会得到我们希望的效果。不幸的是,下一个元素会受到这个浮动元素的影响。为了解决这个问题,有些人选择对布局中的所有东西进行浮动,然后使用适当的有意义的元素(常常是站点的页脚)对这些浮动进行清理。这有助于减少或消除不必要的标记。
因此,给父类元素添加一个clearfix类,并且添加一个伪元素after,其实和添加一个空的div差不多。
总结:防止父容器塌陷,可以通过两个方法解决:一方面是将父元素通过BFC化;另一方面是将给父容器添加子元素(块状元素)或者伪元素来进行clear:both
综合比较两个方法
事实上,W3School 站点上的所有页面都采用了这种技术,如果您打开我们使用 CSS 文件,您会看到我们对页脚的 div 进行了清理,而页脚上面的三个 div 都向左浮动。
float的应用【不能滥用,浮动主要的应用流体布局】
1.文字环绕效果(浮动的设置之处,看家本领)
《1》
《2》文字环绕变身
2.流体布局
《1》文字环绕衍生——单侧固定
(二)position定位
position属性规定应用于元素定位方法的类型:
有五个不同的位置值:
- static
- relative
- fixed
- absolute
- sticky
absolute:绝对定位。完全离开文档流,使用left,right,top,bottom等属性相对于其最接近的一个具有定位设置(即position值不为默认值static)的父对象进行绝对定位。如果不存在这样的父对象,则依据body对象。而其层叠通过z-index属性定义。当对象定位在浏览器窗口以外,浏览器因此显示滚动条。
relative:相对定位,原本所占的空间仍保留。对象不可层叠,但将依据left,right,top,bottom等属性在正常文档流中偏移位置。当对象定位在浏览器窗口以外,浏览器因此显示滚动条。
fixed:固定定位。完全离开文档流,对象定位遵从绝对(absolute)方式,但是要遵守一些规范。当对象定位在浏览器窗口以外,浏览器不会因此显示滚动条,而当滚动条滚动时,对象始终固定在原来位置,即相关于视区进行偏移。
static:元素框正常生成。块级元素生成一个矩形框,作为文档流的一部分,行内元素则会创建一个或多个行框,置于其父元素中。
inherit:继承值,对象将继承其父对象相应的值。
元素其实是使用 top、bottom、left 和 right 属性定位的。但是,除非首先设置了 position 属性,否则这些属性将不起作用。根据不同的 position 值,它们的工作方式也不同。
注意:使用float脱离文档流时,其他盒子会无视这个元素,但其他盒子内的文本依然会为这个元素让出位置,环绕在周围。而对于使用absolute positioning脱离文档流的元素,其他盒子与其他盒子内的文本都会无视它 。
float不具备继承。
层模型?
(一)相对定位relative(相对于自身的定位,并且原来的位置在普通流中仍然保留着)
1.relative的特性:
3.不具有包裹性:即原来是什么类型的元素,相对定位置后,仍然是什么元素。跟原来一模一样,只是不在原来的层级,但是原来的位置仍然保留着。
相对自身:设置了position:relative的元素,该元素相对于该元素本应该出现的位置进行定位,并且本应该出现的位置仍然保留着,该元素定位在一个新的位置,但是新的位置完全脱离文档流,在普通文档流的上一面一个层级显示即和普通流文档是两个平行面,互不影响。absolute和相对应的、设置了relative的父元素在同一层级。
无侵入,指的是,进行relative的元素并不会影响其他的元素,即一个元素进行relative定位后,其原来位置仍然保留着,故而其他的元素还是和原来的布局一样,没有其他的变化,即设置相对定位的元素的 top、right、bottom 和 left 属性将导致其偏离其正常位置进行调整,而调整后的位置在另一个层面上,而其本应该出现的位置一直保留着,故而不会对其余内容进行调整来适应元素留下的任何空。
相对定位的特点:设置为相对定位的元素框会偏移某个距离。元素仍然保持其未定位前的形状,它原本所占的空间仍保留。即尺寸和类型都不变即原来是内联现在还是内联、原来是内联块状现在仍是内联块状、原来是独占一行的块状元素现在仍是独占一行的块状元素。
对于浮动和position:absolute,都会改变元素的显示水平即都成为块状水平元素。但是,表现又都是类似内联块状的表现,但又不同于块状元素,尤其对于仍占据文档流位置的float元素来说,其虽然是块状元素,但是表现又是内联块状元素,但是在和其他元素在一起布局的时候,又像内联元素,最典型的解释就是“文字环绕效果”
2.相对定位的作用:
I.用于定位
II.还有一个主要的特性就是对absolute的限定;
I.定位(相对于自己原来的位置进行定位,但是原来的位置不会消失也不会发生任何变化,其新的位置在与普通文档流相互平行的一个面中而且在普通文档就的上面,因此,相对定位的元素可能会遮盖普通文档流中的元素【本质是不遮盖的,因为相互平行,但是我们是从下往下看的,因此视觉上是遮盖的】。)
相对定位是一个非常容易掌握的概念。如果对一个元素进行相对定位,它将出现在它所在的位置上。然后,可以通过设置垂直或水平位置,让这个元素“相对于”它的起点(左上角)进行移动。
如果将 top 设置为 20px,那么框将在原位置顶部下面 20 像素的地方。如果 left 设置为 30 像素,那么会在元素左边创建 30 像素的空间,也就是将元素向右移动。
#box_relative { position: relative; left: 30px; top: 20px; }
如下图所示:
一。在未发生相对定位:
二。进行相对定位后:
发生相对定位后,span标签中的内容并没有上移到前面去,还在其原来的位置,充分证明发生相对定位后,其原来的位置仍然保留,但是移动到别的位置改框会覆盖掉其他文档,如上图中的span里的内容被覆盖。不过,我们同样可以通过z-index来改变两者谁覆盖谁。
一个元素设置了relative之后,默认该元素的层级(z-index)比其他元素的层级高,而且,该元素包含的所有子元素也在层级高的这一层.即该元素的所有子元素和该元素在同一层面(同一级别)
relative的用处:
1.用于自定义的拖拽
relative:left top right bottom值设定的规律(坐标点都是原位置的相应的顶点为坐标点)
1)当设置left top时,相对定位的起点为元素的左上角的顶点(如图所示为正轴),,即该元素向右偏移left设置的橡素、向下偏移top设置的像素
即:原来的位置的左上角向下偏移top设置的像素、向右偏移left设置的像素就移到现在新的位置了。
2)当设置right bottom时,相对定位的起点为元素的右下角(如图所示为正轴), ,即该元素向左偏移right设置的像素,向上偏移bottom设置的像素
即:原来的位置向左偏移right设置的像素,向上偏移bottom设置的像素就移到现在的新的位置了。
3)当设置left,bottom时,相对定位的起点为元素的左下角,垂直方向向上为正轴,水平方向向→为正轴
4)当设置right,top时,相对定位的起点为元素的右上角,垂直方向向下为正轴,水平方向向←为正轴
总结:四个顶点的水平和垂直的正轴都是向内的。
在top和bottom同时存在时候,只有top起作用;当right和left同时存在时,只有left起作用。
II relative和absolute的关系:relative对absolute的限制
1.relative对absolute对位的限制,absolute的坐标点根据最近的父级具有relative的元素进行定位;
2.absolute的z-index除了根据自身层级还跟relative层级有关系,也就是父级relative在有Z-index的情况下,absolute的层级不论原来是多少,都和父级relative同一级了。
3。overflow在position:absolute中失效,父级使用relative就可以让其起作用。
relative的使用规则: 经验心得、最佳实践方案
1.尽量避免使用relative;
2.relative最小化
(1)尽量避免使用relative
absolute定位可以根据自身以及margin来进行定位等等,可以不依赖relative
(2)relative最小化
这里的img要实现绝对定位,就可以给img单独设置一个具有relative属性的父级div
这种情况下,给需要定位的img元素额外添加一个设有position:relative属性的父元素,这个父元素尺寸为0,是不占据任何空间的,不会对原来的布局有任何影响,不会有任何问题(比如乱七八糟的层叠问题)。这样做的好处就,不用导致上面所有的div都因为父元素设置了relative而上升到另一个层级。
(二)绝对定位(绝对定位的元素,彻底从文档流中抽离,正常流中该元素原来的位置也会关闭,绝对定位和文档流中的其他元素不在同一层级。)
1.绝对定位的原理和步骤:
如果想为元素设置层模型中的绝对定位,需要设置position:absolute(表示绝对定位),这条语句的作用1.在Z轴上新建一个新的层级,2.元素从文档流中垂直平行从原来的层级上升到新的层级,而原来层级中的位置不保留,然后父元素等重新布局,最后,该元素使用left、right、top、bottom属性相对于其最接近的一个具有定位属性的父包含块进行绝对定位(具有定位属性指的是除了static外的属性)。如果不存在这样的包含块,则相对于body元素定位。【注:这里一般情况下,绝对定位要是参照父包裹定位的话,尽量根据relative进行定位。具体原因回头再研究】
绝对定位的left top bottom right定位的规则:【以最近的父级定位元素的四个顶点中的一个为坐标点,向内沿着形成这个坐标点的两条线作为正的横轴坐标轴,然后,绝对定位元素根据设置的位移的值以及对应的顶点在对应的坐标点上移动,最后确定其位置。绝对定位完毕】:
分别以屏幕窗口或者包含定位属性的元素的四个顶点作为定位的起始点,x,y轴都是向内的。
例如:left top ,则以最近的包含定位元素的父辈元素的左上角的顶点为坐标点,分别向右和向下↓→为正轴,绝对定位元素的坐上角的顶点根据left和top值在对应的坐标点上的横纵轴上进行定位。
right bottom 以最近的包含定位元素的父辈元素的右下角的顶点为坐标点,分别向左和向上向←↑为正轴,绝对定位元素的右下角的顶点根据right和bottom的值在对应的坐标点上的横纵轴上进行定位。
如下面代码可以实现div元素相对于浏览器窗口向右移动100px,向下移动50px。
div{ width:200px; height:200px; border:2px red solid; position:absolute; left:100px; top:50px; } <div id="div1"></div>
2.绝对定位的特性:包裹性 破坏性 无依赖
绝对定位和float是同父异母的👬。二者都具有包裹性和破坏性
*包裹性:当一个元素设置position:absolute之后,该元素就变成block水平元素了。设置了固定尺寸的,尺寸还是原来那么大;块状元素水平方向如果没有设置尺寸,则自动收缩到实际内容的宽度;而且,该定位元素原来在什么位置,绝对定位之后仍然在原来位置的垂直上方。
*破坏性指的是:绝对定位原来的位置将不保留。
设置为absolute定位的元素框从文档流中抽出来,其现位置是相对于原来的位置的正上方(即现在的位置比与原来的位置z-index大一级,肉眼看屏幕好像位置没变一样,是因为层叠),然后,该元素从文档流完全删除,文档流中的其他元素则按照该元素不存在了重新排列,该元素然后利用top,left,bottom,right相对于其包含块定位(设置了top,left或者其他值之后,该元素的位置才会发生变化,不然一直停留在和原来位置相同的上一层中。例如:
,对图片二设置position:absolute属性,则为下图所示:
)包含块可能是文档中的另一个元素或者是初始包含块。元素原先在正常文档流中所占的空间会关闭,相当于该元素原来不存在一样。元素定位后生成一个块级框,而不论原来它在正常流中生成何种类型的框。
当z-index的值为0或者比0更大的值时,定位框将会覆盖掉其他文档流。
*无依赖性指的是:
1。脱离文档流:当元素设置了position:absolute,该元素彻底脱离文档流,文档中的其他内容根据剔除这个元素后的空间进行重新布局。
2。折翼的天使:当元素设置了position:absolute之后,该元素现在的位置在原来文档流中的原来位置相重合,只不过该元素和原来的位置不在同一层级(宽度可能有变化)。
折翼天使的特性表现:
去浮动:即当float和absolute同时存在时,会把元素的float去除掉,然后进行absolute定位。
位置跟随性:1》原来是block水平的元素,position:absolute之后,依然是换行显示。[如果原来块状元素没有设置宽度,则宽度变为实际的宽度。]
2》原来是inline/inblock水平的元素,比如原来跟在文字后面的,position:absolute之后仍然跟在文字后面。
原来是什么位置绝对定位之后还是什么位置(除了inline水平的元素前面有inline-block水平的元素,这个inline水平的元素设置了position:absoute之后,会移动到和inline-block水平顶部对齐。因为原来是默认的基线对齐,现在inline水平的元素以及在新的一个层级了,谈不上和原来行内中的其他元素基线对齐了。)
折翼天使的实例: (利用absolute的跟随性)
3. (边缘的定位是利用position无依赖是最佳实践效果)
具体思路:在这个例子中,首先第一次布局render树的时候,img因为div设置了text-align故而会在这个div中居中显示;第二次布局的时候,即给img加上position:absolute;这时候,新创建一个层级,img图片从原来的层级中脱离出来,上升到这个新建的层级。然后,因为position:abolute破坏了容器,故而div等重新布局。【然后position再根据top等进行定位】这里,图片从父容器中脱离出来之后,仍然在其原来布局中的位置的正上方,因此该元素绝对定位之后仍然在原来居中位置的正上方。故而其是居中。【个人觉得这里跟 没什么关系】
例如实现如图所示的注册效果:
主要思路:由于标星有时有有时无,这种情况下,可以将*和左边的字体分为一组,字体设置为普通流显示,*使用 position:absolute,这样,文字的布局不受影响有没有*的影响,主要是不需要计算*到文字之间的距离来排版。
同样,右边的表单和提示语也使用同样的方式。
3。天使的翅膀(position:absolute配合top bottom left right使用)
(1)前面所讲的都是折翼的天使,即position:absolute,但是不设置top,bottpn,left,right任何值,充分利用跟随性进行应用
(2)藕断丝连的半天使
只设置一个方向的值,例如,只设置top值,那么水平方向的值还是要借助margin来进行移动
(3)天使的翅膀
垂直和水平方向都设置了值,进行直接进行绝对定位。例如:left:0;top:0等
特殊:当四个方向都设置值如:left:0px;top:0px;right:0px;bottom:0px;
结果:砰!!!即相当于床单四个方向被拉直。遮盖整个父容器。
(1)absolute与width和height
i 两者具有替代性
例如:
普通的实现方案:
另一种实现方案:
总结:
ii.
iii 相互支持性
即:父类容器的高度为百分比或者固定值,这里的百分比是指起作用的百分比。
iiii
即:在有width或者height的情况下,即使设置了对立的两个值(left/right,top/bottom),宽度和高度以width或者height设置的值为主。
例如:实现图片在屏幕中的完全居中:
4.绝对定位和整体页面布局
典型的例子:通过绝对定位拉伸,显示头部、侧边栏、底边栏固定,中间区域实现滚动的效果 。
(一)body降级,子元素升级
(二)具体步骤
1.升级子div(假设类名为page)满屏走起;
同时:
2.各模块——头尾、侧边栏各居其位
(三)内容区域想象成body
重点 :
relative和absolutate定位的关系就是:
即:relative限制absolute
定位一张图片到父元素的左上角:
(三)层模型--固定定位
fixed:表示固定定位,与absolute定位类型类似,但它相对于视口定位的,这意味着即使滚动页面,它也始终位于同一位置。 top、right、bottom 和 left 属性用于定位此元素。由于视图本身是固定的,它不会随浏览器窗口的滚动条滚动而变化,除非你在屏幕中移动浏览器窗口的屏幕位置,或改变浏览器窗口的显示大小,因此固定定位的元素会始终位于浏览器窗口内视图的某个位置,不会受文档流动影响,这与background-attachment:fixed;属性功能相同。以下代码可以实现相对于浏览器视图向右移动100px,向下移动50px。并且拖动滚动条时位置固定不变。
#div1{ width:200px; height:200px; border:2px red solid; position:fixed; left:100px; top:50px; } <p>文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本。</p>
附加:1.clear为float收拾破坏的残局;relative限制absolute
注意:父容器塌陷,如果设置了border等,我们可以看到父容器变为一条线,如果没有设置border等,则页面中关于父容器什么也看不见了,但是并不代表父元素不存在和display:none等完全不一样。我们可以想象为父容器就在原来那个地方,只是因为没有子元素撑开,故而父元素上下两条线因为塌陷合并成为一条不影响页面布局的看不见的、隐形的线。父元素缩成一条线是存在的,只是我们看不到而已。
例如:
<div class="position" style="position: relative;width: 300px;"> <div style="position: absolute;width: 100px;height: 100px;background-color: #bfbfbf;bottom: 100px;right:100px "> </div> </div>
虽然因为子元素div设置了position:absolute导致父元素塌陷,但是子元素仍然可以根据父元素进行绝对定位。
附加三:float、relative、absolute、fixed的渲染布局规则(自己瞎编的,以后再更正);
a.无论是float、relative还是absolute、fixed的元素在HTML的render树第一次布局的时候都是按照正常的元素进行布局即按照其本来应该的位置进行布局。(这里可以认为还没有将float、relative等应用到元素上)
b.整体布局完成之后,对于有float、relative、absolute、fixed的元素以及相关的父元素、祖先元素进行第二次布局。具体的布局流程为:
1.float
(1)给元素应用float:left/right,元素先变成类似内联块状元素,然后在其所在行向左或者向右浮动;
(2)元素浮动完成之后,父元素中的其他元素以及祖先元素以及排在父元素后面的的元素再重新布局(这时候再塌陷等);
2.relative
(1)给元素使用relative,新增一个层级并且元素(包括这个元素中包含的所有元素)原封不动的垂直平行上升到这个层级并且原来的位置仍然保留着。
(2)再根据top\left\bottom\right在新的层级中相对自身位置进行定位。
(3)父元素所有元素的布局都保持不变。
3.absolute/fixed
(1)给元素使用absolute,新增一个层级并且该元素原封不动的垂直平行上升到这个新的层级而原来层级的位置不保留(表面上看到这个元素没有进行任何移动,因为这时候只是垂直方向上升到一个新的层级,我们在屏幕中看过去,刚好是这垂直方向,因此看见像是没有变动)。
(2)父元素以及祖先元素或者后面的所有元素重新布局(这时候可能有塌陷等问题)
(3)再根据最近的父辈元素具有relative(如果没有则以body为参照)的元素作为定位参照,依据top\left\bottom\right在新的层级中进行绝对定位。【其实一个元素relative之后,该元素所包含的所有元素都不在普通文档流中了,都在relative时创建的新的层级中了。这时候absolute和父辈relative不在同一个层级中,absolute的层级应该是比这个relative的层级高,故而这个absolute元素可能会遮盖父辈relative中包含的其他元素。】
注:display:none,我个人认为不会造成父容器塌陷,因为render树中本来就不包括display:none的元素,因此在布局render树的时候没有这些元素。
无论是relative还是absolute还是fixed,只要设置了,该元素就会比原来布局中的层面高一个层面。
二次布局完成之后,render树布局完成,这时候就可以将布局好的页面绘制出来。
附加4 Z-index
(一)z-index基础
0.z-index的定义:【核心:首先一个元素自己有一个层级,然后又设置了z-index属性,则表示该元素自身及其子元素在Z轴上的顺序。Z轴都是一些层级,越靠近屏幕,层级越高】
*Z轴
* 页面中具有层级的元素:HTML的根元素【整个元素在Z轴上形成一个封闭的三维空间盒子】、定位元素、还有其他属性可以让元素具有层级【比如opacity不为1的时候,元素就可以变为具有层级的元素】
即整个HTML都是在以根元素(body)这个具有层级的元素为Z轴方向的第一个也是最低层的二维平面为基础进行排列布局的。这里因为body没有设置z-index为具体的值,因此具有层级的body元素在Z轴上就是一个二维平面。
例如:
<html> <body> <div style="position:relative"> <p>我是一个段落</p> </div> </body> </html>
这里,Z轴方向一共有两个层级:1.body(或者成为HTML吧)
2.div元素,因为其设置了relative,因此,会给该元素新建一个层级,而且其比父元素body的层级高。
p元素也在div这个层级。
因此,div元素可以覆盖body层级的元素。
1.z-index值
auto;(默认,可以近似认为是0,但是和z-index:0还不一样)
整数(正负);
继承
z-index:auto
即:层叠上下文(具有层级的元素就称为层叠上下文),如果z-index值是auto,则其在Z轴上只是一个具有层级的二维平面。其在Z轴中的位置取决于其在dom流中的位置。按照后来居上的原则在Z轴中进行排序。
层叠水平:
[层叠上下文即具有层级的元素即定位元素,其包括的每个元素即子孙后代元素都有一个层叠水平。对于普通的子孙元素,都在层级的底面的二维面中;对于具有层级的子孙则按照先后顺序或者z-index值在该层叠上下文形成的封闭的三维空间盒子上排序,越在前面的,离屏幕越近,即层级越高。这个盒子的顶层就是子孙后代中层级最高的元素。注:那么,对于普通元素,一般情况下都是一在层叠上下文的底面的二维平面中有序的排列着。但是它们有时候也会重叠,比如:margin为负值的时候,元素整个盒子会从父元素中抽离,这时候他们会覆盖一些其他的普通元素。那么这个覆盖也是有规则的。不是谁的margin是负值,就是其遮盖其他元素,而是有其他的规则]
对于,前面两个以及后面两个都是层级元素的在Z轴上的顺序。
中间三个是针对普通元素,当其margin是负值的时候,谁遮盖谁。
z-index:数值
即:层叠上下文(具有层级的元素就称为层叠上下文),如果z-index值不为auto,则1.其在Z轴上的顺序根据z-index来决定。【如果遇到同级的即z-index的值相同,则按照DOM流中的位置,按照后来居上原则在Z轴中进行排序】; 2.该层级元素在Z轴方向上,会以层级面二维平面为底,子孙后代中的层级元素中最高层级为高,形成一个封闭的三维空间盒子。其中,子孙后代层级元素如果设有z-index,这时候z-index不再是Z轴上的位置,而是仅仅代表其在这个三维空间中的位置。
2.z-index所支持的元素或者起作用的场景(对于css2中,z-index只对定位元素起作用)
在css2中, 即只有有层级的元素,z-index能设置。因为relative、absolute、fixed属性都会导致元素新建一个层级,元素从原来层级上升到新建的层级,因此该元素可以根据z-index属性设置该元素在Z轴上的显示顺序。普通元素始终和父元素在同一层级,自身没有层级,因此该元素不能设置z-index。
注:HTML元素就是一个具有层级元素,因此所有的元素都在这个层级上布局显示。
(二)z-index与定位属性
z-index只能设置于具有定位属性的元素【因为该属性是设置具有层级的元素在Z轴方向上显示的位置,而除了body元素本身有是层叠上下文,其余的元素默认都是没有层级的,一个普通元素要有层级,必须使用postion进行定位,这样才能让该元素自身具有层级,因此,z-index只能应用于定位元素】
一旦一个元素设置了z-index即z-index不为auto,那么这个元素在Z轴上会自己按z-index值排序的同时,还会自身形成一个封闭的空间盒子,即其普通的元素就显示在盒子的底部,子孙层叠元素则在这个盒子形成的封闭的Z轴方向上排序即在这个盒子空间范围中排序。即如下所示:
注释:一个具有层级的元素,如果z-index值为auto(或者没有设置z-index属性,这时候,这个元素其实是有z-index属性的,默认值是auto),则该层级元素就是一个平面,在Z轴中。即如果子孙有层级,则子孙在浩瀚的Z轴中根据z-index进行自行排序去。
一个具有层级的元素,如果z-index的值不为auto,则首先该元素会在Z轴上以其在position进行定位的时候创建的平面为底,以其具有层级的子孙元素的最高层级为高,在Z轴上创建一个空间三维盒子。该元素的子孙后代都在这个盒子中进行布局显示。
对于多个层级元素(层叠上下文),在Z轴方向上如何排序呢?
【层级元素是平级关系】
一般情况下:层级元素没有设置z-index(即z-index的值为auto),因此该元素的层级在Z轴上就是一个二维平面,故而在Z轴上的顺序为:后来居上者原则。即哪个层叠上下文在dom流后面,哪个具有层级的元素在Z轴的最上面,即层级越高,即越靠近屏幕。【这时候,这个元素可能会遮盖其他层级的元素。】
第二个图片元素在Z轴的最上面,即层级越高,即越靠近屏幕,即如果有覆盖,第二张图片会覆盖第一张图片
多个层级元素嵌套【层级元素具有父子关系即定位元素嵌套即父元素具有定位属性,子元素也具有定位属性】
在Z轴的显示顺序,遵循:祖先优先原则。【即该定位元素的层级决定了其自身以及其子孙后代元素的层级】【前提:祖先的z-index为auto】
1.祖先定位元素没有设置z-index(即z-index:auto)
(1)子孙后代也没有设置z-index(即z-index:auto):
哪个祖先元素在dom流的后面,哪个元素及其子孙后代元素就在Z轴的最上面,即最靠近屏幕
(2)子孙后代设置了z-index,则这时候子孙后代的在Z轴的顺序取决于自身的z-index的值。
z-index:不为auto:具有层级的元素可以使用z-index属性:1.改变其Z轴上的默认位置。z-index越大,其在Z轴的位置越高、层级就越高、越靠近屏幕;
2.该元素的层级不再是一个二维平面,而是以这个二维平面为底,该元素的具有层级子元素的最高层级为高 ,在Z轴方向上形成一个三维空间盒子。即该元素的普通子孙后代元素都在这个三维空间盒子的底面那个平 面,具有层级的子孙后代元素都在这个三维空间盒子占据的Z轴段中按照层级排序。【这里的子孙层级元素的z-index不再是Z轴上的坐标值了,仅仅是祖先形成为盒子上的代表位置的值。】
注:如果两个层级设置的z-index值一样大,则遵循后来居上原则。
祖先元素设置了z-index(z-index不为auto):这时候祖先元素就形成了一个三维的空间盒子,子孙层级元素哪个的层级最高,就以该元素的层级为顶在Z轴上形成一个封闭的盒子。故而子孙后代元素,遵循祖先优先原则,即使子元素设置了z-index,但是其在Z轴的位置还是取决于祖先元素在Z轴的顺序。
如果祖先元素设置的z-index相同,则遵循后来居上者原则。平级关系。例如:
例二:
故而,第一个div元素的img图片会覆盖后面的div的图片。这是因为第一个div IMg元素在Z轴上的层级为2,而第二个div元素在Z轴上的层级为1,而其内部的img在这个div层级元素所形成的为封闭的三维空间中排序。