モバイルポップアップUX設計ガイド|Googleペナルティ回避×CVR最大化の7原則【実装コード付き】

はじめに ── スマホ時代のポップアップは”設計ミス”で売上を失う

2026年現在、多くのWebサイトでモバイルトラフィックが全体の 70〜80% を占めています。ECサイトでは75〜80%、BtoBサイトでも55〜65%がスマートフォン経由です。

にもかかわらず、多くのサイトがPC基準で設計されたポップアップをそのままモバイルに流用しています。その結果、Googleインタースティシャルペナルティによる検索順位低下と、ユーザー体験悪化によるCVR低下という二重のリスクを抱えることになります。

本記事では、Googleのペナルティを回避しつつCVRを最大化するための7つの設計原則を、実装コード付きで解説します。さらに、業種別の推奨パターンやDataPushを使ったノーコード設定手順も紹介します。

この記事でわかること

  • Googleモバイルインタースティシャルペナルティの正確な対象範囲
  • CVRを最大化する7つのモバイルポップアップ設計原則(CSS/JSコード付き)
  • ペナルティ回避チェックリスト15項目
  • 業種別おすすめ設計パターンと期待CVR改善率
  • DataPushを使った5ステップのノーコード設定手順

想定読者: Webマーケター、フロントエンドエンジニア、EC運営者、サイト改善担当者

関連記事: 離脱防止ポップアップツール21選比較【2026年最新】


1. なぜモバイルポップアップは”危険”なのか?── ペナルティとCVR低下の二重リスク

1-1. 業種別モバイルトラフィック比率

まず現状を把握しましょう。以下は主要業種のモバイルトラフィック比率です。

業種モバイル比率(目安)ポップアップ影響度
ECサイト(アパレル・雑貨)75〜85%極めて高い
ECサイト(家電・BtoB系)60〜70%高い
BtoB SaaS55〜65%中〜高
不動産・人材70〜80%高い
メディア・ブログ65〜80%中(広告収益型)

これだけのトラフィックがモバイル経由である以上、モバイルでのポップアップ設計を”PC版のおまけ”として扱うことは、売上の大半を左右する意思決定を放棄しているに等しいのです。

1-2. Googleインタースティシャルペナルティとは

Googleは2017年1月から、モバイル検索結果からの遷移時にユーザーの閲覧を妨げるインタースティシャルを表示するページの評価を下げるアルゴリズムを導入しています(Google Search Central 公式ドキュメント)。

ペナルティ対象になるもの:

ページのメインコンテンツを覆い隠す形で即座に表示されるポップアップ、ユーザーがメインコンテンツにアクセスする前に閉じなければならないスタンドアロンのインタースティシャル、そしてファーストビューがインタースティシャルのように見えるレイアウト(メインコンテンツはスクロールしないと見えない)がこれに該当します。

ペナルティ対象外のもの:

法律上の義務によるインタースティシャル(Cookie同意、年齢確認)、ログインが必要なコンテンツへのログインダイアログ、そして画面の一部のみを使用し合理的なサイズのバナーはペナルティ対象外です。

ここが最重要ポイントです。「画面の一部のみ」がどこまで許容されるかがグレーゾーンですが、実務的には画面占有率30〜40%以下であれば安全とされています。

1-3. CVRへの実際の影響

即時にフルスクリーンで表示されるポップアップのCVR(ポップアップ経由のコンバージョン率)はわずか0.8%程度です。一方、スクロール50%到達時や離脱検知で表示するポップアップはCVR 3.4%程度と約4.3倍の差があります(ポップアップ表示タイミング設計パターン より)。

つまり、Googleペナルティを回避する設計は、同時にCVR最大化の設計でもあるのです。”ユーザーを邪魔しない = コンバージョンが増える”という好循環を意識しましょう。


2. 7つのモバイルポップアップ設計原則

原則1: 画面占有率は40%以下に抑える

モバイルポップアップの最大の落とし穴は画面占有率です。PCでは違和感のないサイズでも、スマホの小さな画面では全体を覆ってしまいます。

Googleのペナルティを避け、かつユーザーに圧迫感を与えないために、ポップアップの高さは画面の35〜40%以内に収めてください。下からスライドアップする形式が、視認性と非侵襲性の両立に最も適しています。

/* === 原則1: 画面占有率 ≤ 40% === */
.mobile-popup {
  position: fixed;
  bottom: 0;
  left: 0;
  width: 100%;
  max-height: 35vh;          /* ビューポートの35%が目安 */
  overflow-y: auto;          /* 内容が溢れる場合はスクロール */
  background: #ffffff;
  border-radius: 16px 16px 0 0;
  box-shadow: 0 -4px 24px rgba(0, 0, 0, 0.15);
  z-index: 9999;
  padding: 20px 16px;
  box-sizing: border-box;

  /* スライドアップアニメーション */
  transform: translateY(100%);
  transition: transform 0.4s cubic-bezier(0.16, 1, 0.3, 1);
}
.mobile-popup.is-visible {
  transform: translateY(0);
}

ポイント: max-height: 35vh により、どの端末でも画面の35%を超えません。overflow-y: auto でコンテンツ量が多い場合もポップアップ内でスクロール可能にし、画面全体を覆うことを防ぎます。

原則2: タップ領域は48×48px以上を確保する

Google Material Designのガイドラインでは、タッチターゲットのサイズは最低48×48dp(約9mm) が推奨されています(Material Design – Touch Target)。WCAGでは44×44pxですが、より安全な48pxを基準にしましょう。

特に閉じるボタン(×) が小さすぎると、ユーザーが閉じられずにイライラし、離脱に直結します。閉じるボタンこそ最も大きなタップ領域を確保すべき要素です。

/* === 原則2: タップ領域 ≥ 48 × 48 px === */
.mobile-popup__close {
  position: absolute;
  top: 8px;
  right: 8px;
  width: 48px;
  height: 48px;
  min-width: 48px;
  min-height: 48px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  font-size: 24px;
  color: #666;
}

/* CTA ボタンも同様に十分な高さを確保 */
.mobile-popup__cta {
  display: block;
  width: 100%;
  min-height: 52px;           /* 48px + 余裕 */
  padding: 14px 24px;
  font-size: 16px;
  font-weight: 700;
  border: none;
  border-radius: 8px;
  background: #2563eb;
  color: #fff;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

ポイント: ボタン間の余白(gap)も最低8px以上確保し、誤タップ(fat finger problem) を防止してください。

原則3: 即時表示を避け、適切なトリガーで表示する

前述のとおり、即時表示のCVRは0.8%、適切なトリガーで表示した場合は3.4%と4.3倍の差があります。ページ読み込み直後のポップアップはGoogleペナルティの対象にもなり得るため、絶対に即時表示は避けてください

推奨するトリガーは以下の3種類です。

① スクロール到達トリガー(推奨: 50%): ユーザーがコンテンツに興味を持ち、ある程度読み進めた時点で表示します。

/* === 原則3-①: スクロール50%トリガー === */
(function() {
  let popupShown = false;
  const SCROLL_THRESHOLD = 0.5; // 50%

  function getScrollPercent() {
    const h = document.documentElement;
    const b = document.body;
    const scrollTop = h.scrollTop || b.scrollTop;
    const scrollHeight = (h.scrollHeight || b.scrollHeight) - h.clientHeight;
    return scrollHeight > 0 ? scrollTop / scrollHeight : 0;
  }

  window.addEventListener('scroll', function() {
    if (popupShown) return;
    if (getScrollPercent() >= SCROLL_THRESHOLD) {
      popupShown = true;
      document.querySelector('.mobile-popup').classList.add('is-visible');
    }
  }, { passive: true });
})();

② 離脱検知トリガー: モバイルではマウスカーソルの離脱検知が使えないため、「ブラウザバック検知」や「一定時間の無操作」で代用します。

/* === 原則3-②: モバイル離脱検知(popstate + inactivity) === */
(function() {
  let popupShown = false;

  // --- 方法A: ブラウザバック検知 ---
  history.pushState(null, '', location.href);
  window.addEventListener('popstate', function() {
    if (popupShown) return;
    popupShown = true;
    history.pushState(null, '', location.href); // 戻るを無効化
    document.querySelector('.mobile-popup').classList.add('is-visible');
  });

  // --- 方法B: 無操作タイマー(30秒) ---
  let inactivityTimer;
  function resetTimer() {
    clearTimeout(inactivityTimer);
    inactivityTimer = setTimeout(function() {
      if (popupShown) return;
      popupShown = true;
      document.querySelector('.mobile-popup').classList.add('is-visible');
    }, 30000); // 30秒
  }
  ['touchstart', 'scroll', 'click'].forEach(function(evt) {
    document.addEventListener(evt, resetTimer, { passive: true });
  });
  resetTimer();
})();

③ 滞在時間トリガー: 一定時間(15〜30秒)経過後に表示する方法です。実装はシンプルですが、①②と比べるとユーザーの関与度が不明確なため、CVRは中間的です。

/* === 原則3-③: 滞在時間トリガー(20秒) === */
setTimeout(function() {
  document.querySelector('.mobile-popup').classList.add('is-visible');
}, 20000);

推奨の組み合わせ: スクロール50%到達 または ブラウザバック検知のいずれか先に発火した方で表示するのが最もバランスの良い設計です。

関連記事: トリガー設計のさらに詳しいパターンは ポップアップ表示タイミング最適化ガイド で解説しています。

原則4: 閉じやすさを最優先にする

「閉じにくいポップアップ」はユーザーの怒りを買い、サイト自体の離脱を招きます。逆に言えば、閉じやすいポップアップはユーザーの信頼を維持し、次回の表示時にCTAをクリックしてもらえる確率を高めます。

閉じる手段は以下の3つすべてを用意してください。

/* === 原則4: 3つの閉じ手段 === */
(function() {
  const popup  = document.querySelector('.mobile-popup');
  const overlay = document.querySelector('.mobile-popup-overlay');
  const closeBtn = document.querySelector('.mobile-popup__close');

  function hidePopup() {
    popup.classList.remove('is-visible');
    overlay.classList.remove('is-visible');
  }

  // ① 閉じるボタン(×)
  closeBtn.addEventListener('click', hidePopup);

  // ② オーバーレイ(背景タップ)
  overlay.addEventListener('click', hidePopup);

  // ③ スワイプダウン(下方向フリック)
  let startY = 0;
  popup.addEventListener('touchstart', function(e) {
    startY = e.touches[0].clientY;
  }, { passive: true });
  popup.addEventListener('touchmove', function(e) {
    const diffY = e.touches[0].clientY - startY;
    if (diffY > 80) { // 80px以上の下方向スワイプ
      hidePopup();
    }
  }, { passive: true });
})();
/* === オーバーレイ(半透明背景) === */
.mobile-popup-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.3);  /* 薄めに ── 圧迫感を減らす */
  z-index: 9998;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s ease;
}
.mobile-popup-overlay.is-visible {
  opacity: 1;
  pointer-events: auto;
}

ポイント: オーバーレイの透明度は 0.3 程度に抑え、背後のコンテンツがうっすら見える状態を維持します。これにより「コンテンツを覆い隠している」という印象を軽減し、ペナルティリスクも下がります。

関連記事: ユーザーが「うざい」と感じるポップアップの特徴と改善策は ポップアップがうざい?嫌われない設計の全知識 をご覧ください。

原則5: 1アクション・1メッセージに絞る

PCなら複数のCTAやメッセージを並べてもスペースに余裕がありますが、モバイルでは認知負荷が一気に跳ね上がります。

モバイルポップアップでは「1つのメッセージ + 1つのCTAボタン」に徹底して絞ってください。

悪い例:

┌─────────────────────────────┐
│ 🎉 期間限定セール実施中!       │
│ 会員登録で10%OFF              │
│ LINEお友だち追加で送料無料     │
│ [会員登録] [LINE追加] [閉じる] │
└─────────────────────────────┘

良い例:

┌─────────────────────────────┐
│ 今なら会員登録で10%OFFクーポン │
│ [無料で登録する]               │
│                    ×         │
└─────────────────────────────┘

1つのポップアップに複数のオファーを詰め込むと、ユーザーは選択に迷い、結局どれもクリックしません(ヒックの法則)。訴求したい内容が複数ある場合は、ページごとにポップアップの内容を変えるか、A/Bテストで最も効果の高いものを選びましょう。

関連記事: ポップアップのA/Bテスト手法については ポップアップA/Bテスト完全ガイド で詳しく解説しています。

原則6: フォントサイズ・余白はモバイルファーストで設計する

モバイルでの可読性を確保するために、以下のサイズガイドラインを守ってください。

要素推奨サイズ備考
見出し(h3相当)20px / boldポップアップ内の主メッセージ
本文16px / regular最低14px以上。14px未満はGoogleの「テキストが小さすぎる」警告対象
補足テキスト13〜14px / regular注意書き等
CTAボタン文字16px / boldボタン内は太字で視認性確保
左右パディング16px以上──
要素間マージン12px以上──
/* === 原則6: モバイルファーストのタイポグラフィ === */
.mobile-popup__title {
  font-size: 20px;
  font-weight: 700;
  line-height: 1.4;
  margin: 0 0 8px;
  color: #1a1a1a;
}
.mobile-popup__body {
  font-size: 16px;
  font-weight: 400;
  line-height: 1.6;
  margin: 0 0 16px;
  color: #333;
}
.mobile-popup__note {
  font-size: 13px;
  color: #888;
  margin-top: 8px;
}

ポイント: line-height は本文で1.6以上を確保し、行間の詰まりによる読みにくさを防ぎます。

売れるポップアップデザインの法則についても解説しております。

原則7: 表示頻度を1回/24時間に制限する

同じポップアップを何度も表示すると、ユーザー体験は著しく悪化します。一度閉じたポップアップは、最低でも24時間は再表示しないのが基本です。

/* === 原則7: 24時間の表示頻度制限(localStorage) === */
(function() {
  const STORAGE_KEY  = 'datapush_popup_last_shown';
  const INTERVAL_MS  = 24 * 60 * 60 * 1000; // 24時間

  function canShowPopup() {
    const lastShown = localStorage.getItem(STORAGE_KEY);
    if (!lastShown) return true;
    return (Date.now() - parseInt(lastShown, 10)) >= INTERVAL_MS;
  }

  function markPopupShown() {
    localStorage.setItem(STORAGE_KEY, Date.now().toString());
  }

  // ポップアップ表示関数(他の原則のトリガーから呼び出す)
  window.showMobilePopup = function() {
    if (!canShowPopup()) return;
    document.querySelector('.mobile-popup').classList.add('is-visible');
    document.querySelector('.mobile-popup-overlay').classList.add('is-visible');
    markPopupShown();
  };
})();

ポイント: localStorage はドメイン単位で保持されるため、サブドメインが異なる場合は Cookie を使うか、フラグを共有する仕組みが必要です。また、コンバージョン済みユーザーには表示しない制御(Cookie や GTM の変数で判定)を追加すると、さらにUXが向上します。

補足 ── CLS(Cumulative Layout Shift)への配慮: ポップアップが表示される際にページレイアウトがズレると、Core Web VitalsのCLSスコアが悪化します。position: fixed でページフローから外し、コンテンツの押し下げが発生しない設計にしてください。本記事のコード例はすべて position: fixed を使用しているため、CLSへの影響はありません。


3. ペナルティ回避チェックリスト15項目

記事公開前・ポップアップ実装後に、以下の15項目をすべて確認してください。

#チェック項目判定基準対応する原則
1ポップアップの画面占有率≤ 40%(推奨 ≤ 35%)原則1
2ページ読み込み直後に表示していないか即時表示 = NG原則3
3メインコンテンツを完全に覆っていないか背景がうっすら見える原則1・4
4閉じるボタンのサイズ≥ 48 × 48 px原則2
5CTAボタンのサイズ≥ 48 × 48 px原則2
6ボタン間の余白≥ 8 px原則2
7フォントサイズ(本文)≥ 14px(推奨16px)原則6
8CLS への影響position: fixed 使用・CLS < 0.1全体
9閉じる手段が3つあるか×ボタン・オーバーレイ・スワイプ原則4
101アクション・1メッセージかCTA は1つだけ原則5
11表示頻度制限≤ 1回 / 24時間原則7
12コンバージョン済みユーザー非表示Cookie/LS で判定原則7
13法的インタースティシャルとの混同がないかCookie 同意 ≠ マーケ用ポップアップ──
14PageSpeed Insights でモバイルスコア確認≥ 70(ポップアップJS込み)全体
15Google Search Console モバイルユーザビリティ警告なしエラー 0 件全体

このチェックリストをスプレッドシートやNotionにコピーし、ポップアップ変更のたびに確認することをおすすめします。


4. 業種別おすすめ設計パターン

すべてのサイトに同じポップアップ設計が最適というわけではありません。業種ごとにユーザーの意図と行動が異なるため、以下のパターンを参考に設計を調整してください。

4-1. EC サイト(アパレル・雑貨・食品)

EC サイトのモバイルユーザーは購買意欲が高い反面、比較検討のためにすぐ離脱する傾向があります。最も効果的なのは離脱検知 × クーポン訴求の組み合わせです。

推奨トリガーはブラウザバック検知で、メッセージは「今だけ10%OFFクーポン」のような即時メリット型が効果的です。スライドアップ形式で画面下部から表示し、クーポンコードをワンタップでコピーできるボタンを設置します。期待CVR改善率は +30〜50% 程度です。

カゴ落ち対策と組み合わせることで、さらに効果が高まります。

関連記事: ECのカゴ落ち対策全般については ECカゴ落ち対策完全ガイド をご覧ください。

4-2. BtoB SaaS

BtoB SaaS サイトの訪問者は情報収集段階のユーザーが多く、いきなりの購入はハードルが高いです。そのため、ホワイトペーパーDL無料トライアル など段階的なCTAが適しています。

推奨トリガーはスクロール50%到達で、「無料で資料をダウンロード」「14日間無料トライアルを始める」といったメッセージが有効です。フォームはメールアドレス1項目のみにするか、ランディングページへの遷移ボタンにして、ポップアップ内での入力を最小限にします。期待CVR改善率は +20〜40% 程度です。

関連記事: SaaS の無料トライアルCVR最適化については SaaS無料トライアルCVR最適化ガイド で詳しく解説しています。

4-3. 不動産・人材

不動産・人材サイトのユーザーは「物件を見たい」「求人を探したい」という明確な目的があり、横断的な閲覧をします。ポップアップは エリア × 条件の絞り込み提案新着通知登録 が効果的です。

推奨トリガーは物件/求人詳細ページで滞在20秒以上、または一覧ページからの離脱検知です。「このエリアの新着を通知で受け取る」「条件にマッチした求人をLINEでお届け」といったメッセージで、継続的な関係構築を目指します。期待CVR改善率は +25〜45% 程度です。

関連記事: 不動産・人材業界向けの詳しい設計パターンは 不動産・人材業界向けポップアップ活用ガイド をご覧ください。

4-4. メディア・ブログ

メディアサイトでは、回遊率向上とメルマガ登録がポップアップの主な目的です。広告収益モデルの場合はポップアップが広告と競合しないよう注意が必要です。

推奨トリガーは記事のスクロール70〜80%到達(記事を読み終わる直前)で、「毎週の人気記事をメールで受け取る」「関連記事:〇〇」といった次アクション提案型が適しています。期待CVR改善率は +15〜25% 程度です。


5. DataPushを使った5ステップ設定手順

コードを書かずにモバイル最適化ポップアップを実装したい場合は、DataPush を使って5分で設定できます。

ステップ1: タグの設定の設定
DataPush管理画面でポップアップを埋め込みするサイトの登録とタグの発行設置を行います。

ステップ2: テンプレートの選択
新規ポップアップ作成からテンプレートを選択して設定を行います。

ステップ3: コンテンツの編集
見出し(1行、20文字以内推奨)、本文(2行以内)、CTAボタンテキスト、リンク先URLを入力します。1アクション・1メッセージ(原則5)を意識して、情報を詰め込みすぎないようにしてください。

関連記事: CTAの文言で迷ったら ポップアップ文言テンプレート60選 をご活用ください。

ステップ4: トリガーの設定
表示トリガーを「スクロール50%」または「離脱検知」に設定します。「即時表示」は絶対に選択しないでください(原則3)。DataPushの離脱検知はモバイル環境でのブラウザバック検知に対応しています。

ステップ5: 表示頻度の設定
「同一ユーザーへの表示間隔」を「24時間に1回」に設定します(原則7)。さらに「コンバージョン済みユーザーには非表示」のオプションがある場合は有効にしてください。

設定完了後、プレビュー機能で実機表示を確認し、本記事のチェックリスト15項目を最終確認してから公開します。


6. 完成形HTMLテンプレート

上記の7原則をすべて統合した完成形のHTMLテンプレートを以下に掲載します。コピー&ペーストで利用でき、メッセージとリンク先を変更するだけでそのまま使用可能です。

<!-- === モバイルポップアップ 完成形テンプレート === -->

<!-- オーバーレイ -->
<div class="mobile-popup-overlay" id="js-popup-overlay"></div>

<!-- ポップアップ本体 -->
<div class="mobile-popup" id="js-popup" role="dialog" aria-modal="true"
     aria-label="お得なご案内">
  <button class="mobile-popup__close" id="js-popup-close"
          aria-label="閉じる">✕</button>
  <p class="mobile-popup__title">
    <!-- ▼ メッセージをここに入力 ▼ -->
    今なら無料トライアル14日間
  </p>
  <p class="mobile-popup__body">
    5分で設定完了。クレジットカード不要。
  </p>
  <a href="https://data-push.jp/" class="mobile-popup__cta"
     target="_blank" rel="noopener">
    無料で始める →
  </a>
  <p class="mobile-popup__note">
    ※ いつでもキャンセル可能です
  </p>
</div>

<style>
/* --- リセット&共通 --- */
.mobile-popup-overlay {
  position: fixed; inset: 0;
  background: rgba(0,0,0,0.3);
  z-index: 9998;
  opacity: 0; pointer-events: none;
  transition: opacity .3s ease;
}
.mobile-popup-overlay.is-visible {
  opacity: 1; pointer-events: auto;
}
.mobile-popup {
  position: fixed; bottom: 0; left: 0; width: 100%;
  max-height: 35vh; overflow-y: auto;
  background: #fff;
  border-radius: 16px 16px 0 0;
  box-shadow: 0 -4px 24px rgba(0,0,0,.15);
  z-index: 9999;
  padding: 20px 16px;
  box-sizing: border-box;
  transform: translateY(100%);
  transition: transform .4s cubic-bezier(.16,1,.3,1);
}
.mobile-popup.is-visible { transform: translateY(0); }
.mobile-popup__close {
  position: absolute; top: 8px; right: 8px;
  width: 48px; height: 48px;
  display: flex; align-items: center; justify-content: center;
  background: transparent; border: none; cursor: pointer;
  font-size: 22px; color: #666;
  -webkit-tap-highlight-color: transparent;
}
.mobile-popup__title {
  font-size: 20px; font-weight: 700;
  line-height: 1.4; margin: 0 0 6px; color: #1a1a1a;
}
.mobile-popup__body {
  font-size: 16px; line-height: 1.6;
  margin: 0 0 16px; color: #333;
}
.mobile-popup__cta {
  display: block; width: 100%; min-height: 52px;
  padding: 14px 24px; font-size: 16px; font-weight: 700;
  text-align: center; text-decoration: none;
  border: none; border-radius: 8px;
  background: #2563eb; color: #fff;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.mobile-popup__cta:hover { background: #1d4ed8; }
.mobile-popup__note {
  font-size: 13px; color: #888; margin: 8px 0 0; text-align: center;
}
/* PC では非表示 */
@media (min-width: 769px) {
  .mobile-popup, .mobile-popup-overlay { display: none !important; }
}
</style>

<script>
(function(){
  // === 設定値 ===
  var SCROLL_THRESHOLD = 0.5;
  var INACTIVITY_SEC   = 30;
  var STORAGE_KEY      = 'dp_popup_last';
  var INTERVAL_MS      = 86400000; // 24h

  // === 要素 ===
  var popup   = document.getElementById('js-popup');
  var overlay = document.getElementById('js-popup-overlay');
  var closeBtn= document.getElementById('js-popup-close');
  var shown   = false;

  // === 頻度チェック ===
  function canShow(){
    var t = localStorage.getItem(STORAGE_KEY);
    return !t || (Date.now() - parseInt(t,10)) >= INTERVAL_MS;
  }

  // === 表示 ===
  function show(){
    if(shown || !canShow()) return;
    shown = true;
    popup.classList.add('is-visible');
    overlay.classList.add('is-visible');
    localStorage.setItem(STORAGE_KEY, Date.now().toString());
  }

  // === 非表示 ===
  function hide(){
    popup.classList.remove('is-visible');
    overlay.classList.remove('is-visible');
  }
  closeBtn.addEventListener('click', hide);
  overlay.addEventListener('click', hide);

  // スワイプダウンで閉じる
  var startY = 0;
  popup.addEventListener('touchstart', function(e){
    startY = e.touches[0].clientY;
  }, {passive:true});
  popup.addEventListener('touchmove', function(e){
    if(e.touches[0].clientY - startY > 80) hide();
  }, {passive:true});

  // === トリガー: スクロール50% ===
  window.addEventListener('scroll', function(){
    var h = document.documentElement;
    var pct = h.scrollTop / ((h.scrollHeight||document.body.scrollHeight) - h.clientHeight);
    if(pct >= SCROLL_THRESHOLD) show();
  }, {passive:true});

  // === トリガー: ブラウザバック ===
  history.pushState(null,'',location.href);
  window.addEventListener('popstate', function(){
    history.pushState(null,'',location.href);
    show();
  });

  // === トリガー: 無操作 ===
  var timer;
  function reset(){
    clearTimeout(timer);
    timer = setTimeout(show, INACTIVITY_SEC * 1000);
  }
  ['touchstart','scroll','click'].forEach(function(e){
    document.addEventListener(e, reset, {passive:true});
  });
  reset();
})();
</script>

使い方: mobile-popup__titlemobile-popup__bodymobile-popup__cta の内容とリンク先を自サイトに合わせて変更するだけです。CSSカラーはブランドカラーに調整してください。


7. よくある質問(FAQ)

Googleのインタースティシャルペナルティは具体的にどのくらい順位が下がるのですか?

Googleは具体的な順位低下幅を公表していません。ただし、ペナルティは「ランキングシグナルの一つ」として機能するため、競合と僅差の場合に順位が1〜数ポジション下がる可能性があります。完全にフルスクリーンのインタースティシャルを即時表示しているケースでは、検索結果からの流入が10〜30%減少した事例が報告されています。本記事の7原則に従えば、ペナルティの対象になる可能性は極めて低くなります。

PC用とモバイル用でポップアップのデザインは完全に分けるべきですか?

はい、分けることを強く推奨します。PCでは画面中央のモーダル(画面占有率20〜30%)が効果的ですが、同じデザインをモバイルに流用すると占有率が60〜80%になり、ペナルティ対象になり得ます。最低限、CSS の @media クエリで分岐するか、DataPush のようなツールでデバイス別に出し分けてください。本記事のテンプレートには @media (min-width: 769px) で PC非表示の設定が含まれています。

DataPush はモバイル専用の出し分けに対応していますか?

はい、DataPushは管理画面からデバイス条件(PC / モバイル / タブレット)を選択でき、モバイル専用のポップアップを簡単に設定できます。テンプレートにはモバイル最適化されたスライドアップデザインが用意されており、コードを書かずに本記事の7原則に沿った設計が可能です。詳しくは DataPush公式サイト をご覧ください。


まとめ

モバイルポップアップは「表示するかしないか」ではなく「どう設計するか」が成否を分けます。

本記事で解説した7つの原則は、画面占有率40%以下、タップ領域48px以上、即時表示の回避、3つの閉じ手段、1アクション・1メッセージ、モバイルファーストのタイポグラフィ、そして24時間の頻度制限です。これらはすべてGoogleのペナルティ回避とCVR最大化の両方を同時に実現するために設計されています。

即時フルスクリーン表示のCVR 0.8% に対し、適切なトリガーで表示した場合は 3.4% と4.3倍の差があります。正しい設計は、ペナルティを防ぐだけでなく、コンバージョンそのものを増やすのです。

まずは本記事のチェックリスト15項目で現状のポップアップを診断し、改善が必要な箇所から着手してください。コードを使った実装が難しい場合は、DataPush なら5分で本記事の7原則に準拠したモバイルポップアップを設定できます。