固定コンテンツ


positionで固定

  • position:fixed : 基準位置がビューポート 例:ヘッダー、下部固定バナーなど
  • position:sticky : フロートから固定 例:ヘッダー、フロートバナーなど
position:fixed
aside
position:sticky
#Cont01
#Cont02

HTML

<div class="header">
  <div>position:fixed</div>
  <div><a href="#Cont01">Cont01</a></div>
  <div><a href="#Cont02">Cont02</a></div>
  <div><a href="#Cont03">Cont03</a></div>
</div>
<div class="cont">aside</div>
<div class="sticky">
  <div>position:sticky</div>
  <div><a href="#Cont01">Cont01</a></div>
  <div><a href="#Cont02">Cont02</a></div>
  <div><a href="#Cont03">Cont03</a></div>
</div>
<div class="main">
  <div id="Cont01">#Cont01</div>
  <div id="Cont02">#Cont02</div>
  <div id="Cont03">#Cont03</div>
</div>

CSS

html {
  scroll-behavior: smooth;
  scroll-padding-top: 112px;
}
.header {
  position: fixed;
  top: 0;
  z-index: 2;
}
.sticky {
  position: sticky;
  top: 56px;
  z-index: 3;
}
.cont {
  margin-top: 56px;
  height: 35vh;
  background: #aaa;
}
.main {
  & div {
    height: 70vh;
    display: grid;
    place-content: center;
    &:nth-child(2) {
      background: #cca;
    }
  }
}

position: sticky

親要素にoverflow、overflow-yの初期値以外が指定されているとスクロール動作をしないので、overflow、overflow-yは外す

jsでsticky動作をするサンプル

バナー位置の高さ調整

  • レスポンシブ固定バナー
  • ビューポートの幅変更によりヘッダー要素の高さが変わると、バナーの位置をjsで再取得する
  • サンプルは横のバナー →右の黒いの
position:fixed

HTML

<div class="float-banner">
  <div class="batsu"></div>
  position:fixed
</div>

CSS

.float-banner {
  z-index: 4;
  position: fixed;
  top: 235px;
  right: 0;
  background: #111d;
  color: #fff;
}
.hide {
  animation: fo_hide 0.3s ease-in-out forwards;
}

JS

function adjustBannerPosition() {
  const header = document.getElementById("l-header");
  const banner = document.querySelector(".float-banner");
  if (header && banner) {
    const headerHeight = header.offsetHeight;
    banner.style.top = headerHeight + 116 + "px";
  }
}
window.addEventListener("load", adjustBannerPosition);
window.addEventListener("resize", adjustBannerPosition);
// 閉じるボタン
document.addEventListener("DOMContentLoaded", function () {
  const batsu = document.querySelector(".batsu");
  const floatBanner = document.querySelector(".float-banner");
  batsu.addEventListener("click", function () {
    batsu.classList.add("hide");
    floatBanner.classList.add("hide");
  });
});

スクロールで非表示

  • 固定header、バナーをスクロール class triggerでフェードアウト
  • 領域外でフェードイン復帰
Header

HTML

<div class="banner_on">消える</div>
<div class="fixed-content">Header</div>
<div class="banner_off">消える trigger class="banner_off"</div>

CSS

.banner_on {
  display: grid;
  place-content: center;
}

.fixed-content {
  position: fixed;
  width: 80%;
  top: 0;
  left: 50%;
  transform: translateX(-50%);
  pointer-events: all;
  z-index: 2;
}
.banner_off {
  height: 100vh;
}

JS

const fixedElement = document.querySelector(".fixed-content");
      const targetElement = document.querySelector(".banner_off");
      let isHidden = false;
      window.addEventListener("scroll", () => {
        const fixedElementRect = fixedElement.getBoundingClientRect();
        const targetElementRect = targetElement.getBoundingClientRect();

        if ((fixedElementRect.bottom >= targetElementRect.top) & (fixedElementRect.top <= targetElementRect.bottom)) {
          if (!isHidden) {
            fixedElement.classList.remove("visible");
            fixedElement.classList.add("hidden");
            isHidden = true;
          }
        } else {
          if (isHidden) {
            fixedElement.classList.add("visible");
            fixedElement.classList.remove("hidden");
            isHidden = false;
          }
        }
      });

サンプル overflowを親階層に入れるとうまく動かないため

CSS

前の記事

要素の高さを揃える