MENU CLOSE

【CSS】position:sticky;で
要素を追従させる方法

css
css

position:sticky;って?

ヘッダーナビゲーションやサイドメニューなど、その位置までスクロールしたらそこから画面に固定して追従させておきたい時があります。 特にヘッダーをこの手法で固定する場合は「スティッキーヘッダー」と言われているようです。 
このような実装は、JSでスクロール位置を計算しposition:fixed;のCSSを書いたclassを任意のタイミングで付け外しする、といった対応で実現できますが、CSSのみで実現できるのがposition:sticky;です。

文字だけではわかりにくいのでとりあえずデモを作ってみました。

position:sticky;でスティッキーヘッダーを実装したデモ

今回は簡単なコード例を元に使い方と注意点をメモします。

position:sticky;の使い方

まずはhtml。追従させたい要素とその親要素、兄弟要素を用意します。 
なぜ兄弟要素が必要かは後述します。

<div class="sticky-container">
  <div class="sticky">追従させたい要素</div>
  <div class="sticky-next">兄弟要素</div>
  <!-- /.sticky-next -->
</div>
<!-- /.sticky-container -->

CSSの指定はこちら。

.sticky{
  position: -webkit-sticky;
  position:sticky;
  top:0;
}

CSSはたったこれだけです。
これで.stickyクラスの要素が.sticky-containerクラスの要素内でスクロールに追従するようになります。追従させる位置を変えたい時は、topやleftなどで調整できます。

これだけなので指定はめちゃ簡単なのですが、普通に使おうとすると動く時と動かない時があります。 けっこうクセの強いプロパティなので、CSSを指定するだけでなくいくつかの条件をクリアしていないと動きません。

親要素と兄弟要素(高さ)が必要

position:sticky;を指定した要素は「スティッキーアイテム」、親要素は「スティッキーコンテナ」と言います。この2種類が必須なのですが、他にも兄弟要素がないとうまく動きません。
理由としては、兄弟要素がない場合は「スティッキーコンテナの中で唯一の要素になってしまうため要素の高さが生まれないから」です。スティッキーアイテムとスティッキーコンテナの高さが同じなので固定できないということになります。そのため兄弟要素を入れてあげることで、その兄弟要素の高さの分スティッキーコンテナの高さが増えるのでその高さ分のスクロールは追従されるようになります。

極端な話、兄弟要素うんぬんよりも「スティッキーコンテナ」の高さがあれば機能するので、CSSでheightを指定すれば要素が「スティッキーアイテム」のみでも追従はします。

<div class="sticky-container">
  <div class="sticky">追従させたい要素</div>
</div>
<!-- /.sticky-container -->

<style>
.sticky-container{
  /* 兄弟要素がなくても高さをつけてあげると追従はする */
  height:100vh;
}
</style>

親要素・祖先要素にoverflow(hiddenやautoなど)が指定されていない

親要素やその親、さらにその祖先まで辿ってoverflow:hidden;overflow: auto;が指定されていると動きません。

<div class="wrapper">
  <div class="content">
    <div class="sticky-container">
      <div class="sticky">追従させたい要素</div>
      <div class="sticky-next">兄弟要素</div>
    </div>
    <!-- /.sticky-container -->
  </div>
  <!-- /.content -->
</div>
<!-- /.wrapper -->

<style>
.content{
  /* 親要素にこのような指定があると動かない */
  overflow:hidden;
}
.wrapper{
  /* 祖先要素も同じく指定があると動かない */
  overflow:hidden;
}
</style>

これは意外と見落としがちな部分ですが、動かない時は祖先要素にoverflow:hidden;をかけていることがよくあります。
対処法としては、overflow:visible;にする、もしくは記述を削除しましょう。

上記の動かない条件を踏まえてデモを作りました。

position:sticky;の動かない条件のデモ

以上の2つが動かなくなる条件ですが、この2つをクリアできない場合はCSSで実装するのはあきらめてJSで実装した方が良いと思います。

position:sticky;のサポートブラウザ

Can I use... position:sticky;のブラウザ対応状況

主要なブラウザではIE11以外すべて使えます。(2019.12.12現在)
詳細はCan I use...で確認してください。

IE11対応

stickyfillというpolyfillがあります。

yarnもしくはnpmでダウンロードして使うか

//npm
npm install stickyfilljs --save

//Yarn
yarn add stickyfilljs

//JS内でimport
import Stickyfill from 'stickyfilljs';

CDNでも読み込めます。

<script src="https://cdnjs.cloudflare.com/ajax/libs/stickyfill/2.1.0/stickyfill.min.js" crossorigin></script>

読み込んだら、position:sticky;を指定した要素に適用します。

const elements = document.querySelectorAll('.sticky');
Stickyfill.add(elements);

jQueryの場合はこう。

const elements = $('.sticky');
Stickyfill.add(elements);

最初に作ったデモサイトStickyfillを適用しているのでIE11でも動作します。

これで主要なブラウザで問題なく使えますね。

おわりに

今回は記事を書くに当たってスティッキーヘッダーの簡単なデモを作ってみました。
使い方によってはもっとおもしろいUIが作れそうなCSSプロパティだと思います。 ただ実際はJSの方が細かな調整が効くので、使い所はかなり限られる印象ですが、CSSしか使えない状況であったり、JSで全く同じ挙動を実装するならCSSの方が軽くできるという部分でのメリットがあるので、知っておいて損はないと思います。

記事一覧

RELATED

Transients API
inoue
inoue
TIPS

【WordPress】Transients APIを使ってデータをキャッシュする方法

Flatpickr
inoue
inoue
TIPS

Flatpickrで日時入力をカレンダー表示にする

BASE DESIGN THEME
inoue
inoue
TIPS

BASEテーマカスタマイズ【実践編】見出しの文言を変更できるようにする

BASE DESIGN THEME
inoue
inoue
TIPS

BASEテーマカスタマイズ【デザインオプション編】テーマに新しい機能を加える方法

BASE DESIGN THEME
inoue
inoue
TIPS

BASEテーマカスタマイズ【準備編】カスタマイズに必要な前提知識について

BACKGROUND VIDEO
inoue
inoue
TIPS

動画をWebページの背景に埋め込む時のテクニック

NEW POSTS

svg-audiovisualizerAudioVisualizer [ howler.js + SVG ]
inoue
inoue
TRY

【howler.js】ストリーミング音源からオーディオビジュアライザーを作る

Simple GA Ranking
inoue
inoue
TRY

Simple GA Ranking[ver2.1.6]が表示されないので調べてみた

Sass @import → @use
inoue
inoue
TRY

【Sass】@importを@useに置き換えてみる《FLOCSS対応》

Stripe Payment Links
inoue
inoue
TRY

コーディング一切不要のStripe Payment Linksで決済機能を試してみる

BASE Partners
inoue
inoue
COLUMN

【BASE Partners】有料テーマの無償提供特典について

BASE Partners
inoue
inoue
COLUMN

BASEオフィシャルパートナーに認定されました

ブログ記事一覧
  • HOME
  • TIPS
  • 【CSS】position:sticky;で要素を追従させる方法