前端妹子问我 position fixed 失效问题该如何解决?

简介: 这两天公司一位妹子问我,“我这边调试的时候本地显示没问题,到手机端就有问题,该怎么办呢?” 测试环境没问题到线上就有问题了?对此我也很纳闷。

highlight: monokai

背景

这两天公司一位妹子问我,“我这边调试的时候本地显示没问题,到手机端就有问题,该怎么办呢?”
测试环境没问题到线上就有问题了?对此我也很纳闷。
下图是复现的效果图, 这个是一个用户选择组件,当点击按钮的时候,弹窗框可以选择用户,当点击按钮后蒙层并没有覆盖全屏。
选择用户按钮

点击按钮后

问题分析

组件代码

import React,{useState} from "react";

export default function App({children}) {
  const [visible, setVisible] = useState(false)
  return (
    <>
      <span onClick={()=>setVisivle(true)}>{children}</span>
      {visible? <div className="fixed">...</div> :null}
    </>
  );
}

我们知道,position:fixed 在日常的页面布局中非常常用,在许多布局中起到了关键的作用。它的作用是:

position:fixed 的元素将相对于屏幕视口(viewport)的位置来指定其位置。并且元素的位置在屏幕滚动时不会改变。

但是在某些特定场景下,指定了 position:fixed 的元素却无法相对于屏幕视口进行定位。

MDN 中有句话对这些特定场景做了解释:

当元素祖先的 transform, perspectivefilter 属性非 none 时,容器由视口改为该祖先。

其实并不是本地不能复现,只不过这个表单是用户创建的,只有当该选择组件在 Tab 组件内部的时候 100% 复现。
在上面代码中,就是因为在 Tab 中使用了 transform:translate3d(0, 0, 0) 属性,所以会在该场景下失效。

失效的 position:fixed

比如下面一个最简单的代码

<div id="app">
  <div class="fixed"></dix>
</div>
#app{
   width: 100px;
   height: 100px;
   transform: scale(1);
 }
.fixed{
  position: fixed;
  background: blue;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
}

失效的 position:fixed

本来应该全屏的div,消失了,上述代码中 transform: scale(1);也会导致 position:fixed 失效,那么,为什么会发生这种情况呢?

这就涉及到了 Stacking Context ,也就是堆叠上下文的概念了。解释上面的问题分为两步:

  1. 任何非 nonetransform 值都会导致一个堆叠上下文(Stacking Context)和包含块(Containing Block)的创建。
  2. 由于堆叠上下文的创建,该元素会影响其子元素的固定定位。设置了 position:fixed 的子元素将不会基于 viewport 定位,而是基于这个父元素。

解决办法

那么要如何解决呢? 我开发的是一个公共组件,总不能要求使用组件的父元素都不使用 transform, perspectivefilter 这些属性吧?

是不是直接将弹窗插入到 body 下就可以了呢?

在 React 中提供了 createPortal 方法, 该方法可以将子节点渲染到存在于父组件以外的 DOM 节点中

所以我们可以改一下组件代码:

import React, { useState, useRef, useEffect } from "react";
import { createPortal } from "react-dom";

export default function App({ children }) {
  const [visivle, setVisivle] = useState(false);

  const node = useRef();

  useEffect(() => {
    node.current = document.createElement("div");

    document.body.appendChild(node.current);
    return () => {
      if (node.current) {
        node.current.remove();
      }
    };
  }, []);
  return (
    <>
      <span onClick={() => setVisivle(true)}>{children}</span>
      {visivle && node.current
        ? createPortal(<div className="fixed">...</div>,node.current)
        : null}
    </>
  );
}

这样就可以解决 position:fixed 失效的问题,当然,因为在 body元素下,可以使用 position:absolute 代替 。

position:fixed 的其他问题

position: fixed 还有一些其他问题,比如在在移动端实现头部、底部模块定位。或者是在 position: fixed 中使用了 input 也会存在一些问题,可以看下这篇文章:移动端 web 页面使用 position:fixed 问题总结

借用了前端胖头鱼的首图。
以上就是本文全部内容,希望这篇文章对大家有所帮助,也可以参考我往期的文章或者在评论区交流你的想法和心得,欢迎一起探索前端。

本文首发掘金平台,来源小马博客

相关文章
|
2月前
|
前端开发 算法 Java
【CSS】前端三大件之一,如何学好?从基本用法开始吧!(五):背景属性;float浮动和position定位;详细分析相对、绝对、固定三种定位方式;使用浮动并清除浮动副作用
position定位(核心) 我们讲盒模型的时候,提到了3个属性可以用来控制页面排版。 三大属性:position属性,display属性,float属性。 position 属性控制页面上元素间的位置关系。 display 属性控制页面元素是否显示或者是堆叠还是并排显示。 float 属性提供控制方法。 通过float这种控制方法,可以实现多栏布局,导航菜单等等。 position属性是干嘛用的?怎么用?有哪些属性值? position属性控制页面上元素间的位置关系,也就是排版。 怎么用?要知道怎么用
358 1
|
前端开发
前端基础(十三)_定位position、定位层级z-index
本文讲解了CSS中的定位机制,包括静态定位、相对定位、绝对定位和固定定位,并通过实例展示了如何使用这些定位方法调整元素位置。同时,还介绍了z-index属性的使用,解释了如何通过调整z-index值来改变定位元素的层叠顺序。
266 6
前端基础(十三)_定位position、定位层级z-index
|
前端开发
#yyds干货盘点# 前端歌谣的刷题之路-第一百三十五题-定位-fixed-广告
#yyds干货盘点# 前端歌谣的刷题之路-第一百三十五题-定位-fixed-广告
135 0
#yyds干货盘点# 前端歌谣的刷题之路-第一百三十五题-定位-fixed-广告
|
前端开发
前端学习案例2-三栏布局之position
前端学习案例2-三栏布局之position
189 0
前端学习案例2-三栏布局之position
|
JSON 前端开发 JavaScript
SyntaxError: Unexpected number in JSON at position 7 at JSON.parse (<anonymous>)前端接收到数据,无法进入success
SyntaxError: Unexpected number in JSON at position 7 at JSON.parse (<anonymous>)前端接收到数据,无法进入success
307 0
SyntaxError: Unexpected number in JSON at position 7 at JSON.parse (<anonymous>)前端接收到数据,无法进入success
|
前端开发
web前端-CSS(display,position,overflow和浮动float)
web前端-CSS(display,position,overflow和浮动float)
302 0
|
前端开发
#yyds干货盘点# 前端歌谣的刷题之路-第一百三十四题-定位-fixed
#yyds干货盘点# 前端歌谣的刷题之路-第一百三十四题-定位-fixed
204 0
#yyds干货盘点# 前端歌谣的刷题之路-第一百三十四题-定位-fixed
|
前端开发
前端工作小结45-position使用
前端工作小结45-position使用
112 0
前端工作小结45-position使用
|
前端开发
前端工作小结46-代码之解析position 解决
前端工作小结46-代码之解析position 解决
221 0
前端工作小结46-代码之解析position 解决
|
前端开发
web前端-CSS(display,position,overflow和浮动float)
display(显示) display属性指定由元素生成的框的类型,通常用到display对应值有block、none、inline这三个值。 下面我们来看看display的属性有哪些吧。
web前端-CSS(display,position,overflow和浮动float)

热门文章

最新文章

  • 1
    前端工程化演进之路:从手工作坊到AI驱动的智能化开发
  • 2
    Vue 3 + TypeScript 现代前端开发最佳实践(2025版指南)
  • 3
    前端如何存储数据:Cookie、LocalStorage 与 SessionStorage 全面解析
  • 4
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(五):背景属性;float浮动和position定位;详细分析相对、绝对、固定三种定位方式;使用浮动并清除浮动副作用
  • 5
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(六):全方面分析css的Flex布局,从纵、横两个坐标开始进行居中、两端等元素分布模式;刨析元素间隔、排序模式等
  • 6
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(一):CSS发展史;CSS样式表的引入;CSS选择器使用,附带案例介绍
  • 7
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(八):学习transition过渡属性;本文学习property模拟、duration过渡时间指定、delay时间延迟 等多个参数
  • 8
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(九):强势分析Animation动画各类参数;从播放时间、播放方式、播放次数、播放方向、播放状态等多个方面,完全了解CSS3 Animation
  • 9
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(四):元素盒子模型;详细分析边框属性、盒子外边距
  • 10
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(二):CSS伪类:UI伪类、结构化伪类;通过伪类获得子元素的第n个元素;创建一个伪元素展示在页面中;获得最后一个元素;处理聚焦元素的样式