YouTubeの動画はiframeでそのまま埋め込むと、スマホのような小さい画面で見た時に、親要素のpaddingなどの影響で、より小さく表示されてしまいます。
そんな時、モーダルで全幅表示させてみるのも方法の一つです。
この記事では、そんな「モーダルでYouTube動画を表示」するUIを、ネイティブなJavaScriptで作ってみます。
document.createElement()
JavaScriptの document.createElement()
は、 引数に指定したタグ名でHTML要素を生成するメソッドです。
const element = document.createElement('タグ名');
ですが、この一文だけだと要素はJavaScript内にだけ存在することになり、表示されることはありません。ので、指定された親ノードの子ノードリストの末尾にノードを追加するappnedChild()
を使って、生成した要素を追加します。
この記事でも appnedChild()
を使ってモーダルを追加しています。
YouTube動画をモーダルで表示するサンプル
サンプルです。
4つのカードが並んでいますが、各カードをクリックするとモーダルが立ち上がり、所定のYouTube動画が表示されます。
モーダルは、✖️マークか黒いオーバーレイを選択すると非表示になり、それまで再生中だった場合は、動画が停止になります。
実装の手順と方法
各コードの解説の前に、実装の手順と方法について簡単にご説明します。
HTMLを設置したい場所に記述します。
<ul class="youtubeList">
<li><a href="https://www.youtube.com/watch?v=gKFFmBG-Fik" class="modal-youtube"><img src="https://img.youtube.com/vi/gKFFmBG-Fik/sddefault.jpg" class="youtubeImg" alt="youtube"><p>AA=×Kj (Dragon Ash) - M SPECIES (Official Music Video)</p></a></li>
<li><a href="https://www.youtube.com/watch?v=kAdPepeyVY8" class="modal-youtube"><img src="https://img.youtube.com/vi/kAdPepeyVY8/sddefault.jpg" class="youtubeImg" alt="youtube"><p>RIZE / MUPPET - Music Video -</p></a></li>
<li><a href="https://www.youtube.com/watch?v=r3V4Nr3v1HA" class="modal-youtube"><img src="https://img.youtube.com/vi/r3V4Nr3v1HA/sddefault.jpg" class="youtubeImg" alt="youtube"><p>AA= - NOISE OSC (Official Music Video)</p></a></li>
<li><a href="https://www.youtube.com/watch?v=qjN5uHRIcjM" class="modal-youtube"><img src="https://img.youtube.com/vi/qjN5uHRIcjM/sddefault.jpg" class="youtubeImg" alt="youtube"><p>The Who - My Generation live 1967</p></a></li>
</ul>
後述しますが、a
タグの中に設置したいYouTubeの動画IDを記述すればOKです。
次に、JavaScriptのコードを記述します。
// YouTubeのコードを生成
const getYouTubeVideoCode = url => {
let inicio = url.indexOf('?') + 3,
final = url.indexOf('&', inicio),
code = final !== -1 ? url.slice(inicio, final) : url.slice(inicio),
params = url.slice(final);
return final !== -1 ? `${code}?${params}&` : `${code}?`;
};
// タグを出力してオブジェクトを作る
const printYouTubeModal = videoCode => {
let modal = document.createElement('div');
modal.id = "modalYouTube";
modal.classList.add('ed-modal');
modal.innerHTML = `
<div id="modalOverlay">
<div class="modalContent">
<div id="closeModal" class="ed-closeModal"></div>
<div class="video">
<iframe src="https://www.youtube.com/embed/${videoCode}autoplay=1" frameborder="0" allowfullscreen> </iframe>
<div>
</div>
</div>`;
document.body.appendChild(modal);
closeModal(modal);
};
// モーダルを閉じる場合
const closeModal = modal => {
document.getElementById('closeModal').addEventListener('click', () => {
document.body.removeChild(modal);
});
document.getElementById('modalOverlay').addEventListener('click', () => {
document.body.removeChild(modal);
});
window.addEventListener('keyup', e => {
if (e.key === 'Escape') {
document.getElementById('closeModal').click();
}
});
};
// モーダルを開く
const openYouTubeModal = selector => {
let linksElements = [...document.querySelectorAll(selector)],
links = linksElements.map(link => link.href);
linksElements.forEach((el, i) => {
el.addEventListener('click', e => {
e.preventDefault();
printYouTubeModal(getYouTubeVideoCode(links[i]));
});
});
};
openYouTubeModal('.modal-youtube');
コードは <body>〜</body>
の中の、</body>
の閉じタグ(クロージングタグ)の前に記述しましょう。
最後に、CSSを記述して見た目を整えます。
/* カード */
ul.youtubeList {
padding: 0;
margin: 0;
border: none;
list-style: none;
display: flex;
justify-content: space-between;
flex-wrap: wrap;
gap: 25px;
}
ul.youtubeList li {
width: 47%;
}
ul.youtubeList li a {
display: flex;
flex-direction: column;
height: 100%;
border-radius: 2px;
background: #fff;
box-shadow: 0 0 3px 0 rgb(0 0 0 / 12%), 0 2px 3px 0 rgb(0 0 0 / 22%);
cursor: pointer;
transition: 0.2s ease-in-out;
}
ul.youtubeList li a:hover {
box-shadow: 0 15px 30px -5px rgb(0 0 0 / 15%), 0 0 5px rgb(0 0 0 / 10%);
transform: translateY(-4px);
text-decoration: none;
}
ul.youtubeList li a:hover:before {
content: "";
width: 100%;
height: 100%;
position: absolute;
background: rgb(0,0,0,.4);
}
ul.youtubeList li a:hover:after {
content: "\f03d";
font-family: "Font Awesome 5 Free";
font-weight: 900;
font-size: 2rem;
position: absolute;
top: 50%;
transform: translate(-50%, -50%);
left: 50%;
color: #FFF;
}
ul.youtubeList li a img {
border-radius: 2px 2px 0 0;
}
ul.youtubeList li a p {
margin: 0;
text-decoration: none;
color: #313131;
padding: 10px 20px;
line-height: 1.6;
}
/* modal */
.ed-modal {
position: fixed;
width: 100%;
height: 100%;
left: 0;
top: 0;
background: rgba(0, 0, 0, 0.9);
display: flex;
z-index: 9999;
}
div#modalOverlay {
width: 100%;
height: 100%;
display: flex;
cursor: pointer;
}
.ed-closeModal {
position: absolute;
top: -35px;
right: 5px;
cursor: pointer;
width: 1.5rem;
height: 1.5rem;
opacity: 0.5;
}
.ed-closeModal::before, .ed-closeModal::after {
content: "";
width: 35px;
height: 2px;
background: #fff;
position: absolute;
top: 0;
transform: rotate(45deg);
transform-origin: top left;
}
.ed-closeModal::before {
left: 0;
}
.ed-closeModal::after {
right: 0;
transform: rotate(-45deg);
transform-origin: top right;
}
.modalContent {
width: 100%;
max-width: 800px;
margin: auto;
position: relative;
}
.video {
width: 100%;
position: relative;
height: 0;
padding-bottom: 56.25%;
overflow: hidden;
filter: drop-shadow(0px 2px 5px #313131);
animation: fadeIn 1.2s ease 0s 1 normal;
}
.video iframe {
width: 100%;
position: absolute;
top: 0;
left: 0;
height: 100%;
}
@keyframes fadeIn {
0% {
opacity: 0;
transform: translateY(30px);
}
100% {
opacity: 1;
}
}
@media screen and (max-width: 767px) {
/* (ここにモバイル用スタイルを記述) */
ul.youtubeList li {
width: 100%;
}
}
レイアウトや、色味やシャドウのつけ具合を変更するにはCSSをいじれば変更できます。
これで完了です。
ざっくりとしたコードの解説
コードはHTML・JavaScript・CSSの3種です。順に解説していきます。
HTML
HTMLは、li
のリストタグの中に iframe
でYouTubeの動画と、サムネイルの画像。そして p
タグで動画のタイトルを入れます。
<ul class="youtubeList">
<li><a href="https://www.youtube.com/watch?v=gKFFmBG-Fik" class="modal-youtube"><img src="https://img.youtube.com/vi/gKFFmBG-Fik/sddefault.jpg" class="youtubeImg" alt="youtube"><p>AA=×Kj (Dragon Ash) - M SPECIES (Official Music Video)</p></a></li>
<li><a href="https://www.youtube.com/watch?v=kAdPepeyVY8" class="modal-youtube"><img src="https://img.youtube.com/vi/kAdPepeyVY8/sddefault.jpg" class="youtubeImg" alt="youtube"><p>RIZE / MUPPET - Music Video -</p></a></li>
<li><a href="https://www.youtube.com/watch?v=r3V4Nr3v1HA" class="modal-youtube"><img src="https://img.youtube.com/vi/r3V4Nr3v1HA/sddefault.jpg" class="youtubeImg" alt="youtube"><p>AA= - NOISE OSC (Official Music Video)</p></a></li>
<li><a href="https://www.youtube.com/watch?v=qjN5uHRIcjM" class="modal-youtube"><img src="https://img.youtube.com/vi/qjN5uHRIcjM/sddefault.jpg" class="youtubeImg" alt="youtube"><p>The Who - My Generation live 1967</p></a></li>
</ul>
サムネイル画像は任意のもので設定可能ですが、YouTubeの動画サムネイルをそのまま使用したい場合は、以下のように記述すればOKです。
https://img.youtube.com/vi/[YouTubeの動画ID]/sddefault.jpg
https://www.youtube.com/watch?v=gKFFmBG-Fik という動画の場合、[YouTubeの動画ID]には「gKFFmBG-Fik」を記入します。
JavaScript
JavaScriptは、大きく分けて「YouTubeのコードを生成」「タグを生成」「モーダルを閉じる」「モーダルを開く」の4種類です。
// YouTubeのコードを生成
const getYouTubeVideoCode = url => {
let inicio = url.indexOf('?') + 3,
final = url.indexOf('&', inicio),
code = final !== -1 ? url.slice(inicio, final) : url.slice(inicio),
params = url.slice(final);
return final !== -1 ? `${code}?${params}&` : `${code}?`;
};
// タグを出力してオブジェクトを作る
const printYouTubeModal = videoCode => {
let modal = document.createElement('div');
modal.id = "modalYouTube";
modal.classList.add('ed-modal');
modal.innerHTML = `
<div id="modalOverlay">
<div class="modalContent">
<div id="closeModal" class="ed-closeModal"></div>
<div class="video">
<iframe src="https://www.youtube.com/embed/${videoCode}autoplay=1" frameborder="0" allowfullscreen> </iframe>
<div>
</div>
</div>`;
document.body.appendChild(modal);
closeModal(modal);
};
// モーダルを閉じる場合
const closeModal = modal => {
document.getElementById('closeModal').addEventListener('click', () => {
document.body.removeChild(modal);
});
document.getElementById('modalOverlay').addEventListener('click', () => {
document.body.removeChild(modal);
});
window.addEventListener('keyup', e => {
if (e.key === 'Escape') {
document.getElementById('closeModal').click();
}
});
};
// モーダルを開く
const openYouTubeModal = selector => {
let linksElements = [...document.querySelectorAll(selector)],
links = linksElements.map(link => link.href);
linksElements.forEach((el, i) => {
el.addEventListener('click', e => {
e.preventDefault();
printYouTubeModal(getYouTubeVideoCode(links[i]));
});
});
};
openYouTubeModal('.modal-youtube');
CSS
CSSは、カードレイアウトとモーダルとの2種で、カードレイアウトはFlexboxです。
/* カード */
ul.youtubeList {
padding: 0;
margin: 0;
border: none;
list-style: none;
display: flex;
justify-content: space-between;
flex-wrap: wrap;
gap: 25px;
}
ul.youtubeList li {
width: 47%;
}
ul.youtubeList li a {
display: flex;
flex-direction: column;
height: 100%;
border-radius: 2px;
background: #fff;
box-shadow: 0 0 3px 0 rgb(0 0 0 / 12%), 0 2px 3px 0 rgb(0 0 0 / 22%);
cursor: pointer;
transition: 0.2s ease-in-out;
}
ul.youtubeList li a:hover {
box-shadow: 0 15px 30px -5px rgb(0 0 0 / 15%), 0 0 5px rgb(0 0 0 / 10%);
transform: translateY(-4px);
text-decoration: none;
}
ul.youtubeList li a:hover:before {
content: "";
width: 100%;
height: 100%;
position: absolute;
background: rgb(0,0,0,.4);
}
ul.youtubeList li a:hover:after {
content: "\f03d";
font-family: "Font Awesome 5 Free";
font-weight: 900;
font-size: 2rem;
position: absolute;
top: 50%;
transform: translate(-50%, -50%);
left: 50%;
color: #FFF;
}
ul.youtubeList li a img {
border-radius: 2px 2px 0 0;
}
ul.youtubeList li a p {
margin: 0;
text-decoration: none;
color: #313131;
padding: 10px 20px;
line-height: 1.6;
}
/* modal */
.ed-modal {
position: fixed;
width: 100%;
height: 100%;
left: 0;
top: 0;
background: rgba(0, 0, 0, 0.9);
display: flex;
z-index: 9999;
}
div#modalOverlay {
width: 100%;
height: 100%;
display: flex;
cursor: pointer;
}
.ed-closeModal {
position: absolute;
top: -35px;
right: 5px;
cursor: pointer;
width: 1.5rem;
height: 1.5rem;
opacity: 0.5;
}
.ed-closeModal::before, .ed-closeModal::after {
content: "";
width: 35px;
height: 2px;
background: #fff;
position: absolute;
top: 0;
transform: rotate(45deg);
transform-origin: top left;
}
.ed-closeModal::before {
left: 0;
}
.ed-closeModal::after {
right: 0;
transform: rotate(-45deg);
transform-origin: top right;
}
.modalContent {
width: 100%;
max-width: 800px;
margin: auto;
position: relative;
}
.video {
width: 100%;
position: relative;
height: 0;
padding-bottom: 56.25%;
overflow: hidden;
filter: drop-shadow(0px 2px 5px #313131);
animation: fadeIn 1.2s ease 0s 1 normal;
}
.video iframe {
width: 100%;
position: absolute;
top: 0;
left: 0;
height: 100%;
}
@keyframes fadeIn {
0% {
opacity: 0;
transform: translateY(30px);
}
100% {
opacity: 1;
}
}
@media screen and (max-width: 767px) {
/* (ここにモバイル用スタイルを記述) */
ul.youtubeList li {
width: 100%;
}
}
YouTubeのモーダルを表示する時、下からフェードインして表示させるように @keyframes
でアニメーションを定義しています。
またhover時のビデオのアイコンはFontswesomeを使っていますので、そのまま使う場合は本体の読み込みも行うようにしましょう。
さいごに
YouTubeの動画の設置の方法を引き出しに持っていると便利なので、是非参考にしてみてください。