前端技术——3——浮动与定位

Posted kaoa000

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了前端技术——3——浮动与定位相关的知识,希望对你有一定的参考价值。

浮动与定位:float,position

块级标签:<div> <p> <h1-6> <ul><ol><dl>
内联标签:<a> <img> <input> <span><select><textarea>

正常文档流:将元素(标签)在进行排版布局的时候,按照从上到下,从左到右的顺序进行排版的一个布局流。如果都是内联标签,则一行最右边的标签显示长度大于当前行右边的空间长度,自动换行到下一行的最左边,如果是块级标签,则一个标签占一行,即从新的一行的最左边开始独占一行。
脱离文档流:将元素(标签)从正常文档流中取出,进行覆盖,其他元素会按照文档流中不存在该元素从更新进行布局。有两个属性可以使元素脱离文档流:float和position。

float(浮动):非完全脱离
position:absolute | fixed (定位):完全脱离,还有两个relative | static,没有脱离文档流

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .div1
            background-color: green;
            width: 100px;
            height: 100px;
        
        .div2
            background-color: blue;
            width: 100px;
            height: 100px;
        
        .div3
            background-color: yellow;
            width: 300px;
            height: 300px;
        
    </style>
</head>
<body>
<div class="div1"></div>
<div class="div2"></div>
<div class="div3"></div>
</body>
</html>

所有块级标签,每个标签单独占据一行,三个div占据三行:

 内联与块级混合:

<a href="#">aaaaaaa</a><a href="#">bbbbbbbbbb</a>
<div class="div1"></div>
<div class="div2"></div><a href="#">cccccccccc</a>
<div class="div3"></div>

 float:设置div2为float,即让蓝色盒子浮起来

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .div1
            background-color: green;
            width: 100px;
            height: 100px;
        
        .div2
            background-color: blue;
            width: 100px;
            height: 100px;
            float: left;
        
        .div3
            background-color: yellow;
            width: 300px;
            height: 300px;
        
    </style>
</head>
<body>
<div class="div1"></div>
<div class="div2"></div>
<div class="div3"></div>
</body>
</html>

 蓝色盒子浮起来是,就脱离了正常文档流,它的位置会被后面的标签占据,浮起,相当于分层了,浮到了上一层,上一层又遮盖了下面的一层。黄色的盒子顶上去了,占据了原来蓝色盒子的位置,所以蓝色盒子是脱离了文档流的。关键是蓝色盒子浮起后的位置。这里设置的是向左漂浮,原则就是一直向左飘,直到碰到边框为止,然后向上飘,直到遇到第一个正常文档流中的块级标签或内联标签长度超过屏幕一行的长度,然后在其垂直位置下方;或者是上一个浮动标签的左边。

上面的例子是向左浮动然后向上遇到块级标签,即绿色盒子,然后垂直对齐绿色盒子排列。

修改一下:
 

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .div1
            background-color: green;
            width: 100px;
            height: 100px;
        
        .div2
            background-color: blue;
            width: 100px;
            height: 100px;
            float: left;
        
        .div3
            background-color: yellow;
            width: 300px;
            height: 300px;
        
    </style>
</head>
<body>
<div class="div1"></div>
<span>||aaaaa||</span>
<div class="div2"></div>
<div class="div3"></div>
</body>
</html>

蓝色盒子向上浮动,将<span>内联标签挤开, 紧挨着绿色盒子排版。增加内联标签个数,致使其一行超过屏幕长度:这样写<span>||aaaaa||</span><span>||aaaaa||</span><span>||aaaaa||</span><span>||aaaaa||</span>。。。

 如果两个span标签中间有一个空格,或者是一行写一个span标签,如:
<span>||aaaaa||</span>
<span>||aaaaa||</span>
。。。
<span>||aaaaa||</span>

float设置为right:

 如果div1,即绿色盒子也设置为float:left

绿色盒子先浮动,到最左边,蓝色盒子随后向左浮动,一直到到绿色盒子右边,因为绿色和蓝色盒子都浮动,所以位置都让出来,黄色盒子就到了原来绿色盒子位置处。如果绿色盒子设置为float:right,则:

 

 蓝色盒子也设置为float:right

 相当于浮动起来的标签又组成了一个文档流。

如果div中有文本内容:

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .div1
            background-color: green;
            width: 100px;
            height: 100px;
        
        .div2
            background-color: blue;
            width: 100px;
            height: 100px;
            float: left;
        
        .div3
            background-color: yellow;
            width: 300px;
            height: 300px;
        
    </style>
</head>
<body>
<div class="div1">1111</div>
<div class="div2">2222</div>
<div class="div3">3333</div>
</body>
</html>

 2222并没有覆盖3333,这就是float是非完全脱离的原因。它将下面覆盖的标签中的文本给撑出去了。float原本就是为了设置本文围绕图片格式功能设计的,没有完全脱离文档流。

float属性,要知道,div是块级元素,在页面中独占一行,自上而下排列,也就是流。无论多么复杂的布局,其基本出发点都是:如何在一行显示多个div元素。浮动可以理解为让某个div元素脱离标准流,漂浮在标准流之上,和标准流不是一个层次。

假如某个div元素A是浮动的,如果A元素上一个元素也是浮动的,那么A元素会跟随上一个元素的后边(如果一行放不下这两个元素,那么A元素会被挤到下一行);如果A元素上一个元素是标准流中的元素,那么A的相对垂直位置不会改变,也就是说A的顶部总是和上一个元素的底部对齐。

div的顺序是HTML代码中div的顺序决定的。靠近页面边缘的一端是前,远离页面边缘的一端是后。当初float被设计的时候就是用来完成文本环绕的效果,所以文本不会被挡住,这是float的特性,即float是一种不彻底的脱离文档流方式。

清除浮动:在非IE浏览器下,当容器的高度为auto,且容器中有浮动(float为left或right)的元素,在这种情况下,容器的高度不能自动伸长以适应内容的高度,使得内容溢出到容器外面而影响(甚至破坏)布局的现象。这个现象叫做浮动溢出,为了防止这个现象出现而进行的CSS处理,就叫做CSS清除浮动。

清除浮动的关键字是clear:clear : none | left | right | both

取值:
none:默认值。允许两边都可以有浮动对象。
left:不允许左边有浮动对象。
right:不允许右边有浮动对象。
both:不允许有浮动对象。

清除不是去修改其他元素,而是使设置清除的元素自己向下移动一行,使自己的左右或两边不含有浮动元素,也就是原先与浮动元素为伍,现在不想队伍里有浮动对象,但是又不能改变别的元素,只好自己退出,不与他们为伍了。

例子:想做一个如下效果的页面

 初始代码如下:
 

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .outer
            background-color: blue;
        
        .menu1
            width: 100px;
            height: 50px;
            color: gold;
        
        .menu2
            width: 100px;
            height: 50px;
            color: gold;
        
        .bottom
            text-align: center;
            background-color: rosybrown;
        
    </style>
</head>
<body>
<div class="outer">
    <div class="menu1">菜单一</div>
    <div class="menu2">菜单二</div>
</div>
<div class="bottom">底部</div>
</body>
</html>

显示效果:

设置浮动:

 

结果:

 

菜单一二的背景没了,底部上去了。有点乱了。

原因是对于outer盒子来说,当menu1和menu2都浮动后,相当于outer盒子变成了空盒子,空盒子没有内容,又没有设置高度宽度,所以盒子撑不起来了。

可以设置一下outer,设置一个高度50px,就可以撑起这个盒子。但是这就使高度设成固定值了。

 推荐的可以使用清除clear来解决:

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .outer
            background-color: blue;
            /*height: 50px;*/
        
        .menu1
            width: 100px;
            height: 50px;
            color: gold;
            float: left;
        
        .menu2
            width: 100px;
            height: 50px;
            color: gold;
            float: left;
        
        .clear
            clear: both;   /*设置清除*/
        
        .bottom
            text-align: center;
            background-color: rosybrown;
        
    </style>
</head>
<body>
<div class="outer">
    <div class="menu1">菜单一</div>
    <div class="menu2">菜单二</div>
    <div class="clear"></div>   /*添加一个空div*/
</div>
<div class="bottom">底部</div>
</body>
</html>

这是清除的一个固定用法。

第三种方法:在outer盒子上设置overflow:hidden

.outer
         background-color: blue; 
         overflow: hidden;

position:定位

固定在屏幕的固定位置:

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .div1
            height: 1000px;
            background-color: rosybrown;
        
        .div2
            height: 1000px;
            background-color: green;
        
        a
            position: fixed;
            bottom: 20px;
            right: 20px;
        
    </style>
</head>
<body>
<div class="div1"></div>
<div class="div2"></div>
<a>返回顶部</a>
</body>
</html>

 

 随着网页的下拉,返回顶部几个字始终固定在这个位置。这是position:fixed作用。这时就脱离文档流了。

还有position : fixed | absolute | relative | static

relative:相对定位:

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .div1
            background-color: green;
            width: 100px;
            height: 100px;
        
        .div2
            background-color: blue;
            width: 100px;
            height: 100px;
            position: relative;  /*设置定位,为相对定位*/
            top: 100px;
            left: 100px;
            
        .div3
            background-color: yellow;
            width: 300px;
            height: 300px;
        
    </style>
</head>
<body>
<div class="div1">1111</div>
<div class="div2">2222</div>
<div class="div3">3333</div>
</body>
</html>

 因为黄色盒子没有顶上去,说明蓝色盒子的位置还在,所以没有脱离文档流。

absolute:

将上述程序的position设置为absolute,其他不变:

 从上述结果,暂时能够得出,设置absolute后,元素脱离了文档流,黄色盒子顶上去了,然后,蓝色盒子的定位,现在看来是参照浏览器(html标签),即以屏幕0,0坐标来左移100px,下移100px,因为body外边还有空白,所以蓝色和绿色有一点交叉。

对于position属性:

1、static,默认值static:无特殊定位,对象遵循正常文档流。
top,right,bottom,left等属性不会被应用。对于文档流,其实就是文档的输出顺序,也就是我们通常看到的由左到右,由上而下的输出形式,在网页中每个元素都是按照这个顺序进行排序和显示的,而float和position两个属性可以将元素从文档流中脱离出来显示。默认值就是让元素继续按照文档流显示,不做任何改变。

2、position:relative/absolute:
relative:对象遵循正常文档流,但将依据top、right、bottom、left等属性在正常文档流中偏移位置。而其层叠通过z-index属性定义。
absolute:对象脱离文档流,使用top、right、bottom、left等属性进行绝对定位。而其层叠通过z-index属性定义。如果设定position:relative,就可以使用top、right、bottom、left来相对于元素在文档中应该出现的位置来移动这个元素。【意思是元素实际上依然占据文档中的原有位置,只是视觉上相对于它在文档中的原有位置移动了】,当指定position:absolute时,元素脱离了文档【即在文档中已经不占据位置了】,可以准确的按照设置的top、right、bottom和right来定位了

如果没有设置left,top又没有设置right,bottom,它跟static时的位置一样,会被他的上一个static或relative兄弟挤下去,但是它本身不占位置。

对于absolute的元素,会找其最近的、且为非static的父元素为参照基准进行位置调整,即运用top、right、bottom、left以这个父元素位置为基准进行调整。

3、position:fixed:在理论上,被设置为fixed的元素会被定位于浏览器窗口的一个指定坐标,不论窗口是否滚动,它都会固定在这个位置。

fixed:对象脱离正常文档流,使用top、right、bottom、left等属性以窗口为参考点进行定位,当出现滚动条时,对象不会随着滚动。而其层叠通过z-index属性定义。注意,一个元素若设置了position:absolute | fixed,则该元素就不能设置float。这是一个常识性知识点,因为这是两个不同的流,一个是浮动流,另一个是定位流。但是relative可以,因为它原本所占的空间仍然占据文档流。

对于上面的例子,我们给div2套一个父元素div,class=‘box2’。

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .div1
            background-color: green;
            width: 100px;
            height: 100px;
        
        .div2
            background-color: blue;
            width: 100px;
            height: 100px;
            /*position: absolute;  !*设置定位,为相对定位*!*/
            /*top: 100px;*/
            /*left: 100px;*/
            
        .div3
            background-color: yellow;
            width: 300px;
            height: 300px;
        
        .box2
            border: 10px solid red;
        
    </style>
</head>
<body>
<div class="div1">1111</div>
<div class="box2">
    <div class="div2">2222</div>
</div>
<div class="div3">3333</div>
</body>
</html>

 对div2设置position:absolute

position: absolute;  /*设置定位,为相对定位*/
top: 100px;
left: 100px;

此时,div2的表现与没有加box2相同,也就是div2还是相对于浏览器窗口,即HTML标签进行的参照定位。

对box2进行设置,同时修改一下div3,作为对比:

 <style>
        .div1
            background-color: green;
            width: 100px;
            height: 100px;
        
        .div2
            background-color: blue;
            width: 100px;
            height: 100px;
            position: absolute;  /*设置定位,为相对定位*/
            top: 100px;
            left: 100px;
            
        .div3
            background-color: yellow;
            width: 200px;
            height: 200px;
        
        .box2
            border: 10px solid red;
            position: relative;
        

 

此时,div2将相对于其最近的非static属性的父对象为参考点进行定位,它最近的非static父类就是box2,其有边框10px,所以div2呈现上图的位置。

如果给box2加上padding属性,如padding:20px

 

所以,是以内边框左上角为参照点。 

将box2设置为absolute:

 box2设置为fixed:

 关于margin:0 auto;就是使内层的标签在外层标签中居中:

<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .div1
            background-color: rosybrown;
            height: 30px;
        
        .div2
            background-color: goldenrod;
            height: 30px;
            width: 300px;
            margin: 0 auto;
        
    </style>
</head>
<body>
<div class="div1">
    <div class="div2"></div>
</div>
</body>

 内联标签,只有内容的宽高,不能设置宽高,要设置宽高,就要使用块级标签,如果又要设置宽高,又要在一行显示,就要使用display:inline-block。

以上是关于前端技术——3——浮动与定位的主要内容,如果未能解决你的问题,请参考以下文章

前端3 浮动布局,固定定位,绝对定位,相对定位

前端基础学习浮动与定位

前端基础学习浮动与定位

前端基础学习浮动与定位

python 之 前端开发(盒子模型页面布局浮动定位z-indexoverflow溢出)

3.浮动与定位