フェードイン・フェードアウトで開閉するセレクトボックスの作り方
フェードイン・フェードアウトで開閉するセレクトボックスの作り方を紹介します。このサンプルでは、HTML・CSS・JavaScriptを使用して、選択肢をフェードアニメーションで表示・非表示できるカスタムセレクトボックスを作成します。通常のselect要素とは異なり、メニューがゆっくりと表示・非表示になるため、自然で落ち着いた操作感を実現できます。
プロフィール編集画面やお問い合わせフォーム、設定画面、管理画面など、見た目にもこだわったフォームを作成したい場面で活用できます。項目をクリックすると選択肢がフェードインで表示され、選択後や外側をクリックするとフェードアウトで閉じます。表示・非表示の切り替えが滑らかなため、視認性が高く使いやすいUIになります。
タイトル、説明文、選択項目はHTMLから変更でき、CSSでは横幅、余白、色、角丸、影、フェード時間などを自由に調整できます。JavaScriptは開閉状態や選択処理を管理しており、レスポンシブにも対応しているため、スマートフォン・タブレット・PCで利用しやすいフェードアニメーション付きセレクトボックスとして活用できます。
コードについて
本記事のコードはサンプルコードです。ご利用前に必ず動作確認を行ってください。
免責事項
本コードの利用により発生した損害について、当サイトは一切の責任を負いません。
デモ
都道府県を選択
フェードアニメーション付きのセレクトボックスです。
ボタンをクリックすると選択肢がフェードインし、項目選択または外側クリックでフェードアウトします。
コードをコピーして使おう!
<!DOCTYPE html>
<html lang="ja">
<head>
<!-- 文字コード -->
<meta charset="UTF-8">
<!-- スマートフォン表示対応 -->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- ページタイトル -->
<title>フェードイン・フェードアウトで開閉するセレクトボックス</title>
<!-- CSSファイルを読み込み -->
<link rel="stylesheet" href="style.css">
</head>
<body>
<!-- セレクトボックス全体 -->
<div class="fade-select-box_demo">
<!-- タイトル -->
<div class="fade-select-box_demo_title">
都道府県を選択
</div>
<!-- 説明文 -->
<p class="fade-select-box_demo_text">
フェードアニメーション付きのセレクトボックスです。
</p>
<!-- 項目名 -->
<div class="fade-select-box_demo_label" id="fade-select-box-label">
都道府県
</div>
<!-- セレクトボックス -->
<div class="fade-select-box_demo_wrap">
<!-- 選択肢を開閉するボタン -->
<button
class="fade-select-box_demo_button"
id="fade-select-box-button"
type="button"
aria-expanded="false"
aria-haspopup="listbox"
aria-labelledby="fade-select-box-label fade-select-box-button">
選択してください
</button>
<!-- 選択肢一覧 -->
<div
class="fade-select-box_demo_menu"
id="fade-select-box-menu"
role="listbox">
<!-- 選択肢 -->
<button class="fade-select-box_demo_item" type="button" role="option">
北海道
</button>
<button class="fade-select-box_demo_item" type="button" role="option">
東京都
</button>
<button class="fade-select-box_demo_item" type="button" role="option">
大阪府
</button>
<button class="fade-select-box_demo_item" type="button" role="option">
福岡県
</button>
</div>
</div>
<!-- 操作説明 -->
<p class="fade-select-box_demo_note">
ボタンをクリックすると選択肢がフェードインし、項目選択または外側クリックでフェードアウトします。
</p>
</div>
<!-- JavaScriptファイルを読み込み -->
<script src="script.js"></script>
</body>
</html>
/* ページ全体 */
body{
margin:0; /* ブラウザ標準の外側余白をなくす */
padding:40px 20px; /* 上下40px・左右20pxの余白。値を大きくすると画面端との間隔が広がる */
background:#ffffff; /* ページ全体の背景色 */
color:#111827; /* ページ全体の基本文字色 */
font-family:sans-serif; /* ページ全体で使用するフォント */
}
/* セレクトボックス全体 */
.fade-select-box_demo{
width:100%; /* 画面幅に合わせて横幅を縮小する */
max-width:680px; /* 最大横幅。値を大きくすると全体が横へ広がる */
margin:40px auto; /* 上下40pxの余白を付けて左右中央へ配置する */
padding:36px; /* 内側余白。値を大きくすると内容と枠線の間隔が広がる */
border:1px solid #dbe5f1; /* 全体を囲む枠線 */
border-radius:18px; /* 全体の角丸。値を大きくすると丸みが強くなる */
background:#f8fafc; /* 全体の背景色 */
box-sizing:border-box; /* paddingとborderを横幅へ含める */
}
/* タイトル */
.fade-select-box_demo_title{
margin:0 0 12px; /* 下側12pxの余白。値を大きくすると説明文との間隔が広がる */
color:#111827; /* タイトルの文字色 */
font-size:30px; /* タイトルの文字サイズ。値を大きくすると文字が大きくなる */
font-weight:700; /* タイトルを太字にする */
text-align:center; /* タイトルを中央揃えにする */
}
/* 説明文 */
.fade-select-box_demo_text{
margin:0 0 28px; /* 下側28pxの余白。値を大きくすると選択欄との間隔が広がる */
color:#64748b; /* 説明文の文字色 */
line-height:1.8; /* 説明文の行間。値を大きくすると行間が広がる */
text-align:center; /* 説明文を中央揃えにする */
}
/* 項目名 */
.fade-select-box_demo_label{
display:block; /* 1行分の領域として表示する */
margin-bottom:10px; /* 下側10pxの余白。値を大きくするとボタンとの間隔が広がる */
color:#111827; /* 項目名の文字色 */
font-size:16px; /* 項目名の文字サイズ */
font-weight:700; /* 項目名を太字にする */
}
/* セレクトボックスの配置エリア */
.fade-select-box_demo_wrap{
position:relative; /* 選択肢一覧を配置する基準にする */
width:100%; /* 親要素の横幅いっぱいに表示する */
}
/* 選択肢を開閉するボタン */
.fade-select-box_demo_button{
display:flex; /* 文字と矢印を横並びにする */
align-items:center; /* 文字と矢印を縦中央へ揃える */
justify-content:space-between; /* 文字を左、矢印を右へ配置する */
width:100%; /* 横幅いっぱいに表示する */
min-height:56px; /* ボタンの最小高さ。値を大きくすると押せる範囲が高くなる */
padding:16px; /* 内側余白。値を大きくするとボタンが大きくなる */
border:2px solid #dbe5f1; /* 通常時の枠線 */
border-radius:12px; /* ボタンの角丸。値を大きくすると丸みが強くなる */
background:#ffffff; /* ボタンの背景色 */
color:#111827; /* ボタンの文字色 */
font:inherit; /* ページ全体と同じフォントを使用する */
font-size:16px; /* ボタンの文字サイズ */
line-height:1.5; /* ボタン文字の行間 */
text-align:left; /* ボタン文字を左揃えにする */
cursor:pointer; /* マウスカーソルを指型へ変更する */
box-sizing:border-box; /* paddingとborderを横幅へ含める */
}
/* ボタン右側の矢印 */
.fade-select-box_demo_button::after{
content:"▼"; /* 下向き矢印を表示する */
flex-shrink:0; /* 横幅が狭くても矢印を縮小させない */
margin-left:16px; /* 文字と矢印の間隔。値を大きくすると間隔が広がる */
font-size:12px; /* 矢印のサイズ */
}
/* 選択肢が開いているときの矢印 */
.fade-select-box_demo_button.is-open::after{
content:"▲"; /* 開いている状態では上向き矢印へ変更する */
}
/* ボタンへキーボードフォーカスが当たった状態 */
.fade-select-box_demo_button:focus-visible{
border-color:#2563eb; /* フォーカス時の枠線色 */
outline:3px solid rgba(37,99,235,.18); /* 外側の強調範囲。3pxを大きくすると強調が広がる */
outline-offset:2px; /* 枠線と強調表示の間隔 */
}
/* 選択肢一覧 */
.fade-select-box_demo_menu{
position:absolute; /* ボタンの下へ重ねて配置する */
top:calc(100% + 10px); /* ボタン下から10px離して配置する */
left:0; /* 左端をボタンへ揃える */
right:0; /* 右端をボタンへ揃える */
z-index:10; /* 他の要素より前面へ表示する */
padding:8px 0; /* 上下8pxの内側余白 */
border:1px solid #dbe5f1; /* 選択肢一覧の枠線 */
border-radius:12px; /* 選択肢一覧の角丸 */
background:#ffffff; /* 選択肢一覧の背景色 */
box-shadow:0 12px 28px rgba(15,23,42,.12); /* 選択肢一覧の影 */
opacity:0; /* 閉じた状態では完全に透明にする */
visibility:hidden; /* 閉じた状態では操作できないようにする */
transform:translateY(-10px); /* 閉じた状態では10px上へ移動させる */
pointer-events:none; /* 閉じた状態ではクリックを受け付けない */
/*
フェードイン・フェードアウトの時間です。
0.7秒かけて透明度と位置をゆっくり切り替えます。
値を大きくするとゆっくり、小さくすると速くなります。
*/
transition:
opacity .7s ease,
transform .7s ease,
visibility .7s ease;
}
/* 選択肢一覧を開いた状態 */
.fade-select-box_demo_menu.is-show{
opacity:1; /* 完全に表示する */
visibility:visible; /* 選択肢を操作できる状態にする */
transform:translateY(0); /* 本来の位置へ移動する */
pointer-events:auto; /* クリック操作を有効にする */
}
/* 各選択肢 */
.fade-select-box_demo_item{
display:block; /* 横幅いっぱいに表示する */
width:100%; /* 選択肢一覧の横幅いっぱいに広げる */
padding:14px 18px; /* 上下14px・左右18pxの内側余白 */
border:none; /* ブラウザ標準の枠線をなくす */
background:#ffffff; /* 通常時の背景色 */
color:#111827; /* 選択肢の文字色 */
font:inherit; /* ページ全体と同じフォントを使用する */
font-size:16px; /* 選択肢の文字サイズ */
line-height:1.5; /* 選択肢の行間 */
text-align:left; /* 選択肢を左揃えにする */
cursor:pointer; /* マウスカーソルを指型へ変更する */
}
/* 選択肢へマウスを重ねた状態 */
.fade-select-box_demo_item:hover{
background:#eff6ff; /* マウスを重ねた選択肢の背景色 */
}
/* 選択肢へキーボードフォーカスが当たった状態 */
.fade-select-box_demo_item:focus-visible{
background:#eff6ff; /* フォーカス中の背景色 */
outline:2px solid #2563eb; /* フォーカス位置を示す枠線 */
outline-offset:-2px; /* 枠線を選択肢の内側へ表示する */
}
/* 操作説明 */
.fade-select-box_demo_note{
margin:24px 0 0; /* 上側24pxの余白。値を大きくすると選択欄との間隔が広がる */
color:#64748b; /* 操作説明の文字色 */
line-height:1.8; /* 操作説明の行間 */
text-align:center; /* 操作説明を中央揃えにする */
}
/* 画面幅640px以下 */
@media(max-width:640px){
/* スマートフォン用のセレクトボックス全体 */
.fade-select-box_demo{
padding:24px 18px; /* 上下24px・左右18pxへ余白を縮小する */
}
/* スマートフォン用のタイトル */
.fade-select-box_demo_title{
font-size:24px; /* タイトルを24pxへ縮小する */
}
}
/* セレクトボックス全体を取得 */
const fadeSelectBox=document.querySelector(
".fade-select-box_demo_wrap"
);
/* 選択肢を開閉するボタンを取得 */
const fadeSelectButton=document.getElementById(
"fade-select-box-button"
);
/* 選択肢一覧を取得 */
const fadeSelectMenu=document.getElementById(
"fade-select-box-menu"
);
/* すべての選択肢を取得 */
const fadeSelectItems=document.querySelectorAll(
".fade-select-box_demo_item"
);
/* 選択肢一覧を開く */
function openFadeSelect(){
/* 選択肢一覧を表示する */
fadeSelectMenu.classList.add("is-show");
/* ボタンの矢印を開いた状態へ変更する */
fadeSelectButton.classList.add("is-open");
/* 開いていることを支援技術へ伝える */
fadeSelectButton.setAttribute(
"aria-expanded",
"true"
);
}
/* 選択肢一覧を閉じる */
function closeFadeSelect(){
/* 選択肢一覧を非表示にする */
fadeSelectMenu.classList.remove("is-show");
/* ボタンの矢印を閉じた状態へ戻す */
fadeSelectButton.classList.remove("is-open");
/* 閉じていることを支援技術へ伝える */
fadeSelectButton.setAttribute(
"aria-expanded",
"false"
);
}
/* 開閉ボタンをクリックしたとき */
fadeSelectButton.addEventListener("click",function(){
/* 現在の開閉状態を確認する */
const isOpen=fadeSelectMenu.classList.contains(
"is-show"
);
/* 開いている場合は閉じる */
if(isOpen){
closeFadeSelect();
/* 閉じている場合は開く */
}else{
openFadeSelect();
}
});
/* 各選択肢へクリック処理を設定 */
fadeSelectItems.forEach(function(item){
item.addEventListener("click",function(){
/* 選択した項目をボタンへ表示する */
fadeSelectButton.textContent=item.textContent.trim();
/* すべての選択状態を解除する */
fadeSelectItems.forEach(function(selectItem){
selectItem.setAttribute(
"aria-selected",
"false"
);
});
/* クリックした項目を選択状態にする */
item.setAttribute(
"aria-selected",
"true"
);
/* 選択後に一覧を閉じる */
closeFadeSelect();
});
});
/* セレクトボックスの外側をクリックしたとき */
document.addEventListener("click",function(event){
/* 外側をクリックした場合だけ一覧を閉じる */
if(!fadeSelectBox.contains(event.target)){
closeFadeSelect();
}
});
/* Escapeキーを押したとき */
document.addEventListener("keydown",function(event){
if(event.key==="Escape"){
/* 選択肢一覧を閉じる */
closeFadeSelect();
/* 開閉ボタンへフォーカスを戻す */
fadeSelectButton.focus();
}
});
コードをコピーする場合
使用するコードのタブを選び、「このタブをコピー」をクリックすると、現在表示中のコードをコピーできます。
サンプル一式を取得する場合
HTML・CSSなどすべてのファイルが必要な場合は、「サンプル一式をダウンロード」をクリックしてください。
ファイル構成と設置方法
このサンプルはHTML・CSS・JavaScriptの3ファイルで構成されています。HTMLではセレクトボックス全体の構造を作成し、CSSではデザインとフェードイン・フェードアウトのアニメーションを設定します。JavaScriptでは選択肢の開閉や項目の選択、外側クリックやEscapeキーで閉じる処理を行います。通常のselect要素では実現しにくい、ゆっくりとフェードする開閉アニメーションを取り入れたカスタムセレクトボックスです。
sample/
├── index.html
├── style.css
└── script.js
各ファイルの役割
index.htmlはセレクトボックス全体を構成するファイルです。タイトル、説明文、ラベル、ボタンの初期表示、選択肢の項目を編集できます。用途に合わせて選択肢を追加・削除したり、表示する文章を自由に変更できます。
style.cssはセレクトボックス全体のデザインを設定するファイルです。横幅、余白、背景色、枠線、角丸、文字サイズ、ホバー時の色、フェードイン・フェードアウトのアニメーション時間などを変更できます。
script.jsは開閉や選択処理を行うファイルです。ボタンをクリックしたときの表示・非表示、選択した項目名への変更、外側クリックやEscapeキーで閉じる処理を管理しています。
設置方法・使い方
sampleフォルダへindex.html、style.css、script.jsを配置します。3つのファイルを同じ階層へ保存したあと、sample/index.htmlをブラウザで開いてください。ボタンをクリックすると選択肢がフェードイン表示され、項目を選択するとボタンの表示内容が変更されます。また、選択後・外側クリック・Escapeキーでもフェードアウトしながら閉じます。
カスタマイズできる内容
index.htmlではタイトル、説明文、ラベル、ボタンの初期表示、選択肢の内容を自由に変更できます。選択肢はbutton要素を追加・削除するだけで簡単に増減できます。
style.cssでは全体の横幅、余白、背景色、文字色、枠線、角丸、ボタンサイズ、選択肢のホバー色、影、フェードイン・フェードアウトの速度を変更できます。
script.jsでは開閉方法や選択後の動作を変更できます。クリック時の処理や閉じるタイミングなども用途に合わせて調整できます。
数値調整
style.css
max-width:680px;
セレクトボックス全体の最大横幅です。値を大きくすると横に広がり、小さくするとコンパクトになります。
padding:36px;
全体の内側余白です。値を大きくすると余白が広がり、小さくすると詰まった表示になります。
border-radius:18px;
全体の角丸です。値を大きくすると丸みが強くなり、0にすると四角になります。
min-height:56px;
開閉ボタンの高さです。値を大きくするとボタンが高くなり、小さくするとコンパクトになります。
top:calc(100% + 10px);
ボタンと選択肢一覧の間隔です。10pxを大きくすると隙間が広がり、小さくすると近づきます。
transition: opacity .7s ease, transform .7s ease, visibility .7s ease;
フェードイン・フェードアウトの時間です。.7秒でゆっくり表示・非表示になります。値を大きくするとさらにゆっくり、小さくすると速く切り替わります。
レスポンシブ対応
このサンプルはレスポンシブ対応です。style.cssのwidth:100%とmax-width:680pxにより画面幅に応じて自動で縮小表示されます。また、640px以下ではpadding:24px 18px;とfont-size:24px;へ変更しているため、スマートフォン・タブレット・PCでも見やすく利用できます。
コメント