Reputation: 29453
In CSS, position: sticky
enables an element to display with a position: static
behaviour (ie. it adopts its default position within the document flow) until it reaches a certain scroll position, after which it adopts position: fixed
behaviour.
So... does that mean we cannot use position: sticky
on an element which requires a normal behaviour of position: absolute
?
Context:
I have an out-of-flow element which occupies a position towards the top-left corner of the viewport. After an inch or two of scrolling, the element hits the top of the viewport and, ideally, I'd like it not to carry on disappearing at that point.
Upvotes: 7
Views: 10284
Reputation: 21
To make a div sticky and positioned absolute to the parent, you can use this approach in tailwind, or or you can apply the same logic in css as well.
<div className="sticky right-0 top-0 w-full">
<div className="absolute right-0 top-0 flex flex-col items-end w-full">
//content
</div>
</div>
Upvotes: 1
Reputation: 15020
I came up with this hack that achieves the goal, but I haven't figured out how to fix its one flaw: There's a blank area at the bottom of the scrollable content equal to the height of the sticky element + its initial vertical offset.
See the comments in the code for an explanation of how it works.
#body {
width: 100%;
position: relative;
background: Linen;
font-family: sans-serif;
font-size: 40px;
}
/* to position your sticky element vertically, use the
height of this empty/invisible block element */
#sticky-y-offset {
z-index: 0;
height: 100px;
}
/* to position your sticky element horizontally, use the
width of this empty/invisible inline-block element */
#sticky-x-offset {
z-index: 0;
width: 100px;
display: inline-block;
}
/* this element is sticky so must have a static position,
but we can fake an absolute position relative to the
upper left of its container by resizing the invisible
blocks above and to the left of it. */
#sticky-item {
width: 150px;
height: 100px;
border-radius: 10px;
background-color: rgba(0, 0, 255, 0.3);
display: inline-block;
position: sticky;
top: -80px;
bottom: -80px;
}
/* this div will contain the non-sticky main content of
the container. We translate it vertically upward by
sticky-y-offset's height + sticky-item's height */
#not-sticky {
width: 100%;
background-color: rgba(0, 0, 255, 0.1);
transform: translateY(-200px);
}
.in-flow {
width: 90%;
height: 150px;
border-radius: 10px;
margin: 10px auto;
padding: 10px 10px;
background: green;
opacity: 30%;
}
<div id="body">
<div id="sticky-y-offset"></div>
<div id="sticky-x-offset"></div>
<div id="sticky-item">absolute & sticky</div>
<div id="not-sticky">
<div class="in-flow">in flow</div>
<div class="in-flow">in flow</div>
<div class="in-flow">in flow</div>
<div class="in-flow">in flow</div>
</div>
</div>
Upvotes: 1
Reputation: 7336
The point of position:sticky
is that it is only fixed
while the parent element is not in view. A position:absolute
element isn't attached to it's parent.
It could be interesting if such a position
would exist and the rule would be that the element would be absolute
, while the element it is absolute positioned to is in view, but currently there exists nothing like this nativley, but you could try to recreate it using JS.
Upvotes: 1
Reputation: 421
You actually can leverage display: grid
and have a sticky element that doesn't pushes its siblings:
header {
display: flex;
align-items: center;
justify-content: center;
height: 50vh;
border: 1px dashed #f00;
}
main {
display: grid;
}
div {
display: flex;
align-items: center;
justify-content: center;
}
.section {
grid-column: 1;
height: 100vh;
border: 1px dashed #0f0;
}
.first.section {
grid-row: 1;
}
.sticky {
grid-row: 1;
grid-column: 1;
position: sticky;
top: 0;
height: 30vh;
border: 1px dashed #0ff;
}
footer {
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
border: 1px dashed #f00;
}
<header>I'm the header</header>
<main>
<div class="sticky">I'm sticky</div>
<div class="first section">Just</div>
<div class="section">some</div>
<div class="section">sections</div>
</main>
<footer>I'm the footer</footer>
The trick here is to place the sticky section and its first sibling on the first row and first column of their parent (because grids allow us to place many elements in the same cell).
The sticky element remains sticky in its parent so it will stay on scroll beyond its cell.
Upvotes: 6
Reputation: 723468
As GibboK says, the default positioning scheme isn't absolute positioning, it's the static position. Elements are laid out in normal flow by default — if out-of-flow were the default, then the default HTML page would be impossible to read. Besides, absolutely positioned elements do scroll with the page most of the time — the only time you can make an absolutely positioned behave like a fixed positioned element with respect to page scrolling is through some semi-complicated CSS.
If you're asking whether it's possible for
then unfortunately neither of these is supported by sticky positioning.
Upvotes: 2