The trick is to take advantage of the "stickiness" being dependent on the containing block. As MDN puts it:
...at which point it is treated as "stuck" until meeting the opposite edge of its containing block.
So you need the containing block to start where you want the sticky element to start being sticky (in your case, at the top of the page), and to end where you want the sticky element to stop being sticky (in the footer).
It gets a little tricky if you wanted it to get "unstuck" somewhere in the middle of a footer (like I was needing), but it's totally doable. Here's a basic example where I "split" the footer into top and bottom elements to allow the button to appear like it's getting unstuck inside the footer (see at JS Fiddle).
HTML
<div class="sticky-wrapper">
<main>
Scroll down
</main>
<footer class="top">
</footer>
<div class="sticky">
<button>Button</button>
</div>
</div>
<footer class="bottom">
</footer>
CSS
main {
min-height: 200vh;
}
.sticky {
position: sticky;
bottom: 50px;
height: 0;
padding: 0 16px;
}
footer {
background: #808080;
}
footer.top {
height: 16px;
}
footer.bottom {
height: 100px;
}