资讯专栏INFORMATION COLUMN

探究:绝对定位没有设置 top, right, bottom, left 的世界是怎样的?

kbyyd24 / 2937人阅读

摘要:一个元素如果设置了但没有设置此元素的位置在哪在涉及到绝对定位元素的位置问题时一个重要的概念是想要了解元素的位置还得找到此元素的才行如下是我进行的一系列测试以及对测试结果的试探性解释文中的英文术语都不翻译方便直接查或者其他技术文档请持有怀疑精

一个元素如果设置了"position: absolute;", 但没有设置top, right, bottom, left, 此元素的位置在哪?

在涉及到绝对定位元素的位置问题时, 一个重要的概念是containing block, 想要了解元素的位置, 还得找到此元素的containing block才行. 如下是我进行的一系列测试, 以及对测试结果的试探性解释.

文中的英文术语都不翻译, 方便直接查W3C或者其他技术文档.
请持有怀疑精神阅读此文, 欢迎讨论.

在inline box里的情况

http://jsfiddle.net/medifle/s00Laa0a/3
上面的例子没有对任何元素设置"position: absolute;"

http://jsfiddle.net/medifle/9qnp9uh4/1
增加如下代码

span.left {
  margin-right: 10px;
  padding-right: 10px;
}
span.inner {
  position: absolute;
}

span.inner 只设置"position: absolute;", 没有设置top, right, bottom或left. 此时top, right, bottom或left的initial value是auto.

现在, 尝试用chrome开发者工具对span.inner元素的"position: absolute;"进行勾选或者取消勾选, 看看发生了什么? (提醒: 在这个例子里, span.inner与span.left元素之间是没有空白符(white space)的, span.inner内部有一个空格, 两个 .)

取消勾选"position: absolute;"后, 多出一个空白符. 再次勾选后, 多出的那个空白符消失. 这个消失的空白符是谁? 为什么会消失?

现在我们先把span.inner的"position: absolute;"取消勾选. 如果我们再尝试对span.inner分别设置"float: left;", "display: inline-block;", "display: table-cell;", "display: table;", "display: inline-table;", "display: inline-flex;", 你会发现span.inner内的第一个空白符(是一个空格)都会发生同样的现象: 消失.

消失原因得从上面的一堆属性种找共同点: BFC(block formatting context). 上面的每一个属性(包括"position: absolute;")都能够触发一个新的BFC, 所以span.inner里的内容进入了BFC后成为了新的一行, 而根据W3C的规范:

a sequence of collapsible spaces at the beginning of the line is removed

即行首部分的一个或多个可折叠(collapsible)的空白符是被移除的. 我想这就是消失的原因. 所以, 这个现象并不是"position: absolute;"没有设置top, right, bottom, left情况下的专属, 应该可以排除了.

注:

"overflow: hidden;" 不能应用于inline box, 不满足触发BFC的条件. 详情见
flow-root
BFC

"display: table;"通过产生anonymous "table-cell" box触发一个新的BFC.

从上面的例子里, 似乎span.inner的containing block的左边缘就是span.inner前面紧挨着的那个元素的margin右边缘. 情况是这样吗? 继续看下一个例子.

https://jsfiddle.net/medifle/t22sng4a/
此例中CSS未变, HTML的span.inner与span.left之间多了一个空白符, span.inner内部的第一个空白符(是个空格)去掉了, 留下了两个 .

Beginning of body contents.   Inner contents.

现在, 尝试用chrome开发者工具对span.inner元素的"position: absolute;"进行勾选或者取消勾选, 看看发生了什么?

这一次, 如果取消"position: absolute;"后再尝试对span.inner分别设置"float: left;", "display: inline-block;", "display: table-cell;", "display: table;", "display: inline-table;", "display: inline-flex;", 结果是: 没变化.

此例与上例的唯一改变就在于空白符的位置, 这说明了 span.inner的containing block的左边缘应该是span.inner前面紧挨着的那个元素(不考虑空白符)的margin右边缘. 并且left的initial value, 即"auto", 会把span.inner定位到它的containing block的左边缘 (本文只考虑文本的"direction"为"left-to-right"的情况).

https://jsfiddle.net/medifle/sccpersL/
html有改动, 加了两个图片, span与span元素之间没有空白符, 恢复span.inner的那个去掉的空白符(是个空格).

Beginning of body contents.   Inner contents.

现在测试的是span.inner(别忘了它只设置了"position: absolute;"且不设置top, right, bottom, left)的containing block的上边缘.

尝试用chrome开发者工具对span.inner元素的’position: absolute;’进行勾选或者取消勾选, 看看发生了什么?

span.inner在被赋予’position: absolute;’的时候, 其在垂直方向上的表现与对其设置"vertical-align: top;"没有差异. 从上述测试结果看, span.inner的containing block的上边缘应该与其所处的line box的content box的上边缘在位置上是一致的.

两个验证例子:
http://jsfiddle.net/medifle/3y7ucLLy/
http://jsfiddle.net/medifle/proa0fru/

对于上述的第二个例子, 尝试用chrome开发者工具对img.img1元素的’position: absolute;’进行勾选或者取消勾选, 看看发生了什么? (留意: img.img1和img.img2都设置了"position: absolute;"且没有设置top, right, bottom, left).

结果说明, 对一个元素(img.img1)进行绝对定位会影响到另一个绝对定位的元素(img.img2)的位置, 当然, 这个"绝对定位"是没有设置四个方向属性的值的情况.

http://jsfiddle.net/medifle/upg4da8o/
此例CSS变动如下:

.inbox {
    color: blue;
    position: absolute;
    top: -10px;
}
.floatele {
    float: right;
    width: 300px;
    height:50px;
    background: tomato;
    padding: 10px;
}
.demorel {
    position: relative;
}

HTML如下:

Beginning of body contents.

  Inner contents.   Inner contents.

此例的第二个"Inner contents.", 即span.inbox设置了top: -10px; 其他三个方向仍然不设置, 即为auto. section.demorel设置了"position: relative;". div.floatele设置了"float: right;", 此时span.inbox的containing block的左边缘仍然满足前面的结论.

在block box里的情况

http://jsfiddle.net/medifle/26dgo5k7/

CSS主要有:

.inbox2 {
    background: #6c4ecd;
    width: 50px;
    height: 50px;
    position: absolute;
}
.floatele {
    float: right;
    width: 300px;
    height:50px;
    background: tomato;
    padding: 10px;
}
.demorel {
    position: relative;
}

div.inbox2的containing block的左边缘和上边缘都是其直系父元素content box的左边缘和上边缘 (content box的边缘又称content edge).

但值得注意的是, 此例与常规绝对定位情况下的区别:
http://jsfiddle.net/medifle/j7xevk78/

CSS有改变, 包含在HTML内:

这是一个常规的绝对定位例子, 因为设置了top和left的值. 值得注意的一点是, 此时div.inbox2的containing block的左边缘和上边缘是其直系父元素的padding edge.

如果div.inbox2的前面有一个block box:
https://jsfiddle.net/medifle/dvcfev3s/3/

此例中有两个div.inbox2, 在它们之前分别有一个block box, 一个是div.blockbox, 另一个是p元素.

从这个例子可以发现, 如果div.inbox2不是其父元素的第一个元素, 且前面是一个block box, 则div.inbox2的containing block的上边缘是div.blockbox的margin下边缘.

小结

当绝对定位且不设置方向值的元素在inline box里时:

未设置的方向(top, right, bottom, left)的值是auto.

此元素containing block的左边缘应该是该元素前一个元素(空白符除外)的margin右边缘.

此元素containing block的上边缘应该是该元素所在的line box的content box的上边缘

如果left的值为auto, 则该元素会定位到其containing block的左边缘. 如果top的值为auto, 则该元素会定位到其containing block的上边缘.

当绝对定位且不设置方向值的元素在block box里时:

未设置的方向(top, right, bottom, left)的值是auto.

此元素的containing block的左边缘应该是其父元素创建的content box的左边缘.

如果该元素前面存在一个与其相邻的block box, 则该元素的containing block的上边缘应该是这个block box的margin下边缘.

如果该元素是其父元素的第一个子元素, 则该元素的containing block的上边缘应该是其父元素创建的content box的上边缘.

如果left的值为auto, 则该元素会定位到其containing block的左边缘. 如果top的值为auto, 则该元素会定位到其containing block的上边缘.

本文只探讨了元素分别在line box和block box里的containing block的左边缘和上边缘(文本的"direction"为默认的"ltr", 即从左到右), 还有更多有待探讨.

本文所探讨的问题我没有找到直接相关的W3C规范, 如果有请一定要@bolo :)

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/111115.html

相关文章

  • BFC一些探究

    摘要:它是用于决定盒子的布局及浮动相互影响范围的一个区域。小白反思如果世界的运行都有自我运行的一套机制,那么的世界必然有自己的一套规则。外边距合并当时在回答外边距的问题时,总结出了合并的一条规则必须相邻。 最初的梦 了解BFC后,能够更深入的明白外边距合并原理。了解BFC后,能够更深入的明白浮动的行为。了解BFC后,知识就是你的,总不会吃亏对吧?哈哈 之前有两篇文章《行内元素的一些探索》、《...

    curlyCheng 评论0 收藏0
  • 你有所不知margin属性

    摘要:前言致谢本文总结于张鑫旭老师的深入理解之课程,感谢张老师的辛苦付出难学的作为前端狗的我们,每天都要和网页打交道。页面中任何地方,嵌套或直接放入任何空的,都不会影响原来的布局。比如,给元素声明,但在中的属性是。 前言 致谢  本文总结于 张鑫旭老师的 CSS深入理解之margin课程,感谢张老师的辛苦付出! 难学的 CSS  作为前端狗的我们,每天都要和网页打交道。当 UI 将设计稿发给...

    joywek 评论0 收藏0
  • 《css世界》- 详细重点笔记与技巧

    摘要:概述在世界这本书中有一些黑魔法给列举出来,在结合自己的理解。篇幅有点长,希望大家能够坚持看完,一定会有收获以下是摘自每章内一些重要的概念与技巧。 概述 在《css世界》这本书中有一些黑魔法给列举出来,在结合自己的理解。篇幅有点长,希望大家能够坚持看完,一定会有收获!!!以下是摘自每章内一些重要的概念与技巧。其中有解决图片间隙的问题、小图标与文字居中问题等; ps: 特别是 line-h...

    MasonEast 评论0 收藏0
  • 《css世界》- 详细重点笔记与技巧

    摘要:概述在世界这本书中有一些黑魔法给列举出来,在结合自己的理解。篇幅有点长,希望大家能够坚持看完,一定会有收获以下是摘自每章内一些重要的概念与技巧。 概述 在《css世界》这本书中有一些黑魔法给列举出来,在结合自己的理解。篇幅有点长,希望大家能够坚持看完,一定会有收获!!!以下是摘自每章内一些重要的概念与技巧。其中有解决图片间隙的问题、小图标与文字居中问题等; ps: 特别是 line-h...

    赵连江 评论0 收藏0

发表评论

0条评论

kbyyd24

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<