I'd like to have a header with one sticky element and one non-sticky element. Hence, the structure would be something like this:
body {
margin: 0;
height: 2000px;
}
header {
position: static;
border: 1px solid blue;
overflow: visible;
}
.sticky-yes {
position: sticky;
top: 0;
border: 1px solid blue;
}
.sticky-no {
position: relative;
top: 0;
border: 1px solid orange;
}
<header>
<div class="sticky-yes">Sticky</div>
<div class="sticky-no">Not sticky</div>
</header>
<div>... Rest of the webpage ...</div>
The header sits as a direct child of the body.
As far as I know, sticky elements want to stick to the nearest ancestor with a "scrolling mechanism". And I can "ignore" the parent element by giving it position: static;
I also added overflow: visible;
to the parent after reading this related question: CSS - Allow an div to stick out of its parent
But this snippet won't work.
I am constrained to use it with that markup, I cannot move the sticky element outside of the header.
What approach can I take?
You can do this with a bit of creative CSS. Adds a bit of maintenance but does stick the element. Note here I sized both elements and used that as the base height of the header. I also used box-sizing to avoid issues with this is zoomed in a browser.
body {
margin: 0;
padding: 0;
font-size: 16px;
height: 2000px;
--sticky-height: 3rem;
--non-sticky-height: 2rem;
--header-height: calc(var(--sticky-height) + var(--non-sticky-height));
}
header {
box-sizing: border-box;
border: 1px solid cyan;
height: var( --header-height);
}
.sticky-yes {
box-sizing: border-box;
position: fixed;
top: 0;
border: 1px solid blue;
height: var(--sticky-height);
}
.sticky-no {
box-sizing: border-box;
position: relative;
top: var(--sticky-height);
height: var(--non-sticky-height);
border: 1px solid orange;
}
<header>
<div class="sticky-yes">Sticky</div>
<div class="sticky-no">No</div>
</header>