The following page displays a thumbnail image, that when clicked, brings up a Bootstrap 3 modal with the video. It works, but if the video is too tall for the window, it extends below the window, and the user can’t see the entire video (and has to scroll). I’ve tried various resizing strategies, but nothing seems to work. Suggestions appreciated. URLs obscured, sorry. And I’m required to use Bootstrap 3.
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
<script src="https://vjs.zencdn.net/7.8.4/video.js"></script>
<link href="https://vjs.zencdn.net/7.8.4/video-js.css" rel="stylesheet">
</head>
<body>
<a href="#" data-toggle="modal" data-target="#viewVideoModal" data-video-url="https://VIDEOFILE" class="video-link">
<img id="img-401" src="https://VIDEOFILE?thumb=1" height="280" width="157">
</a>
<div class="modal fade" id="viewVideoModal" tabindex="-1" role="dialog" aria-labelledby="viewVideoModalLabel">
<div class="modal-dialog" role="document" style="margin-top:50px;">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">
<span aria-hidden="true">
×
</span>
<span class="sr-only">
Close
</span>
</button>
</div>
<div class="modal-body" id="viewVideoBody"></div>
</div>
</div>
</div>
<script>
var player;
$('#viewVideoModal').on('show.bs.modal', function (event) {
var button = $(event.relatedTarget); // Button that triggered the modal
var videoSrc = button.data('video-url');
var videoTag = document.createElement('video');
videoTag.setAttribute('class', 'video-js vjs-fluid center-block vjs-default-skin');
videoTag.setAttribute('controls', '');
videoTag.setAttribute('preload', 'auto');
videoTag.setAttribute('data-setup', '{}');
// Create a new source tag
var sourceTag = document.createElement('source');
sourceTag.setAttribute('src', videoSrc);
sourceTag.setAttribute('type', 'video/mp4');
// Append the source tag to the video tag
videoTag.appendChild(sourceTag);
// Get the modal body and clear its contents
var modalBody = document.getElementById('viewVideoBody');
modalBody.innerHTML = '';
// Append the video tag to the modal body
modalBody.appendChild(videoTag);
// Initialize the video player
player = videojs(videoTag);
});
</script>
</body>
</html>
2
Answers
I've settled on the following solution. It's not perfect, because, depending on the aspect ratio of the video, there are black bars either on the sides of the video or above and below the video. But otherwise, it works.
I made 3 changes to the original code I posted.
width:80vw; height: 80vh
vjs-fluid
class tovjs-fill
videoModalBody
every time that a video is instantiated, towidth:80vw; height: 80vh
Here is the modified code:
You are creating a new
<video>
tag each time the modal is shown and appending it to the modal body. The video is set to be fluid, which should make it responsive, but it seems that the modal is not responding as expected when the video dimensions exceed the viewport height.CSS-based solution
One way to make the video fit within the modal (and the viewport) is to limit the height of the video by using CSS and to also ensure that the video maintains its aspect ratio. The CSS
max-height
andobject-fit
properties can be quite helpful here.First, add a new CSS class in the
<head>
section of your HTML:Next, wrap your
<video>
element in a<div>
with this class, so modify your JavaScript code like this:The
80vh
value formax-height
means that the video will take up to 80% of the viewport height. You can adjust this value as needed. Theoverflow: auto
will provide a scrollbar in case the video height still exceeds the modal height. Theobject-fit: contain;
ensures the aspect ratio of the video is maintained.Warning:
object-fit
is not supported in Internet Explorer. If you need to support IE, you may need to find a different solution or use a polyfill.If you want the video to resize to fit within the modal without the need for a scroll bar, you will need to adjust the CSS and JavaScript a bit.
First, update the CSS with
max-height
set to100%
andheight
set toauto
for the.video-js
class:Then, modify the JavaScript. Instead of setting the height of the video directly, set the height of the modal body to a percentage of the viewport height, and then let the video fill the available space:
With this adjustment, the video should fill the modal body up to its maximum height and adjust its size according to the viewport height. The video will maintain its aspect ratio due to the
vjs-fluid
class.If the aspect ratio of the video does not match the aspect ratio of the modal body, there may be some unused space in the modal body, but the video itself should fit without a scrollbar.
Note: The value
80vh
for.modal-video-container
‘sheight
can be adjusted to suit your needs. This value means the modal body will be 80% of the viewport height.jQuery UI-based solution
As an alternative, assuming you can add/use jQuery UI to your project, you could consider "Apply size of video element to bootstrap modal while scaling".
This jQuery code uses the
.resizable()
function from the jQuery UI library to make the modal content resizable, and thealsoResize
option to apply the same resizing to the video element.Then, it binds a function to the
resizestop
event, which is fired when the user stops resizing the element. This function adjusts the video’s height and width according to the new size of the modal content, subtracting some pixels to account for padding.That would be:
The values
-60
and-30
are the padding to be removed from the calculated height and width respectively.Do ensure to replace
"#video"
with the appropriate selector for your video element. Also, you might need to adjust the padding values (-60
and-30
) depending on your exact modal design and layout.Incorporating this new piece of code into the previous code, we can modify the ‘show.bs.modal’ event as follows:
This code first assigns an id of ‘
video
‘ to thevideo
tag so that we can select it with jQuery in the ‘shown.bs.modal
‘ event.The
shown.bs.modal
event is a Bootstrap-specific event that is fired after the modal has been made visible to the user. At this point, we can resize the video to fit the modal content, taking into account any padding.Again, do adjust the
-60
and-30
values in the resize function based on the padding in your modal. If you don’t have any padding, you can set these values to0
.