1

I have a container that scrolls up and down vertically. Within the container there are some absolutely positioned items. Here is an example to illustrate.

#body {
  height: 200px;
  overflow: scroll;
  font-family: sans-serif;
  font-size: 40px;
}

#container {
  width: 100%;
  height: 600px;
  background-color: rgba(255, 0, 0, 0.1);
  position: relative;
  display: flex;
  align-items: start;
  justify-content: center;
}

#item {
  display: inline;
  background-color: rgba(0, 0, 255, 0.1);
  padding: 10px 20px;
  border-radius: 5px;
  position: absolute;
  top: 150px;
}
<div id="body">
  <div id="container">
    <div id="item">
      Hello
    </div>
  </div>
</div>

I want to make sure a little portion of the item is always visible as the user scrolls up and down, so that the user can always see something there, and doesn't lose track of it. When the user scrolls too far down, it should look like this...

An image showing a small portion of the item at the top of the screen

Conversely, if the user scrolls too far up, it should look like this...

An image showing a small portion of the item at the bottom of the screen

It's also important that the element can be positioned anywhere in the container.

Is this possible with pure CSS? If this is not possible, what's the most efficient approach to achieving the same result with pure CSS & JS (bearing in mind the container might have multiple items in it)?

Proposed duplicate

This question was suggested as a duplicate, but I don't think it is what I am seeking. This question is about anchoring elements to the top AND bottom of a scroll window depending on position. The provided question does not cover that, it only covers how to anchor things on one edge.

halfer
  • 19,824
  • 17
  • 99
  • 186
Kieran
  • 2,554
  • 3
  • 26
  • 38
  • @Inigo It would be helpful if you could explain why you think positioning something absolutely in the container is incompatible with the container being scrollable. The requirement is that elements can be absolutely placed anywhere vertically or horizontally in the container, and the container can still be scrollable. No matter where the item is placed initially, when it scrolls off screen, it should stick to the top or bottom. – Kieran Dec 25 '22 at 23:16
  • I mistakenly read container as the container of the scrolling viewport... silly me. I deleted my comment as noise. Feel free to delete yours as I don't think anyone else will make the same silly mistake. – Inigo Dec 26 '22 at 00:46
  • I'm wondering if this is a case of an [XY Problem](https://en.wikipedia.org/wiki/XY_problem)? For example, I can't think of a use case for an element that is both sticky and absolutely positioned. The whole point of absolute positioning is to say the element is positioned *here* irrespective of the container's main content, i.e. the children that participate in the content flow, and irrespective of that content scrolling. See my answer. I did come up with a workaround for the other question. If I can understand your underlying need, I might come up with one for you too. – Inigo Dec 26 '22 at 06:17

2 Answers2

2

Not sure if I understand the conditions correctly, but assuming the goal is to have #item always partially visible while scrolling within the container, perhaps try set position: sticky on #item.

This way, the offset range of #item when it sticks to the border can be specified by top and bottom.

Example:

#body {
  height: 200px;
  overflow: scroll;
  font-family: sans-serif;
  font-size: 40px;
  background-color: rgba(255, 0, 0, 0.1);
}

#container {
  width: 50%;
  margin: 0 auto;
  height: 900px;
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

#item {
  background-color: rgba(0, 0, 255, 0.1);
  padding: 10px 20px;
  border-radius: 5px;
  position: sticky;
  top: -50px;
  bottom: -50px;
}

#spacer {
  height: 220px;
}
<div id="body">
  <div id="container">
    <div id="spacer"></div>
    <div id="item">
      Hello
    </div>
  </div>
</div>
Kieran
  • 2,554
  • 3
  • 26
  • 38
John Li
  • 6,976
  • 3
  • 3
  • 27
0

div{
  width:150px;
  height:150px;
  background: purple;
  opacity: .25;
  border-radius:10px;
  margin:auto;
  position:sticky;
  top:-130px;
  bottom:-130px;
}
<p>Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</p>
<p>Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</p>
<div></div>
<p>Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</p>
<p>Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</p>

Let me know your thoughts.

Inigo
  • 12,186
  • 5
  • 41
  • 70
Aslam khan
  • 315
  • 1
  • 7