モーダル
Featherlightのモーダル
テスト03
HTML
<!-- Featherlight CSS -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/featherlight@1.7.14/release/featherlight.min.css">
<!-- Featherlight JS -->
<script src="https://cdn.jsdelivr.net/npm/featherlight@1.7.14/release/featherlight.min.js"></script>
<div class="modalBox">
<!-- 開くボタン -->
<div class="modalOpen modalOpen-featherlight">
<a href="javascript:void(0)" class="featherlight__link" data-featherlight="#featherlight__open">テスト03</a>
</div>
<!-- モーダル中身 -->
<div id="featherlight__open" class="featherlight__open">
<div class="featherlight__contents">
<span class="test-number">テスト03</span>
</div>
</div>
</div>
CSS
コードの説明
/*******************************************
featherlight.js
*******************************************/
/* ↓↓↓リセット用↓↓↓ */
.featherlight .featherlight-content {
width: 90%;
height: 90%;
max-height: none;
margin: 0;
padding: 0;
}
/* ↑↑↑リセット用↑↑↑ */
.modalOpen-featherlight {
background-color: var(--red);
border: 3px solid var(--red);
padding: 0;
&:hover {
color: var(--red);
}
}
.featherlight__link {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
padding: 15%;
}
.featherlight__open {
display: none;
}
#featherlight__open {
background-color: rgba(0, 0, 0, 0.5);
}
JavaScript
コードの説明
/*******************************************
モーダル内に閉じるボタン追加
*******************************************/
$(document).on('click', '.modalClose', function (e) {
e.preventDefault();
if ($.featherlight.current()) {
$.featherlight.current().close();
}
});
javascriptのみのモーダル
シンプルなモーダルには適しているが、複雑な機能が求められる場合はライブラリを使用した方が効率的なこともある。
【メリット】
軽量で速い、柔軟なカスタマイズ、依存性がない
【デメメリット】
コードが長くなる、古いブラウザなどで互換性問題が発生することがある、
テスト01
テスト01
HTML
<button class="btn modalOpen" data-target="modal01">
1日の流れを見る
</button>
<!-- モーダル -->
<div class="modal modal-interview">
<div class="section__inner modalBox-outer" id="modal-interview02">
<div class="modalBox">
<div class="modal__inner">
<button class="modalClose modalClose-top"></button>
<div class="modalMv ">
<div class="modalMv__txtBox">
<div class="modalMv__ttl">
<p></p>
<p></p>
</div>
<div class="modalMv__detail">
<p></p>
</div>
</div><!-- modalMv__txtBox -->
<div class="modalMv__img">
<img src="img/interview/img02.jpg" width="950" height="1000" alt="">
</div>
</div><!-- modalMv -->
<dl class="modal__q">
<dt>
<span class="q-icon"></span>
<p>
</p>
</dt>
<dd>
<p>
</p>
</dd>
</dl>
<div class="btn-outer modalClose btn-outer-modal">
<button class="btn">
閉じる
</button>
</div>
</div><!-- modal__inner -->
</div><!-- modalBox-->
</div><!-- modalBox-outer -->
</div><!-- modal -->
<!--↑↑↑ モーダル↑↑↑-->
CSS
コードの説明
/*******************************************
modal
*******************************************/
/* 共通
ーーーーーーーーーーーーーーーーーーー */
.no-scroll {
overflow: hidden;
body {
overflow: scroll;
}
}
.modal {
/* 背景 */
opacity: 0;
visibility: hidden;
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 100vw;
height: auto;
background-color: var(--blue06);
z-index: -100;
overflow: auto;
transition: var(--transitionBase);
}
.modalBox-outer {
/* 最大幅*/
position: absolute;
width: min(100vw, 1000px);
height: auto;
top: 0;
left: 50%;
opacity: 0;
visibility: hidden;
transform: translate(-50%, 0);
transition: var(--transitionBase);
padding: clamp(40px, 10%, 140px) 0;
z-index: -100;
}
.modalBox {
position: relative;
width: 100%;
margin: 0 auto;
background-color: var(--beige01);
height: auto;
}
.active {
opacity: 1;
visibility: visible;
z-index: 1000;
.show.modalBox-outer {
opacity: 1;
visibility: visible;
transform: translate(-50%, 0);
z-index: 1001;
}
}
.modal__inner {
/* モーダル中身のインナー */
width: min(100%, 915px);
margin: 0 auto;
padding: 65px 0;
}
.modalClose-top {
position: absolute;
content: "";
width: 60px;
aspect-ratio: 1;
background-color: var(--blue01);
border: 1px solid var(--blue01);
top: 0;
right: 0;
border-radius: var(--borderRadiusCircle);
transform: translate(50%, -50%);
z-index: 10;
transition: var(--transitionBase);
&::before,
&::after {
position: absolute;
content: "";
width: 50%;
height: 2px;
top: 50%;
left: 50%;
background-color: var(--white);
transition: var(--transitionBase);
}
&::before {
transform: translate(-50%, -50%) rotate(45deg);
}
&::after {
transform: translate(-50%, -50%) rotate(-45deg);
}
&:hover {
background-color: var(--white);
&::before,
&::after {
background-color: var(--black);
}
}
}
.btn-outer-modal {
width: min(100%, 400px);
margin: max(6.5%, 40px) auto 0;
}
@media screen and (max-width:1024px) {
.modal__inner {
padding: 80px 15px;
}
.modalClose-top {
top: 10px;
right: 10px;
transform: none;
}
}
@media screen and (max-width:960px) {
.modal__inner {
padding-left: 15px !important;
padding-right: 15px !important;
}
}
@media screen and (max-width:768px) {
.modalClose-top {
width: 40px;
&:hover {
background-color: var(--blue01);
&::before,
&::after {
background-color: var(--white);
}
}
}
}
/* 共通
ーーーーーーーーーーーーーーーーーーー */
.modalMv {
position: relative;
margin: 0 auto max(8.81%, 35px);
}
.modalMv__txtBox {
position: absolute;
width: 100%;
top: 9%;
left: 0;
}
.modalMv__ttl {
p {
background-color: var(--blue04);
color: var(--white);
font-size: var(--font30);
border-radius: var(--borderRadius10);
width: fit-content;
margin-bottom: 0.34em;
line-height: 1.7;
padding: 0 0.5em;
&:last-child {
margin-bottom: 0;
}
}
}
.modalMv__img {
width: 64.44%;
margin-left: auto;
img {
border-radius: var(--borderRadius10);
}
}
.modalMv__detail {
margin-top: 35px;
p {
font-size: var(--font19);
line-height: 1.47;
}
}
.modal__q {
font-size: var(--font23);
dt {
display: flex;
align-items: flex-start;
justify-content: flex-start;
gap: 10px;
margin-bottom: 10px;
p {
flex: 1;
font-size: var(--font23);
line-height: 1.217;
}
}
dd {
margin-bottom: max(6.396%, 30px);
background-color: var(--white);
padding: 20px;
border-radius: var(--borderRadius10);
&:last-child {
margin-bottom: 0;
}
}
}
.q-icon {
position: relative;
display: block;
width: 1.74em;
aspect-ratio: 1;
transform: translateY(-15%);
background-color: var(--blue04);
border-radius: var(--borderRadiusCircle);
&::before {
position: absolute;
content: "Q";
font-size: 1em;
color: var(--white);
top: 50%;
left: 50%;
transform: translate(-50%, -60%);
font-family: var(--notoSan);
}
}
@media screen and (max-width: 768px) {
.modalMv {
display: flex;
flex-direction: column-reverse;
align-items: center;
width: min(100%, 600px);
margin-left: auto;
margin-right: auto;
}
.modalMv__txtBox {
position: initial;
}
.modalMv__img {
width: min(100%, 400px);
margin: 0 0 max(5%, 15px) 0;
img {
border-radius: var(--borderRadius10);
}
}
.modalMv__detail {
margin-top: max(3%, 10px);
}
.modal__q {
dd {
padding: 15px 10px;
}
}
}
/* 共通↑↑↑
ーーーーーーーーーーーーーーーーーーー */
JavaScript
コードの説明
/*******************************************
モーダル data-target="modal01"
*******************************************/
// モーダル開く
document.querySelectorAll('.modalOpen').forEach(btn => {
btn.addEventListener('click', () => {
const targetId = btn.dataset.target;
const modal = document.getElementById(targetId)?.closest('.modal');
const targetBox = document.getElementById(targetId);
if (!modal || !targetBox) return;
// 同じモーダル内の他の Box を非表示にする
modal.querySelectorAll('.modalBox-outer').forEach(box => {
box.style.display = 'none';
box.classList.remove('show');
});
// 対象だけ表示
targetBox.style.display = 'block';
targetBox.classList.add('show');
modal.classList.add('active');
document.documentElement.classList.add('no-scroll');
});
});
// モーダル閉じる
document.querySelectorAll('.modalClose').forEach(btn => {
btn.addEventListener('click', () => {
const modal = btn.closest('.modal');
if (!modal) return;
modal.classList.remove('active');
// そのモーダル内の Box を全部閉じる
modal.querySelectorAll('.modalBox-outer').forEach(box => {
box.classList.remove('show');
box.style.display = 'none';
});
// 他に開いてるモーダルがなければスクロール許可
if (!document.querySelector('.modal.active')) {
document.documentElement.classList.remove('no-scroll');
}
});
});
SweetAlert2のモーダル
テスト02
JavaScript
コードの説明
// SweetAlert2のモーダルを開くためのボタン
const swalModalOpen = document.getElementById('swalModal__open');
// ボタンにクリックイベントを設定
swalModalOpen.addEventListener('click', function () {
Swal.fire({
title: 'テストモーダル',
text: 'SweetAlert2を使用したモーダルです。',
icon: 'info',
confirmButtonText: '閉じる'
});
});