flex布局与position:absolute/fixed的冲突问题

2020-04-03 13:07:46

参考地址 当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);
        }
    }})




  • 2020-06-02 08:57:12

    clipboard复制成功但是粘贴板是空的

    将文本复制到剪贴板应该不难。配置它不需要几十个步骤,也不需要加载数百KB的js文件 。但最重要的是,它不应该依赖Flash或任何臃肿的框架。这就是clipboard.js存在的原因。

  • 2020-06-04 13:54:21

    vue生成的__ob__: Observer无法解析jsonp

    computed 从vuex获得数据,watch监听数据 然而问题就出现在了监听上,监听不到,给个setTimeOut 1000 就能检测到数据了,不然打印时又数据,用的时候时空的,不知道时什么原因。

  • 2020-06-06 20:22:56

    laravel 接收json串

    在做项目的时候发现 用平时的$request->all() 无法获取到请求值

  • 2020-06-09 08:50:28

    LRU原理以及js实现

    LRU(Least recently used,最近最少使用)算法根据数据的历史访问记录来进行淘汰数据,其核心思想是“如果数据最近被访问过,那么将来被访问的几率也更高”。

  • 2020-06-20 06:31:16

    mac下全局配置adb环境

    不提示“command not found”,而是出现一长串帮助说明,那就证明adb已经配置好了。

  • 2020-06-20 06:31:39

    Android 无线调试手机(WiFi 调试)

    手机需要开启 USB 调试 手机和电脑要在同一个局域网(连接同一个 WiFi) adb connect 连接成功后要拔出 USB 线,不然出现同时连接两个设备的问题 执行命令 ”adb tcpip 6666“ 后可能需要重新开启 USB 调试

  • 2020-08-16 16:09:30

    android WebView 注入js 几种方式

    有时我们开发中需要将js 注入到我们本地,有可能你会说,放在Web不就可以了吗,的确,但是需求就是这样的