单击链接时避免固定标题的节重叠:油漆顺序问题

时间:2018-09-10 23:45:25

标签: html css

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

我创建了一个对此问题的解决方案,使用具有负边距的pseudo-element,它利用了 parent-child margin collapsing 来防止报头重叠发生。

简而言之,伪元素的上边距随着主要元素的上边距折叠,导致伪元素保留在main内,但将main的内容向下推,同时将其上方的内容向下拉。

效果很好,除了main的背景会在其上方的元素背景上绘制。

在所有元素上使用position: relativez-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> -->

2 个答案:

答案 0 :(得分:2)

  

有更好的方法吗?

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

  

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

您已经注意到,该问题涉及painting order,因此解决此问题的典型方法是添加/更改某些属性,以根据需要调整绘画顺序。您可能还会注意到,不仅z-index更改顺序,而且其他属性如transformfilteropacityfloat


在这种情况下,您无需调整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> -->

答案 1 :(得分:1)

您可以添加一个不可见的锚点作为顶部链接的目标,然后向该目标添加与标题相同的顶部填充:

body {
  height: 300vh;
  text-align: center;
  width: 100%;
  padding: 0px;
  margin: 0px;
}

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

#anchor {
  padding-top: 40px;
  visibility: hidden;
}

.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;
}

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

<div class="foo">foo: section</div>
<div class="foo">foo2ndchild: section</div>
<div class="main" id="scroll">
  <a id="anchor">not shown</a>
  <div class="main2">scrolling to this section</div>
</div>