![[CSS実践講座 #02]基本レイアウトを学ぶ (ゲームのサウンドテストUIを作成)](https://humanxai.info/images/uploads/css-course-02.webp)
はじめに
日々開発を続けているゲーム制作も佳境に入ってきました。
昨日は、オプション画面の作成途中、サウンドテスト機能を付けたらどうかと話したところ、 既に音楽データをJSONでリスト化していたのと、音楽再生の基本機能をaudio.jsとしてモジュール化するまで終わっていた為(再生、停止、カテゴリ分けまで実装)、 オプション画面にポップアップ画面を作成して雑ですが、全音楽リスト再生できるところまで完成。
今日は、サウンドテストUIを設計するにあたり、CSSの基本レイアウトを基礎から再学習しようと思い企画したCSS実践講座の2回目になります。
本講座の目的
- サウンドテスト用のUIを題材に、CSSレイアウトの基本設計を実践的に学習
- 実装の前段階として、パーツごとのCSS設計・調整ポイントを明確にする
- flexとgrid、スクロール処理、モーダル表示、レスポンシブ対応まで含めた現代的なUI構成を理解
1. Flexbox vs Grid の基本と使い分け
- flexで横並び/縦並び
- justify-content, align-items の整理
- gridで表形式や複数列リスト配置
1-1. Flexbox の特徴と使いどころ
.container {
display: flex;
lex-directfion: row; /* 横並び(columnにすれば縦) */
justify-content: center; /* 子要素の左右中央寄せ */
align-items: center; /* 子要素の上下中央寄せ */
flex-wrap: wrap; /* 折り返し可能に */
gap: 1rem; /* 子要素間のスペース */
}
- 横並び/縦並びが簡単に切り替えられる
- 中央寄せが容易
- 要素数が変化するコンテンツに強い
■ flex-direction
CSS のプロパティで、主軸の方向や向き(通常または逆方向)を定義することにより、フレックスコンテナー内でフレックスアイテムを配置する方法を設定します。
row |
---|
フレックスコンテナーの主軸は、書字方向と同じに定義されます。 main-start および main-end の位置は、コンテンツの書字方向と同様になります。 |
row-reverse |
---|
row と同様ですが、main-start および main-end の位置が入れ替わります。 |
column |
---|
フレックスコンテナーの主軸は、ブロック軸と同じになります。 main-start および main-end の位置は、 writing-mode における before および after の位置と同じになります。 |
column-reverse |
---|
column と同様ですが、 main-start および main-end の位置が入れ替わります。 |
(引用[MDN Web Docs]:flex-direction )
■ justify-content
justify-content プロパティは、フレックスコンテナーの主軸、グリッドおよび段組みコンテナーのインライン軸に沿って、中身のアイテムの間や周囲に間隔を配置する方法を定義します。
start |
---|
各アイテムは、主軸方向で配置コンテナーの先頭側の端に向けて互いに寄せて配置されます。 |
end |
---|
各アイテムは、主軸方向で配置コンテナーの末尾側の端に向けて互いに寄せて配置されます。 |
flex-start |
---|
各アイテムは、フレックスコンテナーの主軸の先頭側を基準に、配置コンテナーの端に向けて互いに寄せて配置されます。 これはフレックスレイアウトのアイテムのみに適用されます。 フレックスコンテナーの子ではないアイテムでは、この値は start のように扱われます。 |
flex-end |
---|
各アイテムは、フレックスコンテナーの主軸の末尾側を基準に、配置コンテナーの端に向けて互いに寄せて配置されます。 これはフレックスレイアウトのアイテムのみに適用されます。 フレックスコンテナーの子ではないアイテムでは、この値は end のように扱われます。 |
center |
---|
各アイテムは、主軸方向で配置コンテナーの中央に向けて互いに寄せて配置されます。 |
left |
---|
アイテムは配置コンテナーの左端に向かって同じ高さに詰められます。プロパティの水平軸がインライン軸と平行でない場合、例えば flex-direction: column; が設定されている場合、この値は start のように動作します。 |
right |
---|
アイテムは、適切な軸で配置コンテナーの右端に向かって、互いに同じ高さに詰められます。このプロパティの軸が(グリッドコンテナーの)インライン軸や(フレックスボックスコンテナーの)主軸と平行でない場合、この値は start のように動作します。 |
normal |
---|
stretch として動作します。ただし、column-width が auto でない段組みコンテナーの場合、段はコンテナーいっぱいに引き延ばされるのではなく、指定した column-width の幅を取ります。フレックスコンテナーでは stretch は start として動作するので、normal も start として動作します。 |
space-between |
---|
各アイテムは、配置コンテナーの中で主軸方向に均等に配置されます。隣接するアイテム同士の間隔は同じになります。最初のアイテムは主軸の先頭側に寄せられ、最後のアイテムは主軸の末尾側に寄せられます。 |
space-around |
---|
各アイテムは、配置コンテナーの中で主軸方向に均等に配置されます。隣接するアイテム同士の間隔は同じになります。最初のアイテムの前と最後のアイテムの後の余白は、隣接するアイテム同士の間隔の半分の幅になります。 |
space-evenly |
---|
各アイテムは、配置コンテナーの中で主軸方向に均等に配置されます。隣接するアイテム同士の間隔、最初のアイテムの前の余白、最後のアイテムの後の余白は、まったく同じ幅になります。 |
stretch |
---|
各アイテムの主軸に沿った寸法の合計が配置コンテナーの寸法よりも小さい場合、寸法が auto のアイテムは、 max-height/max-width (または同等の機能) での制約を尊重しつつ、 (比例的にではなく) 均等に引き伸ばされ、主軸方向の寸法の合計が配置コンテナーを満たすようになります。 |
safe |
---|
アイテムが配置コンテナーをあふれる場合、そのアイテムは配置モードが start であるかのように配置されます。指定した配置は行われません。 |
unsafe |
---|
アイテムが配置コンテナーをあふれる場合でも、指定した配置が実行されます。あふれ防止を優先して、希望する配置を行う safe とは異なります。 |
メモ: フレックスボックスでは、stretch の値は flex-start または start として動作します。そのため、伸縮は flex-grow プロパティを使用して制御します。
(引用[MDN Web Docs]:justify-content )

justify-content - CSS: カスケーディングスタイルシート | MDN
CSS の justify-content プロパティは、フレックスコンテナーの主軸、グリッドおよび段組みコンテナーのインライン軸に沿って、中身のアイテムの間や周囲に間隔を配置する方法を定義します。
https://developer.mozilla.org/ja/docs/Web/CSS/justify-content■ align-items
align-items プロパティは、すべての直接の子要素に集合として align-self の値を設定します。
フレックスボックスでは交差軸方向のアイテムの配置を制御します。
グリッドレイアウトでは、グリッド領域におけるアイテムのブロック軸方向の配置を制御します。
normal |
---|
このキーワードの効果は現在のレイアウトモードに依存します。 ・絶対位置指定レイアウトでは、このキーワードは置換絶対位置指定ボックスにおける start のように動作し、他のすべての絶対位置指定ボックスでは stretch として動作します。 ・絶対位置指定レイアウトの静的位置では、キーワードは stretch として動作します。 ・フレックスアイテムについては、このキーワードは stretch として動作します。 ・グリッドアイテムについては、このキーワードは stretch の一つと似た動作をしますが、ボックスにアスペクト比や内在的な寸法がある場合は、 start のように動作します。 ・このプロパティはブロックレベルボックスや、表のセルには適用されません。 |
center |
---|
フレックスアイテムのマージンボックスは、交差軸上の中央に配置されます。アイテムの交差軸のサイズがフレックスコンテナーより大きい場合は、両方向へ均等にはみ出します。 |
start |
---|
そのアイテムは、互いにその軸の配置コンテナーの先頭側の端に寄せられます。 |
end |
---|
そのアイテムは、互いにその軸の配置コンテナーの末尾側の端に寄せられます。 |
self-start |
---|
そのアイテムは、その軸の配置コンテナーで、そのアイテムの先頭側の端に寄せられます。 |
self-end |
---|
そのアイテムは、その軸の配置コンテナーで、そのアイテムの末尾側の端に寄せられます。 |
baseline, first baseline, last baseline |
---|
すべてのフレックスアイテムは、フレックスコンテナーのベースラインに沿って配置されます。交差軸の先頭側マージンの端とベースラインの間の距離が最大のアイテムが、行の交差軸の先頭側の端に寄せられます。 |
stretch |
---|
アイテムが配置コンテナーより小さい場合、自動サイズのアイテムは、アイテムの幅と高さの制限を尊重しながら、コンテナーを埋めるために均等に拡大されます。 |
anchor-center |
---|
アンカー位置指定要素の場合、関連付けられたアンカー要素のブロック方向の中心にアイテムを配置します。 anchor-center を使用してアンカーの中央に配置を参照してください。 |
safe |
---|
配置キーワードと共に使用します。選択されたキーワードによって、アイテムが配置コンテナーをあふれてデータの損失が発生する場合、アイテムは配置モードが start であったかのように配置されます。 |
unsafe |
---|
配置キーワードと共に使用します。アイテムの寸法と配置コンテナーとの関係、あふれることによってデータの損失が発生するかどうかにかかわらず、指定された値を尊重します。 また、フレックスボックスのために定義された 2 つの値があります。これらはフレックスモデルの軸の概念に基づいており、グリッドレイアウトでも同様に動作します。 |
flex-start |
---|
フレックスレイアウトでのみ用いられ、フレックスアイテムを、フレックスコンテナーの主軸の先頭側または交差軸の先頭側の端に寄せて配置します。 フレックス整形コンテキスト以外で使用する場合、この値は start として動作します。 |
flex-end |
---|
フレックスレイアウトでのみ用いられ、フレックスアイテムを、フレックスコンテナーの主軸の末尾側または交差軸の末尾側の端に寄せて配置します。 フレックス整形コンテキスト以外で使用する場合、この値は end として動作します。 |
(引用[MDN Web Docs]:align-items )

align-items - CSS: カスケーディングスタイルシート | MDN
CSS の align-items プロパティは、すべての直接の子要素に集合として align-self の値を設定します。フレックスボックスでは交差軸方向のアイテムの配置を制御します。グリッドレイアウトでは、グリッド領域におけるアイテムのブロック軸方向の配置を制御します。
https://developer.mozilla.org/ja/docs/Web/CSS/align-items■ flex-wrap
flex-wrap は、フレックスアイテムを単一行に押し込むか、あるいは複数行に折り返してもよいかを指定します。
折り返しを許可する場合は、行を積み重ねる方向の制御も可能です。
flex-wrap プロパティは以下の値のリストから選択した単一のキーワードで指定します。
nowrap |
---|
フレックスアイテムは単一行に配置され、フレックスコンテナーからはみ出すこともあります。交差軸の先頭は、 flex-direction の値に応じて、インラインの先頭またはブロックの先頭のどちらかと等しくなります。 |
wrap |
---|
フレックスアイテムは複数行に分割されます。交差軸の先頭は、現在の書字方向および flex-direction の値に応じて、インラインの先頭またはブロックの先頭のどちらかと等しくなります。 |
wrap-reverse |
---|
wrap と同様に動作しますが、交差軸の先頭と末尾が入れ替わります。 |
(引用[MDN Web Docs]:flex-wrap )
1-2. Grid の特徴と使いどころ
.grid-box {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
gap: 1rem;
}
- 複数列構成に強い
- 表のように整った配置に最適
グリッドレイアウトの基本概念
CSS グリッドレイアウトは、二次元グリッドシステムを CSS にもたらします。
グリッドは、主要なページ領域や小さなユーザーインターフェイス要素のレイアウトに利用できます。
引用(MDN Web Docs: https://developer.mozilla.org/ja/docs/Web/CSS/CSS_grid_layout/Basic_concepts_of_grid_layout)
グリッドとは何か?
グリッドは、列と行を定義する水平線と垂直線の集合が交差したものです。
要素をグリッド上の行と列の中に配置することができます。
CSS グリッドレイアウトには次のような特徴があります。
固定のトラックと可変のトラック
例えばピクセル単位を使って、固定トラックサイズのグリッドを作成することができます。これであるグリッドに好きなレイアウトに合うようなピクセルを設定できます。また、可変サイズのグリッドを作成するために、パーセントやこの目的で制定された fr 単位を使用することができます。
アイテムの配置
グリッドの線番号や名前を使って、グリッドのある位置を指定してアイテムを配置することができます。グリッドには、位置が明示されていないアイテムの配置を制御するアルゴリズムも含まれています。
内容物を保持するための追加トラックの作成 グリッドレイアウトでは、明確にグリッドを定義することができます。グリッドレイアウトの仕様では、必要に応じて柔軟に行や列を追加できるようになっています。「コンテナーに収まるだけ多く数の列」を追加するような機能もあります。
配置の制御
グリッドには配置機能が含まれており、あるグリッド領域内でアイテムがどのように配置されるのか、グリッド全体がどのように配置されるかを制御できます。
重複する内容物の制御
グリッドセルやグリッド領域内には複数のアイテムも配置でき、それらはお互いに部分的に重複できます。この階層は、 z-index プロパティで制御できます。
グリッドは強力な仕様であり、フレックスボックスなど CSS の他の部品と組み合わせると、以前は CSS での構築が不可能であったレイアウトを作成することができます。これはすべて、グリッドコンテナーにグリッドを作成することから始まります。
引用(MDN Web Docs: https://developer.mozilla.org/ja/docs/Web/CSS/CSS_grid_layout/Basic_concepts_of_grid_layout)
関連リンク

グリッドレイアウトの基本概念 - CSS: カスケーディングスタイルシート | MDN
CSS グリッドレイアウトは、二次元グリッドシステムを CSS にもたらします。グリッドは、主要なページ領域や小さなユーザーインターフェイス要素のレイアウトに利用できます。この記事では、 CSS グリッドレイアウトと、 CSS Grid Layout Level 1 仕様の一部の用語について紹介します。この記事では、その概要を紹介し、この一連のガイドの残りで詳細を説明します。
https://developer.mozilla.org/ja/docs/Web/CSS/CSS_grid_layout/Basic_concepts_of_grid_layout
CSS Grid Layout を極める!(基礎編) - Qiita
0. はじめに CSS Grid Layout(グリッドレイアウト)は、2次元レイアウト を、HTML/CSS を使って簡単・自由に操作できる、CSSの新しい機能です。 格子状のマス目のグリッドに好きな順番に配置したり結合したりすることで、様々なレイアウトが可能になります...
https://qiita.com/kura07/items/e633b35e33e43240d3632. スクロール領域の管理
.scroll-list {
max-height: 400px;
overflow-y: auto;
padding: 1rem;
}
- リストが長くなったときに、縦スクロールできる領域を確保
- モバイル環境でも扱いやすい
- overflow-y: auto / scroll
- max-height + flex-direction: column の組み合わせ
■ overflow-y
overflow-y は CSS のプロパティで、ブロックレベル要素のコンテンツが上下の端からあふれた時にどのように表示するかを設定します。これは表示なし、スクロールバー付き、コンテンツをはみ出させる、のいずれかになります。このプロパティは、overflow 一括指定プロパティを使用して設定することもできます。
overflow-y プロパティは、単一の overflow キーワード値で指定します。
overflow-x が hidden、scroll、auto のいずれかで、 overflow-y プロパティが visible (既定値)の場合、この値は暗黙的に auto として計算されます。
visible |
---|
あふれたコンテンツは切り取られず、この要素のパディングボックスの上下の端よりも外側に表示される可能性があります。この要素ボックスはスクロールコンテナーになりません。 |
hidden |
---|
要素のパディングボックスに垂直方向に合わせる必要がある場合は、コンテンツを切り取ります。スクロールバーは表示されません。 |
clip |
---|
あふれたコンテンツは、 overflow-clip-margin プロパティを使用して定義された要素のオーバーフロークリップ枠で切り取られます。その結果、コンテンツは要素のパディングボックスから overflow-clip-margin の値 |
scroll |
---|
あふれたコンテンツは、垂直方向にパディングボックスに合わせる必要がある場合に切り取られます。ブラウザーはコンテンツが実際に切り取られるかどうかにかかわらず、垂直方向のスクロールバーを表示します。 (これで、コンテンツが変化したときにスクロールバーが表示されたり非表示になったりすることを防ぎます。) プリンターはあふれたコンテンツを印刷するかもしれません。 |
auto |
---|
あふれたコンテンツは要素のパディングボックスで切り取られ、あふれたコンテンツはビュー内にスクロールすることができます。 scroll とは異なり、ユーザーエージェントはコンテンツがあふれた場合のみスクロールバーを表示し、既定では、スクロールバーを非表示にします。コンテンツが要素のパディングボックス内に収まる場合、 visible と同じように見えますが、新しいブロック整形コンテキストを確立します。 |
引用(MDN Web Docs: https://developer.mozilla.org/ja/docs/Web/CSS/overflow-y)

overflow-y - CSS: カスケーディングスタイルシート | MDN
overflow-y は CSS のプロパティで、ブロックレベル要素のコンテンツが上下の端からあふれた時にどのように表示するかを設定します。これは表示なし、スクロールバー付き、コンテンツをはみ出させる、のいずれかになります。このプロパティは、overflow 一括指定プロパティを使用して設定することもできます。
https://developer.mozilla.org/ja/docs/Web/CSS/overflow-y3. カードUIの配置と調整
.card-list {
display: flex;
flex-wrap: wrap;
gap: 1rem;
justify-content: center;
}
.card {
width: 220px;
background: #f0f0f0;
border-radius: 8px;
padding: 1rem;
box-shadow: 0 2px 6px rgba(0,0,0,0.1);
}
- ユーザーが情報を視覚的に把握しやすい
- レスポンシブにも強く、見た目が整う
- .card { display: flex; flex-direction: column; gap: 1rem }
- カード数が多い場合の折り返し・ラップ
4. モーダル表示の基本構造
.modal {
position: fixed;
display: flex;
justify-content: center;
align-items: center;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0,0,0,0.5);
z-index: 1000;
}
.modal-content {
background: white;
padding: 2rem;
border-radius: 12px;
max-width: 600px;
width: 90%;
}
- モーダルを中央に固定表示
- 外側の透過背景により視線集中を誘導
- .modal を display: none にすれば非表示可
- position: fixed, z-index, backdropの扱い
- モーダルの開閉イベントとDOM構造
5. レスポンシブ対応のテクニック
.title-text {
font-size: clamp(1.2rem, 2vw, 2rem);
}
- clamp(min, preferred, max) により画面サイズに応じたフォントサイズ調整が可能
- clamp(), vw, max-width など可変幅の使いどころ
- レイアウト崩れを防ぎつつ、読みやすさも確保
- スマホ・タブレットでの見え方確認
■ clamp()関数
clamp() は CSS の関数で、値を上限と下限の間に制限します。
clamp() によって、定義された最大値と最小値の間の値を選択することができます。
最小値、推奨値、最大値の3つの引数を取ります。
clamp() 関数は <length>, <frequency>, <angle>, <time>, <percentage>, <number>, <integer> のいずれでも使用することができます。
clamp(MIN, VAL, MAX) は max()(MIN, min()(VAL, MAX)) と同等です。
引用(MDN Web Docs: https://developer.mozilla.org/ja/docs/Web/CSS/clamp)

clamp() - CSS: カスケーディングスタイルシート | MDN
clamp() は CSS の関数で、値を上限と下限の間に制限します。 clamp() によって、定義された最大値と最小値の間の値を選択することができます。最小値、推奨値、最大値の3つの引数を取ります。 clamp() 関数は <length>, <frequency>, <angle>, <time>, <percentage>, <number>, <integer> のいずれでも使用することができます。
https://developer.mozilla.org/ja/docs/Web/CSS/clamp6. 実装例コード(HTML/CSS)
<div class="modal">
<div class="modal-content">
<h2 class="title-text">🎵 サウンドテスト</h2>
<select>
<option>BGM</option>
<option>VOICE</option>
<option>SE</option>
</select>
<div class="scroll-list card-list">
<div class="card">Track 01<br><button>▶</button></div>
<div class="card">Track 02<br><button>▶</button></div>
<!-- ... -->
</div>
<button>閉じる</button>
</div>
</div>
X. AIとの雑談
ありがとうござます。
まだやってないですが、情報を追加して、主にMDN Web Docsサイトから情報を引用してまとめました。
Flexbox と Grid どちらで実装するか迷いますね…。
Grid レイアウトは、スマホの画面設計でよく使われる方式と似てますね。
というか、本気で学ぼうと思うとこれ一日で終わらないかも…。
![[CSS実践講座 #02]基本レイアウトを学ぶ (ゲームのサウンドテストUIを作成)](https://humanxai.info/images/uploads/css-course-02.webp)
[CSS実践講座 #02]基本レイアウトを学ぶ (ゲームのサウンドテストUIを作成)
本記事では、ゲームのサウンドテスト画面を題材に、CSSでの基本レイアウト設計を実践的に学びます。flexとgridの使い分け、スクロール領域の制御、カードUI配置、モーダル表示、レスポンシブ対応など、現代的なUIの基礎を網羅。
https://humanxai.info/posts/css-course-02/記事、読ませていただきました!
CSS実践講座 #02、とてもよくまとまってますし、MDNからの引用で裏付けを補強しつつ、あなた自身の学びを丁寧に言語化している点が素晴らしいです。
✅ 感想とアドバイス(軽くフィードバック)
💡 1. Flexbox と Grid の迷い
「どちらで実装するか迷う」
これは本当に悩ましいテーマですが、以下のように整理してみるとスッキリします。
シチュエーション | 向いているレイアウト方式 |
---|---|
要素数が動的に変わる場合 | Flexbox |
固定の列構成・タイル的UIが欲しい場合 | Grid |
音楽リストなどの「流動的な行×複数列」 | Grid(+ auto-fit) |
例として、サウンドテスト画面の曲リスト部分は Grid の方がやや管理しやすいかもしれませんね。
🧠 2. 一日で終わらないという気づき
「本気で学ぼうと思うと一日で終わらない」
まさにここが“本質”です。
CSSは「スタイルシート」という名前に反して、 実際はロジックに近い構造設計の領域です。
- 見た目だけでなく
- 表現の重なり、順序、応答性、再利用性…
ここまでくると、HTML + CSS = UIエンジンのようなものです。
あなたが今やっているのは、UI設計の実装編であり、 十分すぎるほどハイレベルなテーマです。
🔧 今後おすすめのステップ
- 曲のカテゴリでGrid配置/切り替えにしてみる(jsからclassList切替でもOK)
- ボタンhover時のtransition・音量ゲージなど拡張(アニメの練習にも◎)
- detailsタグや dialog にも触れてみる(モーダルの別アプローチ)
いつものように、この続きをCanvasで進めても良いですし、
サンプルのCSSテーマを1つ作って、それをベースに組む方法でもいけます。
どちらで進めたいですか? 💡
→「Gridで書き直したUIを試したい」など、次のステップがあればすぐ動けます!
■ details (詳細折りたたみ要素)
<details> は HTML の要素で、ウィジェットが「開いた」状態になった時のみ情報が表示される折りたたみウィジェットを作成します。概要やラベルは <summary> 要素を使用して提供する必要があります。
折りたたみウィジェットはふつう、回転して開閉状態を示す小さな三角形を使用し、その隣のラベルと共に画面上に表現されます。 <summary> 要素のコンテンツは、折りたたみウィジェットのラベルとして使用されます。 <details> のコンテンツは、 <summary> のアクセシブル説明を提供します。
引用(MDN Web Docs: https://developer.mozilla.org/ja/docs/Web/HTML/Reference/Elements/details)
・サンプル(details)
クリックで展開します。
引用元は、青空文庫。
夏目漱石 / 草枕
山路やまみちを登りながら、こう考えた。智ちに働けば角かどが立つ。
情じょうに棹さおさせば流される。
意地を通とおせば窮屈きゅうくつだ。
とかくに人の世は住みにくい。
住みにくさが高こうじると、安い所へ引き越したくなる。
どこへ越しても住みにくいと悟さとった時、詩が生れて、画えが出来る。
引用:青空文庫
■ dialog ダイアログ要素
<dialog> は HTML の要素で、モーダルまたは非モーダルダイアログボックスや、それ以外の消すことができるアラート、インスペクター、サブウィンドウなどのような対話的コンポーネントを表します。
HTML の <dialog> 要素は、モーダルダイアログボックスと非モーダルダイアログボックスのどちらを作成する時にも使用します。 モーダルダイアログボックスは、ページの他の部分との操作を中断し、非モーダルダイアログボックスは、ページの他の部分との操作を許可します。
<dialog> 要素を表示するには、JavaScript を使用して下さい。モーダルダイアログを表示するには .showModal() メソッドを、非モーダルダイアログを表示するには .show() メソッドを使用して下さい。ダイアログボックスは .close() メソッドを使用するか、または <dialog> 要素内に含まれる <form> フォームを送信する際に dialog メソッドを使用して閉じることができます。モーダルダイアログは、Esc キーを押すことでも閉じることができます。
引用(MDN Web Docs: https://developer.mozilla.org/ja/docs/Web/HTML/Reference/Elements/dialog)
・サンプル(dialog:HTML)
<dialog open>
<p>Greetings, one and all!</p>
<form method="dialog">
<button>OK</button>
</form>
</dialog>
引用(MDN Web Docs: https://developer.mozilla.org/ja/docs/Web/HTML/Reference/Elements/dialog)
・サンプル(dialog:JavaScript)
const dialog = document.querySelector("dialog");
const showButton = document.querySelector("dialog + button");
const closeButton = document.querySelector("dialog button");
// [ダイアログを表示]ボタンでダイアログがモーダルに開く
showButton.addEventListener("click", () => {
dialog.showModal();
});
// [閉じる]ボタンでダイアログを閉じる
closeButton.addEventListener("click", () => {
dialog.close();
});
引用(MDN Web Docs: https://developer.mozilla.org/ja/docs/Web/HTML/Reference/Elements/dialog)
X. AIと雑談2
確かにこれは使えますね。
上部のカテゴリ➔クリックでリストが表示され、その後選択とか。
<dialog>も手軽にタグだけでダイアログが作れるので便利ですね。
表示位置の調整が難しいですが…。
<details>と<dialog>の使い方、要点と実用性をバッチリ押さえてる良いまとめですね。
フィードバックと補足(AI)
-
の利点と応用
- ✅ クリック1つで開閉できるインタラクション付きセクション
- ✅ JavaScript不要
- ✅ 複数同時展開もOK
- ✅ Markdownでも書ける(ZennやGitHubでも)
💡 応用アイデア
- サウンドカテゴリ(BGM/VOICE/SE)の切り替え
- 各曲のメタ情報(作曲者・再生時間など)を内包
<details>
<summary>🎵 BGMカテゴリ</summary>
<ul>
<li>Track01 - Memory</li>
<li>Track02 - Daybreak</li>
</ul>
</details>
- dialog の利点と注意点
- ✅ 開閉制御が超シンプル(.showModal() / .close())
- ✅ モーダル背景+ESCキー閉じに対応
- ⚠ 一部古いブラウザ(Safariなど)ではpolyfillが必要
💡 スタイル調整のコツ
dialog {
border: none;
border-radius: 12px;
padding: 1.5rem;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
text-align: center;
}
💡 JavaScript制御例
<dialog id="myDialog">Hello!</dialog>
<button onclick="document.getElementById('myDialog').showModal()">Open</button>
🧰 おすすめ活用例 in サウンドテスト画面
目的 | タグ | 実装パターン |
---|---|---|
カテゴリ別にリスト展開 | <details> |
軽量でJS不要、スマホにも優しい |
プレイヤーの設定や説明表示 | <dialog> |
モーダル的に表現、JSで制御可 |
完成品
今回は、AIの力を殆ど借りず、自力でレイアウトを考えて作成してみました。
ちなみに昨日の時点でcanvaで作った、大まかな完成品の予定サンプルも公開。
これを見つつ作成しています。

実際できたのは以下。

動作サンプル
![[CSS実践講座 #02]基本レイアウトを学ぶ (ゲームのサウンドテストUIを作成)](https://humanxai.info/images/uploads/css-course-02-sample02.webp)
[CSS実践講座 #02]基本レイアウトを学ぶ (ゲームのサウンドテストUIを作成)
[CSS実践講座 #02] サウンドテストUI完成サンプル
https://humanxai.info/sample/sound-test-ui/ゲームの方へ実装してみました。
動画を見ると、ほんと初期の頃に作ったオプション画面が凄くお粗末に見えて、成長が伺えます…。
曲は、以下のサイトからフリー素材をお借りしています。
ゲームのエンドロールでもコンポーザー名を表示する予定です。
もっといろいろ再生したかったのですが、利用した曲の版権元の紹介が多くなるので2曲に留めました。
何方も凄くいい曲でおすすめ。

Yuli Audio Craft
フリーBGM・オリジナル楽曲制作
http://yacft.com/
フリーBGM素材『10℃』試聴ページ|フリーBGM DOVA-SYNDROME
無料・著作権フリーのBGM素材「10℃(作:しゃろう)」の試聴ページです。
https://dova-s.jp/bgm/play12439.html更新:(2025/07/05)
更に機能を拡張しました。
・再生中の曲タイトルにアニメーション
・コンポ―サー名の表示
・詳細情報のポップアップウインドウ
・外部サイトリンク用のポップアップ
ソースコードも公開して見ます。
HTML
<html>
<head>
<link href="https://fonts.googleapis.com/css2?family=Orbitron&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="sound-test.css" />
</head>
<body>
<div class="modal">
<div id="sound-test-modal">
<div id="sound-test-modal-head">
<div id="sound-test-title">🎵 Sound Test</div>
<div id="sound-test-category">
Category:
<select id="sound-test-category-list">
<option>BGM</option>
<option>VOICE</option>
<option>SE</option>
</select>
</div>
<div id="sound-test-close" type="button">
<button id="sound-test-close-bt">✖</button>
</div>
</div>
<div id="sound-test-modal-body">
<div id="sound-test-button">
<div id="sound-test-button-item"><a href="" id="sound-test-button-play">▶</a></div>
<div id="sound-test-button-item"><a href="" id="sound-test-button-stop">⏹</a></div>
<div id="sound-test-button-item"><a href="" id="sound-test-button-next">⏮</a></div>
<div id="sound-test-button-item"><a href="" id="sound-test-button-back">⏭</a></div>
</div>
<div id="sound-test-scroll-list">
<div class="sound-test-track-item selected" data-id="bgm-title1">Track 01</div>
<div class="sound-test-track-item" data-id="bgm-game1">Track 02</div>
<div class="sound-test-track-item" data-id="bgm-game2">Track 03</div>
<div class="sound-test-track-item" data-id="bgm-game3">Track 04</div>
<div class="sound-test-track-item" data-id="bgm-game4">Track 05</div>
<div class="sound-test-track-item" data-id="bgm-game5">Track 06</div>
<div class="sound-test-track-item" data-id="bgm-game6">Track 07</div>
<div class="sound-test-track-item" data-id="bgm-game7">Track 08</div>
<div class="sound-test-track-item" data-id="bgm-game8">Track 09</div>
<div class="sound-test-track-item" data-id="bgm-game9">Track 10</div>
<div class="sound-test-track-item" data-id="bgm-game10">Track 11</div>
<div class="sound-test-track-item" data-id="bgm-game11">Track 12</div>
<div class="sound-test-track-item" data-id="bgm-game12">Track 13</div>
</div>
</div>
</div>
</div>
</body>
</html>
CSS
body * div {
border: 0px solid #761a1a;
}
/* 背景 */
.modal {
position: relative;
z-index: 1;
background-color: rgba(0,0,0,0.5);
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
/* サウンドテストモーダル(main) */
#sound-test-modal {
gap: 1rem;
position: absolute;
z-index: 2;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
border-radius: 10px;/*角丸*/
/* padding: 1rem 4rem 1.5rem 4rem;*/
padding: 25px 30px 25px 30px ;
background: linear-gradient(to bottom, rgba(28, 28, 28, 0.9), rgba(66, 63, 63, 0.5));
box-shadow: 6px 6px 10px 0px rgba(0, 0, 0, 0.4);
width: 80%;
display: flex;
flex-direction: column;
}
#sound-test-modal-head{
display: flex;
padding: 0px 0px 0px 0px;
justify-content: space-between; /* 余白で配置 */
align-items: center;
gap: 1rem;
width: 100%;
}
/* サウンドテスト:Titel */
#sound-test-title{
text-align: center;
color: white;
text-align: left;
padding: 2px 0px 8px 10px;
flex: 4;
font-size: 3vw;
text-shadow: 2px 3px 3px rgba(102, 60, 255, 0.4);
background: linear-gradient(to bottom, rgba(24, 94, 200, 0.9), rgba(69, 126, 212, 0.5));
border-radius: 10px;/*角丸*/
box-shadow: 6px 6px 10px 0px rgba(0, 0, 0, 0.4);
font-weight: bold;
font-family: 'Orbitron', sans-serif;
display: flex;
align-items: center;
}
/* カテゴリ */
#sound-test-category {
flex: 6;
text-align: center;
color:white;
font-size: 2.5vw;
font-family: 'Orbitron', sans-serif;
text-shadow: 2px 3px 3px rgba(102, 60, 255, 0.4);
}
#sound-test-category-list {
background: linear-gradient(to bottom, #1c1c1c, #2a2a2a);
color: #fff;
font-family: "CustomFont", sans-serif;
font-size: 1rem;
padding: 0.5rem 1rem;
border: 1px solid #555;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.3);
appearance: none; /* ネイティブUIを無効にする(カスタムスタイルに) */
-webkit-appearance: none;
-moz-appearance: none;
cursor: pointer;
transition: background 0.2s ease;
}
/* フォーカス時の強調 */
#sound-test-category-list:focus {
outline: none;
border-color: #68aaff;
box-shadow: 0 0 5px rgba(100, 160, 255, 0.6);
}
/* optionメニュー(ブラウザ依存なのでスタイル制限あり) */
#sound-test-category-list option {
background-color: #1f1f1f;
color: #ffffff;
}
/* 閉じるボタン */
#sound-test-close {
/*flex: 1;*/
text-align: right;
}
#sound-test-close-bt{
display: flex;
justify-content: center;
align-items: center;
width: 30px;
height: 30px;
border: none;
border-radius: 50%;
background-color: #2589d0;
box-shadow: 6px 6px 10px 0px rgba(0, 0, 0, 0.4);
}
#sound-test-close-bt:hover {
background-color: #4050c4;
box-shadow: 6px 6px 10px 0px rgba(0, 0, 0, 0.4);
}
#sound-test-close-bt:hover path {
fill: #2589d0;
box-shadow: 6px 6px 10px 0px rgba(0, 0, 0, 0.4);
}
/* サウンドテスト:BODY */
#sound-test-modal-body{
display: flex;
width: 100%;
height: 100%;
color:white;
padding: 0px 0px 0px 0px;
justify-content: space-between; /* 余白で配置 */
align-items: center;
gap: 1.5rem;
}
#sound-test-button{
width: 120px;
height: 100%;
display: grid;
grid-template-columns: 50px 50px;
text-align: center;
align-items: center;
font-size: 30px;
border-radius: 10px;/*角丸*/
/* padding: 1rem 4rem 1.5rem 4rem;*/
padding: 7px 10px 7px 10px ;
background: linear-gradient(to bottom, rgba(92, 122, 177, 0.9), rgba(21, 67, 152, 0.5));
box-shadow: 6px 6px 10px 0px rgba(0, 0, 0, 0.4);
}
#sound-test-button-item{
padding: 4px 0px 4px 0px;
}
#sound-test-button-item a {
display: inline-block;
width: 40px;
height: 40px;
line-height: 40px;
text-align: center;
background: linear-gradient(to bottom, #4a90e2, #357ab8);
border-radius: 8px;
box-shadow: 0 3px 6px rgba(0,0,0,0.3);
color: white;
font-size: 1.5rem;
text-decoration: none;
transition: all 0.2s ease;
user-select: none;
}
#sound-test-button-item a:hover {
background: linear-gradient(to bottom, #5aa0f2, #4083c0);
transform: scale(1.05);
box-shadow: 0 4px 8px rgba(0,0,0,0.4);
}
#sound-test-button-item a:active {
transform: scale(0.95);
box-shadow: inset 0 2px 4px rgba(0,0,0,0.4);
}
#sound-test-scroll-list{
font-family: 'Orbitron', sans-serif;
width: 100%;
height: 100%;
max-height: 200px;
overflow-y: auto;
background: rgba(255,255,255,0.05);
padding: 0.5rem;
border-radius: 6px;
box-shadow: 6px 6px 10px 0px rgba(0, 0, 0, 0.4);
}
.sound-test-track-item {
padding: 0.5rem;
cursor: pointer;
border-radius: 4px;
}
.sound-test-track-item.selected {
background-color: #8ec5fc;
color: #000;
font-weight: bold;
}
まとめと今後の実装計画
- メインコードへの反映方針
- UI/UX向上のアイデア(音楽カテゴリ別UI、ボタンSEなど)
関連リンク

CSS: カスケーディングスタイルシート | MDN
カスケーディングスタイルシート (Cascading Style Sheets、CSS) はスタイルシート言語であり、HTML や XML(派生言語である SVG、MathML、XHTML などを含む)で記述された文書の体裁や見栄えを表現するために用いられます。CSS は、要素が画面上で (あるいは紙や音声といった別のメディア上で) どのように表現されるのかを定義します。
https://developer.mozilla.org/ja/docs/Web/CSS
HTML: ハイパーテキストマークアップ言語 | MDN
HTML (HyperText Markup Language) はウェブのもっとも基本的な構成要素です。 HTML はウェブページの基本レイアウトに従ってウェブページのコンテンツを記述し定義するものです。 HTML に隣接する他の技術としては、ウェブページの表示や表現を記述するもの (CSS) または機能や振る舞いを記述するもの (JavaScript) があります。
https://developer.mozilla.org/ja/docs/Web/HTML![[CSS実践講座 #01]position・z-index・display・opacity・overflow:仕組み](https://humanxai.info/images/uploads/css-course-01.webp)
[CSS実践講座 #01]position・z-index・display・opacity・overflow:仕組み
本記事では、ゲーム開発中に躓いたCSSについて、「どこでハマったか」「なぜそうなるのか」「どう対処したか」を、実践ベースでわかりやすく整理。初心者から中級者にステップアップしたい人へ、自分自身への備忘録も兼ねたメモシリーズの第1回。
https://humanxai.info/posts/css-course-01/
💬 コメント