📜

【CSS】透明なヘッダー作成法&重なったコンテンツを透過させる

2022/09/12に公開

はじめに

タイトルの時点でわかりにくくて申し訳ないのですが、下記のようなものを作る記事となっています。
透明なヘッダーを作り、スクロールした際にヘッダーと被ったメインコンテンツ部分を透過して背景を魅せるデザインとなります。

現在の背景はグラデーション1色ですが、アニメーション等で変化したり動きのあるbackgroundの場合、メインコンテンツの上下を透明することで、より背景デザインを魅せることができます。

また、下記のWEBアプリでこちらのデザインを使用しています。
https://task-bgm.vercel.app/

完成したもの

詳しくは下記のCodeSandBoxから見ていただければと思います。実際に動作確認しながら見られるのでおすすめです。
https://codesandbox.io/s/ztmc6k?file=/index.html

html
<header class="header">
      <h1 class="title">
        Title
      </h1>
      <div class="logo">logo</div>
      <nav class="pc-nav">
        <ul>
          <li>List1</li>
          <li>List2</li>
          <li>List3</li>
        </ul>
      </nav>
    </header>

    <div class="main">
      <div class="mask">
        <div class="maskScroll">
          <div class="blank"></div>
          <div class="flex">
            <div class="Contents">Content1</div>
          </div>
          <div class="flex">
            <div class="Contents">Content2</div>
          </div>
          <div class="flex">
            <div class="Contents">Content3</div>
          </div>
	  <div class="blank"></div>
        </div>
      </div>
    </div>

css
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  font-weight: 350;
  color: white;
}

header {
  width: 100%;
  padding: 10px;
  position: fixed;
  top: 0;
  left: 0;
  display: flex;
  align-items: center;
  justify-content: space-around;
  z-index: 10;
}

h1.title {
  margin-left: 30px;
  font-size: 20px;
}
.logo {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  -webkit-transform: translate(-50%, -50%);
  -ms-transform: translate(-50%, -50%);
}

ul {
  list-style: none;
  margin: 0;
  display: flex;
}

li {
  margin: 0 0 0 15px;
  font-size: 14px;
}

nav.pc-nav {
  margin: 0 0 0 auto;
  margin-right: 5vw;
}

.main {
  background: linear-gradient(to right, rgb(72, 216, 144), rgb(106, 209, 214));
  width: 100vw;
  height: 100vh;
  margin: 0 auto;
  z-index: 0;
  position: relative;
  display: block;
}

.mask {
  height: 100%;
  -webkit-mask-image: linear-gradient(
    to bottom,
    rgba(0, 0, 0, 0) 50px,
    black 70px,
    rgb(0, 0, 0) -webkit-calc(100% - 70px),
    rgba(0, 0, 0, 0) -webkit-calc(100% - 50px)
  );
  mask-image: linear-gradient(
    to bottom,
    rgba(0, 0, 0, 0) 50px,
    black 70px,
    rgb(0, 0, 0) -webkit-calc(100% - 70px),
    rgba(0, 0, 0, 0) -webkit-calc(100% - 50px)
  );
  position: relative;
}

.maskScroll {
  overflow-y: scroll;
  box-sizing: border-box;
  height: 100%;
}
.maskScroll::-webkit-scrollbar {
  display: none;
}

.blank {
  padding-top: 50px;
}
.Contents {
  padding: 50px;
  font-size: 6vh;
  word-wrap: break-word;
  text-align: center;
  height: 50vh;
  width: 50vw;
  background: blue;
}

.flex {
  padding: 50px;
  display: flex;
  justify-content: center;
}

ポイント

①ヘッダーと背景デザインの準備

まずは普通にヘッダーを用意します。細かいデザインについて今回は触れませんが、透明なヘッダーを制作するので、CSSのbackground等の色は指定しないよう注意してください。

次に背景として使用したいデザインをmainクラスのCSSに記述していきます。今回はグラデーション1色ですが、違う背景デザインにしたい方はmainクラスのCSSを変更してください。

css
.main {
  background: linear-gradient(to right, rgb(72, 216, 144), rgb(106, 209, 214)); /* 今回の背景色 */
  width: 100vw;
  height: 100vh;
  margin: 0 auto;
  z-index: 0;
  position: relative;
  display: block;
}

②maskクラスでコンテンツを隠す

maskクラスの内部に配置したものをグラデーションマスクで消します。今回はヘッダー分の高さと、ページの最下部も消すようにしています。
-webkit-mask-imageと、mask-imageの2種類を記載しないと上手く動作しないので注意してください。中身の設定は同じです。

今回の設定では画面の上から50pxは、コンテンツを完全に透過させています。50pxから70pxの間で徐々にグラデーションをかけてコンテンツを表示するようにしています。

css
.mask {
  height: 100%;
  -webkit-mask-image: linear-gradient(
    to bottom,  /* 画面の一番上を始点とし、画面下部の方向にグラデーションがかかる*/
    rgba(0, 0, 0, 0) 50px,  /* グラデーションの始まるポイント。透明度1.0 */
    black 70px, /* グラデーションの終わるポイント。透明度0 */
    rgb(0, 0, 0) -webkit-calc(100% - 70px), /* 画面下部のグラデーションの始まるポイント。透明度0 */
    rgba(0, 0, 0, 0) -webkit-calc(100% - 50px) /* 画面下部のグラデーションの終わるポイント。透明度1.0 */
  );
  mask-image: linear-gradient( /* 上記と同じ設定 */
    to bottom,
    rgba(0, 0, 0, 0) 50px,
    black 70px,
    rgb(0, 0, 0) -webkit-calc(100% - 70px),
    rgba(0, 0, 0, 0) -webkit-calc(100% - 50px)
  );
  position: relative;
}

画面下部のグラデーション位置の指定は、画面全体(100%)から必要なpx数を引いた計算で出しています。-webkit-calc(100% - ○○px)というような書き方で、計算した値を入れられます。

③maskScrollクラスでコンテンツ内部のみスクロールできるように

②のmaskクラスによって、コンテンツの上下を隠す処理が完成しました。ですが、コンテンツが長くなって溢れる場合があります。そこでoverflow-yを使って、内部をスクロールで動かせるようにします。表示したいコンテンツは全てこのクラスのタグ内に入れましょう。

css
.maskScroll{
    overflow-y: scroll;
    box-sizing: border-box;
    height: 100%;
}

④スクロールバーを隠す

上下をマスクした時の弊害で、スクロールバーも一部隠れています。今回はスクロールバーを完全に非表示にします。

css
.maskScroll::-webkit-scrollbar{
    display: none;
}

⑤ヘッダー分の高さの空白を入れる

コンテンツの始まり位置が、デフォルトでヘッダーにかかってマスクされてしまうのを防ぐために、コンテンツの最上部、最下部にそれぞれ余白を取りましょう。

css
.blank {
  padding-top: 50px; /*ヘッダーの高さ分の空白*/
}

まとめ

透明なヘッダーを作ると通常はコンテンツと重なって邪魔になるケースが多いですが、今回の実装でそれらが解消できたと思います。
今回はメインコンテンツをdivタグで囲ってヘッダーとフッター部分を透過させていますが、もっと楽な方法があるかもしれません…。色々勉強中です。

Discussion