tag:crieit.net,2005:https://crieit.net/tags/scroll-margin-top/feed 「scroll-margin-top」の記事 - Crieit Crieitでタグ「scroll-margin-top」に投稿された最近の記事 2022-04-28T00:04:15+09:00 https://crieit.net/tags/scroll-margin-top/feed tag:crieit.net,2005:PublicArticle/18178 2022-04-28T00:04:15+09:00 2022-04-28T00:04:15+09:00 https://crieit.net/posts/bootstrap5-scroll-margin-top-darkmode-parallax-demo-20220430 Bootstrap 5 + scroll-margin-top + ダークモード + パララックス についてメモ <h2 id="経緯"><a href="#%E7%B5%8C%E7%B7%AF">経緯</a></h2> <p><a target="_blank" rel="nofollow noopener" href="https://labor.ewigleere.net/">Bootstrap 5 で JavaScript の記述なしにアンカーリンクへのアニメーション付きスクロールが <code>scroll-behavior</code> で実装されていることを最小限構成で確認した</a>ので、改めて Bootstrap 5 で検証したいと思います。</p> <h2 id="デモ"><a href="#%E3%83%87%E3%83%A2">デモ</a></h2> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://arm-band.github.io/test-scroll-mt-vault-celestia/">Home - Vault Celestia</a></li> </ul> <p>早速ですがデモを。</p> <h2 id="scroll-margin-top"><a href="#scroll-margin-top">scroll-margin-top</a></h2> <p>上述の通り、 Bootostrap 5 ではアンカーリンクへのアニメーション付きスクロールは <code>scroll-behavior: smooth;</code> で実装されているのでこの部分はそちらに任せて、 <code>scroll-margin-top</code> のみ自前で記述。</p> <pre><code class="scss">// foundation/_variable.scss $navbar-height: 56px; /* css変数 + Scss変数 */ :root { --navbar-height: #{$navbar-height}; } // object/utility/_u-ssnapmt.scss .u-ssnapmt { scroll-margin-top: var(--navbar-height); } </code></pre> <p>今回は css変数 + Scss の併用で記述してみました。</p> <h2 id="css変数 + ページごとのキービジュアル画像の変更"><a href="#css%E5%A4%89%E6%95%B0+%2B+%E3%83%9A%E3%83%BC%E3%82%B8%E3%81%94%E3%81%A8%E3%81%AE%E3%82%AD%E3%83%BC%E3%83%93%E3%82%B8%E3%83%A5%E3%82%A2%E3%83%AB%E7%94%BB%E5%83%8F%E3%81%AE%E5%A4%89%E6%9B%B4">css変数 + ページごとのキービジュアル画像の変更</a></h2> <p>キービジュアル (ページ最上部にある画像 + 見出し + キャッチコピー等のパーツ) の背景画像について、ページごとに異なる画像を表示させたい、というのはよくある話だとは思います。</p> <pre><code class="html"><head> <style> .c-eyecatch { /* css変数で キービジュアル の画像をページごとに切替 */ background-image: var(--img); } </style> </head> <body> <!-- css変数で キービジュアル の画像をページごとに切替 --> <div class="p-3 p-sm-5 c-eyecatch" style="--img:url('https://source.unsplash.com/ROVBDer29PQ/1920x1080')"> <div class="container"> <h1 class="display-4">ほげ</h1> <p class="lead">ふがふが</p> </div> </div> <main class="l-main"> <section class="container py-5"> <h1 class="display-4">ぴよ</h1> <p>ほげら</p> </section> <!-- 流用 --> <div class="p-3 p-sm-5 mb-4 c-eyecatch" style="--img:url('https://source.unsplash.com/lNxMcE8mvIM/1920x1080')"></div> </body> </code></pre> <p>今回は css変数 を使って</p> <ul> <li>予め <code>head</code>タグ 内の <code>style</code>タグ では <code>background-image: var(--img);</code> でcss変数で指定しておく</li> <li>各要素で変数の値を都度差し替える</li> </ul> <p>という形で画像を切り替える形式を採ってみました。</p> <p>なお、今回はデモなので Jumbotron風 の実装で。</p> <h2 id="ダークモード"><a href="#%E3%83%80%E3%83%BC%E3%82%AF%E3%83%A2%E3%83%BC%E3%83%89">ダークモード</a></h2> <pre><code class="scss">// layout/_l-main.scss @charset "utf-8"; @use "../foundation" as f; .l-main { background-color: f.$bg-color; color: f.$color; #dark > & { /* ダークモード対応 */ @media (prefers-color-scheme: dark) { background-color: f.$color; color: f.$bg-color; } } } </code></pre> <p>メディアクエリ <code>@media (prefers-color-scheme: dark)</code> によるダークモードを試しに記述。</p> <p>ブログのような色に対して中立性の高いコンテンツの場合は使えそうですが、ブランドカラーが決まっている場合は難しそうな感。</p> <p>個人的には基本ダークモードの方がありがたいのですが……。</p> <h2 id="パララックス"><a href="#%E3%83%91%E3%83%A9%E3%83%A9%E3%83%83%E3%82%AF%E3%82%B9">パララックス</a></h2> <p>最後はパララックス。これについてはパッケージを利用しました。</p> <pre><code class="json"> "dependencies": { "ukiyojs": "^3.0.0" }, </code></pre> <pre><code class="js">import Ukiyo from 'ukiyojs'; window.addEventListener( 'load', () => { const ukiyoParallaxes = document.querySelectorAll( '.ukiyo' ); ukiyoParallaxes.forEach( ( ukiyoParallax ) => { new Ukiyo( ukiyoParallax, { scale: 1.75, speed: 1.75, } ); }); }); </code></pre> <p>公式のドキュメント通りです。</p> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://github.com/yitengjun/ukiyo-js">GitHub - yitengjun\/ukiyo-js: ⛰️Modern parallax library for picture elements and any images</a></li> </ul> <p>検索すると自前実装も出てくるのですが、後々を考えるとパッケージの方が良さそうな気がするので。</p> <h2 id="参考"><a href="#%E5%8F%82%E8%80%83">参考</a></h2> <h3 id="scroll-margin-top"><a href="#scroll-margin-top">scroll-margin-top</a></h3> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://www.aizulab.com/blog/sticky-header-overlap/">アンカーリンクの遷移先が隠れる…。追従ヘッダーの重なりを回避するCSS | 会津ラボ</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://tech.arms-soft.co.jp/entry/2020/01/29/090000">アンカーリンクのズレをscroll-snapを使って直せるか試してみた - arms inc. Engineers' Blog</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://wb-hp.com/blog/2021/10/04/google-ie-support-ended.html">scroll-margin-top でヘッダー固定されたページのアンカーリンクの座標を調整する | ホワイトボードオフィシャルブログ</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://zenn.dev/catnose99/articles/75d3c69bf71bad">【追記: Safariでも動くようになった!】scroll-margin-topがsafariでうまく効かない問題と現状のワークアラウンド</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://developer.mozilla.org/ja/docs/Web/CSS/scroll-margin-top">scroll-margin-top - CSS: カスケーディングスタイルシート | MDN</a></li> </ul> <h3 id="Bootstrap 5 での jumbotron"><a href="#Bootstrap+5+%E3%81%A7%E3%81%AE+jumbotron">Bootstrap 5 での jumbotron</a></h3> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://bootstrap-guide.com/sample/jumbotron-bgimage">背景が画像のジャンボトロンの実例~Bootstrap5設置ガイド</a></li> </ul> <h3 id="css変数 で背景画像指定"><a href="#css%E5%A4%89%E6%95%B0+%E3%81%A7%E8%83%8C%E6%99%AF%E7%94%BB%E5%83%8F%E6%8C%87%E5%AE%9A">css変数 で背景画像指定</a></h3> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/sygnas/items/5a08d2462b6fc46850d7">CSS変数でbackground-imageを指定するとChromeとSafariで挙動が異なるのを解決する - Qiita</a></li> </ul> <h3 id="ダークモード"><a href="#%E3%83%80%E3%83%BC%E3%82%AF%E3%83%A2%E3%83%BC%E3%83%89">ダークモード</a></h3> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://www.webcreatorbox.com/tech/dark-mode">Webサイトをダークモードに対応させよう | Webクリエイターボックス</a></li> </ul> <h3 id="パララックス"><a href="#%E3%83%91%E3%83%A9%E3%83%A9%E3%83%83%E3%82%AF%E3%82%B9">パララックス</a></h3> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://zenn.dev/nye/articles/b3cbcf347a0291">モダンアニメーションのパララックス(視差効果)背景のライブラリを作った</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://github.com/yitengjun/ukiyo-js">GitHub - yitengjun\/ukiyo-js: ⛰️Modern parallax library for picture elements and any images</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://www.npmjs.com/package/ukiyojs">ukiyojs - npm</a></li> </ul> arm-band tag:crieit.net,2005:PublicArticle/18177 2022-04-27T23:58:57+09:00 2022-04-27T23:58:57+09:00 https://crieit.net/posts/css-scroll-behavior-and-scroll-margin-top-note-20220428 (css) scroll-behavior と scroll-margin-top についてメモ <p>css の <code>scroll-behavior</code> と <code>scroll-margin-top</code> について検証したのでメモ。</p> <h2 id="経緯"><a href="#%E7%B5%8C%E7%B7%AF">経緯</a></h2> <p>Bootstrap 5 で何気なく検証をしていたら、特に何をしたわけでもないのに同一ページ内のアンカーリンクにアニメーション付きでスクロールしたので気になりました。</p> <p>自前の JavaScript では何も記述していないプレーンな状態だったので、 Bootstrap 5 の JavaScript かと思ったのですが、該当の CDN からの読み込みの <code>script</code>タグ を削除しても動作したので「すわ css 側か?」となり調べてみることにしました。</p> <h2 id="調査結果"><a href="#%E8%AA%BF%E6%9F%BB%E7%B5%90%E6%9E%9C">調査結果</a></h2> <p>結果、 <code>scroll-behavior</code>プロパティ に依るものと分かりました。具体的には、</p> <pre><code class="css">html { scroll-behavior: smooth; } </code></pre> <p>この記述でページ全体にスクロールアニメーションが付与されていました。</p> <p>しかも調べてみると、別ページのアンカーリンクに遷移する場合は</p> <ol> <li>ページ遷移</li> <li>遷移先のページでアンカーリンクまで自動的にアニメーション付きでスクロール</li> </ol> <p>という挙動をすることが分かりました。</p> <p>css で別ページのアンカーリンクまで対応しているのであれば、上述の挙動が気になる場合を除けばもはやこれ1つで済んでしまうのではないでしょうか……。</p> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://caniuse.com/?search=scroll-behavior">"scroll-behavior" | Can I use... Support tables for HTML5, CSS3, etc</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/yoshitake_1201/items/05a13fd77c18ff380eb6">iOSのバージョンと Safariバージョンの対応表(2022\/4\/6 現在 - Qiita</a></li> </ul> <p>注意点としては、 iOS Safari が15.4(2022/3/14リリース、2022/4/27記事執筆時点で最新版) のみサポートとなっているため、最新版以外の Safari のサポートが必要な場合は polyfill 等の代替手段を講じる必要性がありそうです。</p> <p>PJAX 等のデフォルトではない遷移をした際の挙動については未検証なので何ともですが少し気になります。</p> <p>それと、もう一点気になったのは Bootstrap のケースで言うとナビゲーションバーに <code>.fixed-top</code> を付けていた場合。つまりナビゲーションバーが画面上部に固定表示で追従するパターンですね。</p> <p>頻出するパターンですが、このケースでは工夫しないとアンカーリンク移動時にナビゲーションバーの裏側にコンテンツが隠れてしまうという課題がありました。</p> <p>かつてはこれを <code>margin-top: -80px; padding-top: 80px;</code> 等とネガティブマージンとパディングで調整・相殺するテクニックを使っていましたが……。</p> <h2 id="scroll-margin-top"><a href="#scroll-margin-top">scroll-margin-top</a></h2> <p>ここで兼ねてより目を付けていたのが <code>scroll-margin-top</code> 。 <code>scroll-snap</code> と呼ばれるスクロール時に特定の位置で止めたり誘導するプロパティの1つで、上述のアンカーリンク遷移時にナビゲーションバーの裏側に隠れてしまう問題を解決する方法として利用できます。</p> <pre><code class="css">.anchor-link { scroll-margin-top: 80px; } </code></pre> <p>これまで上述のようなネガティブマージョンとパディングの相殺や、あるいは <code>before</code>疑似要素 を利用した方法で調整していた手間が、上述の通り1行指定するだけで解決できます。</p> <p>css変数を使用するならば、</p> <pre><code class="css">:root { /* 変数定義 */ --navbar-height: 80px; } html { /* スムーススクロール */ scroll-behavior: smooth; } .header { /* ナビゲーションバーを上部固定表示 */ position: fixed; top: 0; left: 0; width: 100%; z-index: 10; /* css変数を使用して高さを指定 */ height: var(--navbar-height); } .main { /* スクロール可能なコンテンツ領域の上端部分はめり込むのでここは普通に margin-top でナビゲーションバー分下げる。css変数使用。 */ margin-top: var(--navbar-height); } .anchor-link { /* アンカーリンクが裏側に隠れるのを抑止。css変数使用。 */ scroll-margin-top: var(--navbar-height); } </code></pre> <p>このようなイメージですね。</p> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://caniuse.com/?search=scroll-margin-top">"scroll-margin-top" | Can I use... Support tables for HTML5, CSS3, etc</a></li> </ul> <p>ちなみにこちらは iOS Safari 14.7 以降で有効ですが、やはりそこそこ新しめの Safari である必要があるので、こちらもケースによっては注意が必要そうです。</p> <h2 id="参考"><a href="#%E5%8F%82%E8%80%83">参考</a></h2> <h3 id="scroll-behavior"><a href="#scroll-behavior">scroll-behavior</a></h3> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://coliss.com/articles/build-websites/operation/work/scroll-page-smoothly-by-css-and-javascript.html">CSSだけでも実装できる!ページ内アンカーやページ上部にアニメーションでスクロールさせるCSS, JavaScriptのまとめ | コリス</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://web.havincoffee.com/design/2020/09/2009281.html#inpage-ank21">CSSでページ内リンクをなめらかにスクロールする|web design-havin' a coffee break|珈琲とウェブデザイン</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://caniuse.com/?search=scroll-behavior">"scroll-behavior" | Can I use... Support tables for HTML5, CSS3, etc</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/yoshitake_1201/items/05a13fd77c18ff380eb6">iOSのバージョンと Safariバージョンの対応表(2022\/4\/6 現在 - Qiita</a></li> </ul> <h3 id="ネガティブマージョンとパディングの調整"><a href="#%E3%83%8D%E3%82%AC%E3%83%86%E3%82%A3%E3%83%96%E3%83%9E%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3%E3%81%A8%E3%83%91%E3%83%87%E3%82%A3%E3%83%B3%E3%82%B0%E3%81%AE%E8%AA%BF%E6%95%B4">ネガティブマージョンとパディングの調整</a></h3> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://designsupply-web.com/media/programming/1999/">ネガティブマージン・パディングで固定ヘッダー使用時のアンカーリンクに対応する</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://www.softel.co.jp/blogs/tech/archives/6083">【CSS】ページ内リンクのジャンプ先の位置を調整する at softelメモ</a> <ul> <li>疑似要素を使う手法もあり</li> </ul></li> </ul> <h3 id="scroll-margin-top"><a href="#scroll-margin-top">scroll-margin-top</a></h3> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://www.aizulab.com/blog/sticky-header-overlap/">アンカーリンクの遷移先が隠れる…。追従ヘッダーの重なりを回避するCSS | 会津ラボ</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://tech.arms-soft.co.jp/entry/2020/01/29/090000">アンカーリンクのズレをscroll-snapを使って直せるか試してみた - arms inc. Engineers' Blog</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://wb-hp.com/blog/2021/10/04/google-ie-support-ended.html">scroll-margin-top でヘッダー固定されたページのアンカーリンクの座標を調整する | ホワイトボードオフィシャルブログ</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://zenn.dev/catnose99/articles/75d3c69bf71bad">【追記: Safariでも動くようになった!】scroll-margin-topがsafariでうまく効かない問題と現状のワークアラウンド</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://developer.mozilla.org/ja/docs/Web/CSS/scroll-margin-top">scroll-margin-top - CSS: カスケーディングスタイルシート | MDN</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://caniuse.com/?search=scroll-margin-top">"scroll-margin-top" | Can I use... Support tables for HTML5, CSS3, etc</a></li> </ul> arm-band