Search code examples
cssbootstrap-4bootstrap-modal

What is the correct way to put a frame in a bootstrap modal?


I want to put a frame in a css modal, but the way it is being displayed is not the most pleasant, and besides, as I did the adjustment (top and left) manually, for other screen sizes the image is misconfigured (frame outside the modal). As per the image below.

On big screen

On big screen

On small screen

On small screen

I used the following code to get the above results

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
        integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
    <title>Document</title>
    <style>
        body {
            width: 100vw;
            height: 100vh;
            background: lightgray;
        }

        .frame-card {
            width: 800px;
            height: 520px;
            position: absolute;
            top: 25%;
            left: 31.2%;
        }
    </style>
</head>

<body>
    <div class="container mt-2">
        <!-- Button trigger modal -->
        <button type="button" class="btn btn-primary video-btn" data-toggle="modal"
            data-src="https://player.vimeo.com/video/58385453?badge=0&autoplay=1&loop=1" data-target="#myModal">
            Play Vimeo Video
        </button>
        <!-- Modal -->
        <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel"
            aria-hidden="true">
            <div class="modal-dialog modal-dialog-centered modal-lg" role="document">
                <div class="modal-content">
                    <div class="modal-body">
                        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                            <span aria-hidden="true">&times;</span>
                        </button>
                        <!-- 16:9 aspect ratio -->
                        <div class="embed-responsive embed-responsive-16by9">
                            <iframe class="embed-responsive-item" src="" id="video" allowscriptaccess="always"
                                allow="autoplay">
                            </iframe>
                        </div>
                    </div>
                </div>
            </div>
            <img class="frame-card" src="https://uploaddeimagens.com.br/images/004/266/329/original/frame-card.png?1671470988">
        </div>
    </div>
    <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"
        integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous">
        </script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/popper.min.js"
        integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous">
        </script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js"
        integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous">
        </script>
    <script>
        $(document).ready(function () {
            // Gets the video src from the data-src on each button
            var $videoSrc;
            $('.video-btn').click(function () {
                $videoSrc = $(this).data("src");
            });
            // when the modal is opened autoplay it  
            $('#myModal').on('shown.bs.modal', function (e) {
                // set the video src to autoplay and not to show related video. Youtube related video is like a box of chocolates... you never know what you're gonna get
                $("#video").attr('src', $videoSrc);
            })
            // stop playing the youtube video when I close the modal
            $('#myModal').on('hide.bs.modal', function (e) {
                // a poor man's stop video
                $("#video").attr('src', $videoSrc);
            })
            // document ready  
        });
    </script>
</body>
</html>

What classes or styling should I use?

Thanks in advance!

I used position property with absolute value to align the image, I don't know if it's the right approach to do, besides, I used left and top alignment, I would like a more "automatic" way to align the image.


Solution

  • I'm not entirely sure about your desired result but, I have managed to put the frame neatly around the video. Move the .frame-card inside the .embed-responsive.embed-responsive-16by9 right after the iframe and just give it .embed-responsive-item and no additional styles are necessary, as it will have the same size/position as the video (iframe.embed-responsive-item)

    $(document).ready(function() {
      // Gets the video src from the data-src on each button
      var $videoSrc;
      $('.video-btn').click(function() {
        $videoSrc = $(this).data("src");
      });
      // when the modal is opened autoplay it  
      $('#myModal').on('shown.bs.modal', function(e) {
        // set the video src to autoplay and not to show related video. Youtube related video is like a box of chocolates... you never know what you're gonna get
        $("#video").attr('src', $videoSrc);
      })
      // stop playing the youtube video when I close the modal
      $('#myModal').on('hide.bs.modal', function(e) {
        // a poor man's stop video
        $("#video").attr('src', $videoSrc);
      })
      // document ready  
    });
    body {
      width: 100vw;
      height: 100vh;
      background: lightgray;
    }
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
    
    <div class="container mt-2">
      <!-- Button trigger modal -->
      <button type="button" class="btn btn-primary video-btn" data-toggle="modal" data-src="https://player.vimeo.com/video/58385453?badge=0&autoplay=1&muted=1&loop=1" data-target="#myModal">
        Play Vimeo Video
      </button>
      <!-- Modal -->
      <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
        <div class="modal-dialog modal-dialog-centered modal-lg" role="document">
          <div class="modal-content">
            <div class="modal-body">
              <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                <span aria-hidden="true">&times;</span>
              </button>
              <!-- 16:9 aspect ratio -->
              <div class="embed-responsive embed-responsive-16by9">
                <iframe class="embed-responsive-item" src="" id="video" allowscriptaccess="always" allow="autoplay">
                </iframe>
                <img class="embed-responsive-item" src="https://uploaddeimagens.com.br/images/004/266/329/original/frame-card.png?1671470988">
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
    
    <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous">
    </script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous">
    </script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous">
    </script>

    Note:

    You need to add &muted=1 to your video source URL in order for autoplay to work: https://vimeo.zendesk.com/hc/en-us/articles/115004485728-Autoplay-and-loop-embedded-videos The video doesn't work in the snippet but you can check it out in my fiddle.