JSFiddle - React, Tailwind, and code Playground

by pleinx

HTML

<div class="page">
  <div class="header">
    Header
  </div>
  <div class="wrapper">
    <div class="main">
      <p>
        Main Content
      </p>
    </div>
    <div class="sidebar">
      <div class="example-sidebar">
        Hello, iam a Widget!
      </div>
    </div>
  </div>
  <div class="footer">
  Footer
  </div>
</div>

CSS

body, html {
  width: 100%;
  height: 100%;
  padding: 0;
  margin: 0;
  box-sizing: border-box;
}

div {
  box-sizing: border-box;
}

p {
  margin: 0;
  height: 1000px;
}

.page .header, .page .footer {
  height: 50px;
  background: lightblue;
}

.page .main {
  width: 70%;
  float: left;
  background: #ccc;
}

.wrapper:after, .wrapper:before {
  content:'';
  display: table;
  clear: both;
}

.page .sidebar {
  width: 24%;
  margin-left: 5%;
  float: left;
  background: #ddd;
}

.example-sidebar {
  height: 300px;
}

.page .main, .page .sidebar {
  padding: 5%;
}

Babel + JSX

"use strict";

class StickyBar {
    constructor(targetSelector, options, parentSelector) {
        this._target = this._resolveSelector(targetSelector);
        this._parent = this._resolveSelector(this._resolveParent(parentSelector));
        this._options = {...this._getDefaultOptions(), ...options};

        this._targetInitialOffset = {};
        this._init();
    }

    _getDefaultOptions() {
        return {
            spacer: 10,
            marginBottom: 0
        };
    }

    _init() {
        this._getParent().style.position = 'relative';
        this._targetInitialOffset = this._getTargetOffset();

        this._registerOnScroll();
        this._registerOnResize();
    }

    recalcuateOffset() {
        let lastPositionValue = this._getTargetComputedStyle().position;
        this._getTarget().style.position = 'static';
        this._targetInitialOffset.left = this._getTargetOffset().left;
        this._getTarget().style.position = lastPositionValue;
    }

    _registerOnResize() {
        window.onresize = () => {
            this.recalcuateOffset();
            this._procress();
        };
    }

    _registerOnScroll() {
        window.onscroll = () => {
            this._procress();
        };
    }

    _procress() {
        this.resetTarget();

        if (this._getWindowHeight() <= (this._getTargetHeight() + this._getSpacer())) {
            this._stickOnBottom();
        }
        else {
            this._stickOnTop();
        }

        if (((this._getTargetOffset().top + this._getTargetHeight()) - this.getTargetInitialOffset().top) >= (this._getParentHeight() + this._getSpacer())) {
            // onParentBottom
            this._getTarget().style.left = 'auto';
            this._getTarget().style.right = '0';
            this._getTarget().style.bottom = 'auto';
            this._getTarget().style.top = this._toPx(this._getBottomLimit());
            this._getTarget().style.position = 'absolute';
        }

        this._lastScrollTop =...