hideable side menu layout with opener draft (click handler)

by ShaCP

HTML

<section class="container">
  <div class="left side menu">
    <div class="side_contents">
    </div>
    <div class="tab">
      >
    </div>
  </div>
  <div class="center">
  </div>
  <div class="right side padding">
    <div class="side_contents">
    </div>
  </div>
</section>

CSS

body {
  margin: 0;
}

body,
.container {
  min-height: 100vh;
}

/* * {
  overflow: hidden;
} */

.container {
  max-width: 800px;
  margin: auto;
  display: grid;
  grid-template-columns: 1fr minmax(0, 500px) 1fr;
  /* justify-content: center; */
  overflow: hidden;
  position: relative;
}

/* .center_container {
  position: absolute;
  grid-column: 2 / 3;
  width: 100%;
  height: 100%;
} */

.center {
  background-color: lightskyblue;
  width: 500px;
  height: 100%;
  /*   min-width: 500px;    */
  overflow: hidden;
  /*   position: absolute;
  grid-column: 2 / 3;
  width: 100%;
  height: 100%; */
  /* justify-self: center; */
}

/* .inner_center {
  position: absolute;
  background-color: lightyellow;
  width: 500px;
  height: 100%;
}
 */
.left {
  background-color: lightpink;
  width: 100%;
  transition: width 1s linear;
}

.right {
  width: 0;
}

.element_width {
  position: absolute;
}

.tab {
  position: absolute;
  z-index: 9999;
}

@media screen and (max-width: 649px) {
  .left {
    width: 0;
  }

  .expand {
    width: 150px;
  }
}

@media screen and (max-width: 499px) {
/*   .center {
    position: absolute;
    left: 0;
    right: 0;
    transition: 1s left linear;
    width: 100%;
  }
  
  .expand~.center {
    left: 150px;
  } */

/* this can replace everything above */
  .center{ 
  width: 100vw;
  }
}

JavaScript

Function.prototype.throttle = function(limit) {
  var callback = this;
  var timeout;
  var waiting = false; // Initially, we're not waiting
  return function() { // We return a throttled function
    clearTimeout(timeout);
    if (!waiting) { // If we're not waiting
      callback.apply(this, arguments); // Execute users function
      waiting = true; // Prevent future invocations
      setTimeout(function() { // After a period of time
        waiting = false; // And allow future invocations
      }, limit);
    }
    var runAtTheEnd = callback.bind(this, arguments[0]);
    timeout = setTimeout(runAtTheEnd, limit);
  }
}

function appendElement(element, elementToAdd) {
  var lastElement = element.children[element.children.length - 1];
  if (element.children[0] && lastElement.className === "element_width") {
    element.replaceChild(elementToAdd, element.children[element.children.length - 1])
  } else {
    element.appendChild(elementToAdd);
  }
}

var sides = document.querySelectorAll(".side");
var tab = document.querySelector(".tab");
var container = document.querySelector(".container");
var center = document.querySelector(".center");
var left = document.querySelector(".left");
var innerCenter = document.querySelector(".inner_center");


function indexedWidthReports(i) {
  return function reportWidth(entries) {
    for (var entry of entries) {
      var {
        target,
        contentRect
      } = entry;

      var widthElement = document.createElement("span");
      widthElement.className = "element_width"
      widthElement.style.top = `${!i ? i + 2 : i === 1 ? i + 3 : (i + 1) * 2}em`
      widthElement.innerHTML = (target.className || target.localName) + " " + parseInt(contentRect.width) + "px";
      appendElement(target, widthElement);
    }
  }
}

/* const throttledReportWidth = reportWidth.throttle(150); */

var elementsToObserve = [...sides, container, center, document.body];

addObserver(elementsToObserve);

function addObserver(elementArray) {
 ...