In this article we will see how we can center an image to its parent element, regardless of its dimensions, with a small JavaScript plugin.
The plugin re-sizes the image to fit to its parent element and sets margin-top or margin-left so that the image centers and crops its sides. If the image is smaller than its container, we have the option to either stretch the image so it fills its container or just center to its container. In any case the image maintains its aspect ratio.
In the case where both dimensions of the image are smaller than its parents dimensions and we don’t want to stretch the image we use a simple CSS solution, which is presented below.
.image_container { position:relative; } .image_container img { position:absolute; top:0px; bottom:0px; left:0px; right:0px; margin:auto; }
In all other cases the script calculates the top and left margin required to center the image.
(function ($) { $.fn.center_img = function (options) { options = $.extend({}, $.fn.center_img.defaultOptions, options); this.each(function (idx, item) { var jItem = $(item); var jImg = jItem.find('img'); if(options.set_overflow) { jItem.css('overflow', 'hidden'); } var width = ((jItem.attr('data-width') == undefined) ? jItem.width() : jItem.attr('data-width')); var height = ((jItem.attr('data-height') == undefined) ? jItem.height() : jItem.attr('data-height')); var img_width = ((jImg.attr('data-width') == undefined) ? jImg.width() : jImg.attr('data-width')); var img_height = ((jImg.attr('data-height') == undefined) ? jImg.height() : jImg.attr('data-height')); if (width <= img_width && height <= img_height) { if (width / height > img_width / img_height) { jImg.css('max-width', width + 'px'); var offset = parseInt(((img_height * width / img_width) - height) / 2); jImg.css('margin-top', '-' + offset + 'px'); } else { jImg.css('max-height', height + 'px'); var offset = parseInt(((img_width * height / img_height) - width) / 2); jImg.css('margin-left', '-' + offset + 'px'); } } else { if (options.must_fit) { if (width / height > img_width / img_height) { jImg.css('width', width + 'px'); var offset = parseInt(((img_height * width / img_width) - height) / 2); jImg.css('margin-top', '-' + offset + 'px'); } else { jImg.css('height', height + 'px'); var offset = parseInt(((img_width * height / img_height) - width) / 2); jImg.css('margin-left', '-' + offset + 'px'); } } else { if (width > img_width && height > img_height) { jItem.css('position', 'relative'); jImg.css('position', 'absolute').css('margin', 'auto').css('top', '0').css('bottom', '0').css('right', '0').css('left', '0'); } else { jImg.css('margin-left', parseInt((width - img_width) / 2) + 'px'); jImg.css('margin-top', parseInt((height - img_height) / 2) + 'px'); } } } }); $.fn.center_img.defaultOptions = { must_fit: true, // The image will re-size in order to fill its container set_overflow: true // Set this to true if the image container doesn't have the css property overflow:hidden; } } })(jQuery);
The plugin has an option that defines whether we want the image to be stretched in order to fill its container.
Note that you should call the plugin on the window.load event and not on the document.ready event, since the window.load event fires when the images of the document are loaded. Alternatively you can use the WaitForImages plugin.
On the other hand, if you know the dimensions of your image, you can assign the data-width and data-height attributes to the img tag and avoid the problematic event firing of the image loading.
Leave a Reply