首先,来段代码进行css的postion属性的学习之路。
<html>
<head>
<title> position </title>
<style>
body { margin: 0px; padding: 0px; color: white; text-align: right; }
.box { width: 50px; border: dotted yellow; }
.square { width: 100px; height: 100px; }
.r { background-color: red; }
.g { background-color: green; }
.b { background-color: blue; }
#l { float: left; }
#r { float: right; }
#abs { position: absolute; top: 150px; left: 50px; }
#rel { position: relative; top: 150px; left: -50px; }
</style>
</head>
<body>
<div class="box" id="l">
<div class="r" class="square" id="abs">R</div>
<div class="g" class="square">G</div>
<div class="b" class="square">B</div>
</div>
<div class="box" id="r">
<div class="r" class="square" id="rel">R</div>
<div class="g" class="square">G</div>
<div class="b" class="square">B</div>
</div>
</body>
</html>
其实这段代码写的不是很规范,例如document,meta等,我们就先忽视这个问题。。。
postion属性有四个值,分别是static,absolute, relative, fixed。其中static和relative两个属性值是跟文档流有关,其他两个跟文档流无关。那么什么是叫文档流呢?我的理解是文档流就是对文档的读入和输出顺序,例如上述所贴的代码,box类下有三个div,如果我们忽视它们的css样式,那么它们在浏览器的展示方式是从上到下是R,G,B,并且每一个占用一层。
static,默认的position值,如果对元素进行TLBR操作,是不起任何作用的(怪不得刚开始没设置position的值,根本没发生偏移,囧)。
relative,相对定位。其实这里的相对定位,是相对它本身在正常文档流的位置的偏移,尽管偏移了,它原本在正常文档流的位置还在保存着,例如上例的结果,你在浏览器中可以看到右上角的L的位置还存在,尽管L已经飘走了。所以尽管L进行了相对定位,但是它的存在还是对G和B有影响,并不抽离出文档流。
absolute,绝对定位。这里的绝对定位,是指它本身被抽离出文档流,即一旦它的positive设置为absolute,它原先在文档流中所占的位置就被其他的元素所占用。那么对它进行TLBR操作则是怎么定位呢?它会首先寻找距离它最近的父元素,并且该父元素的position属性值不为static,如果查找不到,ok,这是它就会相对body进行TLBR操作。
fixed,该属性值相对于浏览器窗口,因此拖动滚动条不影响它在窗口中的位置。
之所以研究position是因为看到了阿里2014的一个线上笔试题,如下:
有两个盒子A和B,其中B在A盒子内,现在要求实现B在A中水平方向和垂直方向均居中。
.A {
position: relative;
width: 500px;
height: 500px;
background-color: green;}
.B {
position: absolute;
max-width: 300px;
max-height: 300px;
background-color: blue;}
这里设定A为宽度和高度一定的relative定位,B相对A进行TLBR操作使其相对A居中。
刚开始拿到这题时,我把它想的巨简单,既然B的父元素A相对定位,那么把B相对A的top进行50%,left进行50%偏移,不就居中了么?然后很happy的测试一下,果然居中,好吧,其实只是B的左上角坐标居中,当B中有content、border、padding中任何一项内容时,就不满足要求了,还是继续思考怎么解决。
接下来想到一种比较暴力的方法,因为题中并没有要求用的是CSS解决这个问题,所以想到了用JS实现。首先计算出A的宽度,当然这个宽度是padding+border+content。先把代码贴上,明天继续分析。
<script>
var b = document.getElementsByClassName('B')[0];
var a = document.getElementsByClassName('A')[0];
var width = b.offsetWidth;
var height = b.offsetHeight;
var w = a.offsetWidth;
var h = a.offsetHeight;
b.style.marginLeft = (w - width) / 2 + 'px';
b.style.marginTop = (h - height) / 2 + 'px';
</script>
后来在网上看到有种解法,把B的position重新设置为非absolute,然后添加A的css样式
.A {
display: -webkit-box;
-webkit-box-align: center;
-webkit-box-pack: center;}
这样也能解决问题,可是我觉得既然题目要求A是relative,B是absolute,篡改题意这种做法不可取