Quantcast
Channel: Active questions tagged flexbox - Stack Overflow
Viewing all articles
Browse latest Browse all 1675

Slideshow should scale proportionately and stay within confines of its container

$
0
0

I'm designing a dashboard-style web page to be used on desktops and large tablets. By this I mean there is no body-scrolling: all components will be visible in the browser window, whatever its dimensions (within reason).

Thanks to an earlier post I was advised to use a grid layout for a dashboard. I'm now trying to adapt that answer to include, in another panel of the page, a slideshow. The images should be scaled down proportionally, if necessary, to fit and appear centered inside the panel.

These screenshots demonstrate where I stand:

slideshow scaling

The bottom right picture shows what happens when trying to scale a width: 1000 / height: 4000 image. Apparently it only tries to make the width fit. In this case, it should have scaled it down enough for the height to fit.

Here's my code. I tried using a flexbox for the slideshow, since that's how I solved it earlier. Be sure to click the "Full page" link.

/* * Slideshow_test generates a sequence of five images that are * inserted into the right panel, scaled proportionally to fit * the available space. * * - 4000x500px exceeds the width of the container * - 1000x4000px exceeds the height of the container * - 4000x4000px exceeds both the width and the height of the container. * - 600x400px should fit within the container without any scaling * - 100x200px should also fit. It's included to prove that it isn't scaled up. */const duration = 2000; // time (msec) to display each slideconst min_size = 0; // min file size to selectconst max_size = 0; // max file size (0 means no limit)const sleep = ms => new Promise(r => setTimeout(r, ms));const sizes = [  /* wd, ht */  [4000, 500],  [1000, 4000],  [4000, 4000],  [600, 400],  [100, 200]];async function slideshow_test(duration, min = 0, max = 0) {  let n = 0;  const my_img = document.querySelector('#slide-div-img');  let my_randomizer;  while (true) {    let size_index = n++ % sizes.length;    let w = sizes[size_index][0];    let h = sizes[size_index][1];    let my_randomizer = `https://placehold.co/${w}x${h}/orange/black/png?text=Pre-scaled+size\\n${w}+x+${h}+px`;    try {      const my_response = await fetch(my_randomizer);      const my_blob = await my_response.blob();      URL.revokeObjectURL(my_img.src);      const my_url = URL.createObjectURL(my_blob);      my_img.src = my_url;      await sleep(duration);    } catch (my_error) {      console.error('Error: ', my_error);      break;    }  }}
:root {  /* I don't know of any way to give <body> the margins I want without somehow           * destroying the "dashboard" appearance, so I set variables here           * and use it in several places to fake it.           */  --html-background: indigo;  --body-margin: 1em;}* {  box-sizing: border-box;}html,body {  height: 100%;}html {  background: var(--html-background);}/* Body has four "rows": fake top margin, header, panels, and fake bottom       * margin       */body {  outline: 4px dashed red;  outline-offset: -4px;  background-color: #dbd2c3;  font-family: Arial, Helvetica, sans-serif;  margin: 0 var(--body-margin);  /* side margins only */  overflow: hidden;  /* prevent any body scroll */  display: grid;  /* grid = best for dashboard layout */  grid-template-rows: var(--body-margin)    /* fake top margin */    auto    /* header */    1fr    /* widget area */    var(--body-margin);  /* fake bottom margin */}fake-body-margin {  background: var(--html-background);}header {  background: yellow;  text-align: center;}panels {  background: cyan;  display: grid;  grid-template-columns: 45fr 5fr 50fr;}left-panel {  outline: 4px dotted green;  outline-offset: -4px;  display: grid;  grid-template-rows: auto 1fr;}left-panel-top {}left-panel-bottom {}left-panel-bottom-content {}gap-panel {  background: black;}right-panel {  outline: 4px dotted green;  outline-offset: -4px;  display: grid;  grid-template-columns: 1fr;}.grid-item-thats-a-flexbox {  width: 100%;  height: 100%;  display: flex;  justify-content: center;  /* Centers horizontally */  align-items: center;  /* Centers vertically */}.scaled-picture {  max-width: calc(100% - 1em);  /* leave a little breathing room */  max-height: calc(100% - 1em);  outline: 8px double black;  outline-offset: -8px;}
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"></head><body onload="slideshow_test(duration)"><!-- Fake top margin of <body> --><fake-body-margin></fake-body-margin><header><h1>Page Heading</h1></header><panels><left-panel><left-panel-top><h2>Welcome</h2>        Blah blah blah</left-panel-top><left-panel-bottom><left-panel-bottom-content></left-panel-bottom-content></left-panel-bottom></left-panel><gap-panel></gap-panel><right-panel><!-- This div will hold the <img> --><div class="grid-item-thats-a-flexbox"><!-- slideshow.js will plug pix here --><img class="scaled-picture"                 id="slide-div-img"></div> <!-- END image holder --></right-panel></panels><!-- Fake bottom margin of <body> --><fake-body-margin></fake-body-margin></body></html>

Viewing all articles
Browse latest Browse all 1675

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>