Description
- gallery section grid video but make text/overlay color on hover + make full video slide up on item click
- view demo – password: abc
- buy me a coffee

#1. Install Code
#1.1. Make sure you used Grid Simple + Enable Captions

#1.2. Add Video (Youtube/Vimeo) + Text

#1.3. Hover on top right of section > Click EDIT SECTION

at Gallery > Anchor Link, enter word: gs-video

#1.4. Hover on Page where you use Gallery Grid > Click Gear icon

Click Advanced > Paste this code
- If you use Personal/Basic Plan and your plan doesn’t support Injection, see #3.1
<!-- 06.26c19v4 Gallery Section Grid Video -->
<script>
window.GSVideoConfig = {
sectionSelector: 'section[id*="gs-video"]',
wrapperSelector: '.gallery-grid-wrapper',
itemSelector: '.gallery-grid-item',
linkSelector: '.gallery-grid-image-link',
playerBlockId: 'gs-video-player-block',
scrollPadding: 80,
overlayBackgroundColor: 'rgba(0, 21, 173, 0.85)',
closeIconSize: '20px',
closeIconColor: '#ffffff',
closeBackgroundColor: '#000000'
};
</script>
<script>
(function () {
if (typeof window.EPPZScrollTo === 'undefined') {
window.EPPZScrollTo =
{
documentVerticalScrollPosition: function ()
{
if (self.pageYOffset) return self.pageYOffset;
if (document.documentElement && document.documentElement.scrollTop) return document.documentElement.scrollTop;
if (document.body.scrollTop) return document.body.scrollTop;
return 0;
},
viewportHeight: function ()
{ return (document.compatMode === "CSS1Compat") ? document.documentElement.clientHeight : document.body.clientHeight; },
documentHeight: function ()
{ return (document.height !== undefined) ? document.height : document.body.offsetHeight; },
documentMaximumScrollPosition: function ()
{ return this.documentHeight() - this.viewportHeight(); },
elementVerticalClientPositionById: function (id)
{
var element = document.getElementById(id);
var rectangle = element.getBoundingClientRect();
return rectangle.top;
},
scrollVerticalTickToPosition: function (currentPosition, targetPosition)
{
var filter = 0.2;
var fps = 60;
var difference = parseFloat(targetPosition) - parseFloat(currentPosition);
var arrived = (Math.abs(difference) <= 0.5);
if (arrived)
{
scrollTo(0.0, targetPosition);
return;
}
currentPosition = (parseFloat(currentPosition) * (1.0 - filter)) + (parseFloat(targetPosition) * filter);
scrollTo(0.0, Math.round(currentPosition));
setTimeout("EPPZScrollTo.scrollVerticalTickToPosition(" + currentPosition + ", " + targetPosition + ")", (1000 / fps));
},
scrollVerticalToElementById: function (id, padding)
{
var element = document.getElementById(id);
if (element == null)
{
console.warn('Cannot find element with id \'' + id + '\'.');
return;
}
var targetPosition = this.documentVerticalScrollPosition() + this.elementVerticalClientPositionById(id) - padding;
var currentPosition = this.documentVerticalScrollPosition();
var maximumScrollPosition = this.documentMaximumScrollPosition();
if (targetPosition > maximumScrollPosition) targetPosition = maximumScrollPosition;
this.scrollVerticalTickToPosition(currentPosition, targetPosition);
}
};
}
var instanceCount = 0;
function buildEmbedSrc(url) {
if (!url) return null;
var yt = url.match(/(?:youtube\.com\/(?:watch\?v=|embed\/|v\/)|youtu\.be\/)([A-Za-z0-9_-]{11})/);
if (yt) {
return 'https://www.youtube.com/embed/' + yt[1] + '?autoplay=1&mute=1&playsinline=1&rel=0';
}
var vimeo = url.match(/vimeo\.com\/(?:video\/)?(\d+)/);
if (vimeo) {
return 'https://player.vimeo.com/video/' + vimeo[1] + '?autoplay=1&muted=1';
}
return null;
}
function injectStyle(config) {
if (document.getElementById('gsvVideoStyle')) return;
var S = config.sectionSelector;
var css =
S + ' .gallery-grid-item{position:relative;}' +
S + ' .gallery-caption{position:absolute;top:0;left:0;width:100%;height:100%;margin:0;display:flex;align-items:center;justify-content:center;text-align:center;padding:0px;background-color:' + config.overlayBackgroundColor + ';opacity:0;visibility:hidden;pointer-events:none;transition:opacity 0.3s ease;z-index:2;}' +
S + ' .gallery-grid-item:hover .gallery-caption{opacity:1;visibility:visible;}' +
S + ' .gallery-caption-wrapper{padding:0 10px;}' +
S + ' .gallery-caption-content{color:#fff;margin:0;}' +
S + ' .gsv-player-block{position:relative;width:100%;margin-bottom:20px;padding-top:40px;display:none;}' +
S + ' .gsv-player-inner{position:relative;width:100%;padding-bottom:56.25%;background:#000;}' +
S + ' .gsv-player-inner iframe{position:absolute;top:0;left:0;width:100%;height:100%;border:0;}' +
S + ' .gallery-caption-content {height:100%;display:flex;align-items: center;justify-content:center;}' +
S + ' .gsv-close{position:absolute;top:0;right:0;border:0;cursor:pointer;display:flex;align-items:center;justify-content:center;padding:8px;z-index:3;background-color:' + config.closeBackgroundColor + ';}';
var style = document.createElement('style');
style.id = 'gsvVideoStyle';
style.textContent = css;
document.head.appendChild(style);
}
function initGSVideo(section, config) {
if (section.dataset.gsVideoDone === 'true') return;
var wrapper = section.querySelector(config.wrapperSelector);
if (!wrapper) return;
var items = section.querySelectorAll(config.itemSelector);
if (!items.length) return;
section.dataset.gsVideoDone = 'true';
var index = instanceCount++;
var playerBlockId = config.playerBlockId + '-' + index;
var playerBlock = document.createElement('div');
playerBlock.className = 'gsv-player-block';
playerBlock.id = playerBlockId;
var closeButton = document.createElement('button');
closeButton.className = 'gsv-close';
closeButton.type = 'button';
closeButton.innerHTML =
'<svg viewBox="0 0 40 40" stroke-width="1.5" style="width:' + config.closeIconSize +
'; height:' + config.closeIconSize + '; stroke:' + config.closeIconColor +
';"><path d="M4.3,35.7L35.7,4.3"></path><path d="M4.3,4.3l31.4,31.4"></path></svg>';
var playerInner = document.createElement('div');
playerInner.className = 'gsv-player-inner';
playerBlock.appendChild(closeButton);
playerBlock.appendChild(playerInner);
wrapper.parentNode.insertBefore(playerBlock, wrapper);
function openPlayer(src) {
if (!src) return;
playerInner.innerHTML = '';
var iframe = document.createElement('iframe');
iframe.src = src;
iframe.setAttribute('allow', 'autoplay; fullscreen; picture-in-picture; clipboard-write; encrypted-media; web-share');
iframe.setAttribute('allowfullscreen', '');
iframe.setAttribute('frameborder', '0');
iframe.setAttribute('referrerpolicy', 'strict-origin-when-cross-origin');
playerInner.appendChild(iframe);
playerBlock.style.display = 'block';
window.EPPZScrollTo.scrollVerticalToElementById(playerBlockId, config.scrollPadding);
}
function closePlayer() {
playerInner.innerHTML = '';
playerBlock.style.display = 'none';
}
closeButton.addEventListener('click', function (e) {
e.preventDefault();
closePlayer();
});
Array.prototype.forEach.call(items, function (item) {
if (item.dataset.gsItemDone === 'true') return;
var link = item.querySelector(config.linkSelector);
if (!link) return;
var href = link.getAttribute('href');
var src = buildEmbedSrc(href);
if (!src) return;
link.addEventListener('click', function (e) {
e.preventDefault();
openPlayer(src);
});
item.dataset.gsItemDone = 'true';
});
}
function attemptInitAll() {
var config = window.GSVideoConfig;
if (!config) return false;
injectStyle(config);
var sections = document.querySelectorAll(config.sectionSelector);
if (!sections.length) return false;
var pending = 0;
Array.prototype.forEach.call(sections, function (section) {
if (section.dataset.gsVideoDone === 'true') return;
var wrapper = section.querySelector(config.wrapperSelector);
var items = section.querySelectorAll(config.itemSelector);
if (wrapper && items.length) {
initGSVideo(section, config);
} else {
pending++;
}
});
return pending === 0;
}
var pollTimer = null;
function startPolling() {
if (attemptInitAll()) return;
if (pollTimer) clearInterval(pollTimer);
var attempts = 0;
var maxAttempts = 60;
pollTimer = setInterval(function () {
attempts++;
if (attemptInitAll() || attempts >= maxAttempts) {
clearInterval(pollTimer);
pollTimer = null;
}
}, 150);
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', startPolling);
} else {
startPolling();
}
window.addEventListener('load', startPolling);
window.addEventListener('mercury:load', startPolling);
})();
</script>

#2. Customize
#2.1. To change overlay background color, change Line 10
overlayBackgroundColor: 'rgba(0, 21, 173, 0.85)',
#2.2. To change close icon style, change Line 11 to Line 13
closeIconSize: '20px', closeIconColor: '#ffffff', closeBackgroundColor: '#000000'
#3. Other
#3.1. If you use Personal/Basic Plan and your plan doesn’t support Injection, you can edit current page (page where you use Gallery Grid) > Add a Block.

Add a Markdown Block
![]()
Paste this code into Markdown Block
<script>
window.GSVideoConfig = {
sectionSelector: 'section[id*="gs-video"]',
wrapperSelector: '.gallery-grid-wrapper',
itemSelector: '.gallery-grid-item',
linkSelector: '.gallery-grid-image-link',
playerBlockId: 'gs-video-player-block',
scrollPadding: 80,
overlayBackgroundColor: 'rgba(0, 21, 173, 0.85)',
closeIconSize: '20px',
closeIconColor: '#ffffff',
closeBackgroundColor: '#000000'
};
</script>
<script>
(function () {
if (typeof window.EPPZScrollTo === 'undefined') {
window.EPPZScrollTo =
{
documentVerticalScrollPosition: function ()
{
if (self.pageYOffset) return self.pageYOffset;
if (document.documentElement && document.documentElement.scrollTop) return document.documentElement.scrollTop;
if (document.body.scrollTop) return document.body.scrollTop;
return 0;
},
viewportHeight: function ()
{ return (document.compatMode === "CSS1Compat") ? document.documentElement.clientHeight : document.body.clientHeight; },
documentHeight: function ()
{ return (document.height !== undefined) ? document.height : document.body.offsetHeight; },
documentMaximumScrollPosition: function ()
{ return this.documentHeight() - this.viewportHeight(); },
elementVerticalClientPositionById: function (id)
{
var element = document.getElementById(id);
var rectangle = element.getBoundingClientRect();
return rectangle.top;
},
scrollVerticalTickToPosition: function (currentPosition, targetPosition)
{
var filter = 0.2;
var fps = 60;
var difference = parseFloat(targetPosition) - parseFloat(currentPosition);
var arrived = (Math.abs(difference) <= 0.5);
if (arrived)
{
scrollTo(0.0, targetPosition);
return;
}
currentPosition = (parseFloat(currentPosition) * (1.0 - filter)) + (parseFloat(targetPosition) * filter);
scrollTo(0.0, Math.round(currentPosition));
setTimeout("EPPZScrollTo.scrollVerticalTickToPosition(" + currentPosition + ", " + targetPosition + ")", (1000 / fps));
},
scrollVerticalToElementById: function (id, padding)
{
var element = document.getElementById(id);
if (element == null)
{
console.warn('Cannot find element with id \'' + id + '\'.');
return;
}
var targetPosition = this.documentVerticalScrollPosition() + this.elementVerticalClientPositionById(id) - padding;
var currentPosition = this.documentVerticalScrollPosition();
var maximumScrollPosition = this.documentMaximumScrollPosition();
if (targetPosition > maximumScrollPosition) targetPosition = maximumScrollPosition;
this.scrollVerticalTickToPosition(currentPosition, targetPosition);
}
};
}
var instanceCount = 0;
function buildEmbedSrc(url) {
if (!url) return null;
var yt = url.match(/(?:youtube\.com\/(?:watch\?v=|embed\/|v\/)|youtu\.be\/)([A-Za-z0-9_-]{11})/);
if (yt) {
return 'https://www.youtube.com/embed/' + yt[1] + '?autoplay=1&mute=1&playsinline=1&rel=0';
}
var vimeo = url.match(/vimeo\.com\/(?:video\/)?(\d+)/);
if (vimeo) {
return 'https://player.vimeo.com/video/' + vimeo[1] + '?autoplay=1&muted=1';
}
return null;
}
function injectStyle(config) {
if (document.getElementById('gsvVideoStyle')) return;
var S = config.sectionSelector;
var css =
S + ' .gallery-grid-item{position:relative;}' +
S + ' .gallery-caption{position:absolute;top:0;left:0;width:100%;height:100%;margin:0;display:flex;align-items:center;justify-content:center;text-align:center;padding:0px;background-color:' + config.overlayBackgroundColor + ';opacity:0;visibility:hidden;pointer-events:none;transition:opacity 0.3s ease;z-index:2;}' +
S + ' .gallery-grid-item:hover .gallery-caption{opacity:1;visibility:visible;}' +
S + ' .gallery-caption-wrapper{padding:0 10px;}' +
S + ' .gallery-caption-content{color:#fff;margin:0;}' +
S + ' .gsv-player-block{position:relative;width:100%;margin-bottom:20px;padding-top:40px;display:none;}' +
S + ' .gsv-player-inner{position:relative;width:100%;padding-bottom:56.25%;background:#000;}' +
S + ' .gsv-player-inner iframe{position:absolute;top:0;left:0;width:100%;height:100%;border:0;}' +
S + ' .gallery-caption-content {height:100%;display:flex;align-items: center;justify-content:center;}' +
S + ' .gsv-close{position:absolute;top:0;right:0;border:0;cursor:pointer;display:flex;align-items:center;justify-content:center;padding:8px;z-index:3;background-color:' + config.closeBackgroundColor + ';}';
var style = document.createElement('style');
style.id = 'gsvVideoStyle';
style.textContent = css;
document.head.appendChild(style);
}
function initGSVideo(section, config) {
if (section.dataset.gsVideoDone === 'true') return;
var wrapper = section.querySelector(config.wrapperSelector);
if (!wrapper) return;
var items = section.querySelectorAll(config.itemSelector);
if (!items.length) return;
section.dataset.gsVideoDone = 'true';
var index = instanceCount++;
var playerBlockId = config.playerBlockId + '-' + index;
var playerBlock = document.createElement('div');
playerBlock.className = 'gsv-player-block';
playerBlock.id = playerBlockId;
var closeButton = document.createElement('button');
closeButton.className = 'gsv-close';
closeButton.type = 'button';
closeButton.innerHTML =
'<svg viewBox="0 0 40 40" stroke-width="1.5" style="width:' + config.closeIconSize +
'; height:' + config.closeIconSize + '; stroke:' + config.closeIconColor +
';"><path d="M4.3,35.7L35.7,4.3"></path><path d="M4.3,4.3l31.4,31.4"></path></svg>';
var playerInner = document.createElement('div');
playerInner.className = 'gsv-player-inner';
playerBlock.appendChild(closeButton);
playerBlock.appendChild(playerInner);
wrapper.parentNode.insertBefore(playerBlock, wrapper);
function openPlayer(src) {
if (!src) return;
playerInner.innerHTML = '';
var iframe = document.createElement('iframe');
iframe.src = src;
iframe.setAttribute('allow', 'autoplay; fullscreen; picture-in-picture; clipboard-write; encrypted-media; web-share');
iframe.setAttribute('allowfullscreen', '');
iframe.setAttribute('frameborder', '0');
iframe.setAttribute('referrerpolicy', 'strict-origin-when-cross-origin');
playerInner.appendChild(iframe);
playerBlock.style.display = 'block';
window.EPPZScrollTo.scrollVerticalToElementById(playerBlockId, config.scrollPadding);
}
function closePlayer() {
playerInner.innerHTML = '';
playerBlock.style.display = 'none';
}
closeButton.addEventListener('click', function (e) {
e.preventDefault();
closePlayer();
});
Array.prototype.forEach.call(items, function (item) {
if (item.dataset.gsItemDone === 'true') return;
var link = item.querySelector(config.linkSelector);
if (!link) return;
var href = link.getAttribute('href');
var src = buildEmbedSrc(href);
if (!src) return;
link.addEventListener('click', function (e) {
e.preventDefault();
openPlayer(src);
});
item.dataset.gsItemDone = 'true';
});
}
function attemptInitAll() {
var config = window.GSVideoConfig;
if (!config) return false;
injectStyle(config);
var sections = document.querySelectorAll(config.sectionSelector);
if (!sections.length) return false;
var pending = 0;
Array.prototype.forEach.call(sections, function (section) {
if (section.dataset.gsVideoDone === 'true') return;
var wrapper = section.querySelector(config.wrapperSelector);
var items = section.querySelectorAll(config.itemSelector);
if (wrapper && items.length) {
initGSVideo(section, config);
} else {
pending++;
}
});
return pending === 0;
}
var pollTimer = null;
function startPolling() {
if (attemptInitAll()) return;
if (pollTimer) clearInterval(pollTimer);
var attempts = 0;
var maxAttempts = 60;
pollTimer = setInterval(function () {
attempts++;
if (attemptInitAll() || attempts >= maxAttempts) {
clearInterval(pollTimer);
pollTimer = null;
}
}, 150);
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', startPolling);
} else {
startPolling();
}
window.addEventListener('load', startPolling);
window.addEventListener('mercury:load', startPolling);
})();
</script>
