Если использовать position: sticky в css, который именно для этого и предусмотрен, нельзя, то сделай так чтоб было можно. Потому что это единственный реально адекватный вариант, а какие-то там проблемы с твоим overflow - это твой косяк, который и надо решать.
С программным изменением позиции оно всегда будет "дёргаться" без вариантов. До того как появилось sticky - это решали хитрой вёрсткой, где "на самом деле" никакая позиция не меняется, а fixed(а ещё раньше absolute) дубликат элемента показывали\скрывали по условию.
P.S. Возможно можно что-то плавное изобразить при помощи requestAnimationFrame и getBoundingClientRect, не привязываясь к событию scroll, но не пробовал ибо не нужно.