解决position:fixed导致下层组件覆盖问题

15,134 阅读3分钟

问题描述

当上层组件固定(多见于导航栏的css样式)时,易造成下层组件被覆盖的问题。

我们来写一个案例,当fixed样式未被使用时,我们的组件样式如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<style>
    .outer-container {
        margin: 0 auto;
        display: block;
        max-width: 100%;
    }

    .header {
        height: 50px;
        background-color: red;
        display: flex;
        width: 100%;
    }

    .content {
        height: 100px;
        background-color: yellow;
        border: 2px black solid;
        display: block;
        position: relative;
        /*methods1 */
        /*margin-top: 50px;*/
    }

    .footer {
        height: 50px;
        background-color: green;
      	postion: relative;
    }
</style>
<body>
<div class="outer-container">
    <div class="header">I am the header</div>
</div>
<div class="content">I am the content1</div>
<div class="content">I am the content2</div>
<div class="footer">I am the footer</div>
</body>
</html>

直观图示如下:

image-20210720114103390.png

当header应用fixed样式后,它将悬浮于页面上方,覆盖下面的content组件:

    .header {
        height: 50px;
        background-color: red;
        position: fixed;
        display: flex;
        top: 0;
        width: 100%;
        z-index: 1000;
    }

图示如下(content1被覆盖了一半):

image-20210720114249714.png

原理相关

fixed relative简介

CSS **position**属性用于指定一个元素在文档中的定位方式。toprightbottomleft 属性则决定了该元素的最终位置。

  • static

该关键字指定元素使用正常的布局行为,即元素在文档常规流中当前的布局位置。此时 top, right, bottom, leftz-index 属性无效。

  • relative

该关键字下,元素先放置在未添加定位时的位置,再在不改变页面布局的前提下调整元素位置(因此会在此元素未添加定位时所在位置留下空白)。position:relative 对 table-*-group, table-row, table-column, table-cell, table-caption 元素无效。

相对定位的元素是在文档中的正常位置偏移给定的值,但是不影响其他元素的偏移。

  • fixed

元素会被移出正常文档流,并不为元素预留空间,而是通过指定元素相对于屏幕视口(viewport)的位置来指定元素位置。元素的位置在屏幕滚动时不会改变。打印时,元素会出现在的每页的固定位置。fixed 属性会创建新的层叠上下文。当元素祖先的 transform, perspectivefilter 属性非 none 时,容器由视口改为该祖先。

分析

因为fixed元素脱离了正常文档流,所以relative元素的原本位置向上提了,产生了覆盖的行为。

需要添加marginor padding属性到下层内容组件上,使其发生向下偏移,不再被覆盖。

top、margin-top的区别:

  1. margin-top 属性设置元素的上外边距。是盒子模型的组成部分。它可以推开周围元素。注意相邻块元素的垂直边距会塌陷。
  2. top 属性规定元素的顶部边缘。该属性定义了一个定位元素的上外边距边界与其包含块上边界之间的偏移。如果希望元素对周围元素没有影响,可以使用top与绝对定位元素

解决方法

方法一

如上文所分析的一样,给内容设置margin-top,同时设置header中的top:0和z-index,否则引起margin-top失效

失效原因可看这个案例,写得太好了,像篇优美的小作文:html - Why isn't my margin working with position: fixed? - Stack Overflow

    .content {
        height: 100px;
        background-color: yellow;
        border: 2px black solid;
        display: block;
        position: relative;
        /*methods1 */
        margin-top: 50px;
    }

效果如下:

image-20210720165837194.png

方法二

用空div占位,同时设置body margin=0,使div的位置相对于视窗口无边距,变得可计算。

    .empty-content{
        position: relative;
        display: block;
        height: 50px;
    }
<body>
<div class="outer-container">
    <div class="header">I am the header</div>
</div>
<div class="empty-content"></div>
<div class="content">I am the content1</div>
<div class="content">I am the content2</div>
<div class="footer">I am the footer</div>
</body>

效果图如下:

image-20210720170305381.png

以上

参考文档