CSSの実装だけで固定ヘッダーが実現した話
みなさんこんにちはこんばんは。
もう年の瀬ですね。私は思ったよりもアドベントカレンダーのネタが見つからず、脳内で右往左往しています。
話が脱線しますが、私が開発に参加している「らくしふ」は従業員のシフト管理に特化しているプロダクトです。
メイン機能には各企業が会社の従業員を管理できるシフト表がありますが、このテーブルの組み方が非常に綺麗だったので、是非多くの方に導入して見てもらいたいです!
(代わりにLPを貼ります)
※本文では主に「らくしふ」で使用されていた、CSSの position: sticky
の話をします。
これからお話しするのは、表題の通り、上部固定ヘッダーと縦横のスクロールができるテーブルを新しく実装した時の話です。
実装例
文章では分かりづらいので、サンプルを自分の環境で作ってみました。
(個人サイトにする予定のものに実装したので、デザインに違和感があるかも…🙏)
縦スクロール時、テーブルの最初の行は固定される。(画面の一番上で張り付く)
横スクロール時、テーブルの最初の列が固定される。
これ、JS使っていないんだぜ…
position: stickyとは
MDNより抜粋
要素は文書の通常のフローに従って配置され、直近のスクロールする祖先
および包含ブロック(直近のブロックレベル祖先、表関連要素を含む) に対して top, right, bottom, leftの値に基づいて相対配置されます。オフセットは他の要素の配置には影響を与えません。
「スクロールの仕組み」を持つ直近の祖先 (overflow が hidden, scroll, auto, overlay として作成されたもの) に「粘着」します。
ポイントは、包含ブロック(直近のブロックレベル祖先、表関連要素を含む) に対して top, right, bottom, leftの値に基づいて相対配置するというところですね。
position: stickyを指定する要素は親要素に対して粘着(固定されたかのような動き)をしますが、その際には相対的な配置の指定が必要になります。
動画だと、固定されるテーブルヘッダは position: sticky; top: 0;
としているので、親要素にピッタリと被さるように粘着しています。topの数値を大きくすれば、一番上の間隔が開いた形で粘着します。
※ちなみに、2021/5/26~からChromeで一般的な使用が可能になったようです。
※使用する際には、他のブラウザのサポートについても注意深く見ておきましょう。
考慮すべきポイント
他の要素がある際には、重なりの順序を意識する必要があります。(z-index)
動画のように固定ヘッダを無視してトップに粘着させるには、固定したい要素 > 他の要素という関係値でz-indexを指定することが必要です。
// 固定したい要素に当てるCSS
.first-row {
display: flex;
position: sticky;
top: 0;
z-index: 2;
}
考慮すべきポイント2
現場によってはatomicデザインやflocssで設計しているようなところもあるかもしれません。
これらのCSS設計は、再利用可能なコンポーネントやレイヤーを定義しているところが強みですが、特にレイアウトをテンプレートとして使用する場合には、気をつけてほしいことがあります🙏
overflowの存在です。
私は最初下図のようにhtmlを組んでいました。
黄色い枠がテーブルを内包している親要素です。
この親要素に、overflow-x: scrollを指定してしまったことでテーブルヘッダが固定されない事件が起きてしまいました><
こちらの原因については、他の方が詳しく調べてくださっているので、引用させていただきます🙏
直近の祖先であるscroll containerのscrollportを基準にして張り付く仕様となっているため、その祖先にscroll containerを正しく設置しなければいけない
まとめ
CSS系は自身の特性だけではなく、影響する子要素の特性まで把握する必要があるので、個人的には奥深い分野だと思っています。
この辺について助けていただいたらくしふの先輩には感謝の念でいっぱいです🙏
🌟宣伝🌟
株式会社クロスビットでは、デスクレスワーカーのためのHR管理プラットフォームを開発しています。
一緒に開発を行ってくれる各ポジションのエンジニアを募集中です。
Discussion