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:
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>