メールフォーム.JP
テンプレート一覧
← アプリページに戻る
フォーム雛形集(プレビュー付き)
まずプレビューで見た目を確認し、下のコードをそれぞれ(HTML / CSS / JS)にコピペしてください。カスタマイズは
GPT活用Tips
を参照。
Template 01:シンプル(画像添付あり)
プレビュー
HTML(<form>の中身だけ)
コピー
<h1>お問い合わせ</h1> <label>お名前<span style="color:red">*</span> <input type="text" name="name" required autocomplete="name"> </label> <label>メールアドレス<span style="color:red">*</span> <input type="email" name="email" required autocomplete="email"> </label> <label>件名 <input type="text" name="subject"> </label> <label>お問い合わせ内容<span style="color:red">*</span> <textarea name="message" rows="6" required></textarea> </label> <div class="drop-zone" tabindex="0"> <input class="file-input" type="file" name="images[]" accept="image/*" multiple> <div>画像をドラッグ&ドロップ、またはクリックして選択(複数可・1ファイル最大50MB)</div> </div> <ul class="previews"></ul> <div><button type="submit">送信</button></div>
CSS(<style>…</style> の中だけ)
コピー
body{font-family:sans-serif;line-height:1.5;padding:20px;} form{max-width:600px;margin:auto;} h1{font-size:1.3rem;margin:0 0 12px;} label{display:block;margin:8px 0;} input[type="text"],input[type="email"],textarea{width:100%;padding:8px;border:1px solid #ccc;border-radius:4px;} textarea{resize:vertical;} .drop-zone{position:relative;border:2px dashed #ccc;padding:16px;text-align:center;cursor:pointer;margin:10px 0;} .drop-zone.is-dragover{border-color:#333;background:#fafafa;} .file-input{position:absolute;inset:0;opacity:0;cursor:pointer;} .previews{list-style:none;margin:10px 0 0;padding:0;} .preview{font-size:.9rem;margin-bottom:6px;} button[type="submit"]{padding:8px 16px;border:1px solid #ccc;border-radius:4px;background:#f2f2f2;cursor:pointer;} button[type="submit"]:hover{background:#e6e6e6;}
JavaScript(<script>…</script> の中だけ)
コピー
const form = document.querySelector("form"); const fileInput = form.querySelector(".file-input"); const dropZone = form.querySelector(".drop-zone"); const previewList = form.querySelector(".previews"); const MAX_FILE_SIZE = 50 * 1024 * 1024; let selectedFiles = []; function addFiles(list){ for(const file of list){ if(!file.type.startsWith("image/")) { console.warn("画像以外は不可:", file.name); continue; } if(file.size > MAX_FILE_SIZE) { console.warn("50MB超過:", file.name); continue; } selectedFiles.push(file); } const dt = new DataTransfer(); selectedFiles.forEach(f => dt.items.add(f)); fileInput.files = dt.files; previewList.innerHTML = ""; selectedFiles.forEach(f => { const li = document.createElement("li"); li.className = "preview"; li.textContent = `${f.name} (${(f.size/1024/1024).toFixed(1)} MB)`; previewList.appendChild(li); }); } // 誤ドロップ遷移防止 addEventListener("dragover", e => e.preventDefault()); addEventListener("drop", e => e.preventDefault()); // D&D ["dragenter","dragover"].forEach(ev => { dropZone.addEventListener(ev, e => { e.preventDefault(); dropZone.classList.add("is-dragover"); }); }); ["dragleave","drop"].forEach(ev => { dropZone.addEventListener(ev, e => { e.preventDefault(); dropZone.classList.remove("is-dragover"); }); }); dropZone.addEventListener("drop", e => addFiles(e.dataTransfer.files)); fileInput.addEventListener("change", e => addFiles(e.target.files)); // 実送信はアプリ側で行う想定(ここでは書かない)