CSSのposition:stickyがすごく便利
最近新しく追加された position の新しい値 sticky が場合によってはすごく便利なので記事を書いてみます。
対応ブラウザがまだあまり多くないので実用性は乏しいかもしれませんが、今まで JavaScript の力を借りなきゃ出来なかったことがたったの2行の CSS で出来てしまう魔法みたいな position の値です。
position: sticky
MDN が説明が詳しいので貼っておきます。
簡単に言うと「スクロールでその位置まで来たらそれ以降は fixed する」みたいな感じです。
サンプル
この記事内で「position: sticky」や「サンプル」など h2 要素に position: sticky をかけています。対応ブラウザであれば h2 要素が fixed しているはずです。
HTML
<h2 class="h2-sticky">position: sticky</h2>
CSS
.h2-sticky {
position: -webkit-sticky; /* Safari */
position: sticky;
top: 0;
}
h2 要素の位置までスクロールしてくると fixed されます。「その位置に来ると」という部分が通常の fixed とは異なります。
最終的にどこまで固定されて要素がついてくるかは「sticky がかかった要素の親の端」までです。この記事では h2 タグは各 section タグに含まれているので section タグの下端まで fixed します。親要素の中でのみ fixed されるということですね。
<section>
<!-- h2 要素はここから -->
<h2 class="h2-sticky">position: sticky</h2>
・・・
<!-- ここまで fixed する -->
</section>
上の HTML の場合、position: sticky な要素の親は section 要素になるので、その section 要素の中でのみ fixed します。
その他のサンプル
よく使われる追尾型の目次なんかにも position: sticky は使うことが出来ます。目次の場所まで来たらその後のスクロールでは fixed を勝手にしてくれるので便利です。
縦方向の fixed だけでなく横方向の fixed にも使えます。
下記の table で横バージョンの position: sticky を使っています。横スクロールをしてみてください。
ブラウザ対応
Google Chrome | Internet Explorer | Edge | Firefox | Opera | Safari |
---|---|---|---|---|---|
○ | ✕ | ✕ (今後対応予定?) | ○ | ○ | ○ (-webkit-) |
IE が対応していないことが大事なので IE を横固定しています。
HTML
<table id="browser-check">
<tbody>
<tr>
<th>Google Chrome</th>
<th class="table-sticky">Internet Explorer</th>
<th>Edge</th><th>Firefox</th>
<th>Opera</th>
<th>Safari</th>
</tr>
<tr>
<td>○</td>
<td class="table-sticky">✕</td>
<td>✕ (今後対応予定?)</td>
<td>○</td>
<td>○</td>
<td>○(-webkit-)</td>
</tr>
</tbody>
</table>
CSS
.table-sticky {
position: -webkit-sticky; /* Safari */
position: sticky;
left: 0;
}
left 値や right 値を指定すると横でのスクロールの fixed に対応します。
sticky を使うことで2番目のセルを固定したりも簡単に出来てしまいます。sticky を使わないで JavaScript でやろうとすると結構面倒くさいコードになっちゃいます。
バグ報告などの追記
table に使う際、border-collapse: collapse との相性が position: sticky はあまり良くないようです。使う際は table を border-collapse: separate で組んだほうが position: sticky を使う際は安全です。
バグの可能性もあるので今後治るかもしれませんが。
また、Firefox、Opera は table を使った際 sticky が反応しないようです。バグとして上がっているようなので今後治ると思われます。
sticky させたい要素を含む親、それ以上の先祖要素までふくめて overflow: hidden を当てていると sticky が効かないそうです。悲しいですがこれもバグのようなので、治るまで待つか先祖要素までふくめて overflow: hidden を使わないようにすれば OKです。
まとめ
h2 要素を固定する意味があるのか無いのかという問題はありますが、途中から fixed して追尾してくる目次や広告?なんかにも使えそうな CSS です。JavaScript 要らずは便利です。
IE が対応していないので結局完全に CSS だけで対応が出来ないのが悲しい限りですが、モバイルのみ使いたい場合、例えば先の teble の2番目のセルを固定などであればモバイルブラウザは古いアンドロイドでなければ基本対応しているので使えるかもしれません。
ちなみに本題とは関係ないですが sticky は「ベタベタする、ネバネバする」という意味だそうです。