CSS transform 使 fixed 定位失效?

CSS transform 使 fixed 定位失效?

1. 最终实现效果如下

另类解决transform使fixed失效

看似简单的一个动画,却出现了种种bug,也不叫bug,毕竟是W3C官方的嘛,整整耗费了我一下午的时间去搞它。

2. 布局样式(关键点)
  • 先来看一下我的布局吧

    • 首先 index_bar_containercl_header 的父元素(坑)
    • 就先看这个父子关系吧,其他的都一样了
    <!-- 收藏位置弹窗 start -->
    <div v-if="show" :class="isShow ? 'index_bar_container ' + overhidden : 'index_bar_container cl_show'">
        <!-- 头部 start -->
        <div :class="isShow ? 'cl_header ' + clhpos : 'cl_header cl_show ' + clhpos">
            <span class="cl_text">请选择收藏位置</span>
            <van-icon class="cl_close" :name="require('@/assets/关闭.svg')" @click="onCClose"></van-icon>
        </div>
        <!-- 头部 end -->
    
        <!-- 当前壁纸信息 start -->
            此处省略...
        <!-- 当前壁纸信息 end -->
    
        <!-- indexBar 索引栏 start -->
        	此处省略...
        <!-- indexBar 索引栏 start -->
    </div>
    <!-- 收藏位置弹窗 end -->
    

    我把没用的代码都删了,方便阅读

  • 再来看看我的样式

    .cl_show {
        display: none !important;
    }
    
    .index_bar_container {
        background: #fff;
        position: fixed;
        left: 0;
        top: 0;
        right: 0;
        bottom: 0;
        margin: auto;
        width: 300px;
        height: 439px;
        border-radius: 14px;
        overflow: scroll;
        padding: 0 4.5px;
        z-index: 10;
    
        animation: rotateInDownLeft 1s;
    }
    
    /* 禁止滚动 */
    .overhidden {
        overflow: hidden;
    }
    
    .index_bar {
        position: relative;
        left: 0;
        top: 0;
        font-size: 13px;
        color: #101010;
        font-weight: 700;
    }
    
    /* cl_header 共同样式 */
    .cl_header {
        /* width: 300px; */
        height: 84px;
        background: #fff;
        border-radius: 14px;
        display: flex;
        align-items: center;
        padding: 0 0px 0 16px;
        color: #101010;
        z-index: 11;
    }
    
    /* cl_header fixed 定位布局样式 */
    .cl_header_fixed {
        position: fixed;
        left: 37.5px;
    }
    
    /* cl_header 非 fixed 定位布局样式 */
    .cl_header_abs {
        position: absolute;
        left: 0;
        top: 0;
    }
    
    @keyframes rotateInDownLeft {
        0% {
            transform-origin: left bottom;
            transform: rotate(-90deg);
            opacity: 0;
        }
    
        100% {
            transform-origin: left bottom;
            transform: rotate(0);
            opacity: 1;
        }
    }
    

    注意动画中是使用了 transform 属性的,不仅 transform 能够使 fixed 定位失效,变成 absolute 的效果,rotatescale 等等属性也能够使 fixed 定位失效

    transform使fixed失效

    好了,扯了这么多主要是给不知道原因的人看的,接下来请看我的解决方案吧!

3. 另类解决 transform 使 fixed 定位失效问题
  • 监听那个点击事件,无论什么方式都好
  • 首先要知道 transform 只会使 fixed 定位失效
  • 那么我可以在动画开始时使当前元素的定位为 absolute 或者 relative 即可,我用的是 absolute
  • 并且在动画执行时是不可以让用户操作的,我使用的是 overflow: hidden;
  • 在动画结束后把 absolute 再变回 fixed 定位,把 overflow 变回 scroll 即可实现无缝切换
  • 最后就是,在动画关闭后即可 v-if 删除当前 dom ,防止当前 dom 保存当前状态,使再次进行动画时,布局出现暂时性(1100ms)失效
data() {
	return {
        clhpos: "cl_header_fixed",
        overhidden: "overhidden",
    }
}


watch: {
    show(val, oldVal) {
        console.log(val);
        // 保证dom加载完毕之后再操作dom
        this.$nextTick(()=>{
            if(val == true) {
                this.clhpos = "cl_header_abs"
                    this.overhidden = "overhidden"
                    let indexBar = this.$refs.indexBar.$el;
                let sidebar = indexBar.getElementsByClassName("van-index-bar__sidebar")[0];

                // 当前 1rem 等于 37.5px
                // 当前页面宽度相对于 750 宽的缩放比例,可根据自己需要修改.
                let top = 1/37.5*80
                    sidebar.setAttribute("style", `position: absolute; right: 0; top: ${top}rem; `);
                // console.log(sidebar);

                setTimeout(()=>{
                    this.clhpos = "cl_header_fixed"
                        this.overhidden = ""
                        sidebar.setAttribute("style", "");
                }, 1100)
            }
        })
    }
}

不知道用 watch 好不好

以上就是我的全部思路了,只能说太难了…

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码小余の博客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值