Force native controls on every video
Custom video players look slick until they break: a missing scrubber, no volume slider, a play button that ignores clicks. The browser ships a reliable control bar for free. A JustZix rule forces it onto every video so you always have working controls.
The one property that matters
Every <video> element has a boolean controls property. When it is true, the browser draws its own control bar. Sites disable it so their custom UI can take over. Turn it back on:
document.querySelectorAll('video').forEach(function (v) {
v.controls = true;
});
That is the core. The recipes below make it stick on dynamic pages and stop the site from removing it again.
Keep controls on dynamic players
Many sites toggle controls off after the page loads, or replace the video element entirely. A MutationObserver that watches both new nodes and attribute changes keeps your setting in place.
(function () {
function force(v) {
if (v.controls !== true) { v.controls = true; }
}
function scan(root) {
if (root.tagName === 'VIDEO') { force(root); }
if (root.querySelectorAll) {
root.querySelectorAll('video').forEach(force);
}
}
scan(document.documentElement);
new MutationObserver(function (records) {
records.forEach(function (rec) {
if (rec.type === 'attributes' && rec.target.tagName === 'VIDEO') {
force(rec.target);
}
rec.addedNodes.forEach(function (n) {
if (n.nodeType === 1) { scan(n); }
});
});
}).observe(document.documentElement, {
childList: true,
subtree: true,
attributes: true,
attributeFilter: ['controls']
});
})();
The attributeFilter narrows the observer to just the controls attribute, so it stays cheap even on busy pages.
Hide the broken custom UI with CSS
Once the native bar is visible, the site's custom overlay often sits on top and steals clicks. A small CSS rule can push it out of the way. Custom controls usually carry a predictable class or data attribute; inspect the page once and target it.
.video-player .custom-controls,
[data-player-ui],
.vjs-control-bar {
display: none !important;
}
video {
pointer-events: auto !important;
}
The second block re-enables clicks on the video itself, in case the site disabled them so its overlay could capture every interaction. Adjust the selectors to match the player you are dealing with.
A combined click-to-fix action
If you only want native controls occasionally, bind it to a key instead of running it always. This rule restores controls and clears blocking overlays when you press a shortcut.
document.addEventListener('keydown', function (e) {
if (e.altKey && e.key.toLowerCase() === 'c') {
document.querySelectorAll('video').forEach(function (v) {
v.controls = true;
v.style.pointerEvents = 'auto';
v.style.zIndex = '2147483647';
v.style.position = 'relative';
});
}
}, true);
Raising the z-index lifts the video above any overlay so its own control bar receives clicks.
Practical notes
- Native controls include speed, volume, fullscreen, and picture-in-picture in most browsers, so one rule covers several needs.
- If a site uses a streaming format the browser cannot scrub, the native bar will still play and pause reliably.
- Keep the JS and CSS as two halves of the same JustZix rule scoped to the same URL pattern.
Find a packaged version in our ready-made examples or download JustZix. To go further with speed, read control video playback speed anywhere.
Rate this post
No ratings yet — be the first.