JSFiddle - React, Tailwind, and code Playground

by GreenMonster

HTML

<div id="article">
  lol
  <br/> lol
  <br/> lol
  <br/> lol
  <br/> lol
  <br/> lol
  <br/> lol
  <br/> lol
  <br/> lol
  <br/> lol
  <br/> lol
  <br/> lol
  <br/> lol
  <br/> lol
  <br/> lol
  <br/> lol
  <br/> lol
  <br/> lol
  <br/> lol
  <br/> lol
  <br/> lol
  <br/> lol
  <br/> lol
  <br/> lol
  <br/> lol
  <br/> lol
  <br/> lol
  <br/> lol
  <br/> lol
  <br/> lol
  <br/> lol
  <br/> lol
  <br/> lol
  <br/> lol
  <br/> lol
  <br/> lol
  <br/> lol
  <br/> lol
  <br/> lol
  <br/> lol
  <br/> lol
  <br/> lol
  <br/> lol
  <br/> lol
  <br/> lol
  <br/> lol
  <br/> lol
  <br/> lol
  <br/> lol
  <br/> lol
  <br/> lol
  <br/>
</div>
<div id="aside1">
  sticky-block
  <br/> lol
  <br/> lol
  <br/> lol
  <br/> lol
  <br/> lol
  <br/> lol
  <br/> lol
  <br/> lol
  <br/> lol
  <br/> lol
  <br/> lol
  <br/> lol
  <br/> lol
  <br/> lol
  <br/> lol
  <br/> lol
  <br/> lol
  <br/> lol
  <br/> lol
  <br/> lol
  <br/> lol
  <br/> lol
  <br/> lol
  <br/> lol
  <br/> lol
  <br/> lol
  <br/> lol
</div>

CSS

div {
  float: left;
}

#article {
  width: 250px;
  padding: 20px;
  margin: 10px;
  background: #FFFFFF;
  border: 1px solid #EEEEEE;
}

#aside1 {
  margin: 20px;
  padding:20px; /* Все проблемы из-за паддингов */
}

.sticky {
  position: fixed;
  z-index: 101;
}
.stop {
  position: relative;
  z-index: 101;
}

JavaScript

(function(){
var a = document.querySelector('#aside1'), b = null, K = null, Z = 0, P = 0, N = 0;  // если у P ноль заменить на число, то блок будет прилипать до того, как верхний край окна браузера дойдёт до верхнего края элемента, если у N — нижний край дойдёт до нижнего края элемента. Может быть отрицательным числом
window.addEventListener('scroll', Ascroll, false);
function Ascroll() {
  var Ra = a.getBoundingClientRect(),
      R1bottom = document.querySelector('#article').getBoundingClientRect().bottom;
  if (Ra.bottom < R1bottom) {
    if (b == null) {
      var Sa = getComputedStyle(a, ''), s = '';
      for (var i = 0; i < Sa.length; i++) {
        if (Sa[i].indexOf('overflow') == 0 || Sa[i].indexOf('padding') == 0 || Sa[i].indexOf('border') == 0 || Sa[i].indexOf('outline') == 0 || Sa[i].indexOf('box-shadow') == 0 || Sa[i].indexOf('background') == 0) {
          s += Sa[i] + ': ' +Sa.getPropertyValue(Sa[i]) + '; '
        }
      }
      b = document.createElement('div');
      b.className = "stop";
      b.style.cssText = s + ' box-sizing: border-box; width: ' + a.offsetWidth + 'px;';
      a.insertBefore(b, a.firstChild);
      var l = a.childNodes.length;
      for (var i = 1; i < l; i++) {
        b.appendChild(a.childNodes[1]);
      }
    }
    var Rb = b.getBoundingClientRect(),
        Rh = Ra.top + Rb.height,
        W = document.documentElement.clientHeight,
        R1 = Math.round(Rh - R1bottom),
        R2 = Math.round(Rh - W);
    if (Rb.height > W) {
      if (Ra.top < K) {  // скролл вниз
        if (R2 + N > R1) {  // не дойти до низа
          if (Rb.bottom - W + N <= 0) {  // подцепиться
            b.className = 'sticky';
            b.style.top = W - Rb.height - N + 'px';
            Z = N + Ra.top + Rb.height - W;
          } else {
            b.className = 'stop';
            b.style.top = - Z + 'px';
          }
        } else {
          b.className = 'stop';
          b.style.top = - R1 +'px';
          Z = R1;
        }
      }...