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

3

22

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>
Hygrostat answered 8/6, 2017 at 14:49 Comment(5)
sticky is still experimental. There's a good chance that this is simply an unaddressed bug and your best bet (as much as I'd like to see a solution to this) is probably to implement your own sticky-like behaviour.Edda
What browser are you seeing this behavior on? It does not occur in Firefox.Antibes
It happens in ChromeOutdate
Vertically centering the input field (or scrolling to top in this scenario as there is not enough content above) when typing in an input field that is out of the viewing range is the default behaviour in Chrome for relative positioned inputs, so that I go with @Edda that this very likely is an edge case they haven't addressed.Apologete
You actually want to have this behaviour, but not in case the input element is visible due to it's currently sticky (fiddle).Apologete
M
1

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>
Mossgrown answered 9/6, 2017 at 9:32 Comment(4)
yes, that's a good way around. Not 100% what I was looking for but I can readapt to my own scenario.Hygrostat
position: -webkit-sticky doesn't exist. You're just adding unnecessary bytes to your CSS by having it.Artis
it looks like it does here: developer.mozilla.org/en-US/docs/Web/CSS/…Mossgrown
Looks like it will still scroll when you press backspaceAccost
S
1

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>
Stylist answered 9/6, 2017 at 20:49 Comment(3)
unfortunately that way-around doesn't work my Angular2+ project using Angular Material. The issue remain visible whether I remove the placeholder and I change the element's overflowHygrostat
any news about that? Is there any reported bug?Darcee
@Darcee yea the bug is reported: bugs.chromium.org/p/chromium/issues/detail?id=1334207 And fixed but still visible in chrome when enable-experimental-web-platform-featuresDesexualize
D
1

For the next person wasting there time like me, This bug has been reported to chrome and has been fixed https://bugs.chromium.org/p/chromium/issues/detail?id=1334207

but, it is still visible in chrome when enable-experimental-web-platform-features flag is enabled

Desexualize answered 22/8, 2022 at 22:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.