<div class="layout min-h-dvh bg-gray-100">
  <header class="sticky top-0 z-10 h-[57px] max-h-[57px] shrink-0 border-b bg-gray-100" style="grid-area: header">header</header>

  <div id="content" class="h-fit" style="grid-area: content">
    <div>
      <div class="content gap-4 max-w-6xl w-full mx-auto p-4">
        <div class="relative flex flex-col gap-4" style="grid-area: intro">
          <div class="rounded-lg bg-white p-6">intro</div>
        </div>
        <div class="flex flex-col gap-4 " style="grid-area: main">
          <div class="min-h-96 rounded-lg bg-white p-6">post</div>
          <div class="min-h-96 rounded-lg bg-white p-6">post</div>
          <div class="min-h-96 rounded-lg bg-white p-6">post</div>
          <div class="min-h-96 rounded-lg bg-white p-6">post</div>
          <div class="min-h-96 rounded-lg bg-white p-6">post</div>
          <div class="min-h-96 rounded-lg bg-white p-6">post</div>
          <div class="min-h-96 rounded-lg bg-white p-6">post</div>
          <div class="min-h-96 rounded-lg bg-white p-6">post</div>
          <div class="min-h-96 rounded-lg bg-white p-6">post</div>
        </div>
        <aside class="relative block w-64 shrink-0" style="grid-area: aside">
          <div id="aside-wrapper" class="flex h-full flex-col justify-end">
            <div id="aside" class="sticky bottom-4 flex flex-col gap-4" style="backface-visibility: hidden;">
              <div id="aside-top" class="shrink-0">top marker</div>
              <div class="min-h-72 rounded-lg bg-white p-6">widget</div>
              <div class="min-h-72 rounded-lg bg-white p-6">widget</div>
              <div class="min-h-72 rounded-lg bg-white p-6">widget</div>
              <div class="min-h-72 rounded-lg bg-white p-6">widget</div>
              <div class="min-h-72 rounded-lg bg-white p-6">widget</div>
              <div id="aside-bottom">bottom marker</div>
            </div>
          </div>
        </aside>
      </div>
    </div>
  </div>
</div>
.layout {
    display: grid;
    grid-template-columns: 288px calc(100% - 288px);
    grid-template-rows: min-content min-content min-content 1fr min-content;
    grid-template-areas:
        "banner banner"
        "header header"
        "subheader subheader"
        "navbar content"
        "navbar footer"
        "navbar fixedBottom";
}

.content {
    display: grid;
    grid-template-columns: 1fr 0fr;
    grid-template-rows: 0fr 1fr;
    grid-template-areas:
        "intro intro"
        "main aside";
}
let lastScrollTop = 0;
let lastScrollDirection = "down";
let scrollDirection = "down";

document.addEventListener("scroll", function () {
  const content = document.getElementById("content");
  const asideWrapper = document.getElementById("aside-wrapper");
  const aside = document.getElementById("aside");

  const asideTop = document.getElementById("aside-top");
  const asideBottom = document.getElementById("aside-bottom");

  const currentScrollTop = window.scrollY;

  if (currentScrollTop > lastScrollTop) {
    scrollDirection = "down";
  } else {
    scrollDirection = "up";
  }

  if (lastScrollDirection !== scrollDirection) {
    aside.classList.add("static");
    aside.classList.remove("sticky", "top-[73px]", "bottom-4");
  
    // Вот здесь какое значение должно быть?
    aside.style.transform = `translate3d(0, ${
      aside.getBoundingClientRect().top -
      asideWrapper.getBoundingClientRect().top
    }px, 0)`;

    if (scrollDirection === "up") {
      asideWrapper.classList.remove("justify-end");
      asideWrapper.classList.add("justify-start");
    }
  }

  if (isElementOnScreen(asideBottom) && scrollDirection === "down") {
    aside.classList.remove("static", "top-[73px]");

    aside.classList.add("sticky", "bottom-4");

    asideWrapper.classList.remove("justify-start");
    asideWrapper.classList.add("justify-end");

    // aside.style.transform = `translate3d(0, 0, 0)`;
  }

  if (isElementOnScreen(asideTop) && scrollDirection === "up") {
    aside.classList.remove("static", "bottom-4");
    aside.classList.add("sticky", "top-[73px]");

    aside.style.transform = `translate3d(0, 0, 0)`;
  }

  lastScrollTop = currentScrollTop;
  lastScrollDirection = scrollDirection;
});

function isElementOnScreen(element) {
  const rect = element.getBoundingClientRect();
  const windowWidth = window.innerWidth || document.documentElement.clientWidth;
  const windowHeight =
    window.innerHeight || document.documentElement.clientHeight;

  if (
    rect.left < 0 ||
    rect.right > windowWidth ||
    rect.top < 0 ||
    rect.bottom > windowHeight
  ) {
    return false;
  }

  return true;
}

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdn.tailwindcss.com