首页 > 解决方案 > 单击链接时避免固定标题的部分重叠:绘制顺序问题

问题描述

假设您有一个带有position: fixed标题的网站。如果我们单击内部(同一页面)链接,该标题将与我们通过链接访问的内容重叠。

我为这个问题创建了一个解决方案,使用pseudo-element负边距,它利用父子 边距折叠来防止标题重叠的发生。

简而言之,伪元素的上边距与主元素的上边距一起折叠,导致伪元素停留在主元素内,但将主元素的内容向下推,同时将其上方的内容向下拉。

它运作良好,除了 main 的背景将绘制在其上方元素的背景之上。

这可能可以通过所有元素position: relative来防止。z-index

我的问题:有没有更好的方法?另外,这是解决此问题的典型方法吗?

可以在下面找到一个最小的工作示例。

注意:伪元素已经background-color设置在它上面,只是为了说明它的存在。测试时应删除该背景。

body {
  height: 300vh;
  text-align: center;
  width: 100%;
}

.header {
  height: 40px;
  width: 100%;
  background-color: yellow;
  position: fixed;
  top: 0;
}

.foo {
  height: 50px;
  background-color: grey;
}

.foo:nth-child(2) {
  margin-top: 40px;
  background-color: red;
}

.main {
  height: 100px;
  background: blue;
}

.main div {
  height: 100px;
}

.main::before {
  content: "pseudo-element (when removing its background-color, you see how .main unfortunately paints on top of foo)";
  display: block;
  background: green;
  height: 40px;
  margin-top: -40px;
}

.main2 {
  height: 100px;
  background-color: blue;
}
<div class="header">
  <a href="#scroll" class="link">Fixed Header: Click Me!</a></div>

<div class="foo">foo: section</div>
<div class="foo">foo: section</div>
<div class="main" id="scroll">
  <div class="main2">main: section</div>
</div>
<!-- <div class="main" id="scroll">main</div> -->

标签: htmlcss

解决方案


有没有更好的办法?

这取决于你所说的更好。在所有情况下,解决方案都不应破坏任何其他功能或布局,然后我们可以将其视为一个好的解决方案。

另外,这是解决此问题的典型方法吗?

您已经注意到的问题涉及绘画顺序,因此解决此类问题的典型方法是添加/更改一些属性,以便按照我们想要的方式调整绘画顺序。您可能还会注意到,不仅z-index会更改顺序,还会更改其他属性,例如transform, filter, opacity,float等。


对于这种特殊情况,您不需要调整z-index和定位所有元素。您只需要增加z-index固定标头的值并使滚动元素定位:

body {
  height: 300vh;
  text-align: center;
  width: 100%;
}

.header {
  height: 40px;
  width: 100%;
  background-color: yellow;
  position: fixed;
  z-index:1;
  top: 0;
}

.foo {
  height: 50px;
  background-color: grey;
}

.foo:nth-child(2) {
  margin-top: 40px;
  background-color: red;
}

.main {
  height: 100px;
  position:relative;
  background: blue;
}

.main div {
  height: 100px;
}

.main::before {
  content: "pseudo-element (when removing its background-color, you see how .main unfortunately paints on top of foo)";
  display: block;
  background: green;
  height: 40px;
  margin-top: -40px;
}

.main2 {
  height: 100px;
  background-color: blue;
}
<div class="header">
  <a href="#scroll" class="link">Fixed Header: Click Me!</a></div>

<div class="foo">foo: section</div>
<div class="foo">foo: section</div>
<div class="main" id="scroll">
  <div class="main2">main: section</div>
</div>
<!-- <div class="main" id="scroll">main</div> -->


推荐阅读