简体   繁体   中英

How to tightly wrap a div around an image, but also resize the image to fit a content area if resolution is larger than content area?

I'm trying to build an image viewer with specific requirements. They are as follows:

  • The content area is a grid-area.
  • If the image is larger than the content area, it should be contained without stretching the image.
  • If the image is smaller than the content area, it should be centred within the content area.
  • There must be a div tightly wrapping the image at all times.

I've made a quick sketch below illustrating the desired behaviour for a portrait (top row), and landscape (bottom row). The images on the left column are the behaviour required if the image's resolution is higher than the content area.

Color code:

  • White box: content area.
  • Red box: image.
  • Blue border: image wrapping div.

要求

My primary approach so far has been to absolutely position the wrapping div around the image, which works fine until I try to get the resize to fit behaviour in. Usually this will break the tightly wrapped div.

I can also use Javascript, but because this is a foundation to build more on top of I'd rather try keep it to HTML and CSS.

You should ensure that your div just assumes the size of the content, the img in this case. So don't use absolute. You mentioned using grid , so the below example will generate the a grid with a main section wrapped by 20px padding. Then just use the max value on the img to make sure it does exceed the grid box's size. Then center it within the grid box:

 const width = document.querySelector( '[name=width]' ); const height = document.querySelector( '[name=height]' ); const image = document.querySelector( 'img' ); function onchange(){ image.src = `http://placehold.it/${width.value}x${height.value}`; image.style = ''; } width.addEventListener( 'change', onchange ); height.addEventListener( 'change', onchange ); window.addEventListener( 'DOMContentLoaded', () => setTimeout( onchange, 100 ) );
 body, html { height: 100%; } body { padding: 0; margin: 0; } main { display: grid; grid-template: "left top right" 20px "left main right" 1fr "left bottom right" 20px / 20px 1fr 20px; height: 100%; } main div { grid-area: main; border: 1px solid red; display: inline; align-self: center; justify-self: center; } main div img { max-width: 100%; max-height: 100%; display: block; } #inputs { position: absolute; top: 0; left: 0; transform: translateY(-100%); transition: transform.4s; width: 100%; padding: 10px; background: black; color: white; } body:hover #inputs { transform: translateY(0); }
 <main> <div> <img /> </div> </main> <div id="inputs"> <label>Width: <input name="width" value="200" type="number" /></label> <label>Height: <input name="height" value="200" type="number" /></label> </div>

I have included some javascript so you can test out different sizes of image. I added a img.style = '' to trigger a CSS recalculate after adding the new image, otherwise its size will be incorrect on load.

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