内容:
1. position定位原理
2. css盒子模型
3. 确定元素在页面的位置
position定位原理
为了制作更多复杂的布局,我们需要讨论下 position 属性。它有一大堆的值,名字还都特抽象,别提有多难记了。让我们先一个个的过一遍,不过你最好还是把这页放到书签里。
1.static
.static {
position: static;
}
static 是默认值。任意 position: static; 的元素不会被特殊的定位。一个 static 元素表示它不会被“positioned”,一个 position 属性被设置为其他值的元素表示它会被“positioned”。
2.relative
.relative1 {
position: relative;
}
.relative2 {
position: relative;
top: -20px;
left: 20px;
background-color: white;
width: 500px;
}
imagerelative 表现的和 static 一样,除非你添加了一些额外的属性。在一个相对定位(position属性的值为relative)的元素上设置 top 、 right 、 bottom 和 left 属性会使其偏离其正常位置。其他的元素的位置则不会受该元素的影响发生位置改变来弥补它偏离后剩下的空隙。
3.fixed
一个固定定位(position属性的值为fixed)元素会相对于视窗来定位,这意味着即便页面滚动,它还是会停留在相同的位置。和 relative 一样, top 、 right 、 bottom 和 left 属性都可用。
4.absolute
absolute 是最棘手的position值。 absolute 与 fixed 的表现类似,但是它不是相对于视窗而是相对于最近的“positioned”祖先元素。如果绝对定位(position属性的值为absolute)的元素没有“positioned”祖先元素,那么它是相对于文档的 body 元素,并且它会随着页面滚动而移动。记住一个“positioned”元素是指 position 值不是 static 的元素。
这里有一个简单的例子:
.relative {
position: relative;
width: 600px;
height: 400px;
}
.absolute {
position: absolute;
top: 120px;
right: 0;
width: 300px;
height: 200px;
}
image
css盒子模型
盒模型(box model)是CSS中的一个重要概念,它是元素大小的呈现方式。需要记住的是:"every element in web design is a rectangular box"。如图:
image
CSS3中新增了一种盒模型计算方式:box-sizing熟悉。盒模型默认的值是content-box, 新增的值是padding-box和border-box,几种盒模型计算元素宽高的区别如下:
1.content-box(默认)
布局所占宽度Width:
Width = width + padding-left + padding-right + border-left + border-right
布局所占高度Height:
Height = height + padding-top + padding-bottom + border-top + border-bottom
2.padding-box
布局所占宽度Width:
Width = width(包含padding-left + padding-right) + border-top + border-bottom
布局所占高度Height:
Height = height(包含padding-top + padding-bottom) + border-top + border-bottom
3.border-box
布局所占宽度Width:
Width = width(包含padding-left + padding-right + border-left + border-right)
布局所占高度Height:
Height = height(包含padding-top + padding-bottom + border-top + border-bottom)
不同盒子模型计算方式的影响
上述三种设定方式将会影响设定元素宽度和高度的值时,元素所占页面的实际空间。例如设定一个元素值如下:
<div id="demo" style="position:absolute;
left:518px; right:100px;
width:500px; height:500px;
background:#CC0000; top: 114px;
margin-left: 0px; border:5px solid blue;
padding:20px;">
Demo为了方便就直接用绝对定位的元素
</div>
因为盒子模型的计算方式默认为content-box,所以上述代码中设定的width:500px; height:500px;
设定的是content的宽度,元素实际占用的页面空间宽度为:
width = 5 + 20 + 500 + 20 + 5 =550
height = 5 + 20 + 500 + 20 + 5 =550
获取元素在页面的位置
getBoundingClientRect
getBoundingClientRect用于获取某个元素相对于视窗的位置集合。集合中有top, right, bottom, left等属性。
<img src="https://i.loli.net/2017/12/28/5a44af2995596.png" alt="" width="200" height="200" />
getBoundingClientRect访问方式
1. jquery访问
$('#m-price')[0].getBoundingClientRect()
2. 原生访问
document.getElementById('m-price-calculate').getBoundingClientRect()
返回元素:
{
bottom: 553, //元素下边到视窗上边的距离;
height: 553, //元素高度,ie9以上支持
left: 840, //元素左边到视窗左边的距离;
right: 1190, //元素右边到视窗左边的距离;
top: 0, //元素上边到视窗上边的距离
width: 350 //元素宽度,ie9以上支持
}
举个例子
页面源码如下
<!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>Demo</title>
<script src="jquery.js" type="text/javascript"></script>
</head>
<body style="width:2000px; height:1000px;">\
<div id="demo" style="position:absolute;
left:108px; right:100px;
width:500px; height:500px;
background:#CC0000; top: 114px;
margin-left: 0px; border:5px solid blue;
padding:20px;">
Demo为了方便就直接用绝对定位的元素
</div>
<body>
</html>
<script>
document.getElementById('demo').onclick=function (){
var str = "";
if (document.documentElement.getBoundingClientRect) {
str += "left:"+this.getBoundingClientRect().left + "\n"
+ "top:"+this.getBoundingClientRect().top + "\n"
+ "right:"+this.getBoundingClientRect().right + "\n"
+ "bottom:"+this.getBoundingClientRect().bottom + "\n"
+ "原生js获取位置是X:" + (parseFloat(this.getBoundingClientRect().left) + parseFloat(document.documentElement.scrollLeft) )+ ";Y:"+ (parseFloat(this.getBoundingClientRect().top)+parseFloat(document.documentElement.scrollTop))+"\n"
+ "scrollLeft:" + document.documentElement.scrollLeft + "scrollTop: " + document.documentElement.scrollTop + "\n";
console.log(str);
console.log( "jquery获取的位置X:" + $(this).offset().left + " Y:" + $(this).offset().top ) ;
//console.log($(this)[0].getBoundingClientRect());
}
}
</script>
点击红色区域,控制台输出如下:
left:108
top:114
right:658
bottom:664
原生js获取位置是X:108;Y:114
scrollLeft:0scrollTop: 0
position.html:25 jquery获取的位置X:108 Y:114
由上可知:
jquery中
offset().left = (parseFloat(this.getBoundingClientRect().left) + parseFloat(document.documentElement.scrollLeft) ;
offset().left等于元素距离最近的“positioned”祖先元素。如果绝对定位(position属性的值为absolute)的元素没有“positioned”祖先元素,那么它是相对于文档的 body 元素的距离,
同时等于页面元素距离浏览器(亦称为视口viewport)的距离加上滚动条滚动的距离。
注意offset().left指的是元素盒子距离父元素的距离
例如如下元素生成的信息如下
<div id="demo" style="position:absolute; left:58px;
right:100px; width:500px; height:500px;
background:#CC0000; top: 114px; margin-left:
100px; border:5px solid blue; padding:20px;">
Demo为了方便就直接用绝对定位的元素
</div>
image
网友评论