Assume you have a website with a position: fixed
header. If we click internal (same-page) links, that header will overlap the content we are taken to via the link.
I created a solution to this problem, using a pseudo-element
with negative margin, which takes advantage of parent-child margin collapsing to prevent header overlap from occurring.
In short summary, the pseudo-element's top margin collapses with main element's top margin, causing the pseudo-element to stay within main, but push main's content down while at the same time pull content above it downwards.
It works well, except main's background will paint on top of background of element above it.
That can probably be prevented with position: relative
and z-index
on all elements.
My question: Is there a better way? Also, is this the typical way this problem is solved?
A minimal working example can be found below.
Note: The pseudo-element has background-color
set on it, just to illustrate its presence. That background should be removed when testing it.
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> -->