Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Editing a sticky input element in Chrome causes the page to scroll to the top

I was trying to use the css position: sticky in one of my personal project when I noticed that having editable elements like input fields or text-areas inside, trigger the page to scroll to the top.

I would really like to remove this behaviour if possible.

.container {
  height: 5000px;
}

.heading{
  background: #ccc;
  height: 50px;
  line-height: 50px;
  margin-top: 10px;
  font-size: 30px;
  padding-left: 10px;
  position: -webkit-sticky;
  position: sticky;
  top: 0px;
}
<h1>Lorem Ipsum</h1>

<div class="container">
  <div class="heading">
    <input placeholder="Edit this while scrolling...">
  </div>
  <div>Lorem Ipsum</div>
  <div>Lorem Ipsum</div>
  <div>Lorem Ipsum</div>  
  <div>Lorem Ipsum</div>
  <div>Lorem Ipsum</div>
  <div>Lorem Ipsum</div>
  <div>Lorem Ipsum</div>
  <div>Lorem Ipsum</div>
  <div>Lorem Ipsum</div>
  <div>Lorem Ipsum</div>
  <div>Lorem Ipsum</div>
  <div>Lorem Ipsum</div>
  <div>Lorem Ipsum</div>
  <div>Lorem Ipsum</div>
  <div>Lorem Ipsum</div>
</div>
like image 334
andreasonny83 Avatar asked Jun 08 '17 14:06

andreasonny83


People also ask

Which property is used to make an element stick to the top of the page?

Introduction. You may have used the CSS position property with the relative and absolute values in the past. Modern web browsers now support the sticky value. It allows you to make elements stick when the scroll reaches a certain point.

Does position sticky work in Chrome?

It is available on Chrome (yay), Firefox and Safari. Here are more details about position:sticky : Specification.

Why is sticky position not working?

That can happen for many reasons: Position sticky will most probably not work if overflow is set to hidden, scroll, or auto on any of the parents of the element. Position sticky may not work correctly if any parent element has a set height. Many browsers still do not support sticky positioning.

How do I make my sticky element scroll?

To make an element sticky, do: make_sticky('#sticky-elem-id'); When the element becomes sticky, the code manages the position of the remaining content to keep it from jumping into the gap left by the sticky element. It also returns the sticky element to its original non-sticky position when scrolling back above it.


2 Answers

I have managed to make it work, but it's probably not the best solution.

  1. Add add either overflow: auto or overflow: hidden to the class with position: sticky.
  2. Remove the placeholder from <input>.

I'm not sure why adding overflow or removing the placeholder makes it work, maybe someone can help explain this.

.container {
  height: 5000px;
}

.heading{
  background: #ccc;
  height: 50px;
  line-height: 50px;
  margin-top: 10px;
  font-size: 30px;
  padding-left: 10px;
  position: -webkit-sticky;
  position: sticky;
  top: 0px;
  overflow: auto;
}
<h1>Lorem Ipsum</h1>

<div class="container">
  <div class="heading">
    <input>
  </div>
  <div>Lorem Ipsum</div>
  <div>Lorem Ipsum</div>
  <div>Lorem Ipsum</div>  
  <div>Lorem Ipsum</div>
  <div>Lorem Ipsum</div>
  <div>Lorem Ipsum</div>
  <div>Lorem Ipsum</div>
  <div>Lorem Ipsum</div>
  <div>Lorem Ipsum</div>
  <div>Lorem Ipsum</div>
  <div>Lorem Ipsum</div>
  <div>Lorem Ipsum</div>
  <div>Lorem Ipsum</div>
  <div>Lorem Ipsum</div>
  <div>Lorem Ipsum</div>
</div>
like image 61
akcan Avatar answered Oct 13 '22 22:10

akcan


You'll have to do some validation of the key - probably best with a regex check to confirm acceptable characters, but you can call a javascript function from the keypress, update the value of the input, and return false:

var e = document.getElementById('input');
e.onkeypress = myFunction;

function myFunction(t) {
  document.getElementById('input').value += t.key;
  return false;
}
.container {
  height: 1000px;
}

.heading{
  background: #ccc;
  height: 50px;
  line-height: 50px;
  margin-top: 10px;
  font-size: 30px;
  padding-left: 10px;
  position: -webkit-sticky;
  position: sticky;
  top: 0px;
}
<h1>Lorem Ipsum</h1>

<div class="container">
  <div class="heading">
    <input id="input" placeholder="Edit this while scrolling...">
  </div>
  <div>Lorem Ipsum</div>
  <div>Lorem Ipsum</div>
  <div>Lorem Ipsum</div>  
  <div>Lorem Ipsum</div>
  <div>Lorem Ipsum</div>
  <div>Lorem Ipsum</div>
  <div>Lorem Ipsum</div>
  <div>Lorem Ipsum</div>
  <div>Lorem Ipsum</div>
  <div>Lorem Ipsum</div>
  <div>Lorem Ipsum</div>
  <div>Lorem Ipsum</div>
  <div>Lorem Ipsum</div>
  <div>Lorem Ipsum</div>
  <div>Lorem Ipsum</div>
</div>
like image 1
Brian Avatar answered Oct 14 '22 00:10

Brian