The page does not have jquery so this needs to be done by vanilla JS only.
The header is fixed to the top i.e position:fixed;
and so is taken away from the regular flow and the banner below takes it place causing an overlap.
<header class="site-header fixed-top">
fixed top header
</header>
<section class="banner">
banner
</section>
To remedy this, I want to give the .banner
section a top margin equaling the height of .site-header
.
I have got the height by using the JS below,
var headerHeight = window.getComputedStyle(document.getElementsByClassName("site-header")[0]).height;
But having trouble finding the right way to target the next element .banner
By traversing the DOM tree in the console I found that the following leads to it but it seems wrong and complicated.
document.getElementsByClassName("site-header")[0].nextSibling.nextElementSibling.style.marginTop = headerHeight;
Is there a better and easier way to do it?
CodePudding user response:
CSS only solution
Sticky acts like a fixed when it is sticked but acts like a static element while it is not. It means you don't need to margin-top anything. It just works in native way.
.site-header {
background: yellow;
padding: 4rem 0;
position: sticky;
top: 0;
}
.wrap {
height: 1000px;
}
<div class="wrap">
<header class="site-header">
fixed top header
</header>
<section class="banner">
banner
</section>
</div>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
You can use offsetHeight
or clientHeight
for the header height, and use previousElementSibling
to find the section preceded by the header. Something like:
setTimeout(setSectionMargin, 1000);
function setSectionMargin() {
const sectionAfterFixedHeader = [...document.querySelectorAll(`.banner`)]
.filter(b => b.previousElementSibling.classList.contains(`fixed-top`)).pop();
if (sectionAfterFixedHeader) {
const header = sectionAfterFixedHeader.previousElementSibling;
sectionAfterFixedHeader.style.marginTop = `${header.clientHeight}px`;
}
}
.fixed-top {
position: fixed;
top: 0;
}
.site-header {
font-size: 1.2em;
font-weight: bold;
padding: 0.3em 0;
}
.banner {
color: red;
transition: all 1s 0s;
}
<header class="site-header fixed-top">
fixed top header
</header>
<section class="banner">
banner 1
</section>
<section class="banner">
banner 2
</section>
<section class="banner">
banner 3
</section>
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
Or indeed jax-p's css sticky
solution (not (completely) supported by specific or older browsers)