简体   繁体   English

居中图像和缩放高度/宽度以适应Flexbox父级内部?

[英]Center an image and scale height/width to fit inside flexbox parent?

I'm trying to center and scale an image inside a container. 我正试图在容器内居中并缩放图像。 In the following diagrams, the pink box is a 16:9 container and the blue box is the image. 在下图中,粉色框是16:9容器,蓝色框是图像。

在此输入图像描述 If the image is wider than the container, it will scale to fit. 如果图像比容器 ,它将缩放以适合。

在此输入图像描述 If the image is taller than the container, it will also scale to fit. 如果图像比容器 ,它也会缩放以适合。

在此输入图像描述 If the image fits in the container, it will simply be centered. 如果图像适合容器,它将只是居中。

As you can see in the diagrams, there is also a caption div aligned to the bottom left of the image, and a close icon aligned to the top right. 正如您在图表中看到的那样,还有一个与图像左下角对齐的标题 div,以及一个与右上角对齐的关闭图标

Here is the code I have now: 这是我现在的代码:

 /* The page */ .container { width: 100%; height: 100%; } /* 16:9 container */ .imageWrapper { padding-bottom: 56.25%; position: relative; width: 100%; border: 1px solid red; } .imageInnerWrapper { position: absolute; top: 0; bottom: 0; left: 0; right: 0; display: flex; align-items: center; justify-content: center; } /* The image, footer and close button all need to fit inside the container */ .imageAndFooterWrapper { display: inline-flex; flex-direction: column; position: relative; border: 1px solid lightblue; } .image { max-height: 100%; object-fit: contain; } .footer { text-align: left; } .closeButton { position: absolute; top: -30px; right: -30px; } 
 <div class="container"> <div class="imageWrapper"> <div class="imageInnerWrapper"> <div class="imageAndFooterWrapper"> <img class="image" src="https://images.theconversation.com/files/204986/original/file-20180206-14104-1hyhea9.jpg?ixlib=rb-1.1.0&rect=0%2C1212%2C5550%2C2775&q=45&auto=format&w=1356&h=668&fit=crop"> <div class="footer"> Caption </div> <div class="closeButton">X</div> </div> </div> </div> </div> 

The following CodePen contains the above code, with some examples of different sized images. 以下CodePen包含上面的代码,以及不同大小的图像的一些示例。

https://codepen.io/anon/pen/NMKxxm https://codepen.io/anon/pen/NMKxxm

This may not be a direct answer to your question but usually when I have to do something like this, I use a div with a background image instead of an img tag. 这可能不是你的问题的直接答案,但通常当我必须做这样的事情时,我使用带有背景图像而不是img标签的div Using a div with a bg image allows you to use styles like background-image , background-position and background-size which allow you to create the effect as described by you. 使用带有bg图像的div可以使用background-imagebackground-positionbackground-size等样式,这些样式允许您按照自己的描述创建效果。

Sample: 样品:

 var imgDiv = $('.image')[0]; var closeButton = $('.fixed-el')[0]; var img = document.createElement('img'); img.src = getComputedStyle(imgDiv).backgroundImage.split('"')[1]; var calculate_positions = { img_width: img.naturalWidth, img_height: img.naturalHeight, img_ratio: function() { return calculate_positions.img_width / calculate_positions.img_height; }, elm_ratio: function(elm) { return $(elm).width() / $(elm).height(); }, img_offset: function(elm) { var offset = []; //[x,y] if (calculate_positions.elm_ratio(elm) > calculate_positions.img_ratio()) { //centered x height 100% var scale_percent = $(elm).height() / calculate_positions.img_height; var scaled_width = calculate_positions.img_width * scale_percent; var x_offset = ($(elm).width() - scaled_width) / 2; offset = [x_offset, 0]; } else { //centered y width 100% var scale_percent = $(elm).width() / calculate_positions.img_width; var scaled_height = calculate_positions.img_height * scale_percent; var y_offset = ($(elm).height() - scaled_height) / 2; offset = [0, y_offset]; } return offset; } } function updatePosition() { var offset = calculate_positions.img_offset($('div.image')); closeButton.style.top = offset[1] + 'px'; closeButton.style.left = offset[0] + 'px'; } $(window).resize(updatePosition) $(img).load(function() { updatePosition(); }); 
 div.image { width: 100%; background-image: url('http://via.placeholder.com/100x100'); background-position: center; background-size: contain; background-repeat: no-repeat; flex: 1; } html, body, div.container { width: 100%; height: 100% } div.container { display: flex; position: relative; flex-direction: column; } div.fixed-el { position: absolute; width: 20px; height: 20px; background: red; } div.caption { text-align: center; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="container"> <div class="image"></div> <div class="caption">Some caption here</div> <div class="fixed-el"></div> </div> 

EDIT: You can change the image size in the styles and resize the window to see the scaling in action. 编辑:您可以更改样式中的图像大小并调整窗口大小以查看操作中的缩放。

I also noticed the comment which mentioned that you do not want to use background image as it will clip the image. 我还注意到提到你不想使用背景图片的评论,因为它会剪辑图像。 This will not happen if you use background-size:contain 如果您使用background-size:contain contains,则不会发生这种情况

EDIT 2: It turns out you can actually figure out what the coordinates of the image are and position other elements around it. 编辑2:事实证明,你实际上可以弄清楚图像的坐标是什么,并在其周围定位其他元素。 Have created a dirty hack to demonstrate this (mixed jQuery and vanilla JS, no proper scoping etc).. But you should be able to get the main idea and implement a neater solution. 已经创建了一个肮脏的黑客来演示这个(混合的jQuery和vanilla JS,没有适当的范围等)。但是你应该能够获得主要想法并实现更简洁的解决方案。 The main idea is derived from this question on SO 主要思想源于SO的这个问题

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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