8

In the snippet given below element with position sticky does not sticks to the end of the page.

body {
  margin: 0;
}

div.sticky {
  position: -webkit-sticky;
  position: sticky;
  top: 0;
  padding: 5px;
  background-color: #cae8ca;
  border: 2px solid #4CAF50;
}
<!DOCTYPE html>
<html>

<body>



  <div class="sticky">I am sticky!</div>

  <div style="margin-bottom:2000px;
            border:2px solid black ;">
    <p>In this example, the sticky element sticks to the top of the page (top: 0), when you reach its scroll position.</p>
    <p>Scroll back up to remove the stickyness.</p>
    <p>Some text to enable scrolling.. Lorem ipsum dolor sit amet, illum definitiones no quo, maluisset concludaturque et eum, altera fabulas ut quo. Atqui causae gloriatur ius te, id agam omnis evertitur eum. Affert laboramus repudiandae nec et. Inciderint
      efficiantur his ad. Eum no molestiae voluptatibus.</p>
    <p>Some text to enable scrolling.. Lorem ipsum dolor sit amet, illum definitiones no quo, maluisset concludaturque et eum, altera fabulas ut quo. Atqui causae gloriatur ius te, id agam omnis evertitur eum. Affert laboramus repudiandae nec et. Inciderint
      efficiantur his ad. Eum no molestiae voluptatibus.</p>
  </div>

</body>

</html>

but when you add a border to the body , position sticky works fine.

body {margin:0;
      border:5px solid red;}
      
      div.sticky {
  position: -webkit-sticky;
  position: sticky;
  top: 0;
  padding: 5px;
  background-color: #cae8ca;
  border: 2px solid #4CAF50;
}
<!DOCTYPE html>
<html>

<body>



<div class="sticky">I am sticky!</div>

<div style="margin-bottom:2000px;
            border:2px solid black ;">
  <p>In this example, the sticky element sticks to the top of the page (top: 0), when you reach its scroll position.</p>
  <p>Scroll back up to remove the stickyness.</p>
  <p>Some text to enable scrolling.. Lorem ipsum dolor sit amet, illum definitiones no quo, maluisset concludaturque et eum, altera fabulas ut quo. Atqui causae gloriatur ius te, id agam omnis evertitur eum. Affert laboramus repudiandae nec et. Inciderint efficiantur his ad. Eum no molestiae voluptatibus.</p>
  <p>Some text to enable scrolling.. Lorem ipsum dolor sit amet, illum definitiones no quo, maluisset concludaturque et eum, altera fabulas ut quo. Atqui causae gloriatur ius te, id agam omnis evertitur eum. Affert laboramus repudiandae nec et. Inciderint efficiantur his ad. Eum no molestiae voluptatibus.</p>
</div>

</body>
</html>

I have 2 questions .

  1. in first snippet why did element with position sticky did not stick to the end of the page just like in second snippet?

  2. why did element with position sticky started sticking all the way to the end of the page in second snippet when i added a border in body element ?

Alexandre Elshobokshy
  • 10,720
  • 6
  • 27
  • 57
noob
  • 87
  • 6

3 Answers3

1

The scrollable element needs to be of type inline e.g. inline, inline-block, inline-flex or inline-grid:

It's quite interesting behaviour you have discovered though - somehow adding a border completely changes the height of the element so that it's full height instead of just fitting the content. That part I can't explain only the normal solution of using an inline element to make it full height

body {
  margin: 0;
  display: inline-block;
}

div.sticky {
  position: -webkit-sticky;
  position: sticky;
  top: 0;
  padding: 5px;
  background-color: #cae8ca;
  border: 2px solid #4CAF50;
}
<!DOCTYPE html>
<html>

<body>



  <div class="sticky">I am sticky!</div>

  <div style="margin-bottom:2000px;
            border:2px solid black ;">
    <p>In this example, the sticky element sticks to the top of the page (top: 0), when you reach its scroll position.</p>
    <p>Scroll back up to remove the stickyness.</p>
    <p>Some text to enable scrolling.. Lorem ipsum dolor sit amet, illum definitiones no quo, maluisset concludaturque et eum, altera fabulas ut quo. Atqui causae gloriatur ius te, id agam omnis evertitur eum. Affert laboramus repudiandae nec et. Inciderint
      efficiantur his ad. Eum no molestiae voluptatibus.</p>
    <p>Some text to enable scrolling.. Lorem ipsum dolor sit amet, illum definitiones no quo, maluisset concludaturque et eum, altera fabulas ut quo. Atqui causae gloriatur ius te, id agam omnis evertitur eum. Affert laboramus repudiandae nec et. Inciderint
      efficiantur his ad. Eum no molestiae voluptatibus.</p>
  </div>

</body>

</html>
Dominic
  • 62,658
  • 20
  • 139
  • 163
  • So the border adds a display inline to the contained elements? This, tho, is the closest to the correct answer so you get my +1. But please do explain the actual behavior the border does to the element. – Alexandre Elshobokshy Sep 16 '20 at 08:31
  • 1
    @IslamElshobokshy the intial issue is due to margin collpasing making the margin of the div going outside the body. adding border or making the body inline-block will simply disable this margin collapsing – Temani Afif Sep 16 '20 at 10:54
  • @TemaniAfif your comment is actually the best one liner answer, thanks for the explanation! – Alexandre Elshobokshy Sep 16 '20 at 10:58
1

This documentation really explains why this issue happens

These are the points which i understood

  1. A sticky position is Identical to relative, except that its offsets are automatically adjusted in reference to the nearest ancestor scroll container’s scrollport in whichever axes the inset properties are not both auto, to try to keep the box in view within its containing block as the user scrolls. This positioning scheme is called sticky positioning.

In your case , the ancestor element is no other than body

Body element's height and width are set as autoby default

Once when you added a paragraph , the 'body's height is adjusted to it's height(say 110vh)

Which will let your sticky element to stick till 110vh Even when you add margin-bottom of 200vh to a div , this will never change the height of body it still remains 110vh (why right ? answer below).

If there is no border, padding, inline part, block formatting context created, or clearance to separate the margin-top of a block from the margin-top of one or more of its descendant blocks; or no border, padding, inline content, height, min-height, or max-height to separate the margin-bottom of a block from the margin-bottom of one or more of its descendant blocks, then those margins collapse. The collapsed margin ends up outside the parent.


In your case,since the parent body doesn't has no border ,mannual height ,... which resulted your division margin of 2000px to go outside the body

Conclusion :

  1. sticky position is very relative to its parent element's height.
  2. Analyse whether there is a margin collision between the parent and children element or not. 3.To avoid margin collision , we can use border , inline part, block formatting , etcc on the parent element .

I have commented some css attributes you can add on the parent to avoid margin collision.

body {
/*border :1px solid transparent;*/
/*display:inline-block;*/
/*padding :1px;*/
float:left;
}

div.sticky {
  position: -webkit-sticky;
  position: sticky;
  top: 0;
  padding: 5px;
  background-color: #cae8ca;
  border: 2px solid #4CAF50;
}
<!DOCTYPE html>
<html>

<body >



  <div class="sticky">I am sticky!</div>

  <div style="margin-bottom:2000px;
            border:2px solid black ; background:#aaa;">
    <p>In this example, the sticky element sticks to the top of the page (top: 0), when you reach its scroll position.</p>
    <p>Scroll back up to remove the stickyness.</p>
    <p>Some text to enable scrolling.. Lorem ipsum dolor sit amet, illum definitiones no quo, maluisset concludaturque et eum, altera fabulas ut quo. Atqui causae gloriatur ius te, id agam omnis evertitur eum. Affert laboramus repudiandae nec et. Inciderint
      efficiantur his ad. Eum no molestiae voluptatibus.</p>
    <p>Some text to enable scrolling.. Lorem ipsum dolor sit amet, illum definitiones no quo, maluisset concludaturque et eum, altera fabulas ut quo. Atqui causae gloriatur ius te, id agam omnis evertitur eum. Affert laboramus repudiandae nec et. Inciderint
      efficiantur his ad. Eum no molestiae voluptatibus.</p>
  </div>

</body>

</html>
Sandrin Joy
  • 1,120
  • 10
  • 28
0

Edit: i did some experimentation. And my dev-tools definetly show me, that the height of the body-element is not the same in both cases. When you have no border the body's height is equal to the text-area and the margin overlaps. When the border is added the body-height is full page. I have not a single clue right now why the border does that. it does not work with background color, only with the border.

Explanation for the behaviour is correct, im pretty sure of it. The position: sticky is connected to the parent (body) and in case 1 you can scroll past the body. I just cant explain why the border does this

Warden330
  • 999
  • 1
  • 5
  • 11
  • With or without the border, the page has the same size, this is not the correct answer. – Alexandre Elshobokshy Sep 16 '20 at 08:31
  • @IslamElshobokshy i rechecked like 20 times, without the border the body has 250px height(on my screen) and with the border its 2250px. Thats super interesting and i have no clue why that happens – Warden330 Sep 16 '20 at 09:01
  • @Warden330 . Indeed. I also checked and confirmed when border is added , height of body element increases. As you have good reputation,why dont u ask this question . – noob Sep 16 '20 at 09:16