Shopifyのテーマに会員登録特典を訴求するための追従固定フッター(追従画像バナー)を表示させたい!と思い実装してみました。
私が制作担当させていただきましたペアリングワイン専門EC 'BackStreet' by 横浜のワインビストロ路地裏様にて実装させていただいております。
固定フッターの挙動としては、下記となるように実装しました。
- スクロールを開始したらふわっと表れる。ページ訪問時には非表示。
- マウスホバー時に拡大、ハイライト表示
- 会員登録特典のため、ユーザーがログインした後は非表示
- 会員登録ページとログインページでは非表示
以上の機能をもつ固定フッターを実装する中で、いくつか考えるポイント・引っかかるポイントがいくつかありましたので備忘としてポイントを残しておきます。
本件では画像バナー上のテキストは画像のまま作成・実装しています。またスマートフォンユーザーがほとんどのため、レスポンシブ対応はせずスマートフォン主軸で対応しています。
目次:
- snippetフォルダにliquidファイルを作成し、追従固定フッターをDivタグとして作成
- assetフォルダから使用する画像はasset_img_urlフィルタを使って呼び出す
- 画像は実際に描画させる2倍のサイズで作成・CDNから呼び出しておくのが吉
- layout/theme.liquidで作成した固定フッターのスニペットを出力
- CSSでバナー画像の背景とホバー時アニメーションを設定
- スクロールを開始したときにフッターが現れてくるようにJavaScriptを記述
- 会員がログインした後、および会員登録ページ・ログインページでは固定フッターを非表示
- ifタグで会員ログイン前のユーザーにのみ表示させる
- テンプレート名による判別で表示させないページを指定
- テンプレート名ではなくパス(suffix)で判別する方法も
- テンプレート名・パス名をデバッグして確認
- 完成した追従固定フッターのコード全体
- snippet/sticky-footer.liquid
- layout/theme.liquid
- 会員登録後のリダイレクト先を変更するShopifyテーマカスタマイズ
snippetフォルダにliquidファイルを作成し、追従固定フッターをDivタグとして作成
まず、snippetフォルダ内にsticky-footer.liquidとして固定フッターについての内容を記述するliquidファイルを作成します。
スニペットに関しては、 ざっくりつかむShopify2.0のテーマ構造: Dawnを例に の記事で、全体構成のなかでの役割含めて解説しています。
固定フッターはfooterタグでも良いのでしょうが、ここではdivタグとして追従固定フッターを作成しています。
<!-- Sticky Footer -->
<a href="https://yoursite.com/account/register" class="sticky-footer-link">
<div class="sticky-footer">
<img src="{{ 'banner_2x.png' | asset_img_url: '1000x160'}}" alt="Footer Banner" style="width: 100%; height: 80px;">
</div>
</a>
<!-- END Sticky Footer -->
divタグのなかで画像を出力。フッター箇所をクリックした際に会員登録ページへジャンプさせるため、会員登録へのリンクをaタグで設置しています。
assetフォルダから使用する画像はasset_img_urlフィルタを使って呼び出す
assetフォルダから使用する画像はasset_img_urlフィルタを使って呼び出す必要があります。
注意点として、 asset_img_urlの後にサイズを指定しない場合には、自動的にsmall (100px x 100px)が適用されてしまいます。基本的にはサイズを指定するようにしましょう。
Shopifyブログ本文中に吹き出しコメント挿入を実装するカスタマイズ方法 においても、吹き出し元となるユーザー画像をassetフォルダから出力させるのにasset_img_urlフィルタを利用しました。
画像は実際に描画させる2倍のサイズで作成・CDNから呼び出しておくのが吉
上記では、固定フッターサイズの高さとして80pxとして描画させることを想定していますが、実際に用意した画像サイズおよびCDNから呼び出す際にフィルタasset_img_urlで指定した高さは160pxとしています。
このように2倍程度の解像度を想定しておかないと、画像がジャギーっぽくなったり、blurがかったり(ぼけて見える)してしまうため、このように画像作成・出力させています。
layout/theme.liquidで作成した固定フッターのスニペットを出力
作成したsticky-footerスニペットを出力させるために、レイアウトファイルであるlayout/theme.liquidのなかに出力のためのrenderタグを記述します。
bodyタグ内であればどこへ配置しても大丈夫ですが、今回は追従固定フッターであることから、通常のフッターセクションを出力するタグのすぐ下に配置しました。
...
{% section 'footer' %}
<!-- Sticky Footer -->
{% render 'sticky-footer' %}
<!-- END Sticky Footer -->
...
この段階で何も表示されないという場合は、assetフォルダから画像が読み込まれていない可能性が高いです。記述を見直してみましょう。
フッター位置やアニメーション等はこの後のstyleタグで指定します。
CSSでバナー画像の背景とホバー時アニメーションを設定
sticky-footer.liquidファイルへ戻り、styleを設定していきます。
<!-- Sticky Footer -->
<a href="https://yoursite.com/account/register" class="sticky-footer-link">
<div class="sticky-footer">
<img src="{{ 'banner_2x.png' | asset_img_url: '1000x160'}}" alt="Footer Banner" style="width: 100%; height: 80px;">
</div>
</a>
<!-- END Sticky Footer -->
{% style %}
.sticky-footer-link {
text-decoration: none; /* Removes underline from links */
color: inherit; /* Inherits text color from parent elements */
display: block; /* Make sure it's always block to maintain layout */
position: fixed;
left: 0;
bottom: 0;
width: 100%;
opacity: 0; /* Start with the banner hidden */
transition: opacity 0.5s ease-out, bottom 0.5s ease-out; /* Smooth transition for opacity and sliding up */
z-index: 1000;
}
.sticky-footer {
background-color: #2f2f2f;
text-align: center;
overflow: visible;
height: 80px; /* Adjust this height to fit the image */
}
.sticky-footer img {
width: 100%;
height: 80px;
object-fit: contain;
object-position: center;
image-rendering: -webkit-optimize-contrast;
image-rendering: crisp-edges;
image-rendering: pixelated;
}
.sticky-footer-link:hover .sticky-footer {
transform: scale(1.05); /* Slightly enlarge the footer on hover */
filter: brightness(120%); /* Increase brightness by 20% on hover */
transition: transform 0.3s ease, filter 0.3s ease; /* Ensure smooth transition for hover effects */
}
{% endstyle %}
CSSはあまり得意ではないので、もっと良い記述方法があるのかもしれませんが…。 上記でフッター背景、ホバー時アニメーションを実装しています。
スクロールを開始したときにフッターが現れてくるようにJavaScriptを記述
下記のようにスクロールを検知するフラグを作成し、スクロール開始によって固定フッター部を表示させるようにJavaScriptを記述します。
...
{% endstyle %}
<!-- Detect if the page has been scrolled by the scroll start flag -->
<script>
document.addEventListener('DOMContentLoaded', function() {
let hasScrolled = false; // Flag to check if user has scrolled
let footerLink = document.querySelector('.sticky-footer-link');
document.addEventListener('scroll', function() {
if (window.pageYOffset > 0) {
hasScrolled = true; // Set flag to true when user scrolls
}
if (hasScrolled) {
footerLink.style.opacity = '1'; // Keep the banner visible once scrolling has started
} else {
footerLink.style.opacity = '0'; // Initially hidden
}
});
});
</script>
上記はフラグ制御によって実装しましたが、下記のようにスクロール位置によっても実装可能です。 スクロール位置による制御の場合だと、スクロール位置が最上部へ再度戻った場合においても固定フッターは表示されなくなります。
<!-- Detect if the page has been scrolled by the scroll position -->
<script>
document.addEventListener('scroll', function() {
const footerLink = document.querySelector('.sticky-footer-link');
if (window.pageYOffset > 0) { // Check if the page has been scrolled
footerLink.style.opacity = '1'; // Make the banner fully visible
} else {
footerLink.style.opacity = '0'; // Hide it again when scrolled back to top
}
});
</script>
会員がログインした後、および会員登録ページ・ログインページでは固定フッターを非表示
最後に、条件分岐によってログイン中のユーザー、ログイン状態に関わらず会員登録ページ・ログインページでは非表示とするように実装します。
ifタグで会員ログイン前のユーザーにのみ表示させる
下記のようなifタグで全体を囲むことで、ログインしていないユーザーに対してのみifタグ内のコードが動作するようにします。
<!-- Apply only for non-logged in users -->
{% if customer == nil %}
...
% endif %}
ユーザーがログインすると、customerオブジェクトを取得できるようになります。 そこで customerオブジェクトが不存在(nil)のとき、すなわちログイン前の状態にだけifタグ内のコードが有効になるようにします。
テンプレート名による判別で表示させないページを指定
さらに、ログイン状態の有無にかかわらず会員登録ページ・ログインページにおいてはifタグ内のコードが有効とならないようにします。
言い換えると、会員登録ページ・ログインページ「以外の」ページにおいて、ifタグ内のコードが有効となるようにします。
<!-- Apply only for non-logged in users, and not on the login nor register pages -->
{% if customer == nil and template.name != 'login' and template.name != 'register' %}
...
{% endif %}
テンプレート名ではなくパス(suffix)で判別する方法も
テンプレート名で条件を絞り込める場合は良いですが、たとえば一般ページとしてよく利用される「ページ」テンプレートは数も多くなり、テンプレート名による絞り込みでは範囲が広くなりすぎます。
そこで、テンプレート名ではなくパスで判別する方法があります。たとえば、https://your-site.com/pages/sample-path というURLの場合、テンプレート名であるpages直下のパス(suffix)で判別させることが可能です。
{% if template.suffix != 'email-register' %}
テンプレート名・パス名をデバッグして確認
一般的にはtemplatesフォルダ内のファイル名とテンプレート名は一致しますが、このテンプレート名を実際に出力させて確認する方法があります。
<!-- Debugging to see the template name -->
Current template: {{ template.name }}
Shopify theme devなどのCLIコマンドを用いて、開発環境下のストアで本コードを設置したページを訪問することで、出力されるテンプレート名を把握することができます。
同様に、パス名(suffix)の場合のデバッグ出力は下記。
Current suffix: {{ template.suffix }}
完成した追従固定フッターのコード全体
以上で追従固定フッターの完成です。以下にコードの全体を示します。
snippet/sticky-footer.liquid
<!-- Apply only for non-logged in users, and not on the login nor register pages -->
{% if customer == nil and template.name != 'login' and template.name != 'register' %}
<!-- Sticky Footer -->
<a href="https://yoursite.com/account/register" class="sticky-footer-link">
<div class="sticky-footer">
<img src="{{ 'banner_2x.png' | asset_img_url: '1000x160'}}" alt="Footer Banner" style="width: 100%; height: 80px;">
</div>
</a>
<!-- END Sticky Footer -->
{% style %}
.sticky-footer-link {
text-decoration: none; /* Removes underline from links */
color: inherit; /* Inherits text color from parent elements */
display: block; /* Make sure it's always block to maintain layout */
position: fixed;
left: 0;
bottom: 0;
width: 100%;
opacity: 0; /* Start with the banner hidden */
transition: opacity 0.5s ease-out, bottom 0.5s ease-out; /* Smooth transition for opacity and sliding up */
z-index: 1000;
}
.sticky-footer {
background-color: #2f2f2f;
text-align: center;
overflow: visible;
height: 80px; /* Adjust this height to fit the image */
}
.sticky-footer img {
width: 100%;
height: 80px;
object-fit: contain;
object-position: center;
image-rendering: -webkit-optimize-contrast;
image-rendering: crisp-edges;
image-rendering: pixelated;
}
.sticky-footer-link:hover .sticky-footer {
transform: scale(1.05); /* Slightly enlarge the footer on hover */
filter: brightness(120%); /* Increase brightness by 20% on hover */
transition: transform 0.3s ease, filter 0.3s ease; /* Ensure smooth transition for hover effects */
}
{% endstyle %}
<!-- Detect if the page has been scrolled by the scroll start flag -->
<script>
document.addEventListener('DOMContentLoaded', function() {
let hasScrolled = false; // Flag to check if user has scrolled
let footerLink = document.querySelector('.sticky-footer-link');
document.addEventListener('scroll', function() {
if (window.pageYOffset > 0) {
hasScrolled = true; // Set flag to true when user scrolls
}
if (hasScrolled) {
footerLink.style.opacity = '1'; // Keep the banner visible once scrolling has started
} else {
footerLink.style.opacity = '0'; // Initially hidden
}
});
});
</script>
{% endif %}
layout/theme.liquid
...
{% section 'footer' %}
<!-- Sticky Footer -->
{% render 'sticky-footer' %}
<!-- END Sticky Footer -->
...
会員登録後のリダイレクト先を変更するShopifyテーマカスタマイズ
本記事では会員登録を促すための追従固定フッターを実装しました。
Shopifyのテーマにおいては、会員登録をした後のユーザーはサンクスページ・マイページではなくTOPページへとリダイレクトされてしまう場合があります。標準テーマであるDawnにおいてもそのようになっています。
Shopifyテーマ(Dawn)で会員登録後マイページへ自動リダイレクトさせる の記事で、会員登録後にマイページへ自動リダイレクトさせる方法を解説しています。
1つのパラメータを追記するだけの簡単なカスタマイズなので、ぜひ併せてチェックしてみてください。
この記事の気になる箇所を読み返す:
- snippetフォルダにliquidファイルを作成し、追従固定フッターをDivタグとして作成
- assetフォルダから使用する画像はasset_img_urlフィルタを使って呼び出す
- 画像は実際に描画させる2倍のサイズで作成・CDNから呼び出しておくのが吉
- layout/theme.liquidで作成した固定フッターのスニペットを出力
- CSSでバナー画像の背景とホバー時アニメーションを設定
- スクロールを開始したときにフッターが現れてくるようにJavaScriptを記述
- 会員がログインした後、および会員登録ページ・ログインページでは固定フッターを非表示
- ifタグで会員ログイン前のユーザーにのみ表示させる
- テンプレート名による判別で表示させないページを指定
- テンプレート名ではなくパス(suffix)で判別する方法も
- テンプレート名・パス名をデバッグして確認
- 完成した追従固定フッターのコード全体
- snippet/sticky-footer.liquid
- layout/theme.liquid
- 会員登録後のリダイレクト先を変更するShopifyテーマカスタマイズ