550 lines
16 KiB
HTML
550 lines
16 KiB
HTML
<!doctype html><html lang=en>
|
|
<meta charset=UTF-8>
|
|
<meta http-equiv=X-UA-Compatible content="IE=edge">
|
|
<meta name=viewport content="width=device-width,initial-scale=1">
|
|
<title>Lazy Video Component - Multi-Platform Video Embedding</title>
|
|
<meta name=description content="A lightweight, customizable web component for optimized video embeds from YouTube, Bitchute and more platforms with lazy loading for performance.">
|
|
<link rel=icon href=/images/favi.png type=image/png>
|
|
<link rel=apple-touch-icon href=/images/favi.png>
|
|
<link rel="shortcut icon" href=/images/favi.png>
|
|
<link rel=preload href=/webfonts/Poppins-Regular.woff2 as=font type=font/woff2 crossorigin>
|
|
<link rel=preload href=/webfonts/Poppins-SemiBold.woff2 as=font type=font/woff2 crossorigin>
|
|
<link rel=preload href=/js/u.js as=script>
|
|
<link rel=preload href=/js/lv.js as=script>
|
|
<link rel=stylesheet href=/css/u.css>
|
|
<link rel=stylesheet href=/css/docs.css>
|
|
<link rel=stylesheet href=https://unpkg.com/@speed-highlight/core@1.2.7/dist/themes/github-dark.css integrity=sha384-8HPbLmchBzGvBxngSZZwtxFdhC9KpkvDvgJvjR51kdEvVC7Pn2wLsWuFXRgDpQUh crossorigin=anonymous>
|
|
<script async src=/js/u.js></script>
|
|
<script async src=/js/lv.js></script>
|
|
<script type=module src=/js/docs.js></script>
|
|
<div class=container>
|
|
<h1>Lazy Video Docs</h1>
|
|
<div class=toc>
|
|
<h2>Contents</h2>
|
|
<ul>
|
|
<li><a href=#overview>Overview</a>
|
|
<li><a href=#basic-usage>Basic Usage</a>
|
|
<li><a href=#platforms>Supported Platforms</a>
|
|
<li><a href=#attributes>Attributes</a>
|
|
<li><a href=#styling>Styling & CSS Variables</a>
|
|
<li><a href=#examples>Examples</a>
|
|
<li><a href=#converting>Converting Existing iframes</a>
|
|
<li><a href=#security>Security & Privacy</a>
|
|
<li><a href=#browser-support>Browser Support</a>
|
|
<li><a href=#breaking-change>Breaking Change</a>
|
|
</ul>
|
|
</div>
|
|
<section id=overview class=section>
|
|
<h2>Overview</h2>
|
|
<p>
|
|
Embedding videos with standard <code><iframe></code> tags can dramatically slow down your site and consume large amounts of data. Each iframe loads the full video player and related resources immediately-even if the user never interacts with it. On pages with several videos, this can add <strong>hundreds of megabytes</strong> to the initial page load, resulting in a sluggish and costly experience, especially for users on mobile devices or limited networks.
|
|
<h3>How Lazy Video Helps</h3>
|
|
<p>
|
|
The <code><lazy-video></code> component solves this by loading only a lightweight thumbnail and play button at first. The actual video player is loaded only when the user clicks play (or when the video scrolls into view if <code>autoload</code> is enabled). This keeps your pages fast, responsive, and bandwidth-friendly.
|
|
<div class=lv-btn-group>
|
|
<a href=/js/lv.js target=_blank rel=noopener class="lv-btn lv-btn-primary">View Source</a>
|
|
<a href=/js/lv.js download class="lv-btn lv-btn-outline">Download</a>
|
|
<span class=lv-size-info>~17.0kB / <span>6.0kB</span> (Gzip)</span>
|
|
</div>
|
|
</section>
|
|
<section id=basic-usage class=section>
|
|
<h2>Basic Usage</h2>
|
|
<p>
|
|
To get started, include the script on your page and use the custom element as shown below:
|
|
<div class=code-example>
|
|
<span class=code-label>HTML</span>
|
|
<pre><code><lazy-video
|
|
src="https://www.youtube.com/embed/wPr3kws2prM"
|
|
title="Till We Have Faces by Silent Planet">
|
|
</lazy-video></code></pre>
|
|
</div>
|
|
<div class=note>
|
|
<p>
|
|
Always add a <code>title</code> for accessibility and better alt text on thumbnails.
|
|
</div>
|
|
</section>
|
|
<section id=platforms class=section>
|
|
<h2>Officially Supported Platforms</h2>
|
|
<div class=table-container>
|
|
<table>
|
|
<tr>
|
|
<th>Platform
|
|
<th>URL Pattern
|
|
<th>Notes
|
|
<tr>
|
|
<td>YouTube
|
|
<td>
|
|
<ul class=url-patterns>
|
|
<li><code>youtube.com/embed/ID</code>
|
|
<li><code>youtube.com/watch?v=ID</code>
|
|
<li><code>youtu.be/ID</code>
|
|
</ul>
|
|
<td>Full support for thumbnails and parameters.
|
|
<tr>
|
|
<td>Bitchute
|
|
<td>
|
|
<ul class=url-patterns>
|
|
<li><code>bitchute.com/video/ID/</code>
|
|
<li><code>bitchute.com/embed/ID/</code>
|
|
</ul>
|
|
<td>Custom thumbnails are only needed if autoload is disabled.
|
|
</table>
|
|
</div>
|
|
</section>
|
|
<section id=attributes class=section>
|
|
<h2>Attributes</h2>
|
|
<div class=table-container>
|
|
<table>
|
|
<tr>
|
|
<th>Attribute
|
|
<th>Description
|
|
<th>Default
|
|
<tr>
|
|
<td>src
|
|
<td>Video embed URL (required)
|
|
<td>N/A
|
|
<tr>
|
|
<td>title
|
|
<td>Video title
|
|
<td>"Video"
|
|
<tr>
|
|
<td>width
|
|
<td>Width in pixels or percent
|
|
<td>100% (responsive)
|
|
<tr>
|
|
<td>height
|
|
<td>Height in pixels
|
|
<td>16:9 ratio
|
|
<tr>
|
|
<td>thumbnail
|
|
<td>Custom thumbnail URL
|
|
<td>Auto-detected per platform
|
|
<tr>
|
|
<td>thumbnail-quality
|
|
<td>YouTube thumbnail quality (default, hq, mq, sd, maxres)
|
|
<td>Auto (maxres on desktop, hq on mobile)
|
|
<tr>
|
|
<td>service
|
|
<td>Force a specific service (youtube, bitchute)
|
|
<td>Auto-detected
|
|
<tr>
|
|
<td>sandbox
|
|
<td>Extra security for the iframe. Restricts what the embedded player can do. See <a href=https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe#sandbox target=_blank>MDN</a> for details.
|
|
<td>allow-scripts allow-same-origin allow-popups allow-forms allow-presentation
|
|
<tr>
|
|
<td>no-cookie
|
|
<td>Use youtube-nocookie.com for YouTube (privacy-friendly)
|
|
<td>true
|
|
<tr>
|
|
<td>autoload
|
|
<td>Load video when scrolled into view
|
|
<td>false (YouTube), true (Bitchute)
|
|
<tr>
|
|
<td>hide-title
|
|
<td>Hide the video title bar
|
|
<td>false
|
|
<tr>
|
|
<td>align
|
|
<td>Set alignment (left, right, center)
|
|
<td>center
|
|
<tr>
|
|
<td>container-fit
|
|
<td>Make video fill the container (FitVids style)
|
|
<td>false
|
|
</table>
|
|
</div>
|
|
<div class=warning>
|
|
<p>
|
|
<strong>Warning:</strong> Using <code>autoload</code> with many videos on one page can impact performance as users scroll. Use with care!
|
|
</div>
|
|
<div class=note>
|
|
<p>
|
|
<strong>Note:</strong> With <code>container-fit</code>, the component overrides max-width to 100% and sets max-height to auto, making it fill its container while keeping the aspect ratio.
|
|
</div>
|
|
</section>
|
|
<section id=styling class=section>
|
|
<h2>Styling & CSS Variables</h2>
|
|
<p>
|
|
You can customize the look of <code><lazy-video></code> using CSS variables:
|
|
<div class=code-example>
|
|
<span class=code-label>CSS</span>
|
|
<pre><code>lazy-video {
|
|
--lv-max-width: 600px;
|
|
--lv-border-radius: 8px;
|
|
--lv-play-button-color: #f00;
|
|
--lv-play-button-bg: rgba(0, 0, 0, 0.7);
|
|
--lv-show-title: none;
|
|
}</code></pre>
|
|
</div>
|
|
<div class=table-container>
|
|
<h3>Available CSS Variables</h3>
|
|
<table>
|
|
<tr>
|
|
<th>CSS Variable
|
|
<th>Description
|
|
<th>Default
|
|
<tr>
|
|
<td>--lv-max-width
|
|
<td>Maximum width of the video
|
|
<td>560px
|
|
<tr>
|
|
<td>--lv-aspect-ratio
|
|
<td>Aspect ratio
|
|
<td>16 / 9
|
|
<tr>
|
|
<td>--lv-display
|
|
<td>Display type
|
|
<td>block
|
|
<tr>
|
|
<td>--lv-position
|
|
<td>CSS position
|
|
<td>relative
|
|
<tr>
|
|
<td>--lv-border-radius
|
|
<td>Border radius for the container
|
|
<td>0
|
|
<tr>
|
|
<td>--lv-margin
|
|
<td>Container margin
|
|
<td>0 auto
|
|
<tr>
|
|
<td>--lv-margin-left
|
|
<td>Margin for left alignment
|
|
<td>0
|
|
<tr>
|
|
<td>--lv-margin-right
|
|
<td>Margin for right alignment
|
|
<td>0 0 0 auto
|
|
<tr>
|
|
<td>--lv-margin-center
|
|
<td>Margin for center alignment
|
|
<td>0 auto
|
|
<tr>
|
|
<td>--lv-align
|
|
<td>Set alignment (left, right, center)
|
|
<td>center
|
|
<tr>
|
|
<td>--lv-background
|
|
<td>Background color
|
|
<td>#000
|
|
<tr>
|
|
<td>--lv-thumbnail-opacity
|
|
<td>Thumbnail opacity
|
|
<td>0.85
|
|
<tr>
|
|
<td>--lv-thumbnail-hover-opacity
|
|
<td>Opacity on hover
|
|
<td>1
|
|
<tr>
|
|
<td>--lv-thumbnail-object-fit
|
|
<td>Object-fit for thumbnail
|
|
<td>cover
|
|
<tr>
|
|
<td>--lv-play-button-width
|
|
<td>Play button width
|
|
<td>68px
|
|
<tr>
|
|
<td>--lv-play-button-height
|
|
<td>Play button height
|
|
<td>48px
|
|
<tr>
|
|
<td>--lv-play-button-bg
|
|
<td>Play button background
|
|
<td>rgba(33, 33, 33, 0.8)
|
|
<tr>
|
|
<td>--lv-play-button-bg-hover
|
|
<td>Play button hover background
|
|
<td>rgba(230, 33, 23, 1)
|
|
<tr>
|
|
<td>--lv-play-button-color
|
|
<td>Play button arrow color
|
|
<td>rgba(255, 255, 255, 0.9)
|
|
<tr>
|
|
<td>--lv-play-button-radius
|
|
<td>Play button border radius
|
|
<td>8px
|
|
<tr>
|
|
<td>--lv-play-button-arrow-size
|
|
<td>Play button arrow size
|
|
<td>12px 0 12px 20px
|
|
<tr>
|
|
<td>--lv-title-padding
|
|
<td>Title bar padding
|
|
<td>10px 12px
|
|
<tr>
|
|
<td>--lv-title-bg
|
|
<td>Title background
|
|
<td>rgba(0, 0, 0, 0.75)
|
|
<tr>
|
|
<td>--lv-title-color
|
|
<td>Title text color
|
|
<td>white
|
|
<tr>
|
|
<td>--lv-title-font-family
|
|
<td>Title font family
|
|
<td>Roboto, Arial, sans-serif
|
|
<tr>
|
|
<td>--lv-title-font-size
|
|
<td>Title font size
|
|
<td>18px
|
|
<tr>
|
|
<td>--lv-title-font-weight
|
|
<td>Title font weight
|
|
<td>500
|
|
<tr>
|
|
<td>--lv-title-line-height
|
|
<td>Title line height
|
|
<td>1.2
|
|
<tr>
|
|
<td>--lv-focus-outline
|
|
<td>Focus outline
|
|
<td>2px solid #4285F4
|
|
<tr>
|
|
<td>--lv-focus-outline-offset
|
|
<td>Focus outline offset
|
|
<td>2px
|
|
<tr>
|
|
<td>--lv-show-title
|
|
<td>Show/hide title bar (use 'none' to hide)
|
|
<td>block
|
|
<tr>
|
|
<td>--lv-timestamp-right
|
|
<td>Timestamp right position
|
|
<td>10px
|
|
<tr>
|
|
<td>--lv-timestamp-bottom
|
|
<td>Timestamp bottom position
|
|
<td>10px
|
|
<tr>
|
|
<td>--lv-timestamp-bg
|
|
<td>Timestamp background
|
|
<td>rgba(0, 0, 0, 0.7)
|
|
<tr>
|
|
<td>--lv-timestamp-color
|
|
<td>Timestamp text color
|
|
<td>white
|
|
<tr>
|
|
<td>--lv-timestamp-padding
|
|
<td>Timestamp padding
|
|
<td>2px 6px
|
|
<tr>
|
|
<td>--lv-timestamp-radius
|
|
<td>Timestamp border radius
|
|
<td>3px
|
|
<tr>
|
|
<td>--lv-timestamp-font-size
|
|
<td>Timestamp font size
|
|
<td>12px
|
|
<tr>
|
|
<td>--lv-timestamp-font-family
|
|
<td>Timestamp font family
|
|
<td>system-ui, sans-serif
|
|
<tr>
|
|
<td>--lv-loading-bg
|
|
<td>Loading background
|
|
<td>rgba(0,0,0,0.7)
|
|
<tr>
|
|
<td>--lv-loading-color
|
|
<td>Loading text color
|
|
<td>white
|
|
<tr>
|
|
<td>--lv-loading-font-family
|
|
<td>Loading font family
|
|
<td>system-ui, sans-serif
|
|
<tr>
|
|
<td>--lv-fallback-bg
|
|
<td>Fallback background
|
|
<td>#1a1a1a
|
|
<tr>
|
|
<td>--lv-fallback-color
|
|
<td>Fallback text color
|
|
<td>white
|
|
<tr>
|
|
<td>--lv-fallback-font-family
|
|
<td>Fallback font family
|
|
<td>system-ui, sans-serif
|
|
<tr>
|
|
<td>--lv-fallback-font-size
|
|
<td>Fallback font size
|
|
<td>14px
|
|
</table>
|
|
</div>
|
|
</section>
|
|
<section id=examples class=section>
|
|
<h2>Examples</h2>
|
|
<h3>YouTube Embed with Custom Size</h3>
|
|
<div class=code-example>
|
|
<span class=code-label>HTML</span>
|
|
<pre><code><lazy-video
|
|
src="https://www.youtube.com/embed/wPr3kws2prM"
|
|
title="Till We Have Faces by Silent Planet"
|
|
width="50%"
|
|
height="260px"
|
|
thumbnail-quality="maxres">
|
|
</lazy-video></code></pre>
|
|
</div>
|
|
<div class=example>
|
|
<lazy-video src=https://www.youtube.com/embed/wPr3kws2prM title="Till We Have Faces by Silent Planet" width=50% height=260px></lazy-video>
|
|
</div>
|
|
<h3>Bitchute with Autoload Off</h3>
|
|
<div class=code-example>
|
|
<span class=code-label>HTML</span>
|
|
<pre><code><lazy-video
|
|
src="https://www.bitchute.com/video/zSfeNPF-OpY"
|
|
title="Trump Assassination Attempt Documents LOCKED Away. What are they Hiding?"
|
|
autoload="false"
|
|
thumbnail="https://static-3.bitchute.com/live/cover_images/nDPZqzyLkFKW/zSfeNPF-OpY_640x360.jpg">
|
|
</lazy-video></code></pre>
|
|
</div>
|
|
<div class=example>
|
|
<lazy-video src=https://www.bitchute.com/video/zSfeNPF-OpY title="Trump Assassination Attempt Documents LOCKED Away. What are they Hiding?" autoload=false thumbnail=https://static-3.bitchute.com/live/cover_images/nDPZqzyLkFKW/zSfeNPF-OpY_640x360.jpg>
|
|
</lazy-video>
|
|
<div class=note>
|
|
<p>
|
|
With <code>autoload="false"</code> on Bitchute, users need to click twice: once to load the player, and again to play. This saves bandwidth but may be less convenient.
|
|
</div>
|
|
</div>
|
|
<h3>Bitchute with Autoload</h3>
|
|
<div class=code-example>
|
|
<span class=code-label>HTML</span>
|
|
<pre><code><lazy-video
|
|
src="https://www.bitchute.com/video/zSfeNPF-OpY"
|
|
title="Trump Assassination Attempt Documents LOCKED Away. What are they Hiding?">
|
|
</lazy-video></code></pre>
|
|
</div>
|
|
<div class=example>
|
|
<lazy-video src=https://www.bitchute.com/video/zSfeNPF-OpY title="Trump Assassination Attempt Documents LOCKED Away. What are they Hiding?">
|
|
</lazy-video>
|
|
</div>
|
|
<h3>Responsive Container (FitVids Style)</h3>
|
|
<div class=code-example>
|
|
<span class=code-label>HTML</span>
|
|
<pre><code><div style="max-width: 100%; width: 100%;">
|
|
<lazy-video
|
|
src="https://www.youtube.com/embed/wPr3kws2prM"
|
|
title="Responsive container example"
|
|
container-fit="true">
|
|
</lazy-video>
|
|
</div></code></pre>
|
|
</div>
|
|
<div class=example>
|
|
<div style=max-width:100%;width:100%>
|
|
<lazy-video src=https://www.youtube.com/embed/wPr3kws2prM title="Till We Have Faces by Silent Planet" container-fit=true>
|
|
</lazy-video>
|
|
</div>
|
|
<div class=note>
|
|
<p>
|
|
<code>container-fit="true"</code> makes the video fill its parent container while keeping the aspect ratio. Great for fluid layouts.
|
|
</div>
|
|
</div>
|
|
<h3>YouTube with Hidden Title Bar</h3>
|
|
<div class=code-example>
|
|
<span class=code-label>HTML</span>
|
|
<pre><code><lazy-video
|
|
src="https://www.youtube.com/embed/wPr3kws2prM"
|
|
title="Hidden title example"
|
|
hide-title>
|
|
</lazy-video></code></pre>
|
|
</div>
|
|
<div class=example>
|
|
<lazy-video src=https://www.youtube.com/embed/wPr3kws2prM title="Hidden title example" hide-title>
|
|
</lazy-video>
|
|
</div>
|
|
<h3>Global Title Control with CSS</h3>
|
|
<div class=code-example>
|
|
<span class=code-label>CSS</span>
|
|
<pre><code>/* Hide titles for all videos */
|
|
lazy-video {
|
|
--lv-show-title: none;
|
|
}
|
|
|
|
/* Hide titles for a group */
|
|
.article-videos lazy-video {
|
|
--lv-show-title: none;
|
|
}</code></pre>
|
|
</div>
|
|
<h3>Global Alignment Control with CSS</h3>
|
|
<div class=code-example>
|
|
<span class=code-label>CSS</span>
|
|
<pre><code>/* Set alignment for all videos */
|
|
lazy-video {
|
|
--lv-align: left;
|
|
}
|
|
|
|
/* Responsive alignment */
|
|
@media (max-width: 768px) {
|
|
lazy-video {
|
|
--lv-align: center;
|
|
}
|
|
}
|
|
|
|
/* Different alignments for different contexts */
|
|
.sidebar lazy-video {
|
|
--lv-align: right;
|
|
}</code></pre>
|
|
</div>
|
|
</section>
|
|
<section id=converting class=section>
|
|
<h2>Converting Existing iframes</h2>
|
|
<p>
|
|
You can convert existing video iframes to <code><lazy-video></code> by simply changing the tag name.
|
|
<p>Standard YouTube iframe:
|
|
<div class=code-example>
|
|
<span class=code-label>HTML</span>
|
|
<pre><code><iframe
|
|
src="https://www.youtube.com/embed/wPr3kws2prM?start=30&rel=0&controls=0"
|
|
width="560"
|
|
height="315"
|
|
title="Till We Have Faces by Silent Planet"
|
|
frameborder="0"
|
|
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
|
|
allowfullscreen>
|
|
</iframe>
|
|
</code></pre>
|
|
</div>
|
|
<p>Converted to <code><lazy-video></code> (just change the tag):
|
|
<div class=code-example>
|
|
<span class=code-label>HTML</span>
|
|
<pre><code><lazy-video
|
|
src="https://www.youtube.com/embed/wPr3kws2prM?start=30&rel=0&controls=0"
|
|
width="560"
|
|
height="315"
|
|
title="Till We Have Faces by Silent Planet"
|
|
frameborder="0"
|
|
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
|
|
allowfullscreen>
|
|
</lazy-video></code></pre>
|
|
</div>
|
|
</section>
|
|
<section id=security class=section>
|
|
<h2>Security & Privacy</h2>
|
|
<p>
|
|
<code><lazy-video></code> is built with modern web security and privacy best practices:
|
|
<ul>
|
|
<li>
|
|
All embedded iframes use the <a href=https://developer.mozilla.org/en-US/docs/Web/API/Window/credentialless target=_blank><code>credentialless</code></a> attribute. This helps prevent credential leaks and keeps third-party content isolated from your site's cookies and storage.
|
|
<li>
|
|
The <a href=https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/iframe#sandbox target=_blank><code>sandbox</code></a> attribute is set by default, restricting what the embedded player can do and reducing risk from third-party content.
|
|
<li>
|
|
For YouTube, the <code>youtube-nocookie.com</code> domain is used by default, so no tracking cookies are set unless the user interacts with the video.
|
|
</ul>
|
|
<div class=note>
|
|
<p>
|
|
<strong>Note:</strong> You can override the <code>sandbox</code> attribute if you need to enable additional features, but the default is designed for maximum safety.
|
|
</div>
|
|
</section>
|
|
<section id=browser-support class=section>
|
|
<h2>Browser Support</h2>
|
|
<p>
|
|
Works in all modern browsers (Chrome, Firefox, Safari, Edge). Uses standard web component APIs. For IE11 or older, use the <a href=https://github.com/webcomponents/polyfills/tree/master/packages/custom-elements target=_blank>custom-elements polyfill</a>.
|
|
</section>
|
|
<section id=breaking-change class=section>
|
|
<h2>Breaking Change</h2>
|
|
<p>
|
|
<strong>April 3, 2025:</strong> The old <code><lazy-youtube></code> element is no longer supported. Please update any code to use <code><lazy-video></code> instead.
|
|
</section>
|
|
<footer>
|
|
<div class=doc-version-note>These docs reflect the latest release version of <strong>@lv.js</strong>.</div>
|
|
<p>Last updated: Friday, April 11th, 2025
|
|
</footer>
|
|
</div>
|