I developed a script using javascript only with a layout example applying this situation that described.
I will try to explain what he does, maybe it is a little complex to understand, I am available to explain better.
The script takes the information of distance from the top and height of the element that will be fixed, also takes the height of the footer, subtracts this information by the height of the window, or in this case, the div#main, so it will have the minimum value for when the scroll reach this start to treat the height of the fixed element.
var initTop = 0;
var fixed = document.getElementById('fixed');
var footer = document.getElementById('footer');
var main = document.getElementById('main');
window.addEventListener('scroll', function() {
var alturaMin = main.offsetHeight - footer.offsetHeight - fixed.offsetHeight - fixed.offsetTop;
var altMin = (main.offsetHeight - (footer.offsetHeight + fixed.offsetHeight));
if(this.scrollY > 0) {
fixed.classList.add('fixed');
} else {
fixed.classList.remove('fixed');
}
initTop = initTop == 0 ? fixed.offsetTop : initTop;
if(this.scrollY > alturaMin) {
var sub = alturaMin - this.scrollY + fixed.offsetTop;
fixed.style.top = sub + 'px';
} else if(this.scrollY < altMin) {
if(fixed.offsetTop != initTop) {
fixed.style.top = initTop + 'px';
}
} else {
fixed.style.top = (altMin - this.scrollY) + 'px';
}
});
* {
margin: 0px;
padding: 0px;
}
.main {
position: relative;
height: 1300px;
width: 100%;
}
.offer {
background-color: green;
height: 60px;
width: 100%;
}
.fixed {
position: fixed;
width: 50%;
height: 200px;
z-index: 101;
top: 50px;
}
.footer {
position: absolute;
background-color: tomato;
height: 500px;
width: 100%;
bottom: 0px;
}
<div class="main" id="main">
<div class="offer" id="fixed">
</div>
<div class="footer" id="footer">
</div>
</div>