简体   繁体   中英

Scale different width images to fit a row and maintain equal height

I have three images which are all different widths , but each the same height .

I want these images to be in a responsive row so that the combined width of these three images is 100% the width of the screen, all of the images have equal height, each image maintains its aspect ratio, and the images are not cropped.

One way to do it would be to set a different percentage width for each image in CSS, based upon each image's width according to the others. But I'm curious about a smarter way, probably using JavaScript/jQuery, which would be more efficient for doing this type of thing at a larger scale.

This could work - by using css table layout.

jsFiddle

 body { margin: 0; } ul { list-style: none; padding: 0; margin: 0; display: table; border-collapse: collapse; width: 100%; } li { display: table-cell; } img { display: block; width: 100%; height: auto; } 
 <ul> <li><img src="//dummyimage.com/100x100/aaa" /></li> <li><img src="//dummyimage.com/200x100/bbb" /></li> <li><img src="//dummyimage.com/300x100/ccc" /></li> </ul> 

If the source images vary in height, you will have to use JavaScript. Set all of the images to an arbitrary common height and find their combined width at that height. Then increase the height by multiplying the difference of the target width and the combined width (as a percentage):

 $(window).on("load resize", function () { // wait for the images to complete loading $(".imgRow").each(function () { var row = $(this); var imgs = row.find("img"); imgs.height(1000); var combinedWidth = imgs.get().reduce(function(sum, img) { return sum + img.clientWidth; }, 0); var diff = row.width() / combinedWidth; imgs.height(999 * diff); // 999 allows 1 px of wiggle room, in case it's too wide }); }); 
 .imgRow { clear: left; } .imgRow img { float: left; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="imgRow"> <img src="http://placecage.com/100/300" /> <img src="http://placecage.com/300/300" /> <img src="http://placecage.com/500/300" /> </div> <div class="imgRow"> <img src="http://fillmurray.com/600/300" /> <img src="http://fillmurray.com/200/300" /> <img src="http://fillmurray.com/400/300" /> </div> <div class="imgRow"> <img src="http://nicenicejpg.com/500/300" /> <img src="http://nicenicejpg.com/100/300" /> <img src="http://nicenicejpg.com/300/300" /> </div> <div class="imgRow"> <img src="http://placesheen.com/400/300" /> <img src="http://placesheen.com/600/300" /> <img src="http://placesheen.com/250/300" /> </div> 

My first approach to this would be to create three divs within a container div. Assign a height and a width of 33.33% to each of the three (and a float:left;) and 100% width to the container. Then set your three images to be the background of those three divs with the correct background properties such as

background-size:cover;

It might cut off bits of your images depending on the width of the screen but I don't think you will be able to get around that with images that are not the exact same size.

HTML

<div class="container">
   <div class="image" style="background-image: url('/image.jpg');">
   </div>
   <div class="image" style="background-image: url('/image.jpg');">
   </div>
   <div class="image" style="background-image: url('/image.jpg');">
   </div>
</div>

CSS

.container{
   width:100%;
}
.image{
   float:left;
   width:33.33%;
   background-size:cover;
   background-repeat: no-repeat;
}

The gist of the approach I'd take is to figure out how big your frame is, and figure out how wide the sum of your imgs are. Then, using a ratio of those totals, resize each of the images.

$(document).ready(function(){
var frameWidth = $("div.imgs").width()
var totalImgWidths = $("img#img1").width() + $("img#img2").width() + $("img#img3").width()
var ratio = frameWidth / totalImgWidths
var fudge = .95

$("img#img1").width(Math.floor($("img#img1").width() * ratio * fudge) )
$("img#img2").width(Math.floor($("img#img2").width() * ratio * fudge) )
$("img#img3").width(Math.floor($("img#img3").width() * ratio * fudge) )
})

See a quick plunker I quickly wrote up. It's not fancy, and it's employing a bit of a fudge factor, so I'm happy if anyone can improve on it.

You might want to use this a basis for refining a solution:

https://jsfiddle.net/kb4gg35f/

For some reason this does not work as a snippet. It works as a fiddle, though.

 var images = $('img'); var accumulatedWidth = 0; var widthResizeFactor; var screenWidth = $('div').width(); var originalSizeArray = []; $(document).ready(function() { for (var i = 0; i < images.length; i++) { var theImage = new Image(); theImage.src = images[i].src; accumulatedWidth += theImage.width; originalSizeArray.push(theImage.width); } widthResizeFactor = screenWidth / accumulatedWidth; for (var i = 0; i < images.length; i++) { images[i].width = originalSizeArray[i] * widthResizeFactor; } }); 
 body { margin: 0; } div:after { content: ""; display: table; clear: left; } img { float: left; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <div> <img src="http://lorempixel.com/100/200" /> <img src="http://lorempixel.com/200/200" /> <img src="http://lorempixel.com/400/200" /> </div> 

Twitter Bootstrap (or any decent CSS framework) has special CSS class pre-defined who do that.

See the doc: http://getbootstrap.com/css/#grid

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