Comment puis-je ajuster une image à son conteneur ?

Index

On souhaite qu'une image occupe la place maximale dans son conteneur, en tenant compte des bordures et du padding du conteneur, et en respectant les proportions de l'image.

Le plugin "dvjhImgRatio" traite toutes les images possédant la classe "dvjhClassImg" et un attribut "data-ratio" qui doit être égal à la largeur optimale de l'image divisé par la hauteur optimale de l'image. Cette largeur et cette hauteur sont celles de l'image originale.

Exemple

Code CSS : 

div[class^='classDiv'] { float: left; border: 1px dotted grey; overflow: hidden; 
	word-wrap: break-word; padding: 6px; }
.classDiv1 { width: 100px; max-width: 100px; height: 100px; max-height: 100px; }
.classDiv2 { width: 150px; max-width: 150px; height: 100px; max-height: 100px; }
.classDiv3 { width: 200px; max-width: 200px; height: 100px; max-height: 100px; }
.classDiv4 { width: 250px; max-width: 250px; height: 400px; max-height: 400px; }
.classDiv5 { width: 350px; max-width: 350px; height: 400px; max-height: 400px; }
.classDiv6 { width: 450px; max-width: 450px; height: 400px; max-height: 400px; }
.classDiv7 { width: 550px; max-width: 550px; height: 400px; max-height: 400px; }
.classDiv8 { width: 350px; max-width: 350px; height: 400px; max-height: 400px; }
.classDiv9 { width: 150px; max-width: 150px; height: 400px; max-height: 400px; }
Code HTML : 

<div class="classDiv1">
    <img class="dvjhClassImg" src="https://danielhagnoul.developpez.com/images/twitter.png" data-ratio="1.00"/>
</div>
<div class="classDiv2">
    <img class="dvjhClassImg" src="https://danielhagnoul.developpez.com/images/Noël.jpg" data-ratio="0.6728"/>
</div>
<div class="classDiv3">
    <img class="dvjhClassImg" src="https://danielhagnoul.developpez.com/images/avatarDVJH.jpg" data-ratio="1.00"/>
</div>
<p style="clear:both;">&nbsp;</p>
<div class="classDiv4">
    <img class="dvjhClassImg" src="https://danielhagnoul.developpez.com/images/Noël.jpg" data-ratio="0.6728"/>
</div>
<div class="classDiv5">
    <img class="dvjhClassImg" src="https://danielhagnoul.developpez.com/images/imageTest.png" data-ratio="1.35"/>
</div>
<div class="classDiv6">
    <img class="dvjhClassImg" src="https://danielhagnoul.developpez.com/images/rotating.gif" data-ratio="0.9638"/>
</div>
<p style="clear:both;">&nbsp;</p>
<div class="classDiv7">
    <img class="dvjhClassImg" src="https://danielhagnoul.developpez.com/images/badge.jpg" data-ratio="1.4848"/>
</div>
<div class="classDiv8">
    <img class="dvjhClassImg" src="https://danielhagnoul.developpez.com/images/voeux.gif" data-ratio="4.14"/>
</div>
<div class="classDiv9">
    <img class="dvjhClassImg" src="https://danielhagnoul.developpez.com/images/badge.jpg" data-ratio="1.4848"/>
</div>
<p style="clear:both;">&nbsp;</p>
Code JS : 
    
/*
 * Daniel Hagnoul
 * Plugin dvjhImgRatio
 * Code v1.1.0 du 2011-04-29
 *      v1.0.0 du 2011-04-25
 */
( function( $, W ){
	$.fn.dvjhImgRatio = function( options ){
		var opts = $.extend( true, {}, $.fn.dvjhImgRatio.defaults, options );
		
		return this.each( function( i, item ){
			
			var photo = $( item ),
				ratio = photo.data( "ratio" ),
				photoParent = photo.parent(),
				photoParentWidth = photoParent.innerWidth() - opts.border[ 1 ] - opts.border[ 3 ] 
					- opts.padding[ 1 ] - opts.padding[ 3 ],
				photoParentHeight = photoParent.innerHeight() - opts.border[ 0 ] - opts.border[ 2 ] 
					- opts.padding[ 0 ] - opts.padding[ 2 ],
				w = photoParentWidth,
				h = w / ratio;
			
			if ( h > photoParentHeight ){
				h = photoParentHeight;
				w = h * ratio;
            }
 
            // debug
            
            /*
             
             console.log( "i = " + ( i ).toFixed( 0 ), " | w = " + ( w ).toFixed( 2 ),
                " | h = " + ( h ).toFixed( 2 ),
                " | w / h = " + ( w / h ).toFixed( 2 ), " | ratio = " + ratio );
                
             */
            
            photo.css({
            	"width" : w,
            	"height" : h
            });
		});
	};
	
	$.fn.dvjhImgRatio.defaults = {
		"border" : [ 1, 1, 1, 1 ], // [top, right, bottom, left], l'unité est le pixel exclusivement
		"padding" : [ 0, 0, 0, 0 ] // [top, right, bottom, left], l'unité est le pixel exclusivement
    };
    
})( jQuery, window );

/*
 * Pour des divisions ayant une bordure de 1 px et un padding de 6px.
 */
$( ".dvjhClassImg" ).dvjhImgRatio({
    "padding" : [ 6, 6, 6, 6 ]  // [ top, right, bottom, left ], l'unité est le pixel exclusivement
});

Tests unitaires avec QUnit.