リアルタイムプレビュー(Live Preview)— 名刺カードへの入力連動

フォーム入力 初級

このコンポーネントについて

フォームへの入力内容を、隣に置いたプレビューカードへリアルタイムに反映するコンポーネントです。 名刺作成・プロフィール編集・社員名簿の登録画面など、「入力した結果がどう見えるか」をその場で確認させたい場面で使われます。

各入力欄の値は名刺風のカードに即時反映され、未入力の項目はプレースホルダー文言で表示されるためカードのレイアウトが崩れません。 バニラJavaScriptのみで実装でき、外部ライブラリは不要です。

  • リアルタイム反映 — 入力欄への1文字ごとの入力が即座にプレビューカードへ反映される
  • プレースホルダー表示 — 未入力の項目はグレーの項目名プレースホルダーを表示し、カードの体裁を保つ
  • 5項目対応 — 氏名・会社名・部署・役職・電話番号・メールアドレスをカード上の適切な位置にレイアウト
  • リセット機能 — ボタン1つで全入力欄とプレビューを初期状態に戻す

実装のポイント・注意点

各入力欄には input イベントを登録し、値があれば対応するプレビュー要素の textContent を書き換えます。 値が空になった場合は項目名(「氏名」など)をプレースホルダーとして表示し直し、カードの見た目が崩れないようにします。

5項目とも処理の構造は同じなので、「入力要素・プレビュー要素・プレースホルダー文言」の対応関係を配列にまとめ、 forEach で共通のリスナー登録・更新処理にすると、同じコードを5回書かずに済みます。

プレビューへの反映は必ず textContent で行い、innerHTML に変数を直接結合しないようにしてください。 入力値がそのままHTMLとして解釈されるとXSSの原因になるため、この実装ではその心配がありません。

HTML・CSS・バニラJavaScriptのみで実装しており、フレームワーク不要でコピペすぐに動きます。

デモ

氏名

部署・役職

会社名

電話番号

メールアドレス

サンプルソース

3つのファイルを同じフォルダに保存し、index.html をブラウザで開くとすぐに動作確認できます。
ファイル名:index.html / style.css / script.js — 保存時の文字コードは UTF-8 を指定してください(Shift-JISだと日本語が文字化けします)。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>リアルタイムプレビュー サンプル</title>
  <link rel="stylesheet" href="./style.css">
</head>
<body>

<div class="preview-wrapper">
  <div class="preview-form">
    <div class="preview-field">
      <label for="previewName">氏名</label>
      <input type="text" id="previewName" placeholder="山田 太郎">
    </div>
    <div class="preview-field">
      <label for="previewCompany">会社名</label>
      <input type="text" id="previewCompany" placeholder="株式会社サンプル">
    </div>
    <div class="preview-field">
      <label for="previewTitle">部署・役職</label>
      <input type="text" id="previewTitle" placeholder="営業部 部長">
    </div>
    <div class="preview-field">
      <label for="previewTel">電話番号</label>
      <input type="text" id="previewTel" placeholder="03-1234-5678">
    </div>
    <div class="preview-field">
      <label for="previewEmail">メールアドレス</label>
      <input type="email" id="previewEmail" placeholder="[email protected]">
    </div>
  </div>

  <div class="preview-card" id="previewCard">
    <p class="preview-card-name is-placeholder" id="previewCardName">氏名</p>
    <p class="preview-card-title is-placeholder" id="previewCardTitle">部署・役職</p>
    <p class="preview-card-company is-placeholder" id="previewCardCompany">会社名</p>
    <div class="preview-card-contact">
      <p class="is-placeholder" id="previewCardTel">電話番号</p>
      <p class="is-placeholder" id="previewCardEmail">メールアドレス</p>
    </div>
  </div>
</div>

<script src="./script.js"></script>
</body>
</html>
/* === リアルタイムプレビュー ===
   色を変えたいときは :root の変数を書き換えるだけでOKです */
:root {
  --preview-accent:      #2B7FE8;
  --preview-border:      #D0D7E0;
  --preview-text:        #1A2733;
  --preview-text-muted:  #5A6A7A;
  --preview-placeholder: #C3CBD4;
}

*, *::before, *::after { box-sizing: border-box; }
body {
  font-family: sans-serif;
  padding: 24px;
}

.preview-wrapper {
  display: flex;
  gap: 32px;
  flex-wrap: wrap;
  align-items: flex-start;
}

/* 入力フォーム側 */
.preview-form {
  flex: 1;
  min-width: 260px;
}

.preview-field {
  margin-bottom: 14px;
}

.preview-field label {
  display: block;
  font-size: 13px;
  color: var(--preview-text-muted);
  margin-bottom: 4px;
}

.preview-field input {
  width: 100%;
  padding: 8px 12px;
  font-size: 14px;
  font-family: sans-serif;
  border: 1.5px solid var(--preview-border);
  border-radius: 8px;
  outline: none;
  transition: border-color 0.15s, box-shadow 0.15s;
}

.preview-field input:focus {
  border-color: var(--preview-accent);
  box-shadow: 0 0 0 3px rgba(43, 127, 232, 0.12);
}

/* 名刺風プレビューカード */
.preview-card {
  width: 320px;
  aspect-ratio: 16 / 9;
  background: #fff;
  border: 1px solid var(--preview-border);
  border-radius: 12px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.06);
  padding: 24px;
}

.preview-card-name {
  font-size: 20px;
  font-weight: 700;
  color: var(--preview-text);
  margin: 0 0 6px;
}

.preview-card-title,
.preview-card-company {
  font-size: 13px;
  color: var(--preview-text-muted);
  margin: 0 0 2px;
}

.preview-card-contact {
  margin-top: 16px;
  font-size: 12px;
  color: var(--preview-text-muted);
}

.preview-card-contact p {
  margin: 0 0 2px;
}

/* 未入力時はグレーのプレースホルダー文言にする */
.preview-card .is-placeholder {
  color: var(--preview-placeholder);
}

/* スマホ対応 */
@media (max-width: 480px) {
  body { padding: 16px; }
  .preview-card {
    width: 100%;
    max-width: 320px;
  }
}
// 入力欄・プレビュー要素・プレースホルダー文言の対応関係を配列にまとめる
var previewFields = [
  { input: document.getElementById('previewName'),    preview: document.getElementById('previewCardName'),    placeholder: '氏名' },
  { input: document.getElementById('previewCompany'), preview: document.getElementById('previewCardCompany'), placeholder: '会社名' },
  { input: document.getElementById('previewTitle'),   preview: document.getElementById('previewCardTitle'),   placeholder: '部署・役職' },
  { input: document.getElementById('previewTel'),     preview: document.getElementById('previewCardTel'),     placeholder: '電話番号' },
  { input: document.getElementById('previewEmail'),   preview: document.getElementById('previewCardEmail'),   placeholder: 'メールアドレス' }
];

// 5項目とも同じ処理のため共通関数でリスナー登録・更新を行う
previewFields.forEach(function (field) {
  field.input.addEventListener('input', function () {
    updatePreviewField(field);
  });
});

function updatePreviewField(field) {
  var value = field.input.value;
  if (value) {
    // 入力ありの場合は入力内容をそのまま表示(textContent なので innerHTML は使わない)
    field.preview.textContent = value;
    field.preview.classList.remove('is-placeholder');
  } else {
    // 未入力の場合は項目名をプレースホルダーとして表示
    field.preview.textContent = field.placeholder;
    field.preview.classList.add('is-placeholder');
  }
}

function resetDemo() {
  previewFields.forEach(function (field) {
    field.input.value = '';
    updatePreviewField(field);
  });
}

AI用プロンプト

以下のプロンプトをコピーしてAIに渡すと、同様のコンポーネントを生成できます。

ChatGPTやClaudeにこのプロンプトを渡すと、同様のコンポーネントをゼロから生成・カスタマイズできます。項目の追加やカードデザインの変更など、要件を追記して使うのがおすすめです。

※ このプロンプトを使ってもデモとまったく同じ動作にならない場合があります。AIの解釈や生成タイミングによって差が出ることをご了承ください。

💡 jQuery・Vue・React など特定のライブラリで実装したい場合は、プロンプトの末尾に「〇〇を使って実装してください」と追記してください。

# 入力内容リアルタイムプレビュー(名刺カード) 作成依頼

## 概要
フォームの入力内容を、隣に置いた名刺風プレビューカードにリアルタイムで反映するUIを作成してください。

## 要件
- 入力欄は「氏名」「会社名」「部署・役職」「電話番号」「メールアドレス」の5項目
- 各入力欄に文字を入力すると、対応するプレビューカードの項目に即時反映される
- 未入力の項目はプレビューカード内にグレーの項目名プレースホルダー(例: 「氏名」)を表示し、入力があるとその表示に置き換わる
- リセットボタンで全入力欄とプレビューを初期状態(空欄・プレースホルダー表示)に戻せる
- プレビューへの反映は textContent を使用し、innerHTML への変数結合は行わない

## 技術仕様
- HTML / CSS / バニラJavaScript で実装
- 外部ライブラリ:なし
- レスポンシブ対応:必要

## 動作詳細
各入力欄に input イベントリスナーを設定し、値の有無に応じてプレビューカード側の対応する要素のテキストを書き換えます。値が空の場合は項目名をプレースホルダーとして表示し、値がある場合は入力内容に置き換えます。5項目とも同じ処理のため、入力要素とプレビュー要素の対応関係を配列にまとめ、共通の更新関数で処理してください。

## 出力形式
HTML・CSS・JavaScriptを分けて出力してください。
各ファイルは単独でコピー&ペーストして使えるよう記述してください。