整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

记录CSS中 position-fixed 踩的坑

记录CSS中 position:fixed 踩的坑

html 页面的css样式中,如果将 position 属性的值设置为 fixed,那就表示其元素的位置相当于显示设备的可视区域进行定位,而今天在调试此属性时,却发生了一件奇怪的事件。

position:fixed 定位失效情况复现

失效代码:

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>Document</title>
</head>
<style>
 body{
 height: 150%;
 width: 100%;
 transform: translate(0, 0);
 }
 div{
 position: fixed;
 left: 50%;
 top: 50%;
 width: 100px;
 height: 200px;
 margin: -100px 0 0 -50px;
 background-color: brown;
 }
</style>
<body>
 <div></div>
</body>
</html>

代码动行结果:

注意:

1、代码的样式是规定DIV元素模块,在浏览器的可视窗口中,上下左右居中

2、实际的显示效果,DIV模块已经向上偏移

position:fixed 定位问题解决方法

通过排查代码,可以发现,在 body 样式属性中,有个 transform: translate(0, 0) 属性,去掉此属性后,position:fixed 定位问题解决

修复后的代码

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>Document</title>
</head>
<style>
 body{
 height: 150%;
 width: 100%;
 }
 div{
 position: fixed;
 left: 50%;
 top: 50%;
 width: 100px;
 height: 200px;
 margin: -100px 0 0 -50px;
 background-color: brown;
 }
</style>
<body>
 <div></div>
</body>
</html>

代码运行结果:

position:fixed 定位出错的原因

关于此问题的出现,牵涉到了 Stacking Context(堆叠上下文的概念)。

堆叠上下文,是 HTML 元素的三维概念,这些 HTML 元素在一条假想的相对于面向(电脑屏幕的)视窗或者网页的用户的 z 轴上延伸,HTML 元素依据其自身属性按照优先级顺序占用层叠上下文的空间。

1、任何非 none 的 transform 值都会导致一个堆叠上下文(Stacking Context)和包含块(Containing Block)的创建。

2、由于堆叠上下文的创建,该元素会影响其子元素的固定定位。设置了 position:fixed 的子元素将不会基于 可视窗口定位,而是基于这个父元素。

是摘抄自MDN中对于css属性position的定义:

CSS position属性用于指定一个元素在文档中的定位方式。top,right,bottom 和 left 属性则决定了该元素的最终位置

在日常编写html开发时,我总想有一只魔法棒该多好啊,只要一挥手,页面上所有元素都能放在我想要放的位置。可是愿望很美好,现实很残酷,不但残酷,还有个别不听话的元素经常跟我们作对。

新需求来了

领导找到我说,我的产品要有这样一个功能,在浏览器的最底端始终显示我们公司软件的下载按钮,快去做!

拿到需求后心想,这还不简单,这次分分钟中给你搞定。于是我这样写下

很完美的实现


然后信心满满的拿着我的杰作给产品经理看

杰作

领导看完直说,小伙子不错吗,这么快就完成了,看好你哦。得到领导的夸奖别说多兴奋了 。

。。。

可是好景不长,半夜里领导突然打电话说,有客户投诉了,说咱么这是什么破产品,一个下载按钮不在底下好好呆着,乱跑!

无法控制的绝对定位


吃了领导一顿劈头盖脸的批评,挂了电话,我陷入了深深的沉思。。我到底哪里做错了,明明用的absolute绝对定位,怎么会出现这种情况呢。

哎,学艺不精又能怪谁呢,问题出现了,现在最重要的是怎么快速解决吧

fixed出场

众里寻他千百度,慕然回首,你在mdn处。

原来css中绝对定位不只是absolute,还有一种叫做fixed的选项,MDN中这样说明的

fixed:元素会被移出正常文档流,并不为元素预留空间,而是通过指定元素相对于屏幕视口(viewport)的位置来指定元素位置。元素的位置在屏幕滚动时不会改变

相对于屏幕视口(viewport)的位置来指定元素位置,元素的位置在屏幕滚动时不会改变

一语惊醒梦中人啊,我那个absolute就是被滚动条滚动上去的啊,好想说一句MD.

于是我将我的absolute改成了fixed,终于解决了问题

同为绝对定位,区别在于哪里呢

absolute的位置是相对于整个页面,就像拿一个图钉把它定在了页面,页面滚动元素也会跟着滚动。

而fixed定位呢,是相对于屏幕视口(viewport),即相对于我们肉眼看到的页面屏幕,即使页面滚动,我们的视口是不改变的,所以我们看到的元素就是不动的。

ps:文中的MDN是我经常学习的网站,著名浏览器Fixfox出品

定定位(1)给自身设置宽高(2)设置position:fixed(3)底部元素内顶边距