简体   繁体   中英

Side By Side Gallery with flex display

Currently I need to put together a video gallery which contains a main video and up to 4 sub videos. In this case I am unable to change the dom.

I had it working with flex with the sub videos being below the main video but I need to have the sub videos display along the right side of the main video. The number of sub videos can vary (maximum of 4) and should scale to take up the full height of the main video with 1rem spacing. I have tried using CSS grids but I need to support IE which is proving problematic.

Here is an example of what I currently have: https://jsfiddle.net/gak13ro4/1/

HTML:

<div class="video-container">
  <div class="video"><div class="video-embed"><iframe width="854" height="480" frameborder="0" allowfullscreen="allowfullscreen" src="https://player.vimeo.com/video/25300082?autoplay=0"></iframe></div></div>
  <div class="video"><div class="video-embed"><iframe width="854" height="480" frameborder="0" allowfullscreen="allowfullscreen" src="https://player.vimeo.com/video/25300082?autoplay=0"></iframe></div></div>
  <div class="video"><div class="video-embed"><iframe width="854" height="480" frameborder="0" allowfullscreen="allowfullscreen" src="https://player.vimeo.com/video/25300082?autoplay=0"></iframe></div></div>
  <div class="video"><div class="video-embed"><iframe width="854" height="480" frameborder="0" allowfullscreen="allowfullscreen" src="https://player.vimeo.com/video/25300082?autoplay=0"></iframe></div></div>
  <div class="video"><div class="video-embed"><iframe width="854" height="480" frameborder="0" allowfullscreen="allowfullscreen" src="https://player.vimeo.com/video/25300082?autoplay=0"></iframe></div></div>
</div>

CSS:

.video-container {
  background-color: green;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
}

.video-container .video {
  flex-basis: 20%;
  background-color: grey;
}

.video-container .video:first-child {
  flex-basis: 100%;
  padding-bottom: 1rem;
}

.video-embed {
  width: 100%;
  height: 100%;
  position: relative;
}

.video-embed:after {
  content: '';
  display: block;
  padding-bottom: 56.25%;
}

.video-embed > iframe {
    width: 100%;
    height: 100%;
    position: absolute;

}

I know, maybe it is too late for you, but to find a good solution to your question take me some... days ;-)

I had to find the correct ratio to first video width (the biggest one with its padding) and screen width. Well, finally I found it (for videos with 16/9 aspect ratio):

r= (n-1)/n + 14p/9w * (n-1)/(n+1)

Where n is the video's number, p is your padding and w is the screen witdh.

This is the solution, after you have only to put it in a mathematical system to calcolate videos and their containers width & height:

const videoRap = 0.5625; // 16/9
const padding = 16; // 1rem
const nVideo = $(".video").length;

var widthVideo,
    widthScreen,
    heightVideo,
    widthContainer,
    newHeight,
    rapp

function calc() {
    widthScreen = $(".video-container").outerWidth();
    rapp = (nVideo - 1) / (nVideo) + ((14 * padding) / (9 * widthScreen)) * ((nVideo - 1) / (nVideo + 1));

    widthContainer = parseInt(widthScreen * rapp, 10);
    widthVideo = parseInt(widthScreen - widthContainer, 10);

    newHeight = parseInt(((widthContainer - (padding * 2)) * videoRap) + (padding * 2), 10);
    heightVideo = parseInt((newHeight / (nVideo - 1)), 10);



    $(".video").css({
        "height": heightVideo,
        "width": widthVideo
    });
    $(".video-container .video:first-child").css({
        "width": widthContainer
    });
    $(".video-container").css({
        "height": newHeight
    });
}

Now you can put how many video you want, jQuery does all the operations for you: you have to change only your padding, if you want to change it.

const padding = 16; // 1rem

In CSS, you have to change only your "padding" here:

.video-embed {
    margin:   auto;
    position: relative;
    height:   calc(100% - 2rem); /* your padding * 2 */
    width:    calc(100% - 2rem); /* your padding * 2 */
}

This is all the code in action (I add an example with 4 small video, but you can put how many video you want):

 $(function () { const videoRap = 0.5625; // 16/9 const padding = 16; // 1rem const nVideo = $(".video").length; var widthVideo, widthScreen, heightVideo, widthContainer, newHeight, rapp function calc() { widthScreen = $(".video-container").outerWidth(); rapp = (nVideo - 1) / (nVideo) + ((14 * padding) / (9 * widthScreen)) * ((nVideo - 1) / (nVideo + 1)); widthContainer = parseInt(widthScreen * rapp, 10); widthVideo = parseInt(widthScreen - widthContainer, 10); newHeight = parseInt(((widthContainer - (padding * 2)) * videoRap) + (padding * 2), 10); heightVideo = parseInt((newHeight / (nVideo - 1)), 10); $(".video").css({ "height": heightVideo, "width": widthVideo }); $(".video-container .video:first-child").css({ "width": widthContainer }); $(".video-container").css({ "height": newHeight }); } calc(); $(window).resize(function () { calc(); }); });
 * { box-sizing: border-box; } .video-container { display: flex; flex-wrap: wrap; flex-direction: column; width: 100%; } .video{ flex: 1 1 auto; width:auto; display:flex; } .video-container .video:first-child { height:100% !important; } .video-embed { margin: auto; position: relative; height: calc(100% - 2rem); /* your padding * 2 */ width: calc(100% - 2rem); /* your padding * 2 */ } .video iframe { width: 100%; height: 100%; position: absolute; }
 <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script> <link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.1/normalize.min.css"> <div class="video-container"> <div class="video"><div class="video-embed"><iframe frameborder="0" allowfullscreen="allowfullscreen" src="https://player.vimeo.com/video/25300082?autoplay=0"></iframe></div></div> <div class="video"><div class="video-embed"><iframe frameborder="0" allowfullscreen="allowfullscreen" src="https://player.vimeo.com/video/25300082?autoplay=0"></iframe></div></div> <div class="video"><div class="video-embed"><iframe frameborder="0" allowfullscreen="allowfullscreen" src="https://player.vimeo.com/video/25300082?autoplay=0"></iframe></div></div> <div class="video"><div class="video-embed"><iframe frameborder="0" allowfullscreen="allowfullscreen" src="https://player.vimeo.com/video/25300082?autoplay=0"></iframe></div></div> <div class="video"><div class="video-embed"><iframe frameborder="0" allowfullscreen="allowfullscreen" src="https://player.vimeo.com/video/25300082?autoplay=0"></iframe></div></div> </div>

It was really Interesting to find a solution using only flexbox and some javascript. Thank you very much for the question! ;)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM