オートコンプリート Autocomplete
テキスト入力に応じて候補を表示し選択できるコンボボックス。
ライブデモ
ソースコード
<div class="demo-autocomplete">
<label class="demo-autocomplete-label" for="demo-ac-input">都道府県を検索</label>
<div class="demo-autocomplete-wrap">
<input class="demo-autocomplete-input" id="demo-ac-input" type="text" placeholder="入力して検索..." autocomplete="off" role="combobox" aria-expanded="false" aria-autocomplete="list" aria-controls="demo-ac-list" />
<ul class="demo-autocomplete-list" id="demo-ac-list" role="listbox"></ul>
</div>
</div>.demo-autocomplete { max-width: 320px; min-height: 350px; }
.demo-autocomplete-label { display: block; font-size: 13px; font-weight: 600; color: #333; margin-bottom: 6px; }
.demo-autocomplete-wrap { position: relative; }
.demo-autocomplete-input {
width: 100%; padding: 10px 12px; border: 2px solid #d1d5db; border-radius: 8px;
font-size: 14px; outline: none; transition: border-color 0.2s, box-shadow 0.2s;
box-sizing: border-box;
}
.demo-autocomplete-input:focus {
border-color: var(--ui-primary);
box-shadow: 0 0 0 3px color-mix(in srgb, var(--ui-primary) 20%, transparent);
}
.demo-autocomplete-list {
display: none; position: absolute; top: 100%; left: 0; right: 0;
margin: 4px 0 0; padding: 4px; list-style: none;
background: #fff; border: 1px solid #e5e7eb; border-radius: 8px;
box-shadow: 0 4px 12px rgba(0,0,0,0.1); max-height: 180px; overflow-y: auto; z-index: 10;
}
.demo-autocomplete-list.open { display: block; }
.demo-autocomplete-item {
padding: 8px 12px; border-radius: 6px; font-size: 13px; color: #333; cursor: pointer;
transition: background 0.15s;
}
.demo-autocomplete-item:hover,
.demo-autocomplete-item.active {
background: color-mix(in srgb, var(--ui-primary) 10%, transparent);
color: var(--ui-primary);
}
.demo-autocomplete-match { font-weight: 700; color: var(--ui-primary); }
.demo-autocomplete-empty { padding: 12px; text-align: center; font-size: 13px; color: #9ca3af; }(function(){
var items = ['北海道','青森県','岩手県','宮城県','秋田県','山形県','福島県','茨城県','栃木県','群馬県','埼玉県','千葉県','東京都','神奈川県','新潟県','富山県','石川県','福井県','山梨県','長野県','岐阜県','静岡県','愛知県','三重県','滋賀県','京都府','大阪府','兵庫県','奈良県','和歌山県','鳥取県','島根県','岡山県','広島県','山口県','徳島県','香川県','愛媛県','高知県','福岡県','佐賀県','長崎県','熊本県','大分県','宮崎県','鹿児島県','沖縄県'];
var input = document.querySelector('#demo-ac-input');
var list = document.querySelector('#demo-ac-list');
var activeIdx = -1;
function render(query) {
if (!query) { list.classList.remove('open'); input.setAttribute('aria-expanded','false'); return; }
var filtered = items.filter(function(s){ return s.indexOf(query) !== -1; });
if (filtered.length === 0) {
list.innerHTML = '<li class="demo-autocomplete-empty">候補なし</li>';
} else {
list.innerHTML = filtered.map(function(s){
var hl = s.replace(query, '<span class="demo-autocomplete-match">' + query + '</span>');
return '<li class="demo-autocomplete-item" role="option">' + hl + '</li>';
}).join('');
}
activeIdx = -1;
list.classList.add('open');
input.setAttribute('aria-expanded','true');
}
input.addEventListener('input', function(){ render(this.value); });
list.addEventListener('click', function(e){
var item = e.target.closest('.demo-autocomplete-item');
if (item) { input.value = item.textContent; list.classList.remove('open'); input.setAttribute('aria-expanded','false'); }
});
input.addEventListener('keydown', function(e){
var items = list.querySelectorAll('.demo-autocomplete-item');
if (!items.length) return;
if (e.key === 'ArrowDown') { e.preventDefault(); activeIdx = Math.min(activeIdx + 1, items.length - 1); }
else if (e.key === 'ArrowUp') { e.preventDefault(); activeIdx = Math.max(activeIdx - 1, 0); }
else if (e.key === 'Enter' && activeIdx >= 0) { e.preventDefault(); input.value = items[activeIdx].textContent; list.classList.remove('open'); return; }
else if (e.key === 'Escape') { list.classList.remove('open'); return; }
else return;
items.forEach(function(el){ el.classList.remove('active'); });
if (activeIdx >= 0) items[activeIdx].classList.add('active');
});
document.addEventListener('click', function(e){ if (!e.target.closest('.demo-autocomplete')) list.classList.remove('open'); });
})();AIプロンプト
Basic
オートコンプリート付き入力欄をHTML/CSS/JSで作ってください。文字入力に応じて候補リストが表示されます。
Custom
以下の仕様でオートコンプリートを実装してください。 - 入力に応じてリアルタイムで候補を絞り込み - マッチ部分をハイライト表示 - プライマリカラー: #2563eb - キーボード操作(上下矢印で候補移動、Enterで選択) - 候補がない場合「該当なし」を表示 - debounce処理(300ms) - 候補リストのスクロール対応
Advanced
WAI-ARIA Combobox パターン準拠のオートコンプリートを実装してください。 - role="combobox", aria-expanded, aria-autocomplete, aria-activedescendant - role="listbox" / role="option" による候補リスト - 上下矢印・Enter・Escキーの完全なキーボード操作 - スクリーンリーダーで選択中の候補を読み上げ - debounce + AbortController による非同期候補取得 - バーチャルスクロール(大量候補時のパフォーマンス対策) - モバイルでのタッチ操作最適化