JSFiddle - React, Tailwind, and code Playground

HTML

<div class="wrapper">
    <p>asd</p>
    
    <div class="footer">footer</div>
</div>

CSS

body {
    margin-bottom: 300px;
}

.wrapper {
    background: #ece;
    height: 600px;
    width: 300px;
    /* implied position: static, by browser default */
}

.footer {
    background: #cee;
    bottom: 0;
    position: fixed;
    width: 300px;
}

.fakefooter {
    width: 1px;
    height: 1px;
    background: transparent;
    margin-top; -1px;
}

JavaScript

// add a fake footer after the wrapper
$('.wrapper').after($('<div class="fakefooter" />'));

$(document).on('resize scroll', function(e){
    //measure if the fake footer is in viewport
    if(elementInViewport($('.fakefooter')[0])) {
        // If so, it should be in the bottom of the wrapper. 
        $('.wrapper').css('position', 'relative');
        $('.footer').css('position', 'absolute');
    } else {
        // else it should be in the bottom of the window
        $('.wrapper').css('position', 'static');
        $('.footer').css('position', 'fixed');
    } 
});

function elementInViewport(el) {
  var top = el.offsetTop;
  var left = el.offsetLeft;
  var width = el.offsetWidth;
  var height = el.offsetHeight;

  while(el.offsetParent) {
    el = el.offsetParent;
    top += el.offsetTop;
    left += el.offsetLeft;
  }

  return (
    top >= window.pageYOffset &&
    left >= window.pageXOffset &&
    (top + height) <= (window.pageYOffset + window.innerHeight) &&
    (left + width) <= (window.pageXOffset + window.innerWidth)
  );
}