Skip to content

Commit

Permalink
Make the background more responsive to content size
Browse files Browse the repository at this point in the history
  • Loading branch information
nhoizey committed Jul 6, 2022
1 parent 0f29aad commit 8b3c01a
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 74 deletions.
31 changes: 23 additions & 8 deletions demo/demos.css
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
responsive-video-background {
margin-top: 1rem;
--overlay-background: hsla(0, 0, 0, 0.3);
padding: 1rem;
color: white;
text-shadow: .1em .1em .5em black;
}

.demo > div {
.grid {
display: block;
padding: 1rem;

display: grid;
Expand All @@ -13,31 +16,35 @@ responsive-video-background {

}

.demo h1 {
.grid h1 {
grid-column: 1 / span 3;
grid-row: 2 / span 1;
align-self: center;
justify-self: center;

font-family: system, sans-serif;
color: white;
text-shadow: 1px 1px 5px black;
}

.demo1 {
width: 100%;
--overlay-color: hsla(0, 0%, 0%, 0.3);
}
.demo1 > div {
height: 20rem;
}

.demo2 {
width: clamp(20rem, 50rem - 30vw, 100%);
--overlay-color: hsla(180, 50%, 50%, 0.5);
}
.demo2 > div {
height: 20rem;
margin-left: auto;
margin-right: auto;
--overlay-background: hsla(180, 50%, 50%, 0.3);
}

.demo3 {
--overlay-background: hsla(60, 70%, 80%, 0.7);
--overlay-color: hsla(60, 70%, 80%, 0.7);
width: 100%;
}
.demo3 > div {
height: 150px;
Expand All @@ -47,6 +54,10 @@ responsive-video-background {
text-shadow: 3px 3px 10px hsla(60, 70%, 30%, 0.8);
}

.demo4 {
width: 100%;
--overlay-color: hsla(180, 70%, 80%, 0.5);
}
.demo4 > div {
height: 600px;
}
Expand All @@ -60,6 +71,10 @@ responsive-video-background {
text-shadow: 0 0 5px white;
}

.demo5 {
width: 100%;
--overlay-color: hsla(240, 70%, 80%, 0.5);
}
.demo5 > div {
aspect-ratio: 4/1;
}
14 changes: 11 additions & 3 deletions demo/page.css
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,20 @@ body {
font-family: 'Roboto', sans-serif;
line-height: 1.5;
color: #333;
background-color: #fff;
background-color: #eee;
padding: 1rem;
}

.page {
max-width: 90rem;
margin: 0 auto;
padding: 1rem;
border-radius: .5rem;
background-color: #fff;
}

.github {
float: right;
text-align: center;
font-size: 1.1em;
}
.github a {
Expand All @@ -36,9 +40,13 @@ body {
background-color: #f5f5f5;
color: #333;
border: 1px solid currentColor;
border-radius: .25em;
border-radius: 5px;
}
.github svg {
vertical-align: middle;
fill: currentColor;
}

dt {
font-weight: bold;
}
54 changes: 34 additions & 20 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,32 +12,38 @@

<h1><code>&lt;responsive-video-background&gt;</code> Web Component</h1>

<p>A Web Component that helps <strong>using a video as the background of a content block</strong>.</p>
<p>The video usage can be restricted to large viewports, with an image fallback on thinner ones.</p>
<p class="github">
<a href="https://github.com/cleverage/responsive-video-background/">
View on github
<svg version="1.1" width="16" height="16" viewBox="0 0 16 16" aria-hidden="true"><path fill-rule="evenodd" d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8z"></path></svg>
</a>
</p>

<p>A Web Component helping using a video as the background of a content block.</p>
<p>The video can be limited to large viewports, with an image fallback on thinner ones.</p>
<nav>
<ul>
<li><a href="#syntax">Syntax</a></li>
<li><a href="#api">API</a></li>
<li><a href="#examples">Examples</a></li>
<li><a href="#faq">FAQ</a></li>
</ul>
</nav>

<responsive-video-background
class="demo demo1"
class="demo1"
mp4="https://test-videos.co.uk/vids/bigbuckbunny/mp4/h264/720/Big_Buck_Bunny_720_10s_1MB.mp4"
poster="https://test-videos.co.uk/user/pages/images/big_buck_bunny.jpg"
fallback="https://images.unsplash.com/photo-1601629665203-f9f2b8d07019?auto=format&w=1440&q=80"
srcset="https://images.unsplash.com/photo-1601629665203-f9f2b8d07019?auto=format&w=420&q=80 420w, https://images.unsplash.com/photo-1601629665203-f9f2b8d07019?auto=format&w=768&q=80 768w, https://images.unsplash.com/photo-1601629665203-f9f2b8d07019?auto=format&w=1024&q=80 1024w, https://images.unsplash.com/photo-1601629665203-f9f2b8d07019?auto=format&w=1440&q=80 1440w"
sizes="calc(100vh - 2rem)"
breakpoint="768px">
<div>
<h1>A fixed height component with a responsive video or image background</h1>
</div>
breakpoint="48rem">
<h1>A component with a responsive video background above 48rem viewport</h1>
<p>A paragraph of text</p>
<p>A second paragraph of text</p>
</responsive-video-background>

<h2>Usage</h2>

<h3>Syntax</h3>
<h2 id="syntax">Syntax</h2>

<p>Components configuration is done with attributes:</p>
<code><pre>
Expand All @@ -59,7 +65,7 @@ <h3>Syntax</h3>
&lt;/responsive-video-background&gt;
</pre></code>

<h3>API</h3>
<h2 id="api">API</h2>

<table border="1">
<thead>
Expand Down Expand Up @@ -126,44 +132,52 @@ <h3>API</h3>
</tbody>
</table>

<h2>Examples</h2>
<h2 id="examples">Examples</h2>

<responsive-video-background
class="demo demo2"
class="demo2"
mp4="https://test-videos.co.uk/vids/bigbuckbunny/mp4/h264/720/Big_Buck_Bunny_720_10s_1MB.mp4"
poster="https://test-videos.co.uk/user/pages/images/big_buck_bunny.jpg">
<div style="height: 20rem">
<div class="grid">
<h1>A dynamic width component with a video background</h1>
</div>
</responsive-video-background>

<responsive-video-background
class="demo demo3"
class="demo3"
mp4="https://test-videos.co.uk/vids/bigbuckbunny/mp4/h264/720/Big_Buck_Bunny_720_10s_1MB.mp4"
poster="https://test-videos.co.uk/user/pages/images/big_buck_bunny.jpg">
<div>
<div class="grid">
<h1>A small component with a video background</h1>
</div>
</responsive-video-background>

<responsive-video-background
class="demo demo4"
class="demo4"
fallback="https://images.unsplash.com/photo-1601629665203-f9f2b8d07019?auto=format&w=1440&q=80"
srcset="https://images.unsplash.com/photo-1601629665203-f9f2b8d07019?auto=format&w=420&q=80 420w, https://images.unsplash.com/photo-1601629665203-f9f2b8d07019?auto=format&w=768&q=80 768w, https://images.unsplash.com/photo-1601629665203-f9f2b8d07019?auto=format&w=1024&q=80 1024w, https://images.unsplash.com/photo-1601629665203-f9f2b8d07019?auto=format&w=1440&q=80 1440w"
sizes="(min-width: 92rem) 90rem, calc(100vh - 2rem)">
<div>
<div class="grid">
<h1>A fixed height component with an image background</h1>
<p>Look here!</p>
</div>
</responsive-video-background>

<responsive-video-background
class="demo demo5"
class="demo5"
mp4="https://test-videos.co.uk/vids/bigbuckbunny/mp4/h264/720/Big_Buck_Bunny_720_10s_1MB.mp4">
<div>
<div class="grid">
<h1>A fluid height component with an image background</h1>
</div>
</responsive-video-background>

<h2 id="faq">FAQ</h2>

<dl>
<dt>Why isn't the image switching to a video when the viewport becomes larger?</dt>
<dd>This is not a bug. The idea is to prevent a strong visual change when the user changes the viewport, either by resizing the browser, or rotating the device.</dd>
</dl>

</div>
<script type="module" src="./demo/app.js"></script>
</body>
Expand Down
65 changes: 22 additions & 43 deletions responsive-video-background.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,42 @@ const template = document.createElement('template');
template.innerHTML = `
<style>
:host {
display: grid;
display: inline-block;
box-sizing: border-box;
}
:host * {
box-sizing: inherit;
}
:host {
position: relative;
overflow: hidden;
}
:host .background,
:host .overlay,
:host .content {
grid-row: 1 / 2;
grid-column: 1 / 2;
:host .overlay {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
width: 100%;
height: 100%;
}
:host .background {
width: 100%;
object-position: center center;
object-fit: cover;
// initial state before JS runs
height: 0;
visibility: hidden;
}
:host .overlay {
background: var(--overlay-background, transparent);
background-color: var(--overlay-color, transparent);
}
/* Fix for Safari that puts inline videos on top by default */
:host .background { z-index: 50; }
:host .overlay { z-index: 51; }
:host .content { z-index: 52; }
:host .background { z-index: 48; }
:host .overlay { z-index: 49; }
:host .content { position: relative; z-index: 50; }
</style>
<div class="overlay"></div>
<div class="content">
Expand All @@ -56,7 +64,6 @@ export class ResponsiveVideoBackground extends HTMLElement {
const breakpoint = this.getAttribute('breakpoint');

const overlayElement = this.shadowRoot.querySelector('.overlay');
const contentElement = this.shadowRoot.querySelector('.content');

if (
(webm || mp4) &&
Expand Down Expand Up @@ -90,14 +97,9 @@ export class ResponsiveVideoBackground extends HTMLElement {
videoElement.appendChild(mp4Source);
}

const height = contentElement.offsetHeight;
videoElement.style.setProperty('height', `${height}px`);

// Insert the video element in the DOM before the overlay
this.shadowRoot.insertBefore(videoElement, overlayElement);

// backgroundElement.appendChild(videoElement);
videoElement.style.setProperty('visibility', 'visible');
} else if (srcset) {
// the viewport is less than `breakpoint` pixels wide, or there is no video, and there is an image

Expand All @@ -114,29 +116,6 @@ export class ResponsiveVideoBackground extends HTMLElement {
// Insert the image element in the DOM before the overlay
this.shadowRoot.insertBefore(imageElement, overlayElement);

// Show the image
imageElement.style.setProperty('visibility', 'visible');
}

const resizeObserver = new ResizeObserver(entries => {
window.requestAnimationFrame(() => {
if (!Array.isArray(entries) || !entries.length) {
return;
}
for (const entry of entries) {
// if (entry.target.parentNode.host.classList.contains('demo1')) {
// console.dir(entry.target);
// console.dir(entry.target.parentNode.querySelector(".background"));
// console.log(entry.borderBoxSize[0].blockSize);
// }
const backgroundElement = entry.target.parentNode.querySelector('.background');
if (backgroundElement) {
backgroundElement.style.height = `${Math.ceil(entry.borderBoxSize[0].blockSize)}px`;
}
}
});
});

resizeObserver.observe(this.shadowRoot.querySelector('.content > slot'));
}
}

0 comments on commit 8b3c01a

Please sign in to comment.