HTMLのプルダウン(セレクトボックス)は、省スペースで複数の選択肢を提示できるフォーム必須のパーツです。
本記事では、基本のタグの書き方、CSSによるおしゃれな矢印のカスタマイズ、JavaScriptを使った2段階の連動機能などを解説します。
HTMLでのプルダウンの作り方
Webサイトのお問い合わせフォームや会員登録画面で、「都道府県」や「年齢」などを選ばせる際に使われるのがプルダウンです。
複数の選択肢を格納できるため、スマホなどの画面でも重宝される部品です。
ここでは、実務で使えるプルダウンの作り方を解説します。
基本的なプルダウンの役割から、コピペして使えるプルダウンのサンプル、フォーム作成に必要な情報を網羅しています。
- ドロップダウン・コンボボックスとの違い
selectとoptionタグの書き方- 初期値やプレースホルダーの設定
ドロップダウン・コンボボックスとの違い
Web制作では、人によって「セレクトボックス」「プルダウン」「ドロップダウン」など、呼び方がバラバラで混乱することがあります。
用語の違い理解していきましょう。
- セレクトボックス / プルダウン / ドロップダウン
実はHTMLにおいて、これらは全て同じもの(<select>タグで作る)を指しています。
クリックするとメニューが下に垂れ下がる(ドロップする/プルする)という動きから、様々な呼び名が定着しているだけです。 - コンボボックス
コンボボックスとは本来、「文字を自由に入力できるテキストボックス」と「プルダウンリスト」が合体した部品のことです。
HTML5からは<datalist>というタグを使うと実装できます。
<option>東京都</option>…
</select>
※用意された選択肢の中から「選ぶ」ことしかできません。
<datalist id=”prefs”>…
※文字を直接入力することもでき、「東」と打てば「東京都」が予測変換のように出ます(ダブルクリックで全件表示)。
HTMLコード表示
<div class="hpull1-wrapper">
<div class="hpull1-demo-area">
<div class="hpull1-box">
<div class="hpull1-label">🔻 セレクトボックス (プルダウン/ドロップダウン)</div>
<select class="hpull1-input">
<option value="tokyo">東京都</option>
<option value="osaka">大阪府</option>
<option value="fukuoka">福岡県</option>
</select>
<div class="hpull1-code">
<select><br>
<option>東京都</option>...<br>
</select>
</div>
<p class="hpull1-note">※用意された選択肢の中から「選ぶ」ことしかできません。</p>
</div>
<div class="hpull1-box">
<div class="hpull1-label" style="color:#0d6efd;">⌨️ コンボボックス (入力+選択)</div>
<input type="text" list="prefs" class="hpull1-input" placeholder="入力またはダブルクリック">
<datalist id="prefs">
<option value="東京都"></option>
<option value="大阪府"></option>
<option value="福岡県"></option>
</datalist>
<div class="hpull1-code" style="border-left-color:#0d6efd;">
<input type="text" <span class="hpull1-hl">list="prefs"</span>><br>
<datalist <span class="hpull1-hl">id="prefs"</span>>...
</div>
<p class="hpull1-note">※文字を直接入力することもでき、「東」と打てば「東京都」が予測変換のように出ます(ダブルクリックで全件表示)。</p>
</div>
</div>
</div>CSSコード表示
.hpull1-wrapper {
background-color: #f8f9fa;
padding: 20px;
border: 1px solid #dee2e6;
border-radius: 4px;
font-family: sans-serif;
}
.hpull1-demo-area {
display: flex;
flex-direction: column;
gap: 30px;
align-items: center;
}
.hpull1-box {
background-color: #ffffff;
border: 2px dashed #adb5bd;
padding: 20px;
width: 100%;
max-width: 400px;
border-radius: 4px;
}
.hpull1-label {
font-size: 15px;
font-weight: bold;
color: #333;
margin-bottom: 10px;
}
.hpull1-input {
width: 100%;
padding: 10px;
font-size: 16px;
border: 2px solid #ccc;
border-radius: 4px;
box-sizing: border-box;
margin-bottom: 15px;
}
.hpull1-code {
background-color: #282c34;
color: #abb2bf;
padding: 15px;
font-family: monospace;
font-size: 13px;
border-radius: 4px;
line-height: 1.5;
border-left: 4px solid #333;
}
.hpull1-hl {
color: #61afef;
font-weight: bold;
}
.hpull1-note {
font-size: 13px;
color: #666;
margin-top: 15px;
line-height: 1.5;
}selectとoptionタグの書き方
プルダウンを作るには、2つのタグを組み合わせて記述します。
<select>タグ:プルダウンの「外側の箱(枠組み)」を作ります。<option>タグ:箱の中に入る「一つひとつの選択肢」を作ります。
コーディングとして欠かせないのが<option>タグの中に入れるvalue属性です。
プルダウンを書く際、<option>東京都</option>のように、画面に表示される文字だけを書いて満足することがあります。
しかし、HTMLのフォームにおいて、実際にサーバー(システム側)に送信されるデータは、画面に見えている日本語ではなくvalue属性の中に書かれた値です。
「画面表示用の文字と裏側で送るシステム用のデータ(value)はセットで書く」のがルールです。
inquiry
<option value=”inquiry”>サービスのご質問</option>
<option value=”estimate”>お見積りのご依頼</option>
<option value=”recruit”>採用について</option>
</select>
※プルダウンを切り替えてみてください。画面には丁寧な日本語が表示されていますが、裏側では「inquiry」のような短い英語データが準備されていることが分かります。
HTMLコード表示
<div class="hpull2-wrapper">
<div class="hpull2-demo-area">
<div class="hpull2-box">
<div class="hpull2-label">お問い合わせ種別</div>
<select id="hpull2-select" class="hpull2-select" onchange="showPull2Value()">
<option value="inquiry">サービスについてのご質問</option>
<option value="estimate">お見積りのご依頼</option>
<option value="recruit">採用について</option>
</select>
<div class="hpull2-result-area">
実際に送信される裏側のデータ:<br>
<span id="hpull2-result" class="hpull2-result-text">inquiry</span>
</div>
<div class="hpull2-code">
<select name="contact_type"><br>
<option <span class="hpull2-hl">value="inquiry"</span>>サービスのご質問</option><br>
<option <span class="hpull2-hl">value="estimate"</span>>お見積りのご依頼</option><br>
<option <span class="hpull2-hl">value="recruit"</span>>採用について</option><br>
</select>
</div>
<p class="hpull2-note">※プルダウンを切り替えてみてください。画面には丁寧な日本語が表示されていますが、裏側では「inquiry」のような短い英語データが準備されていることが分かります。</p>
</div>
</div>
</div>CSSコード表示
.hpull2-wrapper {
background-color: #f8f9fa;
padding: 20px;
border: 1px solid #dee2e6;
border-radius: 4px;
font-family: sans-serif;
}
.hpull2-demo-area {
display: flex;
justify-content: center;
}
.hpull2-box {
background-color: #ffffff;
border: 2px dashed #adb5bd;
padding: 25px;
width: 100%;
max-width: 450px;
border-radius: 4px;
}
.hpull2-label {
font-size: 15px;
font-weight: bold;
color: #333;
margin-bottom: 10px;
}
.hpull2-select {
width: 100%;
padding: 12px;
font-size: 16px;
border: 2px solid #ccc;
border-radius: 4px;
box-sizing: border-box;
margin-bottom: 20px;
cursor: pointer;
}
.hpull2-result-area {
background-color: #e7f1ff;
padding: 15px;
border: 1px solid #0d6efd;
border-radius: 4px;
font-size: 14px;
font-weight: bold;
color: #333;
margin-bottom: 15px;
}
.hpull2-result-text {
display: block;
margin-top: 10px;
font-size: 20px;
color: #dc3545;
font-family: monospace;
}
.hpull2-code {
background-color: #282c34;
color: #abb2bf;
padding: 15px;
font-family: monospace;
font-size: 13px;
border-radius: 4px;
line-height: 1.6;
}
.hpull2-hl {
color: #e5c07b;
font-weight: bold;
}
.hpull2-note {
font-size: 13px;
color: #666;
margin-top: 15px;
line-height: 1.5;
}JavaScriptコード表示
function showPull2Value() {
// 選択されたvalueを取得して画面に表示する
const selectBox = document.getElementById('hpull2-select');
const resultText = document.getElementById('hpull2-result');
resultText.textContent = selectBox.value;
}初期値やプレースホルダーの設定
プルダウンを設置した直後、一番上の<option>が自動的に初期値として表示されます。
特定の項目を最初から選ばれた状態にしたい場合は、<option>にselected属性を追記します。
※プルダウンを開くと、一番上に「選択してください」が存在し、ユーザーが選び直すことができてしまいます。このまま送信するとバグの元です。
選択してください
</option>
※プルダウンを開くと、「選択してください」の文字がリストから消えています。また、valueが空のため、選ばずに送信しようとするとrequiredエラーが出ます。
HTMLコード表示
<div class="hpull3-wrapper">
<div class="hpull3-demo-area">
<div class="hpull3-box">
<div class="hpull3-label" style="color:#dc3545;">❌ 悪い例(ただ置いただけ)</div>
<select class="hpull3-select hpull3-select-bad">
<option>選択してください</option>
<option value="1">10代</option>
<option value="2">20代</option>
</select>
<div class="hpull3-code hpull3-code-bad">
<option>選択してください</option>
</div>
<p class="hpull3-note">※プルダウンを開くと、一番上に「選択してください」が存在し、ユーザーが選び直すことができてしまいます。このまま送信するとバグの元です。</p>
</div>
<div class="hpull3-box">
<div class="hpull3-label" style="color:#198754;">⭕️ 良い例(プロの実装)</div>
<form action="#" onsubmit="alert('送信成功!'); return false;">
<select class="hpull3-select hpull3-select-good" required>
<option value="" hidden disabled selected>選択してください</option>
<option value="1">10代</option>
<option value="2">20代</option>
</select>
<button type="submit" class="hpull3-btn">送信テスト</button>
</form>
<div class="hpull3-code hpull3-code-good">
<option <span class="hpull3-hl-green">value="" hidden disabled selected</span>><br>
選択してください<br>
</option>
</div>
<p class="hpull3-note" style="color:#198754;">※プルダウンを開くと、「選択してください」の文字がリストから消えています。また、valueが空のため、選ばずに送信しようとするとrequiredエラーが出ます。</p>
</div>
</div>
</div>CSSコード表示
.hpull3-wrapper {
background-color: #f8f9fa;
padding: 20px;
border: 1px solid #dee2e6;
border-radius: 4px;
font-family: sans-serif;
}
.hpull3-demo-area {
display: flex;
flex-direction: column;
gap: 30px;
align-items: center;
}
.hpull3-box {
background-color: #ffffff;
border: 2px dashed #adb5bd;
padding: 20px;
width: 100%;
max-width: 400px;
border-radius: 4px;
}
.hpull3-label {
font-size: 15px;
font-weight: bold;
margin-bottom: 10px;
}
.hpull3-select {
width: 100%;
padding: 12px;
font-size: 16px;
border: 2px solid #ccc;
border-radius: 4px;
box-sizing: border-box;
margin-bottom: 15px;
cursor: pointer;
}
.hpull3-select-bad {
background-color: #f8d7da;
}
.hpull3-select-good {
background-color: #d1e7dd;
}
.hpull3-btn {
width: 100%;
padding: 10px;
background-color: #198754;
color: white;
border: none;
border-radius: 4px;
font-weight: bold;
cursor: pointer;
margin-bottom: 15px;
}
.hpull3-code {
background-color: #282c34;
color: #abb2bf;
padding: 15px;
font-family: monospace;
font-size: 13px;
border-radius: 4px;
line-height: 1.5;
}
.hpull3-code-bad {
border-left: 4px solid #dc3545;
}
.hpull3-code-good {
border-left: 4px solid #198754;
}
.hpull3-hl-green {
color: #98c379;
font-weight: bold;
}
.hpull3-note {
font-size: 13px;
color: #666;
margin-top: 10px;
line-height: 1.5;
}CSSによるプルダウンのデザイン・装飾
HTMLの標準機能で配置した<select>タグ(プルダウン)は、WindowsやMac、iPhoneなどのOSやブラウザによって見た目がバラバラです。
Webサイトに合わせてフォームを作るには、CSSを使ったカスタマイズが欠かせません。
おしゃれなデザインを施すことで、ユーザーに安心感を与えて使いやすいフォームになります。
ここでは、基本のサイズ調整、設定する矢印のカスタマイズ、ブラウザ仕様の内容について解説します。
- 幅・高さ・文字サイズ・色の変更
- 矢印のデザイン変更と文字の配置
- 表示数・スクロールバー・折り返しの設定
幅・高さ・文字サイズ・色の変更
プルダウンを設置したら、全体の大きさを整えます。
- 横幅の調整
widthプロパティを使用します。
スマホ対応のためにwidth: 100%;にするのが一般的です。 - 高さの調整
heightで指定できますが、文字を上下中央に配置するには内側の余白であるpaddingを使うのが一般的です。 - 文字と色の調整
文字の大きさはfont-size、文字色はcolor、背景色はbackground-colorで指定します。
width: 100%;とpaddingを同時に指定すると、プルダウンが親要素の枠から右側にはみ出るレイアウト崩れが多発します。
幅を100%にする時は、box-sizing: border-box;をセットで指定し、「余白や枠線を含めて100%に収める」という指示を出すのがよいです。
<option>選択してください</option>
</select>
※文字が小さく、クリックできる領域(高さ)も狭いため、スマホでは非常に押しづらいです。
box-sizing: border-box;
width: 100%;
padding: 12px 15px;
font-size: 16px;
background-color: #f8f9fa;
border: 2px solid #ccc;
※余白(padding)を取ることでタップしやすくなり、背景色や枠線をつけることでサイトの世界観に馴染むようになりました。
HTMLコード表示
<div class="hpull-css1-wrapper">
<div class="hpull-css1-demo-area">
<div class="hpull-css1-box">
<div class="hpull-css1-label">❌ 標準(デザインなし)</div>
<select class="hpull-css1-bad-select">
<option>選択してください</option>
<option>デザインコース</option>
<option>プログラミングコース</option>
</select>
<div class="hpull-css1-code hpull-css1-code-bad">
<select><br>
<option>選択してください</option><br>
</select>
</div>
<p class="hpull-css1-note">※文字が小さく、クリックできる領域(高さ)も狭いため、スマホでは非常に押しづらいです。</p>
</div>
<div class="hpull-css1-box">
<div class="hpull-css1-label" style="color:#198754;">⭕️ CSSで装飾(モダンデザイン)</div>
<select class="hpull-css1-good-select">
<option>選択してください</option>
<option>デザインコース</option>
<option>プログラミングコース</option>
</select>
<div class="hpull-css1-code hpull-css1-code-good">
/* はみ出し防止 */<br>
<span class="hpull-css1-hl">box-sizing: border-box;</span><br>
width: 100%;<br>
padding: 12px 15px;<br>
font-size: 16px;<br>
background-color: #f8f9fa;<br>
border: 2px solid #ccc;
</div>
<p class="hpull-css1-note" style="color:#198754;">※余白(padding)を取ることでタップしやすくなり、背景色や枠線をつけることでサイトの世界観に馴染むようになりました。</p>
</div>
</div>
</div>CSSコード表示
.hpull-css1-wrapper {
background-color: #f8f9fa;
padding: 20px;
border: 1px solid #dee2e6;
border-radius: 4px;
font-family: sans-serif;
}
.hpull-css1-demo-area {
display: flex;
flex-direction: column;
gap: 30px;
align-items: center;
}
.hpull-css1-box {
background-color: #ffffff;
border: 2px dashed #adb5bd;
padding: 20px;
width: 100%;
max-width: 400px;
border-radius: 4px;
}
.hpull-css1-label {
font-size: 14px;
font-weight: bold;
color: #dc3545;
margin-bottom: 10px;
}
.hpull-css1-bad-select {
margin-bottom: 15px;
}
/* ============================
⭕️ モダンなプルダウンの装飾
============================ */
.hpull-css1-good-select {
/* レイアウト崩れを防ぐ */
box-sizing: border-box;
width: 100%;
/* 高さではなくpaddingでクリック領域を広げる */
padding: 12px 15px;
font-size: 16px;
color: #333;
/* 背景と枠線のカスタマイズ */
background-color: #f8f9fa;
border: 2px solid #ced4da;
border-radius: 6px;
cursor: pointer;
transition: 0.2s;
margin-bottom: 15px;
}
.hpull-css1-good-select:focus {
outline: none;
border-color: #198754;
box-shadow: 0 0 0 3px rgba(25,135,84,0.25);
}
.hpull-css1-code {
background-color: #282c34;
color: #abb2bf;
padding: 15px;
font-family: monospace;
font-size: 13px;
border-radius: 4px;
line-height: 1.5;
}
.hpull-css1-code-bad {
border-left: 4px solid #dc3545;
}
.hpull-css1-code-good {
border-left: 4px solid #198754;
}
.hpull-css1-hl {
color: #e5c07b;
font-weight: bold;
}
.hpull-css1-note {
font-size: 13px;
color: #666;
margin-top: 15px;
line-height: 1.5;
}矢印のデザイン変更と文字の配置
プルダウンの右端にある「▼」のマークがあります。
この矢印はブラウザ(OS)が強制的に描画しているネイティブな部品です。
矢印をオリジナルのデザインに変更するには、プロパティappearance: none;を使用します。
これを使うとブラウザ標準の見た目をリセットすることができ、矢印が消滅します。
消えたところに、CSSのbackground-imageを使ってオリジナルの矢印画像を背景として配置するというのがよいです。
また、「単位」のテキストを横に置きたい場合はFlexboxを使い、プルダウン内の文字を右寄せにしたい場合はtext-align-last: right;を使用します。
appearance: none;
/* 代わりにオリジナルの矢印を背景画像で置く */
background-image: url(‘矢印の画像’);
background-position: right 15px center;
background-repeat: no-repeat;
display: flex;
align-items: center;
/* 文字を右寄せにする(Safari対策) */
text-align-last: right;
HTMLコード表示
<div class="hpull-css2-wrapper">
<div class="hpull-css2-demo-area">
<div class="hpull-css2-box">
<div class="hpull-css2-label">✨ オリジナルの矢印に変更</div>
<select class="hpull-css2-custom-arrow">
<option>支払い方法を選択</option>
<option>クレジットカード</option>
<option>銀行振込</option>
</select>
<div class="hpull-css2-code">
/* ブラウザ標準の矢印を消滅させる魔法 */<br>
<span class="hpull-css2-hl-red">appearance: none;</span><br><br>
/* 代わりにオリジナルの矢印を背景画像で置く */<br>
background-image: url('矢印の画像');<br>
background-position: right 15px center;<br>
background-repeat: no-repeat;
</div>
</div>
<div class="hpull-css2-box">
<div class="hpull-css2-label" style="color:#0d6efd;">📐 右寄せ & 文字を横に配置</div>
<div class="hpull-css2-flex-row">
<span>注文数:</span>
<select class="hpull-css2-align-right">
<option>1</option>
<option>2</option>
<option>3</option>
</select>
<span>個</span>
</div>
<div class="hpull-css2-code" style="border-left-color:#0d6efd;">
/* 横に並べる(親要素) */<br>
display: flex;<br>
align-items: center;<br><br>
/* 文字を右寄せにする(Safari対策) */<br>
<span class="hpull-css2-hl-blue">text-align-last: right;</span>
</div>
</div>
</div>
</div>CSSコード表示
.hpull-css2-wrapper {
background-color: #f8f9fa;
padding: 20px;
border: 1px solid #dee2e6;
border-radius: 4px;
font-family: sans-serif;
}
.hpull-css2-demo-area {
display: flex;
flex-direction: column;
gap: 30px;
align-items: center;
}
.hpull-css2-box {
background-color: #ffffff;
border: 2px dashed #adb5bd;
padding: 20px;
width: 100%;
max-width: 400px;
border-radius: 4px;
}
.hpull-css2-label {
font-size: 15px;
font-weight: bold;
color: #d63384;
margin-bottom: 15px;
border-bottom: 2px solid #eee;
padding-bottom: 5px;
}
/* ============================
カスタム矢印の実装
============================ */
.hpull-css2-custom-arrow {
box-sizing: border-box;
width: 100%;
padding: 12px 40px 12px 15px; /* 右側に矢印を置くための余白を確保 */
font-size: 16px;
border: 2px solid #d63384;
border-radius: 8px;
background-color: #fff;
cursor: pointer;
/* ★標準の矢印を完全に消す */
-webkit-appearance: none;
appearance: none;
/* ★独自の矢印(今回はSVGのbase64コード)を背景として設定 */
background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23d63384' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
background-repeat: no-repeat;
background-position: right 12px center;
background-size: 18px;
}
.hpull-css2-custom-arrow:focus {
outline: none;
box-shadow: 0 0 0 3px rgba(214,51,132,0.25);
}
/* ============================
右寄せ & 横並び
============================ */
.hpull-css2-flex-row {
display: flex;
align-items: center;
gap: 10px;
font-weight: bold;
color: #333;
}
.hpull-css2-align-right {
box-sizing: border-box;
width: 100px; /* 少し短くする */
padding: 10px 30px 10px 10px;
font-size: 16px;
border: 2px solid #0d6efd;
border-radius: 4px;
background-color: #fff;
cursor: pointer;
/* 標準矢印を消して青い矢印を設定 */
appearance: none;
background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%230d6efd' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
background-repeat: no-repeat;
background-position: right 8px center;
background-size: 16px;
/* ★プルダウンの文字を右寄せにする */
text-align-last: right;
}
.hpull-css2-code {
background-color: #282c34;
color: #abb2bf;
padding: 15px;
font-family: monospace;
font-size: 13px;
border-radius: 4px;
line-height: 1.5;
margin-top: 15px;
border-left: 4px solid #d63384;
}
.hpull-css2-hl-red { color: #e06c75; font-weight: bold; }
.hpull-css2-hl-blue { color: #61afef; font-weight: bold; }表示数・スクロールバー・折り返しの設定
都道府県など47個もある選択肢をクリックする前からすべて見せたい場合は、<select>タグの中にsize属性を追記します。
例えばsize="5"と書けば、最初は5件だけが表示され、はみ出た分には自動的にスクロールバーが付与されます。
<option>…</option>
</select>
※クリックしなくても最初から4件分表示され、残りはスクロールで選べるようになります。
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
※開いた後のリストの中身を2行に折り返すことはHTMLの仕様上不可能です。枠に収まるように「…」で省略するのがCSSの限界値です。
HTMLコード表示
<div class="hpull-css3-wrapper">
<div class="hpull-css3-demo-area">
<div class="hpull-css3-box">
<div class="hpull-css3-label">📜 最初から複数行を表示(size属性)</div>
<select class="hpull-css3-list-box" size="4">
<option>北海道</option>
<option>青森県</option>
<option>岩手県</option>
<option>宮城県</option>
<option>秋田県</option>
<option>山形県</option>
<option>福島県</option>
</select>
<div class="hpull-css3-code">
<select <span class="hpull-css3-hl">size="4"</span>><br>
<option>...</option><br>
</select>
</div>
<p class="hpull-css3-note">※クリックしなくても最初から4件分表示され、残りはスクロールで選べるようになります。</p>
</div>
<div class="hpull-css3-box">
<div class="hpull-css3-label" style="color:#fd7e14;">✂️ 長い文字の「見切れ」を美しく省略</div>
<select class="hpull-css3-ellipsis">
<option>短い選択肢</option>
<option selected>とてつもなく長い名前の選択肢が設定された場合、このままだとレイアウトが崩れてしまいます</option>
</select>
<div class="hpull-css3-code" style="border-left-color:#fd7e14;">
/* 文字が枠を超えたら「...」で省略する */<br>
white-space: nowrap;<br>
overflow: hidden;<br>
<span class="hpull-css3-hl">text-overflow: ellipsis;</span>
</div>
<p class="hpull-css3-note" style="color:#fd7e14;">※開いた後のリストの中身を2行に折り返すことはHTMLの仕様上不可能です。枠に収まるように「...」で省略するのがCSSの限界値です。</p>
</div>
</div>
</div>CSSコード表示
.hpull-css3-wrapper {
background-color: #f8f9fa;
padding: 20px;
border: 1px solid #dee2e6;
border-radius: 4px;
font-family: sans-serif;
}
.hpull-css3-demo-area {
display: flex;
flex-direction: column;
gap: 30px;
align-items: center;
}
.hpull-css3-box {
background-color: #ffffff;
border: 2px dashed #adb5bd;
padding: 20px;
width: 100%;
max-width: 400px;
border-radius: 4px;
}
.hpull-css3-label {
font-size: 15px;
font-weight: bold;
color: #333;
margin-bottom: 15px;
border-bottom: 2px solid #eee;
padding-bottom: 5px;
}
/* ============================
リストボックス(size属性)
============================ */
.hpull-css3-list-box {
box-sizing: border-box;
width: 100%;
padding: 5px;
font-size: 15px;
border: 2px solid #ccc;
border-radius: 4px;
/* リストボックスは見やすく少し背景をつけることが多い */
background-color: #f8f9fa;
margin-bottom: 15px;
}
.hpull-css3-list-box option {
padding: 8px;
cursor: pointer;
}
.hpull-css3-list-box option:checked {
background-color: #0d6efd;
color: white;
}
/* ============================
長文省略(ellipsis)
============================ */
.hpull-css3-ellipsis {
box-sizing: border-box;
width: 100%;
padding: 10px 30px 10px 10px;
font-size: 15px;
border: 2px solid #fd7e14;
border-radius: 4px;
background-color: #fff;
margin-bottom: 15px;
/* 矢印は消さないが、文字が矢印に被らないようにpadding-rightを設定済み */
/* ★長文を見切らせずに「...」で省略する */
white-space: nowrap; /* 1. 改行させない */
overflow: hidden; /* 2. はみ出た部分を隠す */
text-overflow: ellipsis; /* 3. 隠れた部分を「...」にする */
}
.hpull-css3-code {
background-color: #282c34;
color: #abb2bf;
padding: 15px;
font-family: monospace;
font-size: 13px;
border-radius: 4px;
line-height: 1.5;
border-left: 4px solid #333;
}
.hpull-css3-hl {
color: #c678dd;
font-weight: bold;
}
.hpull-css3-note {
font-size: 13px;
color: #666;
margin-top: 15px;
line-height: 1.5;
}UXを向上させる機能(複数選択・検索・自由入力)
Webフォームの利便性を高めるには、「1つを選ぶだけ」の標準的なプルダウンだけでなく、用途に合わせて機能を追加したプルダウンの種類を使い分ける必要があります。
ここでは、アンケートで活躍する複数選択機能、検索・自由入力機能、読み取り専用にできない問題などを解説します。
- 複数選択とチェックボックス化
- 検索機能付き・手入力できるプルダウン
- 非活性や入力必須・読取専用の設定
複数選択とチェックボックス化
「興味のある分野を複数選んでください」といった要件の場合、プルダウンを複数選択に対応させる必要があります。
HTMLの標準機能では、<select>タグにmultiple属性を追記するだけで複数の項目を選べるようになります。
※Ctrlキー(MacはCmdキー)を押しながらでないと複数選べません。スマホではリストが全開になりプルダウンの意味がなくなります。
プルダウンの「見た目」を自作します */
※クリックで開き、直感的に複数選択が可能です。実務で「複数選択プルダウン」を要求されたらこの形を作ります。
HTMLコード表示
<div class="hadv1-wrapper">
<div class="hadv1-demo-area">
<div class="hadv1-box">
<div class="hadv1-label" style="color:#dc3545;">❌ 標準のmultiple(使いにくい)</div>
<select class="hadv1-select-multi" multiple>
<option value="html">HTML</option>
<option value="css">CSS</option>
<option value="js">JavaScript</option>
<option value="php">PHP</option>
</select>
<div class="hadv1-code hadv1-code-bad">
<select <span class="hadv1-hl-red">multiple</span>>
</div>
<p class="hadv1-note">※Ctrlキー(MacはCmdキー)を押しながらでないと複数選べません。スマホではリストが全開になりプルダウンの意味がなくなります。</p>
</div>
<div class="hadv1-box">
<div class="hadv1-label" style="color:#198754;">⭕️ 使いやすい実装(チェックボックス型)</div>
<div class="hadv1-custom-dropdown" id="hadv1-dropdown">
<div class="hadv1-dropdown-header" onclick="toggleDropdown()">
スキルを選択してください ▼
</div>
<div class="hadv1-dropdown-list" id="hadv1-list">
<label class="hadv1-check-item"><input type="checkbox"> HTML</label>
<label class="hadv1-check-item"><input type="checkbox"> CSS</label>
<label class="hadv1-check-item"><input type="checkbox"> JavaScript</label>
<label class="hadv1-check-item"><input type="checkbox"> PHP</label>
</div>
</div>
<div class="hadv1-code hadv1-code-good">
/* <select>は使わず、<div>とチェックボックスで<br>
プルダウンの「見た目」を自作します */
</div>
<p class="hadv1-note" style="color:#198754;">※クリックで開き、直感的に複数選択が可能です。実務で「複数選択プルダウン」を要求されたらこの形を作ります。</p>
</div>
</div>
</div>CSSコード表示
.hadv1-wrapper {
background-color: #f8f9fa;
padding: 20px;
border: 1px solid #dee2e6;
border-radius: 4px;
font-family: sans-serif;
}
.hadv1-demo-area {
display: flex;
flex-direction: column;
gap: 30px;
align-items: center;
}
.hadv1-box {
background-color: #ffffff;
border: 2px dashed #adb5bd;
padding: 20px;
width: 100%;
max-width: 400px;
border-radius: 4px;
}
.hadv1-label {
font-size: 15px;
font-weight: bold;
margin-bottom: 10px;
}
/* ❌ 標準のmultiple */
.hadv1-select-multi {
width: 100%;
padding: 5px;
font-size: 16px;
border: 2px solid #ccc;
border-radius: 4px;
height: 100px; /* 見やすく高さを固定 */
margin-bottom: 15px;
}
/* ⭕️ カスタムドロップダウン */
.hadv1-custom-dropdown {
position: relative;
width: 100%;
margin-bottom: 15px;
}
.hadv1-dropdown-header {
padding: 12px 15px;
background-color: #fff;
border: 2px solid #198754;
border-radius: 4px;
cursor: pointer;
font-weight: bold;
color: #198754;
}
.hadv1-dropdown-list {
display: none; /* 初期状態は隠す */
position: absolute;
top: 100%;
left: 0;
width: 100%;
background-color: #fff;
border: 2px solid #198754;
border-top: none;
border-radius: 0 0 4px 4px;
z-index: 10;
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
}
.hadv1-check-item {
display: flex;
align-items: center;
gap: 10px;
padding: 10px 15px;
cursor: pointer;
border-bottom: 1px solid #eee;
}
.hadv1-check-item:hover { background-color: #f1f3f5; }
.hadv1-check-item input { width: 16px; height: 16px; cursor: pointer; }
/* JavaScriptで付与する表示用クラス */
.hadv1-show { display: block; }
.hadv1-code {
background-color: #282c34;
color: #abb2bf;
padding: 15px;
font-family: monospace;
font-size: 13px;
border-radius: 4px;
line-height: 1.5;
}
.hadv1-code-bad { border-left: 4px solid #dc3545; }
.hadv1-code-good { border-left: 4px solid #198754; }
.hadv1-hl-red { color: #e06c75; font-weight: bold; }
.hadv1-note {
font-size: 13px;
color: #666;
margin-top: 10px;
line-height: 1.5;
}JavaScriptコード表示
function toggleDropdown() {
const list = document.getElementById('hadv1-list');
list.classList.toggle('hadv1-show');
}検索機能付き・手入力できるプルダウン
選択肢が数百個もあるような場合、「探すのが面倒」という理由でユーザーは離脱してしまいます。
そこで、文字を入力して選択肢を絞り込むことができ、さらにリストにない項目は自由に手入力できる「コンボボックス」が役立ちます。
これは<select>ではなく、テキスト入力欄(<input type="text">)とデータリスト(<datalist>)を組み合わせて実装します。
<input type=”text” list=”hadv2-languages”>
<datalist id=”hadv2-languages”>
<option value=”JavaScript”></option>
</datalist>
※「P」と入力すると、PythonやPHPに絞り込まれます(検索機能)。また、「Go」などのリストにない文字も自由に手入力して送信できます。
HTMLコード表示
<div class="hadv2-wrapper">
<div class="hadv2-demo-area">
<div class="hadv2-box">
<div class="hadv2-label">よく使う言語を入力・選択してください</div>
<input type="text" list="hadv2-languages" class="hadv2-input" placeholder="入力して検索 or ダブルクリック">
<datalist id="hadv2-languages">
<option value="HTML5"></option>
<option value="CSS3"></option>
<option value="JavaScript"></option>
<option value="TypeScript"></option>
<option value="Python"></option>
<option value="Ruby"></option>
<option value="PHP"></option>
</datalist>
<div class="hadv2-code">
/* 検索も手入力もできるコンボボックス */<br>
<input type="text" <span class="hadv2-hl">list="hadv2-languages"</span>><br>
<datalist <span class="hadv2-hl">id="hadv2-languages"</span>><br>
<option value="JavaScript"></option><br>
</datalist>
</div>
<p class="hadv2-note">※「P」と入力すると、PythonやPHPに絞り込まれます(検索機能)。また、「Go」などのリストにない文字も自由に手入力して送信できます。</p>
</div>
</div>
</div>CSSコード表示
.hadv2-wrapper {
background-color: #f8f9fa;
padding: 20px;
border: 1px solid #dee2e6;
border-radius: 4px;
font-family: sans-serif;
}
.hadv2-demo-area {
display: flex;
justify-content: center;
}
.hadv2-box {
background-color: #ffffff;
border: 2px dashed #adb5bd;
padding: 25px;
width: 100%;
max-width: 400px;
border-radius: 4px;
}
.hadv2-label {
font-size: 15px;
font-weight: bold;
color: #0d6efd;
margin-bottom: 15px;
}
.hadv2-input {
width: 100%;
padding: 12px;
font-size: 16px;
border: 2px solid #ccc;
border-radius: 4px;
box-sizing: border-box;
margin-bottom: 15px;
}
.hadv2-input:focus {
outline: none;
border-color: #0d6efd;
box-shadow: 0 0 0 3px rgba(13,110,253,0.25);
}
.hadv2-code {
background-color: #282c34;
color: #abb2bf;
padding: 15px;
font-family: monospace;
font-size: 13px;
border-radius: 4px;
line-height: 1.5;
border-left: 4px solid #0d6efd;
}
.hadv2-hl {
color: #61afef;
font-weight: bold;
}
.hadv2-note {
font-size: 13px;
color: #666;
margin-top: 15px;
line-height: 1.5;
}非活性や入力必須・読取専用の設定
フォーム送信時、選択してほしい項目には<select required>を指定します。
逆に、特定の条件下でクリック・選択できないようにグレーアウトさせる場合はdisabled属性を使用します。
HTMLコード表示
<div class="hadv3-wrapper">
<div class="hadv3-demo-area">
<form action="#" onsubmit="alert('送信成功!'); return false;" class="hadv3-form">
<div class="hadv3-box">
<div class="hadv3-label">必須チェック(required)</div>
<select class="hadv3-select" required>
<option value="" hidden disabled selected>選択してください</option>
<option value="yes">同意する</option>
</select>
<p class="hadv3-note">※「選択してください」のまま送信ボタンを押すとエラーになります。</p>
</div>
<div class="hadv3-box">
<div class="hadv3-label" style="color:#6c757d;">完全無効化・非活性(disabled)</div>
<select class="hadv3-select hadv3-disabled" disabled>
<option value="premium" selected>プレミアムプラン</option>
</select>
<p class="hadv3-note">※クリックすらできません。また、送信時に「プレミアムプラン」というデータは送られず消滅します。</p>
</div>
<div class="hadv3-box">
<div class="hadv3-label" style="color:#d63384;">✨ 「読み取り専用」再現</div>
<select class="hadv3-select hadv3-readonly">
<option value="tokyo" selected>東京都</option>
</select>
<div class="hadv3-code">
/* selectにreadonlyは効かないのでCSSで防御 */<br>
.readonly {<br>
<span class="hadv3-hl-pink">pointer-events: none;</span><br>
background-color: #e9ecef;<br>
}
</div>
<p class="hadv3-note">※マウスクリックを無効化しつつ、データはちゃんと送信される「読み取り専用」の状態を完璧に作れます。</p>
</div>
<div class="hadv3-submit-area">
<button type="submit" class="hadv3-btn">チェックして送信する</button>
</div>
</form>
</div>
</div>CSSコード表示
.hadv3-wrapper {
background-color: #f8f9fa;
padding: 20px;
border: 1px solid #dee2e6;
border-radius: 4px;
font-family: sans-serif;
}
.hadv3-demo-area {
display: flex;
justify-content: center;
}
.hadv3-form {
width: 100%;
max-width: 450px;
display: flex;
flex-direction: column;
gap: 20px;
}
.hadv3-box {
background-color: #ffffff;
border: 2px dashed #adb5bd;
padding: 15px;
border-radius: 4px;
}
.hadv3-label {
font-size: 14px;
font-weight: bold;
color: #333;
margin-bottom: 10px;
}
.hadv3-select {
width: 100%;
padding: 10px;
font-size: 15px;
border: 1px solid #ccc;
border-radius: 4px;
box-sizing: border-box;
}
/* disabledの標準的な見た目 */
.hadv3-disabled {
background-color: #e9ecef;
color: #adb5bd;
cursor: not-allowed;
}
/* ★実務の「読み取り専用」の再現スタイル */
.hadv3-readonly {
background-color: #f8d7da; /* 分かりやすく色をつけています */
border-color: #f5c2c7;
color: #842029;
font-weight: bold;
/* マウスクリックなどの操作を一切受け付けなくする */
pointer-events: none;
}
.hadv3-code {
background-color: #282c34;
color: #abb2bf;
padding: 12px;
font-family: monospace;
font-size: 13px;
border-radius: 4px;
margin-top: 10px;
border-left: 4px solid #d63384;
}
.hadv3-hl-pink {
color: #e06c75;
font-weight: bold;
}
.hadv3-note {
font-size: 12px;
color: #666;
margin-top: 10px;
line-height: 1.5;
}
.hadv3-submit-area {
text-align: center;
}
.hadv3-btn {
background-color: #0d6efd;
color: white;
border: none;
padding: 12px 30px;
font-size: 16px;
font-weight: bold;
border-radius: 30px;
cursor: pointer;
transition: 0.2s;
width: 100%;
}
.hadv3-btn:hover {
background-color: #0b5ed7;
}JavaScriptで実装する動的なプルダウン
ユーザーの選択に応じて計算を行ったり、選ばれた項目に合わせて別のメニューを変化させるには、JavaScriptによる動的な制御が必須となります。
ここでは、「値の取得」「ページ遷移」「連動(絞り込み)」という3つの実践的なJavaScript連携について解説します。
- 選択された値を取得する
onchangeイベントでリンク遷移・ページ切り替え- 2段階の連動プルダウン(カテゴリ・条件分岐)
選択された値を取得する
JavaScriptとプルダウンを連携させると、「ユーザーがどれを選んでいるのか」という情報を取得できます。
やり方はシンプルで、対象の<select>要素をJavaScriptで取得し、valueプロパティにアクセスするだけです。
const selectBox = document.getElementById(‘hpull-js1-color’);
// 2. select要素の value を読み取るだけ!
const selectedValue = selectBox.value;
※「情熱のレッド」という日本語ではなく、裏側の「red」というデータが取得できている点に注目してください。
HTMLコード表示
<div class="hpull-js1-wrapper">
<div class="hpull-js1-demo-area">
<div class="hpull-js1-box">
<div class="hpull-js1-label">ご希望のカラーを選択してください</div>
<select id="hpull-js1-color" class="hpull-js1-select">
<option value="red">情熱のレッド</option>
<option value="blue">クールなブルー</option>
<option value="green">癒やしのグリーン</option>
</select>
<button type="button" class="hpull-js1-btn" onclick="getColorValue()">値を取得する</button>
<div class="hpull-js1-result-area">
取得したvalue値: <span id="hpull-js1-result" class="hpull-js1-result-text">---</span>
</div>
<div class="hpull-js1-code">
// 1. select要素を取得<br>
const selectBox = document.getElementById('hpull-js1-color');<br><br>
// 2. select要素の value を読み取るだけ!<br>
const selectedValue = <span class="hpull-js1-hl-green">selectBox.value</span>;
</div>
<p class="hpull-js1-note">※「情熱のレッド」という日本語ではなく、裏側の「red」というデータが取得できている点に注目してください。</p>
</div>
</div>
</div>CSSコード表示
.hpull-js1-wrapper {
background-color: #f8f9fa;
padding: 20px;
border: 1px solid #dee2e6;
border-radius: 4px;
font-family: sans-serif;
}
.hpull-js1-demo-area {
display: flex;
justify-content: center;
}
.hpull-js1-box {
background-color: #ffffff;
border: 2px dashed #adb5bd;
padding: 25px;
width: 100%;
max-width: 400px;
border-radius: 4px;
}
.hpull-js1-label {
font-size: 15px;
font-weight: bold;
color: #333;
margin-bottom: 15px;
}
.hpull-js1-select {
width: 100%;
padding: 12px;
font-size: 16px;
border: 2px solid #ccc;
border-radius: 4px;
margin-bottom: 15px;
cursor: pointer;
}
.hpull-js1-btn {
width: 100%;
padding: 12px;
font-size: 16px;
font-weight: bold;
color: white;
background-color: #198754;
border: none;
border-radius: 4px;
cursor: pointer;
margin-bottom: 15px;
transition: 0.2s;
}
.hpull-js1-btn:hover { background-color: #146c43; }
.hpull-js1-result-area {
background-color: #e7f1ff;
padding: 15px;
border: 1px solid #0d6efd;
border-radius: 4px;
font-size: 14px;
font-weight: bold;
color: #333;
text-align: center;
}
.hpull-js1-result-text {
font-size: 20px;
color: #dc3545;
font-family: monospace;
margin-left: 10px;
}
.hpull-js1-code {
background-color: #282c34;
color: #abb2bf;
padding: 15px;
font-family: monospace;
font-size: 13px;
border-radius: 4px;
line-height: 1.6;
margin-top: 15px;
}
.hpull-js1-hl-green {
color: #98c379;
font-weight: bold;
}
.hpull-js1-note {
font-size: 13px;
color: #666;
margin-top: 15px;
line-height: 1.5;
}JavaScriptコード表示
function getColorValue() {
const selectBox = document.getElementById('hpull-js1-color');
const resultText = document.getElementById('hpull-js1-result');
// select自身のvalueを取得
resultText.textContent = selectBox.value;
}onchangeイベントでリンク遷移・ページ切り替え
「よくある質問」のカテゴリ一覧や「関連サイトへのリンク集」などで、プルダウンの項目を選んだ瞬間にそのページへ飛ぶというUIは一般的です。
実現するには、プルダウンの選択が切り替わったことを検知するonchangeイベントを使用し、JavaScriptのwindow.location.hrefでページ切り替えを行います。
別タブで開きたい場合はwindow.open()を使用します。
<option value=”URL…”>リンク</option>
</select>
function jump(select) {
const url = select.value;
if (url) {
/* 画面を遷移させる処理 */
window.location.href = url;
}
}
HTMLコード表示
<div class="hpull-js2-wrapper">
<div class="hpull-js2-demo-area">
<div class="hpull-js2-box">
<div class="hpull-js2-label">🔗 関連サービスへジャンプ</div>
<select class="hpull-js2-select" onchange="jumpToPage(this)">
<option value="">▼ 選択して移動 ▼</option>
<option value="https://example.com/shop">公式オンラインショップへ</option>
<option value="https://example.com/support">お客様サポートへ</option>
<option value="https://example.com/blog" data-target="_blank">スタッフブログ(別タブ)</option>
</select>
<div class="hpull-js2-code">
<select <span class="hpull-js2-hl-blue">onchange="jump(this)"</span>><br>
<option value="URL...">リンク</option><br>
</select><br><br>
function jump(select) {<br>
const url = select.value;<br>
if (url) {<br>
/* 画面を遷移させる処理 */<br>
<span class="hpull-js2-hl-green">window.location.href = url;</span><br>
}<br>
}
</div>
</div>
</div>
</div>CSSコード表示
.hpull-js2-wrapper {
background-color: #f8f9fa;
padding: 20px;
border: 1px solid #dee2e6;
border-radius: 4px;
font-family: sans-serif;
}
.hpull-js2-demo-area {
display: flex;
justify-content: center;
}
.hpull-js2-box {
background-color: #ffffff;
border: 2px dashed #adb5bd;
padding: 25px;
width: 100%;
max-width: 400px;
border-radius: 4px;
}
.hpull-js2-label {
font-size: 15px;
font-weight: bold;
color: #0d6efd;
margin-bottom: 15px;
}
.hpull-js2-select {
width: 100%;
padding: 12px;
font-size: 16px;
border: 2px solid #0d6efd;
border-radius: 4px;
background-color: #f8f9fa;
cursor: pointer;
}
.hpull-js2-code {
background-color: #282c34;
color: #abb2bf;
padding: 15px;
font-family: monospace;
font-size: 13px;
border-radius: 4px;
line-height: 1.6;
margin-top: 15px;
border-left: 4px solid #0d6efd;
}
.hpull-js2-hl-blue { color: #61afef; font-weight: bold; }
.hpull-js2-hl-green { color: #98c379; font-weight: bold; }JavaScriptコード表示
function jumpToPage(selectObj) {
const url = selectObj.value;
// 「▼選択して移動▼」など、空のvalueを選んだ時は何もしない(重要)
if (!url) return;
// 選択されたoption要素を取得し、別タブ用フラグ(data-target)があるか確認
const selectedOption = selectObj.options[selectObj.selectedIndex];
const target = selectedOption.getAttribute('data-target');
if (target === '_blank') {
// 別ウィンドウ・別タブで開く
alert('シミュレーション:別タブで開きます\nwindow.open("' + url + '", "_blank");');
// 実際の実装: window.open(url, '_blank');
} else {
// 同じ画面で遷移する
alert('シミュレーション:同じ画面で遷移します\nwindow.location.href = "' + url + '";');
// 実際の実装: window.location.href = url;
}
// 遷移後(アラート後)にプルダウンを未選択状態に戻しておく(おもてなしの実装)
selectObj.selectedIndex = 0;
}2段階の連動プルダウン(カテゴリ・条件分岐)
例えば、「都道府県」を選ぶと、次のプルダウンにその県の「市区町村」が表示されるものがあったとします。
または、「問い合わせ種別」によって「表示される入力項目」が変わるものでもよいです。
このような、1つ目の選択に合わせて2つ目の内容が変化する機能を「2段階の連動プルダウン」と呼びます。
仕組みとしては、1つ目のプルダウンのchangeイベントを検知し、2つ目のプルダウンの中身(<option>タグ)をJavaScriptで生成して差し替えるという処理を行います。
subSelect.innerHTML = ”;
// 選ばれたカテゴリに応じて選択肢を追加
if (category === ‘fruit’) {
addOption(subSelect, ‘apple’, ‘りんご’);
}
HTMLコード表示
<div class="hpull-js3-wrapper">
<div class="hpull-js3-demo-area">
<div class="hpull-js3-box">
<div class="hpull-js3-label">カテゴリを選択してください</div>
<select id="hpull-js3-category" class="hpull-js3-select" onchange="updateSubCategory()">
<option value="">▼ 大分類を選択</option>
<option value="fruit">果物</option>
<option value="vehicle">乗り物</option>
</select>
<select id="hpull-js3-sub" class="hpull-js3-select" disabled onchange="checkOther()">
<option value="">大分類を先に選んでください</option>
</select>
<div id="hpull-js3-other-area" style="display: none;">
<input type="text" class="hpull-js3-textbox" placeholder="詳細をご記入ください">
</div>
<div class="hpull-js3-code">
// ★超重要:追加する前に中身を掃除する<br>
<span class="hpull-js3-hl-pink">subSelect.innerHTML = '';</span><br><br>
// 選ばれたカテゴリに応じて選択肢を追加<br>
if (category === 'fruit') {<br>
addOption(subSelect, 'apple', 'りんご');<br>
}
</div>
</div>
</div>
</div>CSSコード表示
.hpull-js3-wrapper {
background-color: #f8f9fa;
padding: 20px;
border: 1px solid #dee2e6;
border-radius: 4px;
font-family: sans-serif;
}
.hpull-js3-demo-area {
display: flex;
justify-content: center;
}
.hpull-js3-box {
background-color: #ffffff;
border: 2px dashed #adb5bd;
padding: 25px;
width: 100%;
max-width: 450px;
border-radius: 4px;
}
.hpull-js3-label {
font-size: 15px;
font-weight: bold;
color: #d63384;
margin-bottom: 15px;
}
.hpull-js3-select {
width: 100%;
padding: 10px;
font-size: 15px;
border: 2px solid #ccc;
border-radius: 4px;
margin-bottom: 15px;
cursor: pointer;
}
.hpull-js3-select:disabled {
background-color: #e9ecef;
cursor: not-allowed;
}
.hpull-js3-textbox {
width: 100%;
padding: 10px;
font-size: 14px;
border: 2px solid #d63384;
border-radius: 4px;
box-sizing: border-box;
background-color: #fff0f6;
}
.hpull-js3-code {
background-color: #282c34;
color: #abb2bf;
padding: 15px;
font-family: monospace;
font-size: 13px;
border-radius: 4px;
line-height: 1.6;
margin-top: 10px;
border-left: 4px solid #d63384;
}
.hpull-js3-hl-pink {
color: #e06c75;
font-weight: bold;
}JavaScriptコード表示
// 裏側で持っておく小分類のデータ(オブジェクト)
const subCategoryData = {
fruit: [
{ value: 'apple', text: 'りんご' },
{ value: 'banana', text: 'ばなな' },
{ value: 'other', text: 'その他(手入力)' }
],
vehicle: [
{ value: 'car', text: '自動車' },
{ value: 'train', text: '電車' },
{ value: 'other', text: 'その他(手入力)' }
]
};
// 1つ目のプルダウンが変更された時の処理
function updateSubCategory() {
const catSelect = document.getElementById('hpull-js3-category');
const subSelect = document.getElementById('hpull-js3-sub');
const otherArea = document.getElementById('hpull-js3-other-area');
const selectedCategory = catSelect.value;
// ★必須処理:2つ目のプルダウンを一旦空にする(無限増殖バグの防止)
subSelect.innerHTML = '';
// その他の入力欄も一旦隠す
otherArea.style.display = 'none';
if (selectedCategory === '') {
// 未選択に戻された場合
subSelect.disabled = true;
const defaultOption = document.createElement('option');
defaultOption.text = '大分類を先に選んでください';
subSelect.appendChild(defaultOption);
} else {
// 分類が選ばれた場合
subSelect.disabled = false;
// 最初のお願いテキストを追加
const defaultOption = document.createElement('option');
defaultOption.value = '';
defaultOption.text = '▼ 小分類を選択';
subSelect.appendChild(defaultOption);
// データに基づいてoptionタグを生成して追加
const items = subCategoryData[selectedCategory];
items.forEach(function(item) {
const option = document.createElement('option');
option.value = item.value;
option.text = item.text;
subSelect.appendChild(option);
});
}
}
// 2つ目のプルダウンが変更された時、「その他」ならテキストボックスを出す処理
function checkOther() {
const subSelect = document.getElementById('hpull-js3-sub');
const otherArea = document.getElementById('hpull-js3-other-area');
if (subSelect.value === 'other') {
otherArea.style.display = 'block'; // その他なら表示
} else {
otherArea.style.display = 'none'; // 違えば非表示
}
}プルダウンのケース別実装サンプル集
実務の現場でそのままコピー&ペーストして使えるプルダウンメニューをケース別にご用意しました。
- 日付の選択(年月日・生年月日・月・時間)
- 都道府県や数量(数字)の選択
- メニューバーや横並びレイアウトでの配置
日付の選択(年月日・生年月日・月・時間)
会員登録フォームにおける生年月日や予約サイトの日付・月・時間帯の選択は、プルダウンがよく使われるケースです。
「年・月・日」を横並びにして実装します。
※実務では、「年」や「月」を変えた時に、JavaScriptで「日」の選択肢を再計算して書き換える連動処理(またはinput type=”date”の利用)が必須になります。
HTMLコード表示
<div class="hcase1-wrapper">
<div class="hcase1-demo-area">
<div class="hcase1-box">
<div class="hcase1-label">🎂 生年月日の入力(年・月・日)</div>
<div class="hcase1-flex-row">
<div class="hcase1-select-wrap">
<select class="hcase1-select">
<option value="" hidden disabled selected>----</option>
<option value="1990">1990</option>
<option value="1991">1991</option>
<option value="1992">1992</option>
</select>
<span class="hcase1-unit">年</span>
</div>
<div class="hcase1-select-wrap">
<select class="hcase1-select">
<option value="" hidden disabled selected>--</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<span class="hcase1-unit">月</span>
</div>
<div class="hcase1-select-wrap">
<select class="hcase1-select">
<option value="" hidden disabled selected>--</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<span class="hcase1-unit">日</span>
</div>
</div>
<p class="hcase1-note">※実務では、「年」や「月」を変えた時に、JavaScriptで「日」の選択肢を再計算して書き換える連動処理(またはinput type="date"の利用)が必須になります。</p>
</div>
<div class="hcase1-box">
<div class="hcase1-label" style="color:#0d6efd;">⏰ 予約時間の選択</div>
<div class="hcase1-select-wrap">
<select class="hcase1-select" style="width: 150px;">
<option value="" hidden disabled selected>希望時間</option>
<option value="10:00">10:00 〜 11:00</option>
<option value="11:00">11:00 〜 12:00</option>
<option value="13:00">13:00 〜 14:00</option>
</select>
</div>
</div>
</div>
</div>CSSコード表示
.hcase1-wrapper {
background-color: #f8f9fa;
padding: 20px;
border: 1px solid #dee2e6;
border-radius: 4px;
font-family: sans-serif;
}
.hcase1-demo-area {
display: flex;
flex-direction: column;
gap: 20px;
align-items: center;
}
.hcase1-box {
background-color: #ffffff;
border: 2px dashed #adb5bd;
padding: 20px;
width: 100%;
max-width: 450px;
border-radius: 4px;
}
.hcase1-label {
font-size: 15px;
font-weight: bold;
color: #333;
margin-bottom: 15px;
border-bottom: 2px solid #eee;
padding-bottom: 5px;
}
/* 年月日を横並びにするFlexboxレイアウト */
.hcase1-flex-row {
display: flex;
align-items: center;
gap: 15px;
flex-wrap: wrap; /* スマホで潰れないように折り返す */
}
/* セレクトボックスと単位(年・月・日)をセットで扱う枠 */
.hcase1-select-wrap {
display: flex;
align-items: center;
gap: 5px;
}
.hcase1-select {
padding: 8px 10px;
font-size: 16px;
border: 2px solid #ccc;
border-radius: 4px;
background-color: #fff;
cursor: pointer;
}
.hcase1-select:focus {
outline: none;
border-color: #0d6efd;
}
.hcase1-unit {
font-size: 14px;
font-weight: bold;
color: #555;
}
.hcase1-note {
font-size: 13px;
color: #dc3545;
margin-top: 15px;
line-height: 1.5;
}都道府県や数量(数字)の選択
ECサイトにおける商品の個数や住所入力での都道府県は、選択肢が固定されているためプルダウンに適した項目です。
※「東京都」という文字列ではなく、全国共通の「13」というコード値を送信するのが本格的なシステム設計の基本です。
※数量のように「上限(在庫数など)があるもの」を自由に手入力させるとバグの元になるため、プルダウンが最適です。
HTMLコード表示
<div class="hcase2-wrapper">
<div class="hcase2-demo-area">
<div class="hcase2-box">
<div class="hcase2-label">🗾 都道府県(JISコード管理)</div>
<select class="hcase2-select" onchange="showPrefCode(this)">
<option value="" hidden disabled selected>都道府県を選択</option>
<option value="01">北海道</option>
<option value="13">東京都</option>
<option value="27">大阪府</option>
<option value="40">福岡県</option>
</select>
<div class="hcase2-result">
裏側で送信されるシステム値: <span id="hcase2-pref-result" class="hcase2-result-text">---</span>
</div>
<p class="hcase2-note">※「東京都」という文字列ではなく、全国共通の「13」というコード値を送信するのが本格的なシステム設計の基本です。</p>
</div>
<div class="hcase2-box">
<div class="hcase2-label" style="color:#d63384;">🛒 数量の選択</div>
<div class="hcase2-flex-row">
<span>購入数:</span>
<select class="hcase2-select hcase2-qty">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
</select>
<span>個</span>
</div>
<p class="hcase2-note">※数量のように「上限(在庫数など)があるもの」を自由に手入力させるとバグの元になるため、プルダウンが最適です。</p>
</div>
</div>
</div>CSSコード表示
.hcase2-wrapper {
background-color: #f8f9fa;
padding: 20px;
border: 1px solid #dee2e6;
border-radius: 4px;
font-family: sans-serif;
}
.hcase2-demo-area {
display: flex;
flex-direction: column;
gap: 20px;
align-items: center;
}
.hcase2-box {
background-color: #ffffff;
border: 2px dashed #adb5bd;
padding: 20px;
width: 100%;
max-width: 400px;
border-radius: 4px;
}
.hcase2-label {
font-size: 15px;
font-weight: bold;
color: #333;
margin-bottom: 10px;
}
.hcase2-select {
width: 100%;
padding: 10px;
font-size: 16px;
border: 2px solid #ccc;
border-radius: 4px;
box-sizing: border-box;
margin-bottom: 10px;
}
.hcase2-qty {
width: 80px; /* 数量なので幅を狭くする */
margin-bottom: 0;
text-align-last: center; /* 数字を中央に寄せる */
}
.hcase2-flex-row {
display: flex;
align-items: center;
gap: 10px;
font-weight: bold;
}
.hcase2-result {
background-color: #f1f3f5;
padding: 10px;
font-size: 13px;
border-radius: 4px;
color: #555;
margin-top: 10px;
}
.hcase2-result-text {
font-weight: bold;
font-size: 16px;
color: #d63384;
}
.hcase2-note {
font-size: 12px;
color: #666;
margin-top: 10px;
line-height: 1.5;
}JavaScriptコード表示
function showPrefCode(selectObj) {
document.getElementById('hcase2-pref-result').textContent = selectObj.value;
}メニューバーや横並びレイアウトでの配置
Webサイトの上部にある「サービス」にマウスを乗せるとサブメニューが下に開くナビゲーションメニューがあることがあります。
「下に開くメニューだからプルダウンを使おう。」と考えてしまうのは、非常によくある間違いです。
<select>タグはあくまで「フォームでデータを送信する部品」であり、サイト内を移動するリンク集に使うのは、HTMLの文法的に間違っています。
検索エンジンからもリンクとして認識されづらく、SEOに悪影響を及ぼします。
ヘッダーのドロップダウンメニューは、<ul>と<li>を使い、CSSの:hoverを利用して隠していたサブリストを表示するという手法で作ります。
また、システム管理画面などで、テーブルの中で複数のプルダウンを横並びに配置する場合は、レイアウト崩れを防ぐためにテーブルのセルに収める技術が必要です。
※マウスを「サービス ▼」に乗せてみてください。selectタグは一切使わず、リストタグとCSS(:hover)だけで実装するのがSEO上も正しい作り方です。
| 検索条件: |
|
|---|
HTMLコード表示
<div class="hcase3-wrapper">
<div class="hcase3-demo-area">
<div class="hcase3-box" style="z-index: 10;">
<div class="hcase3-label">🧭 ナビゲーション(ヘッダーメニュー)の正解</div>
<nav class="hcase3-nav">
<ul class="hcase3-menu-list">
<li class="hcase3-menu-item"><a href="#">ホーム</a></li>
<li class="hcase3-menu-item hcase3-has-dropdown">
<a href="#">サービス ▼</a>
<ul class="hcase3-submenu">
<li><a href="#">Web制作</a></li>
<li><a href="#">SEO対策</a></li>
<li><a href="#">コンサルティング</a></li>
</ul>
</li>
<li class="hcase3-menu-item"><a href="#">会社概要</a></li>
</ul>
</nav>
<p class="hcase3-note">※マウスを「サービス ▼」に乗せてみてください。selectタグは一切使わず、リストタグとCSS(:hover)だけで実装するのがSEO上も正しい作り方です。</p>
</div>
<div class="hcase3-box">
<div class="hcase3-label" style="color:#0d6efd;">📋 テーブル(table)内での横並び・複数列</div>
<table class="hcase3-table">
<tbody>
<tr>
<th>検索条件:</th>
<td>
<div class="hcase3-flex-wrap">
<select class="hcase3-small-select">
<option>すべて</option>
<option>公開中</option>
<option>非公開</option>
</select>
<select class="hcase3-small-select">
<option>新着順</option>
<option>古い順</option>
<option>価格順</option>
</select>
<button type="button" class="hcase3-btn">検索</button>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>CSSコード表示
.hcase3-wrapper {
background-color: #f8f9fa;
padding: 20px;
border: 1px solid #dee2e6;
border-radius: 4px;
font-family: sans-serif;
}
.hcase3-demo-area {
display: flex;
flex-direction: column;
gap: 40px; /* ドロップダウンが開く分の隙間を広めに取る */
align-items: center;
}
.hcase3-box {
background-color: #ffffff;
border: 2px dashed #adb5bd;
padding: 20px;
width: 100%;
max-width: 450px;
border-radius: 4px;
/* position:relativeを入れておかないと、サブメニューの基準位置がおかしくなる */
position: relative;
}
.hcase3-label {
font-size: 14px;
font-weight: bold;
color: #198754;
margin-bottom: 15px;
}
/* ============================
ナビゲーションのCSS
============================ */
.hcase3-nav {
background-color: #333;
border-radius: 4px;
}
.hcase3-menu-list {
display: flex;
list-style: none;
margin: 0;
padding: 0;
}
.hcase3-menu-item {
position: relative; /* サブメニューを絶対配置するための基準 */
}
.hcase3-menu-item > a {
display: block;
padding: 12px 20px;
color: #fff;
text-decoration: none;
font-size: 14px;
font-weight: bold;
}
.hcase3-menu-item:hover > a {
background-color: #555;
}
/* 隠しておくサブメニュー */
.hcase3-submenu {
display: none; /* 初期状態は非表示 */
position: absolute;
top: 100%;
left: 0;
width: 180px;
background-color: #fff;
list-style: none;
margin: 0;
padding: 0;
border: 1px solid #ccc;
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
border-radius: 0 0 4px 4px;
}
.hcase3-submenu li a {
display: block;
padding: 10px 15px;
color: #333;
text-decoration: none;
font-size: 13px;
border-bottom: 1px solid #eee;
}
.hcase3-submenu li a:hover {
background-color: #f1f3f5;
color: #198754;
}
/* ★親(.hcase3-has-dropdown)にマウスが乗ったら表示する */
.hcase3-has-dropdown:hover .hcase3-submenu {
display: block;
}
/* ============================
テーブルと横並びのCSS
============================ */
.hcase3-table {
width: 100%;
border-collapse: collapse;
font-size: 14px;
}
.hcase3-table th, .hcase3-table td {
border: 1px solid #ccc;
padding: 12px;
}
.hcase3-table th {
background-color: #f1f3f5;
white-space: nowrap; /* ヘッダーが折り返さないように */
text-align: right;
width: 30%;
}
.hcase3-flex-wrap {
display: flex;
align-items: center;
gap: 10px;
flex-wrap: wrap; /* 狭い画面では折り返す */
}
.hcase3-small-select {
padding: 6px 10px;
font-size: 14px;
border: 1px solid #ccc;
border-radius: 4px;
background-color: #fff;
}
.hcase3-btn {
padding: 6px 15px;
background-color: #0d6efd;
color: white;
border: none;
border-radius: 4px;
font-weight: bold;
cursor: pointer;
}
.hcase3-note {
font-size: 12px;
color: #666;
margin-top: 15px;
line-height: 1.5;
}まとめ
分かりやすいようにまとめを記載します。
- 基本構文
外枠を<select>、中の選択肢を<option>タグで作る。 - データの送信
画面表示用の文字とは別に、<option value="...">でシステムに送るデータを指定する。 - プレースホルダー
「選択してください」等の初期値は<option value="" hidden disabled selected>と設定し、再選択や空送信を防ぐ。 - CSS装飾(レイアウト)
幅100%にする際はbox-sizing: border-box;を併記し、高さはpaddingで調整してクリック領域を確保する。 - CSS装飾(矢印)
標準の矢印はappearance: none;で消去し、背景画像(background-image)としてオリジナルの矢印を配置する。 - リストボックス化
<select size="5">のようにsize属性を指定すると、最初から開いた状態のスクロール可能なリストになる。 - 複数選択(multiple)
標準のmultiple属性は操作性が悪いため、実務ではチェックボックスを使った疑似プルダウンをUIとして自作することが多い。 - 検索・手入力
文字入力による絞り込みや自由入力が必要な場合は、<select>ではなく<input type="text" list="...">と<datalist>を組み合わせる。 - 無効化の注意点
<select>タグにreadonlyは効かないため、disabledを使うか、CSSのpointer-events: none;で疑似的に再現する。 - JS連携(値の取得)
選択中の値は、個別のoptionを探すのではなく、親の<select>要素の.valueプロパティから直接取得する。 - JS連携(イベント)
項目変更時の処理は、<option>のclickではなく、<select>のchangeイベントで検知する。 - 日付の扱い
年月日を3つのプルダウンで作ると「2月31日」などが選べるバグが起きるため、現代では<input type="date">の使用が推奨される。 - ナビゲーション利用のNG
ヘッダーなどのドロップダウンメニューに<select>タグを使用するのは文法・SEO的にNGであり、<ul><li>とCSSのホバーで実装する。
よくある質問(FAQ)
HTMLで基本的なプルダウン(セレクトボックス)を作るには?
<select>タグと<option>タグを組み合わせて作ります。
<select>で全体の枠組みを作り、その中に複数の<option>で選択肢を並べます。
システム側にデータを送るために、画面に表示するテキストだけでなく、<option value="送信されるデータ">表示テキスト</option>のようにvalue属性をセットで記述するのがよいです。
最初から「選択してください」と表示させておくには?
一番上の<option>タグに selected 属性を付けます。
ただし、「選択してください」という文字自体が誤って送信されるのを防ぐため、実務では<option value="" hidden disabled selected>選択してください</option>と記述します。
これにより、初期表示はされますが、一度リストを開くと選択肢から消え、空のまま送信しようとするとエラーにできるプレースホルダーになります。
プルダウンの右側にある矢印(▼)のデザインをCSSで変えられますか?
はい、可能です。
ただし、ブラウザ標準の矢印はCSSで直接色を変えることができません。
デザインを変更するには、CSSでappearance: none;(標準デザインのリセット)を指定して既存の矢印を消し去ります。
その後、background-imageプロパティを使って、オリジナルの矢印画像(SVGなど)を背景として右端に配置するのが標準的な手法です。
ユーザーが選んだプルダウンの値をJavaScriptで取得するには?
対象の<select>要素を取得し、.valueプロパティを読み取るだけで取得できます。
わざわざ選ばれている<option>を探す必要はありません。
また、選択が変更された瞬間に値を取得して何か処理を行いたい場合は、<select>に対してchangeイベントを設定します。
選択肢から選ぶだけでなく、自由に文字も入力できるプルダウンは作れますか?
はい、作成可能です。(コンボボックスと呼ばれます。)
この場合は<select>タグは使わず、テキスト入力欄(<input type="text">)とデータリスト(<datalist>)を組み合わせて実装します。
<input list="リストのID">と<datalist id="リストのID">を紐付けることで、入力した文字による選択肢の絞り込みやリストにない文字の自由入力が可能になります。

