理想のサイトをカスタマイズ構築
面倒な基本構造やレスポンシブ対応はテーマに任せ、浮いた時間で「あなたにしかできないこだわりの独自カスタマイズ」をとことん追求してみませんか?
「SWELL」の徹底レビュー・詳細を見る
面倒な基本構造やレスポンシブ対応はテーマに任せ、浮いた時間で「あなたにしかできないこだわりの独自カスタマイズ」をとことん追求してみませんか?
「SWELL」の徹底レビュー・詳細を見るHTMLの<video>タグは、プラグインなしでWebサイトに動画を埋め込む必須要素です。
本記事では、基本の記述方法からスマホ環境での自動再生ループ、CSSによる背景動画化、JavaScriptを用いたカスタムプレイヤーの実装などを解説します。
また、HTMLに関するカテゴリーページから学びたい内容を決めたい人は、以下のHTMLページをご確認ください。
レスポンシブ対応や基本レイアウトは最高峰テーマに任せませんか?浮いた時間で、流麗なアニメーションや標準設定を上書きする「あなただけの高度なビジュアル表現」をとことん突き詰めましょう。
「SWELL」であなたのデザインの限界を超えるHTML5から導入されたvideoタグは、ブラウザ標準機能だけでWebページに動画を埋め込める要素です。
Webサイト制作においてvideoタグは、ヒーローエリアの背景動画、商品の使い方を解説するプロモーション映像などあらゆる場面で利用されています。
ここでは、videoタグの基本的な知識、実務でそのまま使えるサンプルコード、動画ソースの適切な取り扱い方を解説します。
videoタグの役割とsrc・sourceによる動画ファイルの指定Webページ上に動画を配置して埋め込む記述方法には、大きく分けて2つのアプローチがあります。
1つは<video>タグに直接属性を書くシンプルな方法、もう1つは<video>タグの中に<source>タグを使って動画ファイルを指定する方法です。
⭕️ 複数の形式を用意する実装
<div class="hvideo-sec1-wrapper">
<div class="hvideo-sec1-demo-area">
<div class="hvideo-sec1-box">
<div class="hvideo-sec1-label">🎬 sourceタグを使った動画の指定</div>
<div class="hvideo-sec1-visual">
<p style="font-size:12px; color:#198754; font-weight:bold; margin:0 0 10px 0;">⭕️ 複数の形式を用意する実装</p>
<div class="hvideo-sec1-mock-player">
<div class="hvideo-sec1-mock-screen">
<span style="font-size:30px; color:#fff;">▶</span>
</div>
<div class="hvideo-sec1-mock-controls">
<span class="hvideo-sec1-mock-btn">▶</span>
<div class="hvideo-sec1-mock-bar"></div>
<span class="hvideo-sec1-mock-btn">🔊</span>
</div>
</div>
</div>
<div class="hvideo-sec1-code">
<!-- ❌ 悪い例:1つの形式しか指定できない --><br>
<video <span class="hvideo-sec1-hl-red">src="movie.mp4"</span> controls></video><br><br>
<!-- ⭕️ 良い例:複数の形式とエラーメッセージを用意する --><br>
<span class="hvideo-sec1-hl-blue"><video controls width="100%"></span><br>
<!-- ブラウザは上から順に再生可能なものを探します --><br>
<span class="hvideo-sec1-hl-green"><source src="movie.webm" type="video/webm"></span><br>
<span class="hvideo-sec1-hl-green"><source src="movie.mp4" type="video/mp4"></span><br>
<br>
<!-- どの形式も再生できない古いブラウザ向けのメッセージ --><br>
<p>お使いのブラウザは動画の再生に対応していません。<br>
<a href="movie.mp4">動画をダウンロード</a>してください。</p><br>
<span class="hvideo-sec1-hl-blue"></video></span>
</div>
</div>
</div>
</div>.hvideo-sec1-wrapper {
background-color: #f8f9fa;
padding: 20px;
border: 1px solid #dee2e6;
border-radius: 4px;
font-family: sans-serif;
}
.hvideo-sec1-demo-area {
display: flex;
justify-content: center;
}
.hvideo-sec1-box {
background-color: #ffffff;
border: 2px dashed #adb5bd;
padding: 25px;
width: 100%;
max-width: 500px;
border-radius: 4px;
}
.hvideo-sec1-label {
font-size: 15px;
font-weight: bold;
margin-bottom: 20px;
color: #333;
}
.hvideo-sec1-visual {
background-color: #f1f3f5;
padding: 20px;
border-radius: 8px;
margin-bottom: 20px;
border: 1px solid #dee2e6;
}
.hvideo-sec1-mock-player {
background-color: #000;
border-radius: 4px;
overflow: hidden;
box-shadow: 0 4px 8px rgba(0,0,0,0.2);
}
.hvideo-sec1-mock-screen {
height: 150px;
display: flex;
justify-content: center;
align-items: center;
background-color: #212529;
}
.hvideo-sec1-mock-controls {
background-color: #343a40;
display: flex;
align-items: center;
padding: 10px;
gap: 10px;
}
.hvideo-sec1-mock-btn {
color: #fff;
font-size: 12px;
}
.hvideo-sec1-mock-bar {
flex-grow: 1;
height: 4px;
background-color: #6c757d;
border-radius: 2px;
position: relative;
}
.hvideo-sec1-mock-bar::after {
content: '';
position: absolute;
top: 0; left: 0;
height: 100%; width: 40%;
background-color: #0d6efd;
border-radius: 2px;
}
.hvideo-sec1-code {
background-color: #282c34;
color: #abb2bf;
padding: 15px;
font-family: monospace;
font-size: 13px;
border-radius: 4px;
line-height: 1.6;
border-left: 4px solid #198754;
}
.hvideo-sec1-hl-green { color: #98c379; font-weight: bold; }
.hvideo-sec1-hl-blue { color: #61afef; font-weight: bold; }
.hvideo-sec1-hl-red { color: #e06c75; font-weight: bold; }動画をWebサイトに埋め込む上で理解しておかなければならないのが、ブラウザがサポートしている動画フォーマットと正しいメディアタイプの指定です。
Webサイトで動画を扱う場合は、ブラウザで再生可能なmp4形式に変換(エンコード)して使用してください。
さらに表示速度を極めたい場合は、Googleが開発した軽量で高画質なwebm形式をメインに設定し、予備としてmp4を配置するのが現代のベストプラクティスです。
軽量・高画質。
優先して読み込ませる。
全ブラウザ対応。
必ず用意する標準形式。
スマホやPCの環境によって
再生エラーになる危険性あり。
<div class="hvideo-sec2-wrapper">
<div class="hvideo-sec2-demo-area">
<div class="hvideo-sec2-box">
<div class="hvideo-sec2-label">📦 動画フォーマットの正しい使い分け</div>
<div class="hvideo-sec2-visual">
<div class="hvideo-sec2-format-grid">
<div class="hvideo-sec2-format-item hvideo-sec2-format-ok">
<span class="hvideo-sec2-badge-ok">推奨</span>
<strong>.webm</strong>
<p>軽量・高画質。<br>優先して読み込ませる。</p>
</div>
<div class="hvideo-sec2-format-item hvideo-sec2-format-ok">
<span class="hvideo-sec2-badge-ok">必須</span>
<strong>.mp4</strong>
<p>全ブラウザ対応。<br>必ず用意する標準形式。</p>
</div>
<div class="hvideo-sec2-format-item hvideo-sec2-format-ng">
<span class="hvideo-sec2-badge-ng">NG</span>
<strong>.mov / .avi</strong>
<p>スマホやPCの環境によって<br>再生エラーになる危険性あり。</p>
</div>
</div>
</div>
<div class="hvideo-sec2-code">
<video controls><br>
<!-- 💡 優先度1:容量が軽く表示が早い WebM を上に書く --><br>
<source src="video<span class="hvideo-sec2-hl-green">.webm</span>" type="<span class="hvideo-sec2-hl-blue">video/webm</span>"><br><br>
<!-- 💡 優先度2:WebM非対応ブラウザ(古いSafari等)向けの MP4 --><br>
<source src="video<span class="hvideo-sec2-hl-green">.mp4</span>" type="<span class="hvideo-sec2-hl-blue">video/mp4</span>"><br><br>
<!-- ❌ 絶対に書いてはいけない形式(変換ツールでMP4にする) --><br>
<!-- <source src="video<span class="hvideo-sec2-hl-red">.mov</span>" type="video/quicktime"> --><br>
<!-- <source src="video<span class="hvideo-sec2-hl-red">.avi</span>" type="video/x-msvideo"> --><br>
</video>
</div>
</div>
</div>
</div>.hvideo-sec2-wrapper {
background-color: #f8f9fa;
padding: 20px;
border: 1px solid #dee2e6;
border-radius: 4px;
font-family: sans-serif;
}
.hvideo-sec2-demo-area {
display: flex;
justify-content: center;
}
.hvideo-sec2-box {
background-color: #ffffff;
border: 2px dashed #adb5bd;
padding: 25px;
width: 100%;
max-width: 550px;
border-radius: 4px;
}
.hvideo-sec2-label {
font-size: 15px;
font-weight: bold;
margin-bottom: 20px;
color: #333;
}
.hvideo-sec2-visual {
background-color: #f1f3f5;
padding: 20px;
border-radius: 8px;
margin-bottom: 20px;
border: 1px solid #dee2e6;
}
.hvideo-sec2-format-grid {
display: flex;
flex-direction: column;
gap: 10px;
}
.hvideo-sec2-format-item {
padding: 15px;
border-radius: 4px;
background-color: #fff;
border-left: 4px solid #ccc;
position: relative;
}
.hvideo-sec2-format-ok {
border-left-color: #198754;
box-shadow: 0 2px 4px rgba(0,0,0,0.05);
}
.hvideo-sec2-format-ng {
border-left-color: #dc3545;
background-color: #f8d7da;
}
.hvideo-sec2-format-item strong {
display: block;
font-size: 16px;
color: #212529;
margin-bottom: 5px;
}
.hvideo-sec2-format-item p {
margin: 0;
font-size: 12px;
color: #495057;
line-height: 1.4;
}
.hvideo-sec2-badge-ok {
position: absolute;
top: 15px; right: 15px;
background-color: #198754;
color: white;
font-size: 10px;
padding: 2px 6px;
border-radius: 4px;
font-weight: bold;
}
.hvideo-sec2-badge-ng {
position: absolute;
top: 15px; right: 15px;
background-color: #dc3545;
color: white;
font-size: 10px;
padding: 2px 6px;
border-radius: 4px;
font-weight: bold;
}
.hvideo-sec2-code {
background-color: #282c34;
color: #abb2bf;
padding: 15px;
font-family: monospace;
font-size: 13px;
border-radius: 4px;
line-height: 1.6;
border-left: 4px solid #0d6efd;
}
.hvideo-sec2-hl-green { color: #98c379; font-weight: bold; }
.hvideo-sec2-hl-blue { color: #61afef; font-weight: bold; }
.hvideo-sec2-hl-red { color: #e06c75; font-weight: bold; }Webサイトのファーストビューなどで、背景として動画を動かし続ける「自動再生」や「ループ」の演出は、Webデザインにおいて定番の手法です。
タグにautoplayとloop属性を追加するだけの簡単な作業に思えます。
しかし、実際にはモバイルデバイス特有の厳格な仕様が存在し、属性をつけただけでは「スマホで見たら動画が止まったままになっている」という事故が多発します。
ここでは、PCだけでなくスマートフォン環境でも自動再生を機能させる必須属性と再生されない時の原因・対策を解説します。
autoplay・muted・playsinlineの組み合わせ背景動画やUIの装飾として動画を無音で自動ループさせる場合、つまづきやすいのが「PCのChromeでは自動再生されたからOK」とテストを終えてしまうミスです。
動画を背景として自動再生させるには、autoplay muted playsinline loopの4点セットを一緒に記述してください。
※なお、ユーザーの操作を待ってから再生させたい場合は、autoplay属性を記述しないだけで機能します。
⭕️ 背景動画で必須となる「4点セット」
<div class="hvideo-auto1-wrapper">
<div class="hvideo-auto1-demo-area">
<div class="hvideo-auto1-box">
<div class="hvideo-auto1-label">🔄 スマホ対応の自動再生・ループ設定</div>
<div class="hvideo-auto1-visual">
<p style="font-size:12px; color:#198754; font-weight:bold; margin:0 0 5px 0;">⭕️ 背景動画で必須となる「4点セット」</p>
<div class="hvideo-auto1-mock-bg">
<div class="hvideo-auto1-mock-video-area">
<span style="font-size:24px;">🎞️</span>
<div style="font-size:12px; margin-top:5px; color:#fff;">無音で永遠にループ再生中...</div>
</div>
<div class="hvideo-auto1-mock-text">Main Visual</div>
</div>
</div>
<div class="hvideo-auto1-code">
<!-- ❌ 危険:スマホで再生されない、全画面になる --><br>
<video src="bg.mp4" <span class="hvideo-auto1-hl-red">autoplay loop</span>></video><br><br>
<!-- ⭕️ 安全:実務で必ず使う鉄壁の4点セット --><br>
<span class="hvideo-auto1-hl-blue"><video</span> <br>
src="bg.mp4" <br>
<span class="hvideo-auto1-hl-green">autoplay</span> <span class="hvideo-auto1-hl-comment"><!-- 自動再生 --></span><br>
<span class="hvideo-auto1-hl-green">muted</span> <span class="hvideo-auto1-hl-comment"><!-- ★スマホ必須:無音にする --></span><br>
<span class="hvideo-auto1-hl-green">playsinline</span> <span class="hvideo-auto1-hl-comment"><!-- ★iPhone必須:全画面化を防ぐ --></span><br>
<span class="hvideo-auto1-hl-green">loop</span> <span class="hvideo-auto1-hl-comment"><!-- ループ再生 --></span><br>
<span class="hvideo-auto1-hl-blue">></video></span><br><br>
<!-- 💡 補足:自動再生させない場合は単に外すだけ --><br>
<video src="movie.mp4" controls playsinline></video>
</div>
</div>
</div>
</div>.hvideo-auto1-wrapper {
background-color: #f8f9fa;
padding: 20px;
border: 1px solid #dee2e6;
border-radius: 4px;
font-family: sans-serif;
}
.hvideo-auto1-demo-area {
display: flex;
justify-content: center;
}
.hvideo-auto1-box {
background-color: #ffffff;
border: 2px dashed #adb5bd;
padding: 25px;
width: 100%;
max-width: 500px;
border-radius: 4px;
}
.hvideo-auto1-label {
font-size: 15px;
font-weight: bold;
margin-bottom: 20px;
color: #333;
}
.hvideo-auto1-visual {
background-color: #f1f3f5;
padding: 20px;
border-radius: 8px;
margin-bottom: 20px;
border: 1px solid #dee2e6;
}
.hvideo-auto1-mock-bg {
position: relative;
width: 100%;
height: 120px;
background-color: #212529;
border-radius: 4px;
overflow: hidden;
display: flex;
justify-content: center;
align-items: center;
}
.hvideo-auto1-mock-video-area {
position: absolute;
top: 0; left: 0; width: 100%; height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
opacity: 0.5;
background-image: repeating-linear-gradient(45deg, #343a40 25%, transparent 25%, transparent 75%, #343a40 75%, #343a40), repeating-linear-gradient(45deg, #343a40 25%, #212529 25%, #212529 75%, #343a40 75%, #343a40);
background-size: 20px 20px;
}
.hvideo-auto1-mock-text {
position: relative;
z-index: 2;
color: #fff;
font-size: 20px;
font-weight: bold;
letter-spacing: 2px;
}
.hvideo-auto1-code {
background-color: #282c34;
color: #abb2bf;
padding: 15px;
font-family: monospace;
font-size: 13px;
border-radius: 4px;
line-height: 1.6;
border-left: 4px solid #198754;
}
.hvideo-auto1-hl-green { color: #98c379; font-weight: bold; }
.hvideo-auto1-hl-blue { color: #61afef; font-weight: bold; }
.hvideo-auto1-hl-red { color: #e06c75; font-weight: bold; }
.hvideo-auto1-hl-comment { color: #6c757d; font-style: italic; }4点セット(autoplay muted playsinline loop)を書いたはずなのに、「iPhoneで確認したら自動再生されない」「スマホ実機で動かない」とパニックに陥るケースは実務でも多いです。
「低電力モードのユーザーには自動再生されないもの」と割り切るのが大前提です。
その上で、自動再生がブロックされてしまった場合、動画エリアが真っ黒な四角になるのを防ぐため、poster属性を使用して「動画が再生される代わりの画像」を設定しておくのがよいです。
⚠️ 自動再生がブロックされた場合の見た目
❌ poster設定なし
⭕️ poster設定あり
<div class="hvideo-auto2-wrapper">
<div class="hvideo-auto2-demo-area">
<div class="hvideo-auto2-box">
<div class="hvideo-auto2-label">🔋 低電力モードによる自動再生ブロック対策</div>
<div class="hvideo-auto2-visual">
<p style="font-size:12px; color:#dc3545; font-weight:bold; margin:0 0 5px 0;">⚠️ 自動再生がブロックされた場合の見た目</p>
<div style="display:flex; gap:10px; justify-content:center;">
<div style="flex:1;">
<p style="font-size:11px; text-align:center; color:#666; margin:0 0 5px 0;">❌ poster設定なし</p>
<div class="hvideo-auto2-mock-noposter">
<span>(真っ黒・無反応)</span>
</div>
</div>
<div style="flex:1;">
<p style="font-size:11px; text-align:center; color:#666; margin:0 0 5px 0;">⭕️ poster設定あり</p>
<div class="hvideo-auto2-mock-poster">
<span>綺麗な代替画像<br>が表示される</span>
</div>
</div>
</div>
</div>
<div class="hvideo-auto2-code">
<!-- 💡 動画が動かない時は poster に指定した画像を表示 --><br>
<span class="hvideo-auto2-hl-blue"><video</span> <br>
src="main-visual.mp4" <br>
<span class="hvideo-auto2-hl-red">poster="fallback-image.jpg"</span> <span class="hvideo-auto2-hl-comment"><!-- ★これが命綱! --></span><br>
autoplay muted playsinline loop<br>
<span class="hvideo-auto2-hl-blue">></video></span><br><br>
/* 💡 (補足知識)JavaScriptでのエラー検知と再生 */<br>
<span class="hvideo-auto2-hl-blue">const</span> video = document.querySelector('video');<br>
<span class="hvideo-auto2-hl-blue">const</span> playPromise = video.play();<br><br>
<span class="hvideo-auto2-hl-blue">if</span> (playPromise !== undefined) {<br>
playPromise.catch(error => {<br>
<span class="hvideo-auto2-hl-comment">// 自動再生がブロックされた場合の処理</span><br>
<span class="hvideo-auto2-hl-comment">// (例: 代わりに「再生ボタン」を画面に出す等)</span><br>
console.log("自動再生がブロックされました");<br>
});<br>
}
</div>
</div>
</div>
</div>.hvideo-auto2-wrapper {
background-color: #f8f9fa;
padding: 20px;
border: 1px solid #dee2e6;
border-radius: 4px;
font-family: sans-serif;
}
.hvideo-auto2-demo-area {
display: flex;
justify-content: center;
}
.hvideo-auto2-box {
background-color: #ffffff;
border: 2px dashed #adb5bd;
padding: 25px;
width: 100%;
max-width: 550px;
border-radius: 4px;
}
.hvideo-auto2-label {
font-size: 15px;
font-weight: bold;
margin-bottom: 20px;
color: #333;
}
.hvideo-auto2-visual {
background-color: #f1f3f5;
padding: 15px;
border-radius: 8px;
margin-bottom: 20px;
border: 1px solid #dee2e6;
}
.hvideo-auto2-mock-noposter {
background-color: #000;
height: 90px;
border-radius: 4px;
display: flex;
justify-content: center;
align-items: center;
color: #fff;
font-size: 10px;
}
.hvideo-auto2-mock-poster {
background-color: #0d6efd;
background-image: linear-gradient(135deg, rgba(255,255,255,0.1) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.1) 50%, rgba(255,255,255,0.1) 75%, transparent 75%, transparent);
background-size: 20px 20px;
height: 90px;
border-radius: 4px;
display: flex;
justify-content: center;
align-items: center;
color: #fff;
font-size: 10px;
text-align: center;
box-shadow: inset 0 0 10px rgba(0,0,0,0.2);
}
.hvideo-auto2-code {
background-color: #282c34;
color: #abb2bf;
padding: 15px;
font-family: monospace;
font-size: 13px;
border-radius: 4px;
line-height: 1.6;
border-left: 4px solid #dc3545;
}
.hvideo-auto2-hl-red { color: #e06c75; font-weight: bold; }
.hvideo-auto2-hl-blue { color: #61afef; font-weight: bold; }
.hvideo-auto2-hl-comment { color: #6c757d; font-style: italic; }HTMLで<video>タグを配置した後は、サイトのデザインに合わせて見た目を整えるCSSの出番です。
Web制作では、PCでもスマートフォンでも画面に合わせて伸縮するレスポンシブ対応、画面いっぱいに広がる背景動画の実装が必須スキルになります。
ここでは、videoサイズの指定、CSSを用いたサイズ自動調整などを解説します。
object-fitを使った全画面背景動画動画のサイズを変更し、スマホ画面からはみ出さないように親要素にフィットさせる基本的なレスポンシブ設定です。
動画のアスペクト比を保ったままレスポンシブにするには、width: 100%;を指定し、高さはheight: auto;に設定します。
これにより、ブラウザが幅に合わせて高さを自動計算し、動画が歪まなくなります。
❌ 悪い例:height: 100% で潰れてしまう
⭕️ 良い例:height: auto で比率をキープ
<div class="hvideo-css1-wrapper">
<div class="hvideo-css1-demo-area">
<div class="hvideo-css1-box">
<div class="hvideo-css1-label">📱 アスペクト比を保ったレスポンシブ動画</div>
<div class="hvideo-css1-visual">
<p style="font-size:12px; color:#dc3545; font-weight:bold; margin:0 0 5px 0;">❌ 悪い例:height: 100% で潰れてしまう</p>
<div class="hvideo-css1-mock-container" style="height: 100px;">
<div class="hvideo-css1-mock-video hvideo-css1-bad">動画が潰れる</div>
</div>
<p style="font-size:12px; color:#198754; font-weight:bold; margin:20px 0 5px 0;">⭕️ 良い例:height: auto で比率をキープ</p>
<div class="hvideo-css1-mock-container">
<div class="hvideo-css1-mock-video hvideo-css1-good">比率キープ(16:9)</div>
</div>
</div>
<div class="hvideo-css1-code">
<!-- HTML --><br>
<span class="hvideo-css1-hl-blue"><div class="video-wrap"></span><br>
<video src="movie.mp4" class="responsive-video"></video><br>
<span class="hvideo-css1-hl-blue"></div></span><br><br>
/* 💡 悪い例:動画が歪む */<br>
<span class="hvideo-css1-hl-blue">.bad-video</span> {<br>
width: 100%;<br>
<span class="hvideo-css1-hl-red">height: 100%;</span> /* ★絶対NG */<br>
}<br><br>
/* 💡 良い例:アスペクト比を維持して伸縮 */<br>
<span class="hvideo-css1-hl-blue">.responsive-video</span> {<br>
<span class="hvideo-css1-hl-green">width: 100%;</span><br>
<span class="hvideo-css1-hl-green">height: auto;</span> /* ★ブラウザに高さを自動計算させる */<br>
display: block; /* 謎の余白(下部)を消すためのおまじない */<br>
}
</div>
</div>
</div>
</div>.hvideo-css1-wrapper {
background-color: #f8f9fa;
padding: 20px;
border: 1px solid #dee2e6;
border-radius: 4px;
font-family: sans-serif;
}
.hvideo-css1-demo-area {
display: flex;
justify-content: center;
}
.hvideo-css1-box {
background-color: #ffffff;
border: 2px dashed #adb5bd;
padding: 25px;
width: 100%;
max-width: 500px;
border-radius: 4px;
}
.hvideo-css1-label {
font-size: 15px;
font-weight: bold;
margin-bottom: 20px;
color: #333;
}
.hvideo-css1-visual {
background-color: #f1f3f5;
padding: 20px;
border-radius: 8px;
margin-bottom: 20px;
border: 1px solid #dee2e6;
}
.hvideo-css1-mock-container {
width: 100%;
border: 2px solid #0d6efd;
background-color: #fff;
}
.hvideo-css1-mock-video {
background-color: #212529;
color: #fff;
display: flex;
justify-content: center;
align-items: center;
font-size: 12px;
font-weight: bold;
background-image: repeating-linear-gradient(45deg, rgba(255,255,255,0.05) 25%, transparent 25%, transparent 75%, rgba(255,255,255,0.05) 75%, rgba(255,255,255,0.05)), repeating-linear-gradient(45deg, rgba(255,255,255,0.05) 25%, transparent 25%, transparent 75%, rgba(255,255,255,0.05) 75%, rgba(255,255,255,0.05));
background-size: 20px 20px;
}
.hvideo-css1-bad {
width: 100%;
height: 100%; /* 親の100pxに潰される */
}
.hvideo-css1-good {
width: 100%;
aspect-ratio: 16 / 9; /* height:autoの代用モック */
}
.hvideo-css1-code {
background-color: #282c34;
color: #abb2bf;
padding: 15px;
font-family: monospace;
font-size: 13px;
border-radius: 4px;
line-height: 1.6;
border-left: 4px solid #198754;
}
.hvideo-css1-hl-green { color: #98c379; font-weight: bold; }
.hvideo-css1-hl-blue { color: #61afef; font-weight: bold; }
.hvideo-css1-hl-red { color: #e06c75; font-weight: bold; }幅と高さの指定方法を詳しく知りたい人は「【html&css】width(横幅)とheight(高さ)の指定とボックスモデル」を一読ください。
Webサイトのトップページで、画面全体に動画を敷き詰め、その上に文字を乗せる「背景動画」は人気の高いレイアウトです。
背景動画を作るには、動画をposition: absolute;で画面いっぱいに広げた上で、object-fit: cover;を指定します。
これにより、動画の比率を保ったまま、余った部分を自動的にトリミング(切り抜き)して、画面(親要素)に隙間なくフィットできます。
⭕️ 比率を崩さず、はみ出した分をトリミングして埋め尽くす
動画の上に文字が乗っています
<div class="hvideo-css2-wrapper">
<div class="hvideo-css2-demo-area">
<div class="hvideo-css2-box">
<div class="hvideo-css2-label">🪟 object-fitを使った全画面背景動画</div>
<div class="hvideo-css2-visual">
<p style="font-size:12px; color:#198754; font-weight:bold; margin:0 0 5px 0;">⭕️ 比率を崩さず、はみ出した分をトリミングして埋め尽くす</p>
<div class="hvideo-css2-hero-mock">
<div class="hvideo-css2-video-mock"></div>
<div class="hvideo-css2-content-mock">
<div style="margin:0; font-size:20px; letter-spacing:2px;">HERO SECTION</div>
<p style="margin:5px 0 0 0; font-size:12px;">動画の上に文字が乗っています</p>
</div>
</div>
</div>
<div class="hvideo-css2-code">
<!-- HTML --><br>
<span class="hvideo-css2-hl-blue"><div class="hero-area"></span><br>
<span class="hvideo-css2-hl-comment"><!-- 💡 必須:自動再生ループの4点セット --></span><br>
<video src="bg.mp4" class="bg-video" autoplay muted playsinline loop></video><br>
<div class="hero-content">動画の上の文字</div><br>
<span class="hvideo-css2-hl-blue"></div></span><br><br>
/* CSS */<br>
<span class="hvideo-css2-hl-blue">.hero-area</span> {<br>
<span class="hvideo-css2-hl-green">position: relative;</span> /* 子要素の基準点にする */<br>
height: 100vh; /* 画面の高さ100% */<br>
overflow: hidden; /* はみ出た動画を隠す */<br>
}<br><br>
<span class="hvideo-css2-hl-blue">.bg-video</span> {<br>
<span class="hvideo-css2-hl-green">position: absolute;</span> /* 親要素に重なるように絶対配置 */<br>
top: 0; left: 0;<br>
width: 100%; height: 100%;<br>
<span class="hvideo-css2-hl-red">object-fit: cover;</span> /* 比率を保って隙間なく埋める */<br>
z-index: -1; /* 文字の裏側に回す */<br>
}
</div>
</div>
</div>
</div>.hvideo-css2-wrapper {
background-color: #f8f9fa;
padding: 20px;
border: 1px solid #dee2e6;
border-radius: 4px;
font-family: sans-serif;
}
.hvideo-css2-demo-area {
display: flex;
justify-content: center;
}
.hvideo-css2-box {
background-color: #ffffff;
border: 2px dashed #adb5bd;
padding: 25px;
width: 100%;
max-width: 500px;
border-radius: 4px;
}
.hvideo-css2-label {
font-size: 15px;
font-weight: bold;
margin-bottom: 20px;
color: #333;
}
.hvideo-css2-visual {
background-color: #f1f3f5;
padding: 20px;
border-radius: 8px;
margin-bottom: 20px;
border: 1px solid #dee2e6;
}
.hvideo-css2-hero-mock {
position: relative;
width: 100%;
height: 150px;
border-radius: 4px;
overflow: hidden;
display: flex;
justify-content: center;
align-items: center;
border: 2px solid #333;
}
.hvideo-css2-video-mock {
position: absolute;
top: 0; left: 0;
width: 100%; height: 100%;
background-color: #0d6efd;
background-image: radial-gradient(circle, #0b5ed7 10%, transparent 20%);
background-size: 30px 30px;
opacity: 0.8;
z-index: 1; /* 手前の文字より下にするモック用設定 */
}
.hvideo-css2-content-mock {
position: relative;
z-index: 2; /* 動画より手前に出す */
color: #fff;
text-align: center;
text-shadow: 0 2px 4px rgba(0,0,0,0.5); /* 文字を読みやすくする影 */
}
.hvideo-css2-code {
background-color: #282c34;
color: #abb2bf;
padding: 15px;
font-family: monospace;
font-size: 13px;
border-radius: 4px;
line-height: 1.6;
border-left: 4px solid #198754;
}
.hvideo-css2-hl-green { color: #98c379; font-weight: bold; }
.hvideo-css2-hl-blue { color: #61afef; font-weight: bold; }
.hvideo-css2-hl-red { color: #e06c75; font-weight: bold; }
.hvideo-css2-hl-comment { color: #6c757d; font-style: italic; }positionプロパティの使い方を詳しく知りたい人は「【html&css】positionの使い方とabsolute・fixed・relativeの使い分け」を一読ください。
埋め込んだ動画をサイトのデザインに馴染ませるため、角を丸くしたり、枠線やドロップシャドウを付けたりする装飾もCSSで行えます。
動画を装飾する場合は、動画タグにCSSクラスを当てるのではなく、動画を囲む親の枠を作り、親要素に対して角丸や影(overflow: hidden;とセット)を指定するのが安全でバグの出ない実装です。
⭕️ 親コンテナに装飾をかけて安全に切り抜く
<div class="hvideo-css3-wrapper">
<div class="hvideo-css3-demo-area">
<div class="hvideo-css3-box">
<div class="hvideo-css3-label">🎨 角丸と影(シャドウ)の安全なデザイン調整</div>
<div class="hvideo-css3-visual">
<p style="font-size:12px; color:#198754; font-weight:bold; margin:0 0 5px 0;">⭕️ 親コンテナに装飾をかけて安全に切り抜く</p>
<div class="hvideo-css3-mock-outer">
<div class="hvideo-css3-mock-inner">
<span style="font-size:30px; color:#fff;">▶</span>
</div>
</div>
</div>
<div class="hvideo-css3-code">
<!-- HTML --><br>
<span class="hvideo-css3-hl-blue"><div class="video-container"></span><br>
<video src="movie.mp4" controls></video><br>
<span class="hvideo-css3-hl-blue"></div></span><br><br>
/* CSS */<br>
<span class="hvideo-css3-hl-blue">.video-container</span> {<br>
width: 100%;<br>
<span class="hvideo-css3-hl-green">border-radius: 20px;</span> /* ★ここで角丸にする */<br>
<span class="hvideo-css3-hl-red">overflow: hidden;</span> /* ★必須:はみ出た動画の角を切り落とす */<br>
<span class="hvideo-css3-hl-green">box-shadow: 0 10px 20px rgba(0, 0, 0, 0.2);</span> /* 影をつける */<br>
border: 4px solid #fff; /* 白い枠線 */<br>
}<br><br>
<span class="hvideo-css3-hl-blue">.video-container video</span> {<br>
width: 100%;<br>
height: auto;<br>
display: block;<br>
<span class="hvideo-css3-hl-comment">/* videoタグ自体には装飾しないのが安全 */</span><br>
}
</div>
</div>
</div>
</div>.hvideo-css3-wrapper {
background-color: #f8f9fa;
padding: 20px;
border: 1px solid #dee2e6;
border-radius: 4px;
font-family: sans-serif;
}
.hvideo-css3-demo-area {
display: flex;
justify-content: center;
}
.hvideo-css3-box {
background-color: #ffffff;
border: 2px dashed #adb5bd;
padding: 25px;
width: 100%;
max-width: 500px;
border-radius: 4px;
}
.hvideo-css3-label {
font-size: 15px;
font-weight: bold;
margin-bottom: 20px;
color: #333;
}
.hvideo-css3-visual {
background-color: #f1f3f5;
padding: 20px;
border-radius: 8px;
margin-bottom: 20px;
border: 1px solid #dee2e6;
display: flex;
flex-direction: column;
align-items: center;
}
.hvideo-css3-mock-outer {
width: 80%;
aspect-ratio: 16 / 9;
border-radius: 20px; /* 角丸 */
overflow: hidden; /* はみ出しを隠す */
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.2); /* 影 */
border: 4px solid #fff; /* 枠線 */
background-color: #fff;
}
.hvideo-css3-mock-inner {
width: 100%; height: 100%;
background-color: #6c757d;
display: flex;
justify-content: center;
align-items: center;
}
.hvideo-css3-code {
background-color: #282c34;
color: #abb2bf;
padding: 15px;
font-family: monospace;
font-size: 13px;
border-radius: 4px;
line-height: 1.6;
border-left: 4px solid #198754;
}
.hvideo-css3-hl-green { color: #98c379; font-weight: bold; }
.hvideo-css3-hl-blue { color: #61afef; font-weight: bold; }
.hvideo-css3-hl-red { color: #e06c75; font-weight: bold; }
.hvideo-css3-hl-comment { color: #6c757d; font-style: italic; }角丸や枠線・影のデザインを詳しく知りたい人は以下から一読ください。
HTMLの<video>タグには、ユーザーが動画を操作する再生ボタンやシークバーを表示する機能が標準で備わっています。
動画をコンテンツとして見せる場合、背景動画として操作パネルを消したい場合、「動画の保存防止」、コントロールバー周りの設定方法を解説します。
controls属性の表示・非表示と各種ボタン動画プレイヤーに標準の操作パネルを表示させるには、controls属性を使用します。
<video controls>と書きます。controlsという単語自体をタグから削除します。⭕️ 表示(controls を記述)
⭕️ 非表示(属性ごと削除する)
※ controls=”false” は機能しないため注意
<div class="hvideo-ctrl1-wrapper">
<div class="hvideo-ctrl1-demo-area">
<div class="hvideo-ctrl1-box">
<div class="hvideo-ctrl1-label">🎛️ controls属性の表示と非表示</div>
<div class="hvideo-ctrl1-visual">
<div style="display:flex; flex-direction:column; gap:15px;">
<div>
<p style="font-size:12px; color:#198754; font-weight:bold; margin:0 0 5px 0;">⭕️ 表示(controls を記述)</p>
<div class="hvideo-ctrl1-mock-player">
<div class="hvideo-ctrl1-mock-screen">動画</div>
<div class="hvideo-ctrl1-mock-bar">
<span>▶</span><span>🔊</span><span style="flex-grow:1; border-bottom:2px solid #ccc; margin:0 10px;"></span><span>⛶</span>
</div>
</div>
</div>
<div>
<p style="font-size:12px; color:#dc3545; font-weight:bold; margin:0 0 5px 0;">⭕️ 非表示(属性ごと削除する)</p>
<div class="hvideo-ctrl1-mock-player">
<div class="hvideo-ctrl1-mock-screen">動画 (操作バーなし)</div>
</div>
<p style="font-size:11px; color:#666; margin-top:5px;">※ controls="false" は機能しないため注意</p>
</div>
</div>
</div>
<div class="hvideo-ctrl1-code">
<!-- ⭕️ 表示させたい場合 --><br>
<video src="movie.mp4" <span class="hvideo-ctrl1-hl-green">controls</span>></video><br><br>
<!-- ❌ 間違い:これでも表示されてしまう! --><br>
<video src="movie.mp4" <span class="hvideo-ctrl1-hl-red">controls="false"</span>></video><br><br>
<!-- ⭕️ 非表示にしたい場合(単に書かない) --><br>
<span class="hvideo-ctrl1-hl-blue"><video src="movie.mp4"></video></span>
</div>
</div>
</div>
</div>.hvideo-ctrl1-wrapper {
background-color: #f8f9fa;
padding: 20px;
border: 1px solid #dee2e6;
border-radius: 4px;
font-family: sans-serif;
}
.hvideo-ctrl1-demo-area {
display: flex;
justify-content: center;
}
.hvideo-ctrl1-box {
background-color: #ffffff;
border: 2px dashed #adb5bd;
padding: 25px;
width: 100%;
max-width: 500px;
border-radius: 4px;
}
.hvideo-ctrl1-label {
font-size: 15px;
font-weight: bold;
margin-bottom: 20px;
color: #333;
}
.hvideo-ctrl1-visual {
background-color: #f1f3f5;
padding: 15px;
border-radius: 8px;
margin-bottom: 20px;
border: 1px solid #dee2e6;
}
.hvideo-ctrl1-mock-player {
background-color: #212529;
border-radius: 4px;
overflow: hidden;
border: 1px solid #000;
}
.hvideo-ctrl1-mock-screen {
height: 60px;
display: flex;
justify-content: center;
align-items: center;
color: #fff;
font-size: 12px;
background-image: repeating-linear-gradient(45deg, #343a40 10%, transparent 10%, transparent 20%, #343a40 20%, #343a40 30%);
}
.hvideo-ctrl1-mock-bar {
background-color: #f8f9fa;
padding: 5px 10px;
display: flex;
align-items: center;
font-size: 14px;
color: #333;
}
.hvideo-ctrl1-code {
background-color: #282c34;
color: #abb2bf;
padding: 15px;
font-family: monospace;
font-size: 13px;
border-radius: 4px;
line-height: 1.6;
border-left: 4px solid #0d6efd;
}
.hvideo-ctrl1-hl-green { color: #98c379; font-weight: bold; }
.hvideo-ctrl1-hl-blue { color: #61afef; font-weight: bold; }
.hvideo-ctrl1-hl-red { color: #e06c75; font-weight: bold; }動画が読み込まれる前や再生されるまでの間に表示しておく画像は、poster属性を使って指定します。
<video>タグに対してobject-fit: cover;を指定します。poster画像も動画領域に隙間なくトリミングされて配置されるようになります。⭕️ poster属性とobject-fitで綺麗に表示
<div class="hvideo-ctrl2-wrapper">
<div class="hvideo-ctrl2-demo-area">
<div class="hvideo-ctrl2-box">
<div class="hvideo-ctrl2-label">🖼️ サムネイル画像(poster)の設定</div>
<div class="hvideo-ctrl2-visual">
<p style="font-size:12px; color:#198754; font-weight:bold; margin:0 0 5px 0;">⭕️ poster属性とobject-fitで綺麗に表示</p>
<div class="hvideo-ctrl2-mock-video">
<div class="hvideo-ctrl2-mock-poster">
サムネイル画像 (poster.jpg)
<div class="hvideo-ctrl2-mock-playbtn">▶</div>
</div>
</div>
</div>
<div class="hvideo-ctrl2-code">
<!-- HTML --><br>
<video <br>
src="movie.mp4" <br>
<span class="hvideo-ctrl2-hl-green">poster="thumbnail.jpg"</span> <span class="hvideo-ctrl2-hl-comment"><!-- ★サムネイルを指定 --></span><br>
controls <br>
class="cover-video"<br>
></video><br><br>
/* CSS */<br>
<span class="hvideo-ctrl2-hl-blue">.cover-video</span> {<br>
width: 100%;<br>
aspect-ratio: 16 / 9;<br>
<span class="hvideo-ctrl2-hl-red">object-fit: cover;</span> <span class="hvideo-ctrl2-hl-comment">/* ★黒帯を消し、隙間なく埋める */</span><br>
}
</div>
</div>
</div>
</div>.hvideo-ctrl2-wrapper {
background-color: #f8f9fa;
padding: 20px;
border: 1px solid #dee2e6;
border-radius: 4px;
font-family: sans-serif;
}
.hvideo-ctrl2-demo-area {
display: flex;
justify-content: center;
}
.hvideo-ctrl2-box {
background-color: #ffffff;
border: 2px dashed #adb5bd;
padding: 25px;
width: 100%;
max-width: 500px;
border-radius: 4px;
}
.hvideo-ctrl2-label {
font-size: 15px;
font-weight: bold;
margin-bottom: 20px;
color: #333;
}
.hvideo-ctrl2-visual {
background-color: #f1f3f5;
padding: 20px;
border-radius: 8px;
margin-bottom: 20px;
border: 1px solid #dee2e6;
}
.hvideo-ctrl2-mock-video {
width: 100%;
aspect-ratio: 16 / 9;
background-color: #000;
border-radius: 4px;
overflow: hidden;
position: relative;
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
}
.hvideo-ctrl2-mock-poster {
width: 100%;
height: 100%;
background-color: #0d6efd;
background-image: linear-gradient(135deg, #0b5ed7 25%, transparent 25%, transparent 50%, #0b5ed7 50%, #0b5ed7 75%, transparent 75%, transparent);
background-size: 40px 40px;
display: flex;
justify-content: center;
align-items: center;
color: #fff;
font-weight: bold;
font-size: 14px;
text-shadow: 0 2px 4px rgba(0,0,0,0.5);
position: relative;
}
.hvideo-ctrl2-mock-playbtn {
position: absolute;
background-color: rgba(0,0,0,0.6);
width: 50px; height: 50px;
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
font-size: 20px;
border: 2px solid #fff;
}
.hvideo-ctrl2-code {
background-color: #282c34;
color: #abb2bf;
padding: 15px;
font-family: monospace;
font-size: 13px;
border-radius: 4px;
line-height: 1.6;
border-left: 4px solid #198754;
}
.hvideo-ctrl2-hl-green { color: #98c379; font-weight: bold; }
.hvideo-ctrl2-hl-blue { color: #61afef; font-weight: bold; }
.hvideo-ctrl2-hl-red { color: #e06c75; font-weight: bold; }
.hvideo-ctrl2-hl-comment { color: #6c757d; font-style: italic; }「自社の動画を勝手に保存されたくない」という要望はWeb制作において多く、動画の保存を防ぐ対策が求められます。
HTMLとJavaScriptでできるダウンロードの防止は、あくまで「一般ユーザーのうっかり保存を防ぐ簡易的な対策」であると顧客に説明することが重要です。
その上で行うべき具体的な防御策は以下の2つです。
controlsList="nodownload"oncontextmenu="return false;"⚠️ 注意:拡張機能等による保存を完全に防ぐものではありません
<div class="hvideo-ctrl3-wrapper">
<div class="hvideo-ctrl3-demo-area">
<div class="hvideo-ctrl3-box">
<div class="hvideo-ctrl3-label">🚫 ダウンロードボタンと右クリックの禁止</div>
<div class="hvideo-ctrl3-visual">
<p style="font-size:12px; color:#dc3545; font-weight:bold; margin:0 0 5px 0;">⚠️ 注意:拡張機能等による保存を完全に防ぐものではありません</p>
<div class="hvideo-ctrl3-mock-video">
<div style="font-size:12px; color:#fff; text-align:center;">
1. ダウンロードボタンが消える<br>
2. 右クリックしてもメニューが出ない
</div>
</div>
</div>
<div class="hvideo-ctrl3-code">
<video <br>
src="movie.mp4"<br>
controls <br>
<span class="hvideo-ctrl3-hl-green">controlsList="nodownload"</span> <span class="hvideo-ctrl3-hl-comment"><!-- 1. DLボタンを非表示 --></span><br>
<span class="hvideo-ctrl3-hl-red">oncontextmenu="return false;"</span> <span class="hvideo-ctrl3-hl-comment"><!-- 2. 右クリック禁止 --></span><br>
></video>
</div>
</div>
</div>
</div>.hvideo-ctrl3-wrapper {
background-color: #f8f9fa;
padding: 20px;
border: 1px solid #dee2e6;
border-radius: 4px;
font-family: sans-serif;
}
.hvideo-ctrl3-demo-area {
display: flex;
justify-content: center;
}
.hvideo-ctrl3-box {
background-color: #ffffff;
border: 2px dashed #adb5bd;
padding: 25px;
width: 100%;
max-width: 500px;
border-radius: 4px;
}
.hvideo-ctrl3-label {
font-size: 15px;
font-weight: bold;
margin-bottom: 20px;
color: #333;
}
.hvideo-ctrl3-visual {
background-color: #f1f3f5;
padding: 20px;
border-radius: 8px;
margin-bottom: 20px;
border: 1px solid #dee2e6;
}
.hvideo-ctrl3-mock-video {
width: 100%;
height: 100px;
background-color: #212529;
border-radius: 4px;
display: flex;
justify-content: center;
align-items: center;
border: 1px solid #000;
cursor: not-allowed;
}
.hvideo-ctrl3-code {
background-color: #282c34;
color: #abb2bf;
padding: 15px;
font-family: monospace;
font-size: 13px;
border-radius: 4px;
line-height: 1.6;
border-left: 4px solid #dc3545;
}
.hvideo-ctrl3-hl-green { color: #98c379; font-weight: bold; }
.hvideo-ctrl3-hl-red { color: #e06c75; font-weight: bold; }
.hvideo-ctrl3-hl-comment { color: #6c757d; font-style: italic; }HTMLの<video>タグに標準で備わっているcontrols属性は便利ですが、サイトのデザインに合わなかったり、機能が制限されていたりすることがあります。
実務で必須となるのが、JavaScriptを活用して、独自の動画プレイヤーを作成する技術です。
JavaScriptを使うことで、再生ボタンからシークバーまで、自由なデザインと仕様でコントロールできます。
ここでは、APIを利用した基本の操作、実務で直面する「シークバーの自作」や「イベント検知」を詳しく解説します。
カスタムプレイヤーを作るには、標準のコントロールバーを非表示にし、自前の再生ボタンや音量スライダーを用意することです。
JavaScriptから動画要素を取得し、play()やpause()メソッドを呼び出すだけで操作が可能です。
また、音量や再生速度もプロパティの数値を書き換えるだけで変更できます。
volumeプロパティは0.0(無音)から1.0(最大)までの小数点で指定します。0.5です。playbackRateプロパティを使用します。1.0で、2倍速なら2.0、スローなら0.5になります。<div class="hvideo-js1-wrapper">
<div class="hvideo-js1-demo-area">
<div class="hvideo-js1-box">
<div class="hvideo-js1-label">▶️ カスタムコントロール(再生・音量・速度)</div>
<div class="hvideo-js1-visual">
<div class="hvideo-js1-player-mock">
<div class="hvideo-js1-screen-mock" id="mockScreen1">
<span style="font-size:30px;">🎬</span>
<div id="mockStatus1" style="font-size:12px; margin-top:5px;">停止中</div>
</div>
<div class="hvideo-js1-custom-controls">
<button id="btnPlay1" class="hvideo-js1-btn">再生</button>
<button id="btnPause1" class="hvideo-js1-btn">停止</button>
<div class="hvideo-js1-control-group">
<label>音量</label>
<input type="range" id="volumeSlider" min="0" max="1" step="0.1" value="0.5">
</div>
<div class="hvideo-js1-control-group">
<label>速度</label>
<select id="speedSelect">
<option value="0.5">0.5x</option>
<option value="1.0" selected>1.0x</option>
<option value="2.0">2.0x</option>
</select>
</div>
</div>
</div>
</div>
<div class="hvideo-js1-code">
<span class="hvideo-js1-hl-blue">const</span> video = document.querySelector('video');<br><br>
/* 💡 1. 再生と一時停止 */<br>
btnPlay.addEventListener('click', () => {<br>
video.<span class="hvideo-js1-hl-green">play()</span>.catch(e => console.log("再生ブロック"));<br>
});<br>
btnPause.addEventListener('click', () => {<br>
video.<span class="hvideo-js1-hl-green">pause()</span>;<br>
});<br><br>
/* 💡 2. 音量の変更(※ 0.0 〜 1.0 の間で指定する!) */<br>
volumeSlider.addEventListener('input', (e) => {<br>
video.<span class="hvideo-js1-hl-red">volume</span> = e.target.value; <span class="hvideo-js1-hl-comment">// 例: 0.5</span><br>
});<br><br>
/* 💡 3. 再生速度の変更 */<br>
speedSelect.addEventListener('change', (e) => {<br>
video.<span class="hvideo-js1-hl-red">playbackRate</span> = e.target.value; <span class="hvideo-js1-hl-comment">// 例: 2.0</span><br>
});
</div>
</div>
</div>
</div>.hvideo-js1-wrapper {
background-color: #f8f9fa;
padding: 20px;
border: 1px solid #dee2e6;
border-radius: 4px;
font-family: sans-serif;
}
.hvideo-js1-demo-area {
display: flex;
justify-content: center;
}
.hvideo-js1-box {
background-color: #ffffff;
border: 2px dashed #adb5bd;
padding: 25px;
width: 100%;
max-width: 550px;
border-radius: 4px;
}
.hvideo-js1-label {
font-size: 15px;
font-weight: bold;
margin-bottom: 20px;
color: #333;
}
.hvideo-js1-visual {
background-color: #f1f3f5;
padding: 15px;
border-radius: 8px;
margin-bottom: 20px;
}
.hvideo-js1-player-mock {
border: 1px solid #ced4da;
border-radius: 4px;
overflow: hidden;
background-color: #000;
}
.hvideo-js1-screen-mock {
height: 120px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
color: #fff;
background-color: #212529;
}
.hvideo-js1-custom-controls {
background-color: #f8f9fa;
padding: 10px;
display: flex;
gap: 10px;
align-items: center;
border-top: 1px solid #dee2e6;
}
.hvideo-js1-btn {
padding: 4px 10px;
background-color: #0d6efd;
color: #fff;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 12px;
}
.hvideo-js1-btn:hover { background-color: #0b5ed7; }
.hvideo-js1-control-group {
display: flex;
align-items: center;
gap: 5px;
font-size: 11px;
color: #333;
}
.hvideo-js1-control-group input[type="range"] { width: 60px; }
.hvideo-js1-control-group select { font-size: 11px; padding: 2px; }
.hvideo-js1-code {
background-color: #282c34;
color: #abb2bf;
padding: 15px;
font-family: monospace;
font-size: 13px;
border-radius: 4px;
line-height: 1.6;
border-left: 4px solid #198754;
}
.hvideo-js1-hl-green { color: #98c379; font-weight: bold; }
.hvideo-js1-hl-blue { color: #61afef; font-weight: bold; }
.hvideo-js1-hl-red { color: #e06c75; font-weight: bold; }
.hvideo-js1-hl-comment { color: #6c757d; font-style: italic; }setTimeout(() => {
const btnPlay = document.getElementById('btnPlay1');
const btnPause = document.getElementById('btnPause1');
const mockStatus = document.getElementById('mockStatus1');
const volumeSlider = document.getElementById('volumeSlider');
const speedSelect = document.getElementById('speedSelect');
if(btnPlay) {
btnPlay.addEventListener('click', () => { mockStatus.textContent = "再生中..."; mockStatus.style.color = "#98c379"; });
btnPause.addEventListener('click', () => { mockStatus.textContent = "停止中"; mockStatus.style.color = "#fff"; });
volumeSlider.addEventListener('input', (e) => { mockStatus.textContent = `音量: ${e.target.value}`; mockStatus.style.color = "#fff"; });
speedSelect.addEventListener('change', (e) => { mockStatus.textContent = `速度: ${e.target.value}x`; mockStatus.style.color = "#fff"; });
}
}, 100);カスタムプレイヤー実装において難易度が高いのが、プログレスバーの構築です。
これを実現するには、現在の再生時間と動画の全体の長さを取得し、パーセンテージを計算してバーの長さを更新する必要があります。
さらに、バーをクリックして好きな時間にジャンプさせる処理も実装します。
自作シークバーを実装する際は、「ユーザーがスライダーを掴んだ瞬間(mousedown や input)に動画を一度pause()して止め、スライダーから手を離した瞬間(change や mouseup)に指定の秒数へジャンプさせてから再びplay()する」という処理の棲み分けが条件です。
⭕️ currentTime と duration を使った連動
<div class="hvideo-js2-wrapper">
<div class="hvideo-js2-demo-area">
<div class="hvideo-js2-box">
<div class="hvideo-js2-label">🎚️ 再生時間の取得と自作シークバー</div>
<div class="hvideo-js2-visual">
<p style="font-size:12px; color:#0d6efd; font-weight:bold; margin:0 0 5px 0;">⭕️ currentTime と duration を使った連動</p>
<div class="hvideo-js2-seek-mock">
<div style="font-size:11px; color:#666; margin-bottom:5px;">シークバー (input type="range")</div>
<div style="display:flex; align-items:center; gap:10px;">
<span id="timeCurrent" style="font-size:11px; font-family:monospace;">00:15</span>
<input type="range" id="seekBar" min="0" max="100" value="25" style="flex-grow:1;">
<span id="timeDuration" style="font-size:11px; font-family:monospace;">01:00</span>
</div>
</div>
</div>
<div class="hvideo-js2-code">
/* 💡 1. ユーザーがバーを操作してジャンプ(シーク)する時 */<br>
seekBar.addEventListener(<span class="hvideo-js2-hl-red">'input'</span>, () => {<br>
<span class="hvideo-js2-hl-comment">// ★ドラッグ中は一時停止してカクつきを防ぐ</span><br>
video.pause(); <br>
<span class="hvideo-js2-hl-blue">const</span> seekTime = video.<span class="hvideo-js2-hl-green">duration</span> * (seekBar.value / 100);<br>
video.<span class="hvideo-js2-hl-green">currentTime</span> = seekTime;<br>
});<br><br>
seekBar.addEventListener(<span class="hvideo-js2-hl-red">'change'</span>, () => {<br>
<span class="hvideo-js2-hl-comment">// ★手を離したら再生再開</span><br>
video.play();<br>
});<br><br>
/* 💡 2. 動画の再生に合わせてバーを動かす(後述のイベント内で実行) */<br>
<span class="hvideo-js2-hl-blue">const</span> percent = (video.<span class="hvideo-js2-hl-green">currentTime</span> / video.<span class="hvideo-js2-hl-green">duration</span>) * 100;<br>
seekBar.value = percent;
</div>
</div>
</div>
</div>.hvideo-js2-wrapper {
background-color: #f8f9fa;
padding: 20px;
border: 1px solid #dee2e6;
border-radius: 4px;
font-family: sans-serif;
}
.hvideo-js2-demo-area {
display: flex;
justify-content: center;
}
.hvideo-js2-box {
background-color: #ffffff;
border: 2px dashed #adb5bd;
padding: 25px;
width: 100%;
max-width: 500px;
border-radius: 4px;
}
.hvideo-js2-label {
font-size: 15px;
font-weight: bold;
margin-bottom: 20px;
color: #333;
}
.hvideo-js2-visual {
background-color: #f1f3f5;
padding: 15px;
border-radius: 8px;
margin-bottom: 20px;
border: 1px solid #dee2e6;
}
.hvideo-js2-seek-mock {
background-color: #fff;
padding: 15px;
border-radius: 4px;
border: 1px solid #ced4da;
}
.hvideo-js2-code {
background-color: #282c34;
color: #abb2bf;
padding: 15px;
font-family: monospace;
font-size: 13px;
border-radius: 4px;
line-height: 1.6;
border-left: 4px solid #198754;
}
.hvideo-js2-hl-green { color: #98c379; font-weight: bold; }
.hvideo-js2-hl-blue { color: #61afef; font-weight: bold; }
.hvideo-js2-hl-red { color: #e06c75; font-weight: bold; }
.hvideo-js2-hl-comment { color: #6c757d; font-style: italic; }JavaScriptで動画を制御するには、動画が「今どんな状態なのか」を監視する各種イベントを使いこなす必要があります。
カスタムプレイヤー構築で多用する3つのイベントを覚えましょう。
timeupdateendedplay/pause⭕️ onloadではなく、動画専用のイベントを検知する
<div class="hvideo-js3-wrapper">
<div class="hvideo-js3-demo-area">
<div class="hvideo-js3-box">
<div class="hvideo-js3-label">📡 必須となる三大イベント処理</div>
<div class="hvideo-js3-visual">
<p style="font-size:12px; color:#198754; font-weight:bold; margin:0 0 5px 0;">⭕️ onloadではなく、動画専用のイベントを検知する</p>
<div class="hvideo-js3-event-mock">
<ul style="margin:0; padding-left:15px; font-size:12px; color:#333; line-height:1.8;">
<li>✅ <strong style="color:#0d6efd">loadedmetadata</strong>:読み込み完了時</li>
<li>✅ <strong style="color:#0d6efd">timeupdate</strong>:再生中に毎秒数回発火</li>
<li>✅ <strong style="color:#0d6efd">ended</strong>:動画が最後まで終わった時</li>
</ul>
</div>
</div>
<div class="hvideo-js3-code">
<!-- ❌ 間違い:videoにonloadは使えない --><br>
<video src="movie.mp4" <span class="hvideo-js3-hl-red">onload="init()"</span>></video><br><br>
/* 💡 1. 読み込み完了(全体の長さを取得可能になる) */<br>
video.addEventListener(<span class="hvideo-js3-hl-green">'loadedmetadata'</span>, () => {<br>
<span class="hvideo-js3-hl-comment">// ここで初めて video.duration が正確に取得できる</span><br>
console.log("全体の長さ: " + video.duration);<br>
});<br><br>
/* 💡 2. 再生位置の更新(シークバーを進める処理) */<br>
video.addEventListener(<span class="hvideo-js3-hl-green">'timeupdate'</span>, () => {<br>
<span class="hvideo-js3-hl-comment">// 再生中は1秒間に数回ここが実行される</span><br>
updateSeekBar(video.currentTime);<br>
});<br><br>
/* 💡 3. 再生終了(リプレイ画面を出す等) */<br>
video.addEventListener(<span class="hvideo-js3-hl-green">'ended'</span>, () => {<br>
showReplayButton();<br>
});
</div>
</div>
</div>
</div>.hvideo-js3-wrapper {
background-color: #f8f9fa;
padding: 20px;
border: 1px solid #dee2e6;
border-radius: 4px;
font-family: sans-serif;
}
.hvideo-js3-demo-area {
display: flex;
justify-content: center;
}
.hvideo-js3-box {
background-color: #ffffff;
border: 2px dashed #adb5bd;
padding: 25px;
width: 100%;
max-width: 500px;
border-radius: 4px;
}
.hvideo-js3-label {
font-size: 15px;
font-weight: bold;
margin-bottom: 20px;
color: #333;
}
.hvideo-js3-visual {
background-color: #f1f3f5;
padding: 20px;
border-radius: 8px;
margin-bottom: 20px;
border: 1px solid #dee2e6;
}
.hvideo-js3-event-mock {
background-color: #fff;
padding: 15px;
border-radius: 4px;
border: 1px solid #ced4da;
box-shadow: inset 0 2px 4px rgba(0,0,0,0.05);
}
.hvideo-js3-code {
background-color: #282c34;
color: #abb2bf;
padding: 15px;
font-family: monospace;
font-size: 13px;
border-radius: 4px;
line-height: 1.6;
border-left: 4px solid #198754;
}
.hvideo-js3-hl-green { color: #98c379; font-weight: bold; }
.hvideo-js3-hl-blue { color: #61afef; font-weight: bold; }
.hvideo-js3-hl-red { color: #e06c75; font-weight: bold; }
.hvideo-js3-hl-comment { color: #6c757d; font-style: italic; }動画をWebサイトに埋め込んだものの再生されないトラブルは、Web制作で多い問い合わせの一つです。
特に「PCのテスト環境では動くのに、再生されないスマホの環境がある」「画面が真っ暗な状態になる」といった問題は、原因の特定が難しいです。
ここでは、「ファイルが見つからない・形式がおかしい」エラーの解決策、サイトの表示速度を落とさない読み込み最適化(Lazy load)を解説します。
コンソール画面やプレイヤー上に「video file not found」と表示される場合、基本的には「動画のパス(URL)が間違っている」ことが原因です。
解決策としては、相対パスの大文字・小文字の打ち間違いやローカルパス(C:\Users\...)を指定していないかを確認するのがよいです。
<source>タグのtype属性を使ってファイル形式をブラウザに明示することで、再生エラーを減らし、読み込みの無駄を省けます。❌ 再生されない・エラーになる原因
<div class="hvideo-err1-wrapper">
<div class="hvideo-err1-demo-area">
<div class="hvideo-err1-box">
<div class="hvideo-err1-label">🚨 動画エラーを防ぐパスとtypeの指定</div>
<div class="hvideo-err1-visual">
<p style="font-size:12px; color:#dc3545; font-weight:bold; margin:0 0 5px 0;">❌ 再生されない・エラーになる原因</p>
<ul style="font-size:12px; color:#333; margin:0 0 15px 15px; padding:0; line-height:1.6;">
<li>PCのローカルフォルダの絶対パスを書いている</li>
<li>コーデックが「H.264」以外(H.265等)になっている</li>
<li>大文字・小文字が間違っている(Movie.MP4 など)</li>
</ul>
</div>
<div class="hvideo-err1-code">
<!-- ❌ 悪い例1:自分のパソコンでしか見れないパス --><br>
<video src="<span class="hvideo-err1-hl-red">C:\Users\Desktop\video.mp4</span>"></video><br><br>
<!-- ❌ 悪い例2:拡張子を無理やり書き換えただけのファイル --><br>
<video src="<span class="hvideo-err1-hl-red">movie_h265.mp4</span>"></video><br><br>
<!-- ⭕️ 良い例:正しい相対パスと、type属性による明示 --><br>
<span class="hvideo-err1-hl-blue"><video controls poster="img/thumb.jpg"></span><br>
<span class="hvideo-err1-hl-comment"><!-- ★ H.264コーデックでエンコードした動画を指定 --></span><br>
<span class="hvideo-err1-hl-green"><source src="./assets/video/movie.mp4" type="video/mp4"></span><br>
<p>お使いのブラウザは動画に対応していません。</p><br>
<span class="hvideo-err1-hl-blue"></video></span>
</div>
</div>
</div>
</div>.hvideo-err1-wrapper {
background-color: #f8f9fa;
padding: 20px;
border: 1px solid #dee2e6;
border-radius: 4px;
font-family: sans-serif;
}
.hvideo-err1-demo-area {
display: flex;
justify-content: center;
}
.hvideo-err1-box {
background-color: #ffffff;
border: 2px dashed #adb5bd;
padding: 25px;
width: 100%;
max-width: 550px;
border-radius: 4px;
}
.hvideo-err1-label {
font-size: 15px;
font-weight: bold;
margin-bottom: 20px;
color: #333;
}
.hvideo-err1-visual {
background-color: #f8d7da;
padding: 15px;
border-radius: 8px;
margin-bottom: 20px;
border: 1px solid #f5c2c7;
}
.hvideo-err1-code {
background-color: #282c34;
color: #abb2bf;
padding: 15px;
font-family: monospace;
font-size: 13px;
border-radius: 4px;
line-height: 1.6;
border-left: 4px solid #198754;
}
.hvideo-err1-hl-green { color: #98c379; font-weight: bold; }
.hvideo-err1-hl-blue { color: #61afef; font-weight: bold; }
.hvideo-err1-hl-red { color: #e06c75; font-weight: bold; }
.hvideo-err1-hl-comment { color: #6c757d; font-style: italic; }動画はデータ容量が大きいため、ページ内に複数配置するとサイトの読み込み速度が激減します。
そこで必須となるのが、「preload」の適切な設定と、画面に表示されるまで動画の読み込みを遅らせる遅延読み込みの技術です。
preload="none"を指定して、ユーザーが再生ボタンを押すまでダウンロードを完全に防ぎます。metadataを指定すると動画の長さ情報だけを先に取得します。)Intersection Observerを使って「画面に動画が見えた瞬間に動画のURLをセットして読み込む」という実装を行います。⭕️ スクロールして枠内に入ると読み込み開始
<div class="hvideo-err2-wrapper">
<div class="hvideo-err2-demo-area">
<div class="hvideo-err2-box">
<div class="hvideo-err2-label">⚡ 動画の遅延読み込み(Lazy Load)</div>
<div class="hvideo-err2-visual">
<p style="font-size:12px; color:#0d6efd; font-weight:bold; margin:0 0 5px 0;">⭕️ スクロールして枠内に入ると読み込み開始</p>
<div id="lazyScrollArea" class="hvideo-err2-scroll-area">
<div style="height:150px; padding:20px; background:#f8f9fa; font-size:12px;">↓ 下へスクロールしてください</div>
<div class="hvideo-err2-mock-video-container">
<div id="lazyVideoMock" class="hvideo-err2-mock-video">
<span id="lazyStatus">待機中 (通信ゼロ)</span>
</div>
</div>
<div style="height:100px; background:#f8f9fa;"></div>
</div>
</div>
<div class="hvideo-err2-code">
<!-- HTML:最初は src を書かず data-src に隠しておく --><br>
<video <span class="hvideo-err2-hl-red">preload="none"</span> class="lazy-video"<br>
<span class="hvideo-err2-hl-green">data-src="heavy-movie.mp4"</span><br>
muted playsinline loop><br>
</video><br><br>
/* 💡 JavaScript:画面に入ったら src を入れて再生 */<br>
<span class="hvideo-err2-hl-blue">const</span> lazyVideos = document.querySelectorAll('.lazy-video');<br><br>
<span class="hvideo-err2-hl-blue">const</span> videoObserver = <span class="hvideo-err2-hl-blue">new</span> IntersectionObserver((entries) => {<br>
entries.forEach(entry => {<br>
<span class="hvideo-err2-hl-blue">if</span> (entry.isIntersecting) {<br>
<span class="hvideo-err2-hl-blue">const</span> video = entry.target;<br>
<span class="hvideo-err2-hl-comment">// data-src のURLを本物の src に移す</span><br>
video.<span class="hvideo-err2-hl-green">src</span> = video.dataset.src;<br>
video.play(); <span class="hvideo-err2-hl-comment">// 読み込み後に再生</span><br>
videoObserver.unobserve(video); <span class="hvideo-err2-hl-comment">// 監視終了</span><br>
}<br>
});<br>
});<br><br>
lazyVideos.forEach(v => videoObserver.observe(v));
</div>
</div>
</div>
</div>.hvideo-err2-wrapper {
background-color: #f8f9fa;
padding: 20px;
border: 1px solid #dee2e6;
border-radius: 4px;
font-family: sans-serif;
}
.hvideo-err2-demo-area {
display: flex;
justify-content: center;
}
.hvideo-err2-box {
background-color: #ffffff;
border: 2px dashed #adb5bd;
padding: 25px;
width: 100%;
max-width: 550px;
border-radius: 4px;
}
.hvideo-err2-label {
font-size: 15px;
font-weight: bold;
margin-bottom: 20px;
color: #333;
}
.hvideo-err2-visual {
background-color: #fff;
padding: 0;
border-radius: 8px;
margin-bottom: 20px;
border: 1px solid #dee2e6;
overflow: hidden;
}
.hvideo-err2-scroll-area {
height: 180px;
overflow-y: scroll;
position: relative;
}
.hvideo-err2-mock-video-container {
padding: 20px;
background-color: #e9ecef;
}
.hvideo-err2-mock-video {
width: 100%;
height: 120px;
background-color: #6c757d;
border-radius: 4px;
display: flex;
justify-content: center;
align-items: center;
color: #fff;
font-size: 12px;
font-weight: bold;
transition: background-color 0.5s;
}
.hvideo-err2-mock-video.is-loaded {
background-color: #198754;
background-image: repeating-linear-gradient(45deg, rgba(255,255,255,0.1) 25%, transparent 25%, transparent 75%, rgba(255,255,255,0.1) 75%, rgba(255,255,255,0.1)), repeating-linear-gradient(45deg, rgba(255,255,255,0.1) 25%, transparent 25%, transparent 75%, rgba(255,255,255,0.1) 75%, rgba(255,255,255,0.1));
background-size: 20px 20px;
}
.hvideo-err2-code {
background-color: #282c34;
color: #abb2bf;
padding: 15px;
font-family: monospace;
font-size: 13px;
border-radius: 4px;
line-height: 1.6;
border-left: 4px solid #0d6efd;
}
.hvideo-err2-hl-green { color: #98c379; font-weight: bold; }
.hvideo-err2-hl-blue { color: #61afef; font-weight: bold; }
.hvideo-err2-hl-red { color: #e06c75; font-weight: bold; }
.hvideo-err2-hl-comment { color: #6c757d; font-style: italic; }setTimeout(() => {
const scrollArea = document.getElementById('lazyScrollArea');
const mockVideo = document.getElementById('lazyVideoMock');
const statusText = document.getElementById('lazyStatus');
if(!scrollArea || !mockVideo) return;
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
// 画面に入った瞬間にクラスを付与して状態を変更
mockVideo.classList.add('is-loaded');
statusText.innerHTML = "読み込み開始!<br>▶ 再生中...";
observer.unobserve(mockVideo);
}
});
}, {
root: scrollArea, // スクロールエリア内での交差を検知
threshold: 0.5 // 半分見えたら発火
});
observer.observe(mockVideo);
}, 100);自社サーバーに動画をアップロードして表示する標準的な方法を解説してきましたが、実務では「YouTubeの動画をサイトに載せたい」というケースも多いです。
YouTubeやVimeoなどの外部プラットフォームの動画を埋め込む場合、<video>タグは使用できません。
代わりに<iframe>タグを使用して、外部の動画ソースを読み込みます。
ここでは、<video>タグとの使い分け、スマホ画面に合わせて伸縮させるレスポンシブ対応を解説します。
videoタグとiframeタグの違いと使い分け自社サーバーの動画ファイルを直接読み込む<video>タグに対し、別のサイトのプレイヤーごと自分のサイトに表示させるのが<iframe>タグです。
実務では、以下の基準でタグを使い分けます。
<video><iframe>❌ videoタグにYouTubeのURLを入れるのはNG
⭕️ 公式の「埋め込む」からiframeコードを取得する
<div class="hvideo-iframe1-wrapper">
<div class="hvideo-iframe1-demo-area">
<div class="hvideo-iframe1-box">
<div class="hvideo-iframe1-label">🔗 YouTube動画の正しい埋め込み方</div>
<div class="hvideo-iframe1-visual">
<p style="font-size:12px; color:#dc3545; font-weight:bold; margin:0 0 5px 0;">❌ videoタグにYouTubeのURLを入れるのはNG</p>
<p style="font-size:12px; color:#198754; font-weight:bold; margin:15px 0 5px 0;">⭕️ 公式の「埋め込む」からiframeコードを取得する</p>
<div class="hvideo-iframe1-mock-youtube">
<div class="hvideo-iframe1-mock-screen">
<span style="color:red; font-size:30px;">▶</span>
<span style="color:#fff; font-size:14px; margin-left:10px;">YouTube Player</span>
</div>
</div>
</div>
<div class="hvideo-iframe1-code">
<!-- ❌ ありがちな間違い:絶対に再生されません --><br>
<span class="hvideo-iframe1-hl-red"><video src="https://www.youtube.com/watch?v=xxxxx"></video></span><br><br>
<!-- ⭕️ 正解:iframeタグを使う(YouTubeの共有ボタンから取得) --><br>
<span class="hvideo-iframe1-hl-blue"><iframe</span> <br>
width="560" <br>
height="315" <br>
<span class="hvideo-iframe1-hl-green">src="https://www.youtube.com/embed/xxxxx"</span> <br>
title="YouTube video player" <br>
frameborder="0" <br>
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"<br>
allowfullscreen<br>
<span class="hvideo-iframe1-hl-blue">></iframe></span>
</div>
</div>
</div>
</div>.hvideo-iframe1-wrapper {
background-color: #f8f9fa;
padding: 20px;
border: 1px solid #dee2e6;
border-radius: 4px;
font-family: sans-serif;
}
.hvideo-iframe1-demo-area {
display: flex;
justify-content: center;
}
.hvideo-iframe1-box {
background-color: #ffffff;
border: 2px dashed #adb5bd;
padding: 25px;
width: 100%;
max-width: 500px;
border-radius: 4px;
}
.hvideo-iframe1-label {
font-size: 15px;
font-weight: bold;
margin-bottom: 20px;
color: #333;
}
.hvideo-iframe1-visual {
background-color: #f1f3f5;
padding: 15px;
border-radius: 8px;
margin-bottom: 20px;
border: 1px solid #dee2e6;
}
.hvideo-iframe1-mock-youtube {
background-color: #000;
border-radius: 4px;
overflow: hidden;
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
}
.hvideo-iframe1-mock-screen {
height: 120px;
display: flex;
justify-content: center;
align-items: center;
}
.hvideo-iframe1-code {
background-color: #282c34;
color: #abb2bf;
padding: 15px;
font-family: monospace;
font-size: 13px;
border-radius: 4px;
line-height: 1.6;
border-left: 4px solid #198754;
}
.hvideo-iframe1-hl-green { color: #98c379; font-weight: bold; }
.hvideo-iframe1-hl-blue { color: #61afef; font-weight: bold; }
.hvideo-iframe1-hl-red { color: #e06c75; font-weight: bold; }iframeタグの使い方を詳しく知りたい人は「【HTML】iframeタグの使い方:YouTube・グーグルマップ等埋め込みとサイズ調整」を一読ください。
YouTubeの共有コードを貼り付けるとサイズが固定(width="560" height="315"など)されてしまうため、スマホで見ると画面からはみ出します。
また、動画を自動再生させるには、少し特殊なURLパラメーターの追加が必要です。
autoplay=1、ミュートのmute=1をセットにして?autoplay=1&mute=1と記述します(パラメーターがすでにある場合は&で繋ぎます)。iframeに対してwidth: 100%;に加え、aspect-ratio: 16 / 9;を指定するだけで縦横比を維持できます。⭕️ アスペクト比を維持して伸縮するiframe
<div class="hvideo-iframe2-wrapper">
<div class="hvideo-iframe2-demo-area">
<div class="hvideo-iframe2-box">
<div class="hvideo-iframe2-label">📱 レスポンシブ化と自動再生パラメーター</div>
<div class="hvideo-iframe2-visual">
<p style="font-size:12px; color:#0d6efd; font-weight:bold; margin:0 0 5px 0;">⭕️ アスペクト比を維持して伸縮するiframe</p>
<div class="hvideo-iframe2-mock-container">
<div class="hvideo-iframe2-mock-responsive">
<span style="font-size:24px; color:#fff;">▶</span>
<div style="font-size:11px; color:#ccc; margin-top:5px;">width: 100% / aspect-ratio: 16/9</div>
</div>
</div>
</div>
<div class="hvideo-iframe2-code">
<!-- HTML --><br>
<iframe <br>
class="youtube-responsive"<br>
<span class="hvideo-iframe2-hl-comment"><!-- 💡 URLの末尾に「自動再生&無音」のパラメーターを付ける --></span><br>
src="https://www.youtube.com/embed/xxxxx<span class="hvideo-iframe2-hl-red">?autoplay=1&mute=1</span>" <br>
frameborder="0" allowfullscreen><br>
</iframe><br><br>
/* CSS */<br>
<span class="hvideo-iframe2-hl-blue">.youtube-responsive</span> {<br>
<span class="hvideo-iframe2-hl-green">width: 100%;</span><br>
<span class="hvideo-iframe2-hl-comment">/* height: auto; は効かないので絶対に書かない */</span><br>
<span class="hvideo-iframe2-hl-green">aspect-ratio: 16 / 9;</span> <span class="hvideo-iframe2-hl-comment">/* ★これで縦横比を16:9に固定して伸縮 */</span><br>
border: none;<br>
}
</div>
</div>
</div>
</div>.hvideo-iframe2-wrapper {
background-color: #f8f9fa;
padding: 20px;
border: 1px solid #dee2e6;
border-radius: 4px;
font-family: sans-serif;
}
.hvideo-iframe2-demo-area {
display: flex;
justify-content: center;
}
.hvideo-iframe2-box {
background-color: #ffffff;
border: 2px dashed #adb5bd;
padding: 25px;
width: 100%;
max-width: 500px;
border-radius: 4px;
}
.hvideo-iframe2-label {
font-size: 15px;
font-weight: bold;
margin-bottom: 20px;
color: #333;
}
.hvideo-iframe2-visual {
background-color: #f1f3f5;
padding: 20px;
border-radius: 8px;
margin-bottom: 20px;
border: 1px solid #dee2e6;
}
.hvideo-iframe2-mock-container {
width: 100%; /* 親要素の幅に合わせて伸縮 */
border: 2px solid #0d6efd;
}
.hvideo-iframe2-mock-responsive {
width: 100%;
aspect-ratio: 16 / 9; /* これがレスポンシブの鍵 */
background-color: #212529;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
background-image: repeating-linear-gradient(45deg, rgba(255,255,255,0.05) 10%, transparent 10%, transparent 20%, rgba(255,255,255,0.05) 20%, rgba(255,255,255,0.05) 30%);
}
.hvideo-iframe2-code {
background-color: #282c34;
color: #abb2bf;
padding: 15px;
font-family: monospace;
font-size: 13px;
border-radius: 4px;
line-height: 1.6;
border-left: 4px solid #0d6efd;
}
.hvideo-iframe2-hl-green { color: #98c379; font-weight: bold; }
.hvideo-iframe2-hl-blue { color: #61afef; font-weight: bold; }
.hvideo-iframe2-hl-red { color: #e06c75; font-weight: bold; }
.hvideo-iframe2-hl-comment { color: #6c757d; font-style: italic; }要素に対するレスポンシブ対応について詳しく知りたい人は「【CSS】レスポンシブデザイン対応の基本:メディアクエリの書き方とパーツ別サンプル集」を一読ください。
分かりやすいようにまとめを記載します。
<video>タグを使用し、複数形式の指定やエラー表示には<source>タグを用いる。autoplay muted playsinline loopの4属性指定が必須。width: 100%; height: auto;を指定し、動画の元のアスペクト比(縦横比)を維持して伸縮させる。object-fit: cover;を使用して隙間なくトリミングする。controls属性の有無で標準コントローラーの表示・非表示を切り替える。poster属性で指定する。controlsList="nodownload"と右クリック禁止(oncontextmenu="return false;")を組み合わせることで簡易的なダウンロード防止策となる。play()やpause()メソッドで直接操作し、timeupdateやendedなどの動画専用イベントで再生状況を監視する。preload="none"の指定やIntersection Observerを用いた遅延読み込み(Lazy Load)により通信量を抑える。<video>タグではなく提供された<iframe>タグを使用する。HTML5から導入された<video>タグを使用します。
簡単な書き方は<video src="movie.mp4" controls></video>のように直接ファイルパスを指定する方法です。
実務ではブラウザの互換性を考慮し、<video>タグの中に<source>タグを配置して複数の動画形式(MP4やWebM)を指定するのが一般的です。
モバイル端末のブラウザは、ユーザーの通信量保護や突然の音の発生を防ぐため、「無音設定」になっていない動画の自動再生をブロックする仕様になっています。
スマホでも自動再生させるには、<video>タグにautoplay(自動再生)に加えて、muted(無音化)とplaysinline(iPhoneでの全画面化を防ぐ)属性をセットで記述する必要があります。
すべてのブラウザで再生できる標準フォーマットは 「MP4(コーデックはH.264)」 です。
また、データ容量が軽く高速に表示できる 「WebM」 形式もGoogleを中心に推奨されています。
一方で、iPhoneで撮影したままの「MOV」形式、古い「AVI」「WMV」などはWeb標準ではないため、ブラウザによっては再生できず画面が真っ暗になります。
MP4等に変換(エンコード)して使用してください。
CSSを使って、動画が親要素(画面枠)からはみ出さないように設定します。
<video>タグに対してwidth: 100%;とheight: auto;を指定するのが確実な方法です。
高さをautoにすることで、ブラウザが動画の元の縦横比を自動計算するため、動画が縦に伸びたり横に潰れたりすることなく伸縮します。
いいえ、使えません。
<video>タグは、自社のサーバー等にアップロードした直接の動画ファイル(.mp4など)を読み込む専用タグです。
YouTubeやVimeoといった外部プラットフォームの動画を表示したい場合は、YouTubeの共有メニューから取得できる<iframe>タグをHTMLに貼り付けて使用する必要があります。
面倒な基本構造やレスポンシブ対応はテーマに任せ、浮いた時間で「あなたにしかできないこだわりの独自カスタマイズ」をとことん追求してみませんか?
「SWELL」の徹底レビュー・詳細を見る