タイトルだとわかりにくいですが、例えばモーダルコンテンツの中の一部だけ内容量に合わせてスクロールさせる、といった実装をしようとして試行錯誤することがあったので実装方法をメモ。
サンプルコード
まずは対応前のサンプルです。
コンテンツ内の一部がスクロールするモーダルを用意します。
<button data-dialog-link="dialog">dialog</button>
<dialog class="dialog" data-dialog-main="dialog">
<div class="dialog_content">
<div class="dialog_head">
<h3 class="dialog_ttl">dialogタイトル</h3>
<p class="dialog_description">説明文テキスト</p>
</div>
<div class="dialog_scroll">
<p>dialogの内容<br>dialogの内容<br>dialogの内容<br>dialogの内容<br>dialogの内容<br>dialogの内容<br>dialogの内容<br>dialogの内容<br>dialogの内容<br>dialogの内容</p>
~略~
</div>
<div class="dialog_foot">
<button class="dialog_close" data-dialog-close="dialog">dialogを閉じる</button>
</div>
</div>
</dialog>
.dialog_scrollがスクロールする想定の要素です。
次にJavaScriptでモーダルの開閉処理を追加します。
const dataDialogMain = 'data-dialog-main';
const dataDialogLink = 'data-dialog-link';
const dataDialogClose = 'data-dialog-close';
const $dialogLinks = document.querySelectorAll(`[${dataDialogLink}]`);
const $dialogCloses = document.querySelectorAll(`[${dataDialogClose}]`);
// ダイアログリンククリック時
$dialogLinks.forEach(function(element) {
element.addEventListener('click', function(e) {
e.preventDefault();
const dialogId = element.getAttribute(`${dataDialogLink}`);
const $dialog = document.querySelector(`[${dataDialogMain} = ${dialogId}]`);
if($dialog) $dialog.showModal();
});
});
// 閉じるボタンクリック時
$dialogCloses.forEach(function(element) {
element.addEventListener('click', function(e) {
e.preventDefault();
const dialogId = element.getAttribute(`${dataDialogClose}`);
const $dialog = document.querySelector(`[${dataDialogMain} = ${dialogId}]`);
if($dialog) $dialog.close();
});
});
最後にCSSの設定です。
.dialog {
inset: unset;
max-width: unset;
max-height: unset;
overflow: unset;
border: none;
padding: 0;
background: none;
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100dvh;
}
.dialog:not([open]) {
display: none !important;
}
.dialog::backdrop {
background: rgba(0, 0, 0, 0.7);
}
.dialog_content {
max-width: 1200px;
width: 90%;
max-height: 90dvh;
padding: 20px;
background: white;
}
.dialog_scroll {
overflow-y: auto;
padding: 20px;
}
モーダル自体は画面高さの90%を最大高さとして設定して、モーダルの中身はスクロールエリアとテキストのエリアがあり、テキストのエリアはテキスト量に応じて高さが変わります。
そのため、スクロールエリアに任意の高さを設定できず、コンテンツがはみ出して表示されます。
対応前のデモページ
対応方法としてはflexboxを使い、モーダル内の要素を縦積みにします。
.dialog {
inset: unset;
max-width: unset;
max-height: unset;
overflow: unset;
border: none;
padding: 0;
background: none;
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100dvh;
}
.dialog:not([open]) {
display: none !important;
}
.dialog::backdrop {
background: rgba(0, 0, 0, 0.7);
}
.dialog_content {
display: flex;
flex-direction: column;
max-width: 1200px;
width: 90%;
max-height: 90dvh;
padding: 20px;
background: white;
}
.dialog_scroll {
overflow-y: auto;
padding: 20px;
}
今回はモーダルの最大高さを90%にした上で高さは内容量に合わせて可変にしていましたが、高さを設定(90%)した上でスクロールエリアを引き延ばしたい場合はflex-growを指定します。
.dialog {
inset: unset;
max-width: unset;
max-height: unset;
overflow: unset;
border: none;
padding: 0;
background: none;
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100dvh;
}
.dialog:not([open]) {
display: none !important;
}
.dialog::backdrop {
background: rgba(0, 0, 0, 0.7);
}
.dialog_content {
display: flex;
flex-direction: column;
max-width: 1200px;
width: 90%;
height: 90dvh;
padding: 20px;
background: white;
}
.dialog_scroll {
flex-grow: 1;
overflow-y: auto;
padding: 20px;
}
コメントが承認されるまで時間がかかります。