CTA · CTAセクション

弾むアニメーションのCTAブロック

保存した一覧を見る 0 →

このブラウザー内に保存します。別の端末との同期はなく、サイトデータを消すと保存も消えます。

印刷時は見本を静止画にし、プロンプトと解説を出力します。PDF保存はブラウザーの印刷画面から選べます。

Vibehaus · デザイン資料
https://vibe.itlibra.com/design/playful-cta/
完全無料・著作権フリー(CC0)· 料金¥0 · 商用利用・改変自由

プレビュー

画面に合わせる

指定幅で実際に組み替えて表示します。表示領域より広い場合は、この枠の中で横へスクロールできます。

vibe.itlibra.com/preview/playful-cta/

AIへの指示文

個人開発プロダクトやクリエイター向けサービスの募集用に、遊び心のあるCTAブロックを作ってください。

キャンバス:
- 暖色オフホワイト (#fef6e4) のページ背景。
- フォントは Inter。weightの強弱(800 / 700 / 400)だけでメリハリをつける。
- 配色: ピンク (#ff6fae)、パープル (#7b5cff)、イエロー (#ffd166)、グリーン (#4ad295)、近黒 (#1d1a2b)。色の数は多いが、派手な塗りは小面積に限定する。

CTA ブロック (中央寄せ、max-width 900px):
- 白カード、3px の近黒ボーダー、28px の角丸、6px/6px の近黒オフセット影 (所謂ネオブルータリスト風)。
- カード全体を `rotate(-1deg)` で少し傾ける。hover で `rotate(-0.5deg) translateY(-2px)` に戻す。

装飾:
- カードの四隅からはみ出すように、絵文字 (✨ 🎯 🪄 💌) を絶対配置で浮かべる。各絵文字に `drop-shadow(2px 2px 0 black)` のオフセット影。`@keyframes bob` で 3.5秒かけて上下に 6px 揺らす。delay を 0 / 0.8 / 1.6 / 2.4 秒にずらして単調さを避ける。
- 左外側に手書き風の矢印書き込み (1行メッセージ + SVG/CSSで描いた矢印)。720px 未満では非表示。

本文:
- eyebrow: 黄色ピル、2px の近黒ボーダー、`rotate(2deg)` で傾ける。"Limited seats · Spring intake" など。
- H1: clamp(2.2rem, 5vw, 3.6rem)、weight 800。2 行構成で、
  - 1 行目の一部の単語を `<span class="wiggle">` で包み、ピンク色 + `@keyframes wiggle` で ±3deg 揺らす。
  - 2 行目のキーワードを `<span class="highlight">` で包み、擬似要素 `::before` で緑のハイライトブロックを下敷きに敷く (少し傾けた下線っぽい表現)。
- リード: muted gray、最大 46ch、2 行程度。
- アクション:
  - プライマリボタン: ピンク背景、3px の近黒ボーダー、14px radius、4px/4px のオフセット影。矢印アイコン付き。hover で `translate(-2px, -2px)` + 影を 6px/6px に深める。active で `translate(1px, 1px)` + 影を 2px/2px に浅くする。
  - セカンダリボタン: 白背景、同じ形。
- マイクロコピー: "No credit card · Cancel any time · Hand-held onboarding"。チェックマークを小さな緑の円 (2px 近黒ボーダー) に入れる。

レスポンシブ: 720px 未満で矢印書き込みを非表示にするだけでOK。ボタンは `flex-wrap` で自然に縦積み。

JS 不要。全てCSSアニメーション。

バリエーション

ダーク版

ページ背景を (#1a1630)、カードを (#2a2540) に変更。
ピンクとイエローはそのまま、緑は (#5efac2) に差し替えて暗背景で発光させる。
全体の境界線と文字色を (#fff9e8) に反転。

フォーム埋込版

CTAボタンの代わりに、メール入力フォーム + 送信ボタン(ピンク背景)を1行に並べる。
入力欄は 3px の近黒ボーダー、14px radius、focus で緑のアウトライン。
送信ボタンは矢印アイコン付きでそのまま。

このプレビューのコード

HTML・CSS・JavaScriptの1ファイルです。外部依存・広告・解析コードはありません。架空のサービスや企画への案内です。日付・人数・価格・特典・利用条件は表示例です。リンクは構成の説明へ移動し、申込み・予約・決済・発券・招待は行いません。演出の停止とOSの動き低減に対応します。

CC0 · 改変・商用利用自由 · revision 27dd68eecb50

コードを表示
<!doctype html>
<!-- Vibehaus · CC0 · 架空の表示・操作見本。外部素材・送信・永続保存なし。 -->
<html lang="ja">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="robots" content="noindex" />
    <title>弾むアニメーションのCTAブロック — Vibehaus プレビュー</title>
    <style>
      :root {
        --bg: #fef6e4;
        --fg: #1d1a2b;
        --fg-muted: #5a556a;
        --pink: #ff6fae;
        --purple: #7b5cff;
        --yellow: #ffd166;
        --green: #4ad295;
        --card: #ffffff;
        --shadow-x: 6px;
        --shadow-y: 6px;
        --sans: "Inter", "Noto Sans JP", "Hiragino Sans", "Hiragino Kaku Gothic ProN", "Yu Gothic", "Meiryo", ui-sans-serif, system-ui, -apple-system, sans-serif;
        --display: "Inter", "Noto Sans JP", "Hiragino Sans", "Hiragino Kaku Gothic ProN", "Yu Gothic", "Meiryo", ui-sans-serif, system-ui, sans-serif;
      }
      * { box-sizing: border-box; }
      html, body { margin: 0; padding: 0; }
      body {
        font-family: var(--sans);
        background: var(--bg);
        color: var(--fg);
        min-height: 100dvh;
        display: grid;
        place-items: center;
        padding: clamp(1.5rem, 5vw, 3rem);
        overflow: hidden;
      }

      .cta-block {
        position: relative;
        width: min(900px, 100%);
        background: var(--card);
        border: 3px solid var(--fg);
        border-radius: 28px;
        box-shadow: var(--shadow-x) var(--shadow-y) 0 var(--fg);
        padding: clamp(2rem, 5vw, 3.5rem) clamp(1.5rem, 4vw, 3rem);
        text-align: center;
        transform: rotate(-1deg);
        transition: transform 0.2s cubic-bezier(0.34, 1.56, 0.64, 1);
      }
      .cta-block:hover { transform: rotate(-0.5deg) translateY(-2px); }

      /* Decorative floaties */
      .float {
        position: absolute;
        font-size: clamp(2rem, 4vw, 3rem);
        line-height: 1;
        animation: bob 3.5s ease-in-out infinite;
        filter: drop-shadow(2px 2px 0 var(--fg));
      }
      .float.f1 { top: -18px; left: 5%; transform: rotate(-15deg); animation-delay: 0s; }
      .float.f2 { top: -28px; right: 8%; transform: rotate(12deg); animation-delay: 0.8s; }
      .float.f3 { bottom: -18px; left: 10%; transform: rotate(20deg); animation-delay: 1.6s; }
      .float.f4 { bottom: -22px; right: 6%; transform: rotate(-8deg); animation-delay: 2.4s; }
      @keyframes bob {
        0%, 100% { translate: 0 0; }
        50% { translate: 0 -6px; }
      }

      .eyebrow {
        display: inline-block;
        padding: 0.35rem 0.9rem;
        background: var(--yellow);
        border: 2px solid var(--fg);
        border-radius: 999px;
        font-size: 0.82rem;
        font-weight: 700;
        letter-spacing: 0.04em;
        margin-bottom: 1.5rem;
        transform: rotate(2deg);
      }

      h1 {
        font-family: var(--display);
        font-weight: 800;
        font-size: clamp(2rem, 4.6vw, 3.2rem);
        line-height: 1.4;
        letter-spacing: 0;
        margin: 0 0 1rem;
      }
      h1 .wiggle {
        display: inline-block;
        color: var(--pink);
        position: relative;
        animation: wiggle 2.4s ease-in-out infinite;
      }
      h1 .highlight {
        display: inline-block;
        position: relative;
        color: var(--fg);
        z-index: 1;
      }
      h1 .highlight::before {
        content: "";
        position: absolute;
        left: -2px;
        right: -2px;
        bottom: 2px;
        height: 0.55em;
        background: var(--green);
        z-index: -1;
        transform: rotate(-0.6deg);
      }
      @keyframes wiggle {
        0%, 100% { rotate: -3deg; }
        50% { rotate: 3deg; }
      }

      p.lede {
        font-size: clamp(1rem, 1.5vw, 1.15rem);
        color: var(--fg-muted);
        max-width: 46ch;
        margin: 0 auto 2rem;
        line-height: 1.55;
      }

      .actions {
        display: inline-flex;
        flex-wrap: wrap;
        gap: 0.75rem;
        justify-content: center;
      }
      a.btn {
        display: inline-flex;
        align-items: center;
        gap: 0.5rem;
        padding: 0.95rem 1.6rem;
        border: 3px solid var(--fg);
        border-radius: 14px;
        font-weight: 700;
        font-size: 1rem;
        text-decoration: none;
        color: var(--fg);
        background: var(--card);
        box-shadow: 4px 4px 0 var(--fg);
        transition: transform 0.12s ease, box-shadow 0.12s ease;
        cursor: pointer;
      }
      a.btn.primary { background: var(--pink); color: var(--fg); }
      a.btn.secondary { background: var(--card); }
      a.btn:hover { transform: translate(-2px, -2px); box-shadow: 6px 6px 0 var(--fg); }
      a.btn:active { transform: translate(1px, 1px); box-shadow: 2px 2px 0 var(--fg); }
      a.btn .icon {
        display: inline-block;
        transition: transform 0.15s;
      }
      a.btn:hover .icon { transform: translateX(3px) rotate(-6deg); }

      .micro {
        margin-top: 1.5rem;
        font-size: 0.88rem;
        color: var(--fg-muted);
      }
      .micro .check {
        display: inline-flex;
        align-items: center;
        gap: 0.3rem;
      }
      .micro .check::before {
        content: "✓";
        color: var(--fg);
        font-weight: 800;
        background: var(--green);
        width: 18px;
        height: 18px;
        display: inline-grid;
        place-items: center;
        border: 2px solid var(--fg);
        border-radius: 999px;
        font-size: 0.65rem;
      }
      .micro .dot { margin: 0 0.5rem; opacity: 0.4; }

      .tiny-arrow {
        position: absolute;
        top: 45%;
        right: calc(100% + 10px);
        transform: translateY(-50%) rotate(-10deg);
        font-family: "Caveat", "Marker Felt", cursive;
        font-size: 1rem;
        color: var(--purple);
      }
      .tiny-arrow::after {
        content: "";
        display: block;
        width: 40px;
        height: 28px;
        border-top: 2px solid var(--purple);
        border-right: 2px solid var(--purple);
        border-top-right-radius: 80% 60%;
        transform: rotate(20deg) skewY(-10deg);
        margin-top: -4px;
        margin-left: 6px;
      }

      @media (max-width: 720px) {
        .tiny-arrow { display: none; }
      }
    [hidden]{display:none!important}
a,button,input,summary{min-width:44px;min-height:44px}
a{touch-action:manipulation}
button{cursor:pointer}
button:disabled{cursor:default}
a:focus-visible,button:focus-visible,input:focus-visible{outline:3px solid currentColor;outline-offset:4px}
nav a{display:inline-flex;align-items:center;justify-content:center}
nav{flex-wrap:wrap}
header.bar{flex-wrap:wrap;gap:1rem}
input{max-width:100%}
.demo-notes{position:relative;z-index:10;box-sizing:border-box;max-width:1080px;width:calc(100% - 2rem);margin:2rem auto;padding:clamp(1rem,3vw,2rem);background:#f6f1e8;color:#211c17;border:1px solid currentColor;text-align:left;font-family:"Hiragino Sans","Yu Gothic",Meiryo,sans-serif;font-size:13px;line-height:1.8;letter-spacing:0;overflow-wrap:anywhere}
.demo-notes h2{font-size:18px;line-height:1.5;margin:0 0 .75rem}
.demo-notes h3{font-size:15px;line-height:1.5;margin:0 0 .4rem}
.demo-notes p{font:inherit;color:inherit;opacity:1;margin:0 0 1rem;max-width:none;letter-spacing:0}
.demo-notes section{margin-top:1.25rem;scroll-margin-top:1rem}
.demo-notes button{font:inherit;color:inherit;background:transparent;border:1px solid currentColor;padding:.4rem .75rem}
.demo-notes a{color:inherit}
.demo-notes .demo-motion{margin-bottom:1rem}
.demo-notes section:focus{outline:3px solid currentColor;outline-offset:4px}
@media(prefers-reduced-motion:reduce){*,*::before,*::after{animation:none!important;transition:none!important}
}
body{overflow:visible;display:block}
body>.stage,body>.cta,body>.container{margin-inline:auto}
html[data-demo-paused] *,html[data-demo-paused] *::before,html[data-demo-paused] *::after{animation-play-state:paused!important}
html[data-demo-paused] .ticker p{animation:none!important;padding-left:8px;white-space:normal}
body>.cta-block,body>.frame{margin-inline:auto}
.wiggle{color:#c72d70}
.cta-block .wiggle{color:#c72d70}
</style>
  <noscript><style>*,*::before,*::after{animation:none!important}.ticker p{padding-left:8px;white-space:normal}</style></noscript>
</head>
  <body>
    <section class="cta-block">
      <span class="float f1" aria-hidden="true">✨</span>
      <span class="float f2" aria-hidden="true">🎯</span>
      <span class="float f3" aria-hidden="true">🪄</span>
      <span class="float f4" aria-hidden="true">💌</span>

      <span class="eyebrow">席数限定 · 春季募集</span>

      <h1>
        ちゃんと<span class="wiggle">息をしてる</span><br />
        ものを<span class="highlight">作ろう。</span>
      </h1>

      <p class="lede">
        テンプレっぽくない、ちょっと変で、嬉しくなるプロダクトを作っているメイカーたちのコミュニティ。週1のオフィスアワー、いつでも批評、ハグもあります。
      </p>

      <div class="actions">
        <a href="#demo-link-0" class="btn primary">
          参加枠を確保する
          <span class="icon">→</span>
        </a>
        <a href="#demo-link-1" class="btn secondary">中身を見てみる</a>
      </div>

      <p class="micro">
        <span class="check">クレカ不要</span>
        <span class="dot">·</span>
        <span class="check">いつでも解約</span>
        <span class="dot">·</span>
        <span class="check">オンボーディング伴走</span>
      </p>
    </section>
  <aside class="demo-notes" aria-label="この見本について">
<h2>この見本について</h2>
<p>架空のサービスや企画への案内です。日付・人数・価格・特典・利用条件は表示例です。リンクは構成の説明へ移動し、申込み・予約・決済・発券・招待は行いません。配布HTMLはCC0・利用料¥0。外部素材やライブラリの取得は不要です。</p>
<div class="demo-motion">
<button type="button" data-demo-motion data-js-control disabled aria-pressed="false">演出を止める</button>
</div>
<section id="demo-link-0" tabindex="-1">
<h3>参加枠を確保する →の見本</h3>
<p>主ボタンから次の案内へ進める配置の例です。ここにある料金・特典・開催条件は架空で、申込み・契約・購入・参加枠の確保は行いません。</p>
</section>
<section id="demo-link-1" tabindex="-1">
<h3>中身を見てみるの見本</h3>
<p>主ボタンから次の案内へ進める配置の例です。ここにある料金・特典・開催条件は架空で、申込み・契約・購入・参加枠の確保は行いません。</p>
</section>
<noscript>
<p>JavaScriptなしでも初期表示と説明リンクを利用できます。絞り込み・入力確認・演出の切替は無効です。</p>
</noscript>
</aside><script>
const motion=matchMedia('(prefers-reduced-motion: reduce)'),toggle=document.querySelector('[data-demo-motion]');let paused=false;function syncMotion(){const stop=paused||motion.matches;document.documentElement.toggleAttribute('data-demo-paused',stop);toggle.setAttribute('aria-pressed',String(stop));toggle.disabled=motion.matches;toggle.textContent=motion.matches?'動きを減らす設定で停止中':stop?'演出を再開':'演出を止める'}toggle.addEventListener('click',()=>{paused=!paused;syncMotion()});motion.addEventListener('change',syncMotion);
document.querySelectorAll('[data-js-control]').forEach(el=>el.disabled=false);syncMotion();
</script>
</body>
</html>

2026年10月14日、Chromiumで320・390・768・1280pxの描画とキーボードのフォーカス表示を確認しました。他のブラウザは未確認です。利用先のブラウザと実データでも確認してください。

概要

遊び心のあるCTAブロックは、「この先にいるのは冷たい企業ではなく、話せる人間だ」というシグナルを視覚で伝える設計です。少し傾いたカード、ふわふわ揺れる絵文字、手書き風の矢印——これらはすべて、完璧に整ったSaaS体験から意図的に外れるための装置です。

「ちゃんとしすぎ」が壁になるとき

個人開発者やクリエイターのコミュニティ募集では、洗練が逆効果になることがあります。完璧な直線、均等な余白、プロの写真素材——それらは訪問者に「自分が気軽に話しかけていい相手ではなさそうだ」と感じさせる。わずかな歪みと手書きの要素は、その心理的な壁を取り払い、「ここには話しかけていい人間がいる」と伝えます。不完全さが、親密さの記号として働きます。

崩しすぎない、という難しさ

このスタイルの難所は、崩しの「度合い」です。少しの歪みは親しみを生みますが、崩しすぎると「子供向けアプリ」や「素人の手作りサイト」に転落する。プロが意図して崩している、と伝わる範囲に留めることが、遊び心と信頼性を両立させる条件です。

崩れる形崩しすぎる

歪みが大きいと、子供向けアプリか素人の手作りサイトに転落します。親しみを狙ったはずが、技術力への疑いに変わります。

効く形プロが意図して崩している

わずかな歪みと手書きの要素は、心理的な壁だけを取り払います。伝わるのは「ここには話しかけていい人間がいる」というシグナルです。

仕上げの判断軸

カードの回転は rotate(-1deg) 程度が上限——これ以上回すとトーンが幼くなりすぎます。境界線を厚くし、4〜6pxのオフセット影(ネオブルータリスト風)を添えると、モダンさとソフトさが両立します。揺れる絵文字は4箇所ほどに置き、@keyframes のディレイを段階的にずらすのがコツ。全部同じタイミングだとロボット的に、バラバラすぎると散漫になります。見出し内の強調は2箇所まで。手書き矢印はデスクトップのみとし、モバイルでは非表示にして場所を節約します。

-1degカードの回転の上限。これ以上回すとトーンが幼くなる
4〜6pxオフセット影。モダンさとソフトさが両立する
4箇所揺れる絵文字。ディレイを段階的にずらす

見本で試せる範囲

架空のサービスや企画への案内です。日付・人数・価格・特典・利用条件は表示例です。リンクは構成の説明へ移動し、申込み・予約・決済・発券・招待は行いません。演出の停止とOSの動き低減に対応します。 作品・記事・サービス名や数値は表示のための設定です。リンク先には、このHTMLに含まれる範囲と利用先で接続する処理を説明しています。配布HTMLはCC0・利用料¥0で、保存した1ファイルだけで表示できます。

CTAの構成要素

CTAの構成要素 見出し ── 得る結果を書く 不安を1つだけ先回りして消す 主CTA ── 動詞で書く 「無料ではじめる」「資料を受け取る」 「送信」「クリック」は避ける 押した先で何が起きるかが読めるほど、押されやすくなる
CTAで最も効くのは装飾ではなくボタンの文言です。動作ではなく、押した先で手に入るものを書いてください。

使いどころ

  • 個人開発プロダクトのコミュニティ募集 / 早期アクセス招待
  • Creator系サービスの登録導線 (コースの開講、メンバー募集など)
  • ブランドが「堅さを捨てる」瞬間を作りたい B2C 製品の途中セクション

このデザインの分類

カテゴリ
CTA
スタイル
プレイフル / ハンドクラフト / ウォーム / ボールド

背景と狙いどころ

よくある質問

動きが強すぎないか心配です。どこまで抑えるべきですか。
`prefers-reduced-motion` メディアクエリで `bob` と `wiggle` の animation を止める分岐を入れてください。モーション苦手なユーザーにはカードの傾きだけ残り、遊び心は保たれます。
絵文字の代わりにカスタムイラストを使えますか。
そのまま置き換えられます。SVGを同じサイズ (clamp 2rem → 3rem) で配置し、`filter: drop-shadow(2px 2px 0 ink)` は残すと「ハンドクラフト感」が続きます。
手書き矢印を落ち着いた注釈に置き換えてもいいですか。
`.tiny-arrow` を削除して、カードの外に小さなラベル(例: '3 seats left'、動的な残席カウントなど) を置くだけでOK。ここに数字を置くと説得力が増します。

この画面を実装する

動くサンプルとコピペできるコードを、技術別にまとめています。