参考地址 当display:flex弹性布局与position:absolute/fixed定位一起用,会出现的问题与解决方法
首先放出使用场景的截图:
使用场景
导航栏固定定位
导航栏内,平均分为四块,为了适配各种移动设备,使用了flex布局。
与此同时,产品经理要求:页面上滚越过封面图时,导航栏变为固定定位,浮在页面顶部。
拿到需求之后,思路就是先搞好布局,然后监听window.onscroll,当页面滚的距离大于封面图的时候,给ul加入position:fixed。
下面再现一下问题:
<!--DOM结构:--><body> <h1>flex布局与position:absolute/fixed踩坑</h5> <ul> <li>协会简介</li> <li>协会章程</li> <li>协会架构</li> <li>资料下载</li> </ul></body>
//主要的样式<style> ul { display: flex; justify-content: space-between; margin: 0 15px; background: pink; } li { flex: 1; list-style: none; height: 100px; line-height: 100px; text-align: center; font-size: 30px; border: 1px solid #fff; } </style>
当单独使用display: flex 时,是没有问题的。
对ul使用了display:flex
当对ul加入position:absolute/fixed时,再来看一下页面变化,我录了gif图直观的感受下flex失效的过程~~~:
flex与position:absolute/fixed 同时作用于ul
所以,被绝对定位与固定定位的盒子不参与flex布局。(注意不包括相对定位哦~)
划重点!这个问题怎么解决呢?
既然被定位的盒子不参与flex,那就在这个盒子外面套一个盒子,给外层盒子使用定位,内层没有使用定位的盒子继续使用flex。这样不就解决了~~~哦对了!还要给外层盒子设置宽度,100%就好啦!
<!--新的DOM结构:--><body> <h1>flex布局与position:absolute/fixed踩坑</h5> <div class="nav-box"> <ul> <li>协会简介</li> <li>协会章程</li> <li>协会架构</li> <li>资料下载</li> </ul> </div></body><!--样式设置:--> .nav-box { width: 100%; position: fixed; } ul { display: flex; justify-content: space-between; margin: 0 15px; background: pink; } li { flex: 1; list-style: none; height: 100px; line-height: 100px; text-align: center; font-size: 30px; border: 1px solid #fff; }
再录一个gif,错乱的样式又改回来啦!~~
在ul外包裹一个新的div,对其使用定位
关于flex布局的知识点,阮大大有两篇博客可以学习:
Flex 布局教程:语法篇
Flex 布局教程:实例篇
最后再记录一下,监听window.onscroll实现下拉到某距离时采用绝对定位:
$(function () { var headerHeight = $('.header').outerHeight(); //logo区域的高度 var imgHeight = $('.topImg').outerHeight(); //图片区域的高度 var distance = imgHeight - headerHeight; //要监测的页面上滚距离 window.onscroll = function () { var top = $(document).scrollTop(); //j记录页面上滚距离 if (top >= distance){ $('.navBox').css({'position':'fixed','top':headerHeight+'px'}); $('.detailsInfo').css('paddingTop',$('.navBox').outerHeight()+'px'); //绝对定位之后,当前元素脱标,不占据原来的位置。下面的元素会挤上来且被ul遮盖。这个时候需要为下面的元素设置上内边距撑住! }else { $('.navBox').css({'position':'static','top':0}); $('.detailsInfo').css('paddingTop',0); } }})