EC-CUBE 4のヘッダー(商品検索・ログインナビ・カート)を画面上部に固定し、スクロールしても付いてくるようにするカスタマイズです。すべて管理画面だけで完結し、ファイルサーバーやコマンド操作は必要ありません。
管理画面だけで完結します。ブロック管理でヘッダーブロックを複製し、CSS管理で position: fixed を当て、レイアウト管理で差し替えるという3手順です。
.header_customize {
position: fixed;
top: 0;
left: 50%;
transform: translateX(-50%);
z-index: 100;
background: #fff;
opacity: 0.95;
padding-bottom: 15px;
}
固定した分だけ後続の要素が上へずれるので、同じ高さの空要素(スペーサー)を1つ置くのがポイントです。ヘッダーの高さは中身によって変わるため、その高さを合わせるところだけJavaScriptを使います。
ページを下までスクロールしても、商品検索・ログインナビ・カートが上部に残る
【動作環境】EC-CUBEのバージョン:4.2.2 / サーバー:Xserver
本記事は4.2.2で検証していますが、4.3.0の Block/header.twig は4.2系と同じ内容のため、同じ手順でそのまま実装できます。
固定・追従ヘッダーのしくみ
スクロールしても表示位置が変わらないようにするには、CSSの position: fixed を使うのが一般的です。ただし、これを当てるだけでは表示が崩れます。理由は次の2つです。
position: fixedを指定した要素は、通常の配置の流れから外れる(=そこに存在しない扱いになる)- そのため後続のコンテンツが上へ詰め、固定したヘッダーの下に潜り込んでしまう
これを防ぐために、ヘッダーと同じ高さの空要素を置いてスペースを確保します。本記事ではこの空要素に header-customize-space というクラスを付け、その高さをJavaScriptで合わせます。
position: fixed と position: sticky の違いや、コンテンツが隠れる問題については以下の記事で図解しています。
実装の手順
作業はすべてEC-CUBEの管理画面で行います。全体の流れは次のとおりです。
- 1ブロック管理より、追従ヘッダー用のブロックを新しく用意する
- 2CSS管理より、追従ヘッダー用のCSSを追記する
- 3JavaScript管理より、スペーサーの高さをヘッダーに合わせるスクリプトを追記する
- 4レイアウト管理より、用意したブロックとデフォルトのブロックを差し替える
ヘッダーの高さを 100px のように固定値で決められる場合、手順3のJavaScriptは不要です。その場合はヘッダーブロックとスペーサーの両方に同じ height を指定してください。
CSSとJavaScriptを管理画面から反映させる手順そのものは、以下の記事にまとめています。
CSSの簡単設定と反映方法 JavaScriptの簡単設定と反映方法-
STEP1
ブロック管理より「追従ヘッダー用ブロック」を用意する
ブロック管理から新しいブロックを作り、以下のコードを貼り付けます。
ブロック管理画面。ブロック名とファイル名を決めてコードを貼る
<div class="header-customize-space"></div> <div class="ec-headerNaviRole header_customize"> <div class="ec-headerNaviRole__left"> <div class="ec-headerNaviRole__search"> {{ render(path('block_search_product')) }} </div> <div class="ec-headerRole__navSP"> {{ include('Block/nav_sp.twig') }} </div> </div> <div class="ec-headerNaviRole__right"> <div class="ec-headerNaviRole__nav"> {{ include('Block/login.twig') }} </div> <div class="ec-headerRole__cart"> {{ include('Block/cart.twig') }} </div> </div> </div>中身はデフォルトの「ヘッダー(商品検索・ログインナビ・カート)」ブロックのコピーで、元のコードに加えているのは次の2点だけです。
加えたもの 何のため header_customizeクラスを追記次の手順でCSSを当てるための目印。ここに position: fixedを指定する先頭に空の divを追加固定したヘッダーの分の高さを確保するスペーサー。中身は空でよい デフォルトの「ヘッダー(商品検索・ログインナビ・カート)」を直接書き換えても実装はできます。ただし後で不具合が出たときに元へ戻しにくいため、新しくブロックを用意するほうが安全です。
-
STEP2
CSS管理より、追従ヘッダー用のCSSを追記する
.header_customize { position: fixed; top: 0; left: 50%; transform: translateX(-50%); z-index: 100; background: #fff; opacity: 0.95; padding-bottom: 15px; }
CSS管理画面。背景色や透過度は好みに合わせて調整する
幅の指定が要らない理由
EC-CUBEのデフォルトCSSでは
.ec-headerNaviRoleにwidth: 100%とmax-width: 1130pxが指定されています。position: fixedを当てるとwidth: 100%の基準が親要素ではなく画面全体に変わるため、画面幅いっぱい(ただし最大1130px)に広がります。だから幅を書き足す必要がありません。左右を画面いっぱいに伸ばしたい場合は
max-width: noneを、逆に狭めたい場合はmax-widthの値を書き換えてください。 -
STEP3
JavaScript管理より、スペーサーの高さを合わせる
STEP1で置いた空要素に、ヘッダーと同じ高さを与えます。デフォルトのヘッダーは高さが固定されておらず、中の要素のサイズによって変わります。そのためページの読み込み時とウィンドウのリサイズ時に、そのときの高さを測って反映させます。
document.addEventListener("DOMContentLoaded", function() { function adjustHeaderSpaceHeight() { var headerCustomizeSpace = document.querySelector(".header-customize-space"); var headerCustomize = document.querySelector(".header_customize"); if (headerCustomizeSpace && headerCustomize) { headerCustomizeSpace.style.height = headerCustomize.offsetHeight + "px"; } } adjustHeaderSpaceHeight(); window.addEventListener("resize", adjustHeaderSpaceHeight); });
JavaScript管理画面。ここに貼るだけで全ページに反映される
ヘッダーの高さを固定値で決められるなら、このJavaScriptは不要です。ただし高さを固定するとウィンドウ幅によっては見づらくなったりレイアウトが崩れたりします。その場合は メディアクエリ で幅ごとに高さを変えることになり、結局は手間が増えることもあります。
-
STEP4
レイアウト管理より、ブロックを差し替える
最後に、用意したヘッダーブロックとデフォルトの「ヘッダー(商品検索・ログインナビ・カート)」ブロックを入れ替えます。
レイアウト管理画面。ドラッグでブロックを差し替える
レイアウトにはトップページ用と下層ページ用の2つがあります。全ページで固定・追従させたい場合は、両方とも差し替えるのを忘れないでください。
思ったとおりに動かないときは
| 症状 | よくある原因と対処 |
|---|---|
| 変更が反映されない | キャッシュが残っている。ブラウザの閲覧履歴からキャッシュを消してページを再読み込みする。EC-CUBE側のキャッシュ削除も試す |
| ヘッダーが content に重なる | スペーサーの高さが0になっている。STEP1の空要素とSTEP3のクラス名(header-customize-space)が一致しているか確認する |
| 下層ページだけ固定されない | レイアウト管理で下層ページ用レイアウトのブロックを差し替え忘れている |
| 他の要素がヘッダーの上に乗る | z-index: 100 より大きい値を持つ要素がある。ヘッダー側の値を上げる |
まとめ
EC-CUBE 4のヘッダーを固定・追従させる方法を紹介しました。管理画面のブロック・CSS・JavaScript・レイアウトの4か所だけで完結するため、ファイルサーバーを触らずに試せます。
- ヘッダーブロックを複製し、
header_customizeクラスとスペーサー用の空要素を足す - CSSで
position: fixedを当てる。幅は指定しなくてよい - スペーサーの高さはJavaScriptでヘッダーに合わせる(固定値で足りるなら不要)
- レイアウト管理でトップページ用と下層ページ用の両方を差し替える

