2022 Update:
A lot has changed on the web since this post was written. The described effect can now be achieved with pure css using object-fit. Unless you’re targeting legacy browsers, use object-fit: cover
. Browser support for object-fit
can be found here.
Original post:
Recently I came across a problem whereby I had to dynamically resize an image to fill its parent container, exactly like the background-size: cover
CSS property but using an image tag instead. The requirements are pretty straightforward – upscale if the image is too small, downscale if it’s too large, and always resize based on the smallest dimension in relation to the aspect ratio of the parent container (which means that you’ll never see any whitespace, the image will always overflow on either height or width). Strangely enough I couldn’t find a jQuery plugin to do quite what I wanted, so I created one.
Check out the demo to see it in action.
The plugin is as follows (also available on github):
To use it, ensure that the image is positioned relatively or absolutely inside a wrapper element which has the `overflow: hidden` property set (so the image can take up the entire height/width of the wrapper with the cropped portion hidden). Then, simply call resizeToParent on your image like so (remembering to put it inside the jQuery ready function):
The plugin will automatically resize the image as soon as it’s finished loading. By default, the image will get resized to the nearest parent div. If you want to target a specific parent, simply pass a selector to the function as the ‘parent’ parameter, like so:
Don’t forget that the parent container must have `overflow: hidden` so that the image doesn’t spill out of the parent, and the image must be positioned relatively or absolutely for it to be centered correctly. If you have any doubts, check the source of the demo to see how it works.
Please feel free to leave any questions, comments, or suggestions in the comments below 🙂
If this post has helped you out, feel free to consider throwing a small donation my way.
Comments are closed.
101 comments
Hi Christian! thanks for your great work.
I am using FlexSlider and your plugin to create a full width and height background.
Im having problems when loading.
The image has ‘position:relative’.
On resize works perfect, but:
1. The image is not centering. On load align is always top – left. Also when the viewport height is greater than the width.
2. When the viewport is landscape, the width and the aspect ratio of the image is not correct and generates like a margin on the right. The size of the parent is correct.
Please help me to find a solution!
thanks in advance!
This is the web im working on “slumber.juanmejia.info/”
Hi Juan,
I’ve created a little test with Flex Slider, and I made it work by explicitly setting a height and width on both the flex slider wrapper and the slides themselves, and by wrapping the .resizeToParent() call in a timeout. It works as intended – both portrait and landscape images resize correctly. If it doesn’t work for you, chances are you have some CSS interfering with the resizing. Please check the following demo, then check your codebase to figure out what you’ve done different.
https://codepen.io/levymetal/pen/WoKmpb
Christian, Thanks for your quick reply!
Im using relative size for conteiner and slides (li) for full viewport withd and height. The timeout function works when the image was loaded before. In case of loading new big images wont be reliable solution 😔.
I see that the code is miscalculating the width of the image and the negative margin-left is not added. Is that because the css? Any ideas?
Thanks!!
When you say the code is miscalculating the width, are you talking about on your website, or the Codepen I provided? The Codepen works for me on Chrome 54.0.2840.98. If the Codepen doesn’t work for you, please let me know your browser and version, and also your operating system and version. If the Codepen works, then there’s a problem with your code. Delete all CSS that targets the slider, use my Codepen as an example, and start adding your CSS back in until it breaks. Then you’ll figure out what’s going on.
I added a 100ms timeout because the Flex Slider takes some time to initialise (I’m not going to investigate why). It has nothing to do with the loading time or size of the image. My plugin runs when the image has loaded by binding to the `load` event. So the size of the image or time taken to download has no effect on the operation of the plugin.
When you say “In case of loading new big images wont be reliable solution”, is that what you’ve actually experienced, or are you just making an assuming it won’t work? Because, again, my Codepen demonstrates that it does work, with both small and large images.
Chrome Versión 54.0.2840.98 on OSX Yosemite 10.10.05.
Christian, I really appreciate your time and your answers. I think i explained myself wrong. Anyway, i made the plugin work together with flexslider as you told me, setting the width and height (100vh, 100vw) to the flexslider and the image container. If the animation property of Flexslider is setted to “fade” works perfect and the setTimeOut function is not necessary. When i set it to “slide” the plugin needs the call wrapping in the setTimeOut function with at least 100 ms. Know it seams to work very well.
Thanks again Christian!
Thanks Christian !!!
Hi Christian
Thanks for this great plugin which has been perfect for my needs – and it’s working in responsive slideshows too which is brilliant.
I have a question – and I’m sorry if I’ve missed the answer somewhere else. Is it possible to position the images in their containing element as, for example, ‘bottom center’ rather than ‘center center’ – in the same way as background images can be positioned with CSS?
Hi James, I haven’t built this into the plugin (interestingly enough no one has really asked for it!). However, you can apply a small tweak yourself which will achieve the result of ‘center bottom’. On line 52, simply change the -2 to -1, and the image will be positioned from the bottom. So line 52 would look like this:
var topOffset = (imageHeight - parentHeight) / -1;
Hope this helps
Hi Christian!
I am appreciate with this awesome plugin, and I have integrated it with a few of my project.
And I found some issue and I cannot find out whether it is bug or I am misusing it.
— coffeescript —
# widgets/resize_image.coffee
class Widgets.ResizeImage
@enable: (image, parent)->
$(document).ready ->
$(image).resizeToParent({parent: parent, delay: 600})
# views/home.coffee
class Views.Home.IndexView extends Views.ApplicationView
render: ->
super()
Widgets.ResizeImage.enable(‘.product-image-resize’, ‘.product-image-resize-parent’)
Widgets.ResizeImage.enable(‘.image-resize’, ‘.about-us-image-resize-parent’)
Widgets.ResizeImage.enable(‘.owl-image-resize’, ‘.gallery-owl-box’)
Haha I think you forgot to describe the issue! Can you perhaps create an isolated version of your problem in jsfiddle?
I think that window resize is not trigger properly in iframe
That’s very unlikely. Like I said, please create an isolated version of your problem in jsFiddle. I can’t fix a problem that I can’t see, I’m not a magician 🙂
Hi Christian,
I got the problem fixed. It’s my fault in using the library,
Anyway Thanks you
Mr. non-magician 🙂
I mean misusing the library.
Great plugin! I’m having one issue with it and wanted to hop on here to see if anyone has some direction to help me. I’m trying to use this script plugin to resize images that I am loading into a ‘latest posts’ section on wordpress. In a nutshell, I’m simply using PHP to query the site’s database for the most recent posts in a certain category and then grabbing the associated thumbnail. This is the image I would like to format with your script but it doesn’t seem to work when I call the thumbnails via PHP. The script seems to run the same way, but it’s results are the same as if I’d just applied a img {height: 100%;} style. The images don’t scale with respect to their aspect ratios and the offsets in the plugin don’t behave properly. Specifically, they offset to the left by seemingly arbitrary amounts leaving some white space in the parent container (on the right portion of it).
However, if I set the images up directly with an tage and a static URL for the source, it works fine. Unfortunately, I need to use the php method so that this section of the site stays updated as posts are added. Any suggestions on how to calibrate this?
Jon, PHP runs on the server and javascript runs on the client. This means that nothing you do in PHP will affect the javascript, and vice versa. So without even seeing your code, I can tell you with absolute and 100% certainty that loading images from a database is not your problem.
Now, without seeing your code it’s virtually impossible for me to diagnose what’s gone wrong. But it sounds like your php script isn’t formatting the images in the same way as when you hard-code it manually. Is your php script adding any width/height attributes to the image, and if so are they correct? Is your php script adding any additional classes that could be affecting the image? Is your php script applying the correct class? Eg: if you’re calling the script like this $(‘.thumbnail’).resizeToParent(), then your images need to have the class ‘thumbnail’.
If this doesn’t help you, then I’ll need you to provide me with an example of the script not working so I can take a look myself (link me to a github repo, or a staging server etc). Without seeing your code, I can’t give any more help than above.
It was just a general sitewide image style that I totally overlooked haha (max-width=100%), thanks for setting me on the right path and getting my head out the box it was in. Great plug-in!
Awesome, glad it’s now working for you!
Hi Christian and thank you so much for this useful plugin 🙂
I have 2 questions for you; I would really appreciate if you could help me with this; nothing too urgent but would be helpful as I’m in middle of a massive build so it’s easier to make changes at this stage 🙂
1- What’s best way to call this function for responsiveness stuff? Should I recall it on both DOCUMENT.READ and WINDOW.RESIZE or is there a better way to approach this?
2- Currently this website I’m building doesn’t uses jQuery or anything libraries due to various reasons, so would it be possible to have a pure JS version of this awesome plugin wihout any dependecies?
Many thanks and again I really appreciate the time and effort you have put into this!
Cheers
Farzad, if you look at the plugin source code, you’ll see it already binds itself to the window resize event, so there’s nothing you need to do to make it responsive. You just need to call it inside the document.ready function, and the plugin will take care of the rest.
I’m sorry, I do not have the time to write a pure javascript solution. It’s up to you to either convert it yourself, or use a library instead.
Thanks for the quick reply 🙂
When I call it within the
document.ready, it won’t respond promptly when resizing the browser,
I’ve added everything as documented and obviously the jQuery hosted by
Google API lib… but when I call it on both ready and resize it works
fine but it’s a bit juddering…
Maybe I’m doing something wrong, however I’ve no other script running simultaneously…
OK, I’ll try to re-do this in pure JS and if you were happy with the code then you code
put it up on your website for others too 🙂
Many thanks
If you want the images to resize quicker, then decrease the delay param (it’s documented on github: https://github.com/levymetal/jquery-resize-image-to-parent). Do not call this plugin inside window.resize. Every time you call .resizeToParent(), the plugin binds an event to window.resize (as you can see in the source code). So if you put .resizeToParent() inside window.resize, every time the window is resized, you’re not just resizing the image; you’re binding more events to window.resize. Some browsers spam the resize event, so after resizing the window a couple of times, you’ll already have hundreds of events bound to window.resize. You really risk crashing the browser by putting my code inside window.resize. As I mentioned, it’s already responsive, so you don’t need to do it.
Wohooooooo finally got it working 🙂
Basically I was pulling images by AJAX which was causig the problem which I just realised now!!! Damn it, anyway it’s now fixed and I had to call this plugin on window.load at the bottom of the page to get it working as I wanted…
Also I’m calling it only once for all the containers targetting the class!
It’s a very silly mistake…
Cheers
Ah I see. If you’re adding images via ajax after window load, you can call .resizeToParent() inside the ajax complete function. You can also check out this issue on github for examples of how to set this up: https://github.com/levymetal/jquery-resize-image-to-parent/issues/2
Thanks for your code. However I do get some failures. Let’s say my parent is
height: 170px
width: 280px
and my image is:
height: 168px
width: 300px
it will do the following calc:
Step 1:
diff = 1.07
Step 2:
168 / 1.07 = 157, smaller than: 170 (parent height) {
css is set to width: auto and height to: 170px (now it’s actually filled the parent)
New imagewidth is set to: 300 / ( 168 / 170 ) = 303,57 px
New imageheight is set to: parentheight = 170 px
}
Step 3:
leftOffset = (303,57 – 280) / -2 = -11,785
topOffset = (170 – 170) / -2 = 0
So the picture will be set to the left which will lead to whitespace on the right while it was actually filling it. Why not include step 3 only to the ‘else’ statement of step 2? It does work in my case.
My plugin is designed to center the image inside the parent. You did the math yourself – the parent width is 280px wide, and the resized image is 303.57px wide. If you leave it there, that means that nothing will be cropped from the left, and 23.57px will be cropped from the right. That is not centered, that is left aligned. In order to center it, you need to offset it to the left by half that amount = 23.57/2 = 11.785px. When you do that, 11.785px is cropped from the left, and 11.785px is cropped from the right. Aka, the image is now centered inside the parent.
I wrote this post three years ago and no one has had a problem with the centering of the image. The math is solid. If it doesn’t work for you then you have some other code interfering with it. I set up a barebones demo with your exact figures and it works perfectly fine: http://codepen.io/levymetal/pen/rukhF
Thanks for your response. That works perfectly indeed. I already see my problem, first I tought is was because I work with percentages, but that seems to work fine. Now I see my image had somewhere a max-width of 100%.. so it didn’t get any bigger than the container! While it was doing the margin-left/top thing, it didn’t resize it (http://codepen.io/anon/pen/qBEAt). Anyway it’s working now.
Awesome, glad you got it working!
Hi Christian, I’m a total noob at this but I’ve learned quite a lot trying to implement your script on my WordPress site during the past week or so. I was ready to give up on a Woothemes template I bought and then came across your life saving “Cover sim”. I managed to get it working (I enqueued it from functions.php to get it loaded) but it doesn’t fire on window load (or reload). Well it does in some browsers and versions (mostly FF). On resize it works ok. I’ve tried all possible “wrapping” variations (jQuery(window).load… .bind(“load”,… .ready) but nothing works for me. Maybe I’m doing it all wrong and missing something obvious – please don’t go hard on me. I have this structure: load(script ready(callScript)).
Possible culprits (just my noobish reasoning): – jQuery versions; – conflicts with template scripts (I didn’t want to mess with those too much so I wouldn’t break the themes functions); – timing of execution.
I also added a piece of code inside yours to make it work on all images of the slider (before that the magic happened only for the first pic).
Can you please help me with your advice? Please take a look at my site
http://www.meshimage.com/
http://jsfiddle.net/NwEc7/ (this code I put in .js and call it in functions.php)
Thank you much for being there…
Hi Andrej,
I can see you’ve put a lot of effort into solving this problem, so I’ll try and point you in the right direction.
First off, you should remove that “pic_real_width” stuff. If you take a look at what that code does, it creates some variables based on the very first image on the page ($(“img”)[0] literally means the very first image jQuery can find), then you are using those widths to apply calculations to all the other images on the page. If you ever tried to use the plugin on any other page, or with images of different aspect ratios, it would completely break. Also, my code already gets the correct values for width & height by waiting for the image to load before it tries to resize it (which is exactly what that Stack Overflow answer does), so the code you added is 100% redundant. You should revert back to my original version of the plugin, I guarantee you that it does not require any modification.
Do you use Developer Tools (Chrome / Safari) or Firebug (Firefox)? You really should, because these tools will give you a great insight into what’s actually happening. For example, when I take a look at your site using dev tools, I can see that the script is actually firing when the window loads, because the image is getting some properties set on it by the resize script.
So what is happening, and why isn’t it being resized properly the first time? This is where it starts to get more tricky. It appears that the home page slider (aka, featured-slider.js) resizes the height of the .slide-media element. Chances are that this is happening after my resize script is run, which means the dimensions of the parent change after my script has positioned the images, resulting in an incorrect position. If you want to edit that file, you can make a call to my script after the featured-slider has been initialised (click here for an answer that describes one such solution). Obviously you’d need to create a child theme to edit that file, which is a bit of a bother if you didn’t plan to already do that.
Alternatively, you can bind my script after a short delay, say starting at 1 second, to give the slider a chance to initialise before the images get resized. 1 second is way too long, but you can start there and keep dropping the delay by 100ms until it no longer works anymore to find the optimum delay.
As a couple of words of advice, you should always bind window.load inside a document.ready call. Never put a document.ready call inside a window.load call. document.ready fires before window.load, so putting it inside window.load can cause problems. Also, the plugins do not go in either document.ready or window.load.
I would recommend trying the following code, which is a combination of all my suggestions, based off your original jsFiddle: http://jsfiddle.net/NwEc7/1/
Put this on your site and try again. If it doesn’t work, let me know and we can go from there.
Thank you! That’s much more than I could’ve hoped for.
I added the “pic_real_width” thing on the assumption that the whole script would be called upon only on the homepage (I’ve enqueued it inside an “if ( ‘fullscreen’ == is_home() ) {})” – don’t know if this is correct but it seemed ok to me – copied from elsewhere and omitted &&…woo options). But I definitely want to do it the right way (for the sake of differently sized images…).
I use Firebug and Notepad++ and just yesterday started using Chrome console and am still a bit clumsy with that. Surely I haven’t used them to their full potential.
I had already created a child theme but reverted back to editing main themes functions.php because I was testing if the order of things being run would improve on the situation. So I’m planning to go with the child theme.
I think that if I enqueue the script from the child functions.php it will run before all the other theme scripts. Do we want that?
I’ve added your new code and it works on first load now – great! – but just for the first image. The behavior for other images is as it had been before I went changing your original code – again are not being sized/positioned correctly. A window resize makes the (whichever is) current image behave ok but not the other consecutive two (kind of offsetting the effect across images).
I thank you again for all the insight…
I really hope we can crack this one…
I’ve re-activated my basic child theme so now your script (sorry I named the file before finding your script – will rename it later) loads right after jquery. But I suspect this order doesn’t really affect the order of events or does it?
I also tried to track down the file that sets the “display: none” with “Break on Attribute Change” method (found on Stackoverflow) but it came up with Jquery itself which makes no real sense to me.
This is a bit too much for me to solve by myself I’m afraid.
Anyways… looking forward to hearing from you.
You can’t change the script that changes the slide to display: none. That’s how the flex-slider is designed to work; changing that will break the slider. You need to work your code around the slider, not rework the slider around your code :).
The best idea I could come up with was to simply check if the image is visible when trying to resize. If the image isn’t visible, wait 100ms and try again. You can see my example here: http://jsfiddle.net/49ZWQ/. The code I added starts on line 20, it’s pretty simple to understand. The rest of the plugin is the same. Copy this new version of the plugin into your project and give it a go. Remember to only copy the plugin; don’t copy the document.ready stuff that’s at the bottom. Instead use the original document.ready code I provided, which handles waiting for the plugin to load first: http://jsfiddle.net/NwEc7/1/
In theory this means you shouldn’t need to edit the theme, so you may not have to use a child theme after all.
Hey man, it works! A few minor issues still though. Pics twitched (got shifted) horizontally on load/switch just a px or so in Chrome. Cancelling some of my css overrides seems to fix it but the issue comes up in FF – vertically (only for the first cycle). But I can live with that.
I even dropped the delay and load timeout to 10 ms to make it “smoother” and everything still looks ok.
I have a question about the hidden image check timeout (haven’t changed that). As I understand it (with my non-existing knowledge 🙂 ) it only delays the execution of other code and repeats just as long as the target image is hidden. Or is it constantly repeating in the background?
I ask because I’d like to try to lower this interval but I wouldn’t want it low if that would make the code repeat constantly and became a hog (don’t know if that’s the right term).
Thank you so much for helping me out!
The timer is constantly running in the background until the image becomes visible. Once the image becomes visible, the image gets resized, and the timer stops running. This has the potential to be a memory hog if you have an image that always remains hidden. However, in your case, the images are always cycling, so the timer for each image will stop consuming resources as soon as the image is shown. On resize the timers are reset, but again – once all images have been cycled, there won’t be any more timers consuming resources. You could probably reduce the timeout to 10ms.
Hopefully that makes sense. It’s not the most ideal solution, but given your current situation it’s probably the most practical. The other option is to build your own slider that doesn’t use display: none, or hook into flexsliders events to try and run the resize script when the slide changes (this might be trickier than it sounds).
Exactly what I was thinking when I first saw the “Perfect Full Page Background Image” article. To somehow turn my images to background images… I was like “if I only knew how to do that with a hammer and an axe” 🙂
It didn’t work right away – I was fiddling with it for quite a while and I think I finally figured it out – think you have a typo in the script.
Shouldn’t backgroundImage: ‘url(‘ + $img.attr(‘src’) + ‘)’ be without the $?
I’ll have to check which browsers are supported. Well I could also be using the previous one for a while and later on make the switch to this one.
Oops, yeah you can either add the dollar sign to the img variable when it’s created, or remove it from the backgroundImage line. Usually when I create a reference to a jquery object I prefix it with a dollar sign, but you don’t have to. Just personal preference.
Unless you want to support really old IE’s, background-size: cover will be fine. Doesn’t work in IE8 and below, but windows XP is past it’s useby date anyway (seriously, Microsoft doesn’t offer support or updates for it any more), so I don’t believe in writing websites that support and unsupported operating system!
Ok, great. Thank you for your kind help. I feel like returning a favor. I draw portraits (https://www.facebook.com/andrej.blazon/photos) and when I find the time I’ll be glad to do one for you as my way of saying thanks. Just drop me a mail (info@mes….) with a pic of your choice If you like the idea.
Hey Andrej, I’ve figured out a better solution. As long as you’re supporting modern browsers, then background-size: cover is really the property you want. My script only emulates that css property for images, but it’s really not the best approach for your site. I’ve written another script that hides your images and applies their source to the parent wrapper, using background-size: cover. This should work a lot better, and remove any need for timers at all.
Remove my old resize script entirely, and try running this instead: http://jsfiddle.net/j447C/
How guys. I have this theme and am trying to use this plugin to place my images in the div, but am having a hard time doing it. I don’t see any changes to the images after the .js have been apply and css changes.Can someone be so kind and tested it for me? I have included a link to download the theme template. What I want to have done is to place my large images (1024-768px) mostly in any of the theme html pages except the contact page of course. You don’t need to do them all. Just one to let me know it is do-able.
I have been searching for an image resizer for days and this one I like most.
https://www.dropbox.com/s/eqcf9bsz65kmhqd/vintage_files.zip
Do you have a link to a demo site where you’ve included the plugin and it’s not working? If you link me to a demo, I can have a look and tell you why it hasn’t resized the images properly. The plugin is unrelated to WordPress or your theme, so there’s no reason it wouldn’t be compatible. It’s a lot of work for me to install your theme and attempt to configure it (especially when your working environment might be totally different), so it’s going to make it a lot easier for me to help you if you can set up a demo with your attempts so that I can point out how to fix it.
Thanks for the quick reply. I am still working on the theme on localhost. The link I provided contains html template files. You don’t really need to install it on a server. Plus, I haven’t changed any of the layout and or css to my website. I kept it stock so to speak.
I will try to have my site up in a day or so if you don’t have time to look at the template. Thanks again.
The problem is that the theme you provided is a blank slate – it doesn’t have the code you’ve used to attempt to install the plugin yourself. Sure, I could install & configure the plugin and set it all up, then zip it up and send it back to you, but that would basically be me doing my job for free – which is not really something I support doing. Instead, I prefer to help people learn, which involves you trying to install the plugin yourself, then me providing assistance & pointers when it doesn’t work as desired. To do this, I need to at least see the code you’ve used to try and get it to work, preferably in your own environment too (aka, on your own site). For me, I’d prefer to see it in a live demo, that way I can help in the most efficient way possible without having to spend valuable time setting it all up on my local machine.
Let me know when you’ve got the site up and running, and I’ll have a look and let you know what the problem might be.
OK. I’ve upload the my site on a test server. If you can take a look at the ‘blog’ page, the image is positioned top left. I have added your .js script and called the jquery with ‘.resize’ class to the img tag. The img tag has a css style of ‘position: absolute’. The div surrounding the img has a defined height:300px, width:560px and overflow: hidden.
The only thing the img is effect by before the edit was from the css. If I, delete the .js file, the image has no change. It is always position left, top.
http://www.ducsu.x10host.com/index.html
The problem is that your javascript is malformed. Your jQuery ready function is missing the end brackets. Eg, it needs to be like this:
$(function() {
$(‘.resize’).resizeToParent();
});
I’ve made the change. I don’t see any effect done to the image still.
Don’t forget to check the console for errors. Notice how it says “Uncaught ReferenceError: $ is not defined”? This means jQuery isn’t defined when you try to call it. Now I can see that you’re including jQuery at the bottom of the document, yet you’re trying to bind the resize script at the top of the document (before jQuery has been loaded). You can only bind events to the jQuery ready function if jQuery has been loaded. So either move jQuery to the top of the document, or put the script below the call to jQuery in the footer.
Thanks for the help thus far. I have moved the script up top. No changes. What console are you referring too? I don’t see any errors on my browser.
You have to move jQuery to the top of the document, not my script.
Assuming you are using Chrome, I am talking about the developer console: https://developers.google.com/chrome-developer-tools/docs/console.
Ah. Got it. It’s centering now after repositioning jquery. I may need to play with css for the other pages as it is displaying funky. Thanks for the guide again. I really appreciated.
No worries mate, you’ve got the CSS right on the blog page so I’m confident you’ll be able to get it working on the other pages too, but just let me know if you have any other troubles with it.
I am running into this little issue. At this page, the images are zoomed in very close.
http://www.ducsu.x10host.com/galleries.html
It’s like my description says: “By default, the image will get resized to the nearest parent div”. The nearest div is your wrapper div. I’ve provided a way to resize to a different parent if you haven’t put the image in a div, take a look at the last example in the blog post. In your case, you probably want to do something like this:
$('.resize').resizeToParent({parent: 'a'});
This resize plugin is a great idea.
Im having a strange issue where the resize only applies to one of my slider images.
Hit the wall.
Without seeing your code it’s impossible for me to say what the problem is. The best way is for you to try and replicate the problem in jsFiddle or similar. Quite often you’ll find the problem yourself when isolating the script from everything else. If not, you can always post back here with a link to the fiddle or ask on StackOverflow.
Currently, you are setting width and height equals to ‘auto’ depending on the condition met.
How would you do it if you compute the actual width/height (actual number)?
Any help would greatly be appreciated.
Thanks
My plugin assumes you’ve put the image in it’s very own wrapper element so that the overflow can be hidden when the image is cropped. Therefore, if you want to explicitly set the width/height manually, all you need to do is apply that value to the image wrapper instead of the image itself.
Great plugin!
Will this work if i make the container/parent of the image resizable using jquery ui Resize?
Lets say i want to resize the parent using mouse, will the image be automatically adjusted?
Currently it’s not responsive, and what you want to do is one step trickier than responsive as it has to be triggered manually on the resize event generated by jQuery UI, not just on window.resize (which is an interesting insight, I hadn’t thought of that). There are people working on making it responsive, or I might get around to it some time relatively soon, but feel free to give it a crack yourself 🙂
Thanks. I made it using resize jquery ui. Great plugin you got there!
Do you want to share your version?
@levymetal:disqus Did you try making this responsive? If so, what’s your progress? If not, I will look in to it if I have the time!
If you trigger your plugin on resize window it resizes the image after 2 times resizing..
Oh btw, EPIC plugin!
Thanks for your comments 🙂
If you take a look into the plugin, you’ll see that it binds a function to the load event of the image. So calling the function from within window.resize won’t work, because all that does is bind another function to the load event, which has already fired on the image.
My advice is to take out all the resizing code (that is, everything inside the load event), put it into a separate function, then bind an event to both image.load and window.resize that calls the resizing function on the image. You’d also have to make sure to reset the height/width of the image so that the calculations are correct.
It’s pretty straightforward, I’ll probably update it within the next few weeks, just don’t have the time now.
I’m working on it.. First experience with a plugin.. Not easy!
Hey mate, sorry it took me so long to get onto this, but I’ve updated my plugin with a few bugfixes and made it responsive. Just in case you’re still in need of it, you can view the updated source on this post or at https://github.com/levymetal/jquery-resize-image-to-parent.
I like this js a lot. It is something I need for a project I’m working on now. Have you figured out a way to move the image once it’s been put into the parent, to allow for further manipulation? Like being able to drag the corners to expand the image, but it only enlarges inside of the parent object?
It’s definitely possible, but manipulation hasn’t been a requirement of mine (I’ve only used it for static purposes). jQuery UI Draggable might help.
the demo doesnt work on ie10
It only works on ie10 if you reload the page and view it a second time after the initial run of the script
Perhaps it’s due to the issue of IE not firing the load event properly. Check out this for a possible fix: http://css-tricks.com/snippets/jquery/fixing-load-in-ie-for-cached-images/#comment-178279. See if you can implement it and let me know if it works!
Hi Alessio, I think you misunderstand the purpose of the plugin. The image is cropped on purpose, I built this plugin to emulate the CSS property background-size: cover on images. Did you check the demo? If you don’t want the images to overflow outside their parent, you don’t need any javascript at all; all you need to do is add the following css to the image:
max-width: 100%; max-height: 100%;
IE6 is the only browser that doesn’t support max-width/height, and there is absolutely no reason why anyone should still be using IE6. Thus, I do not condone any code that is written to support IE6. Also, my plugin was built to solve my requirements of emulating
background-size: cover
, not anything else. So as much as I appreciate your comments, I won’t be including these changes into my plugin. However, my code is free for you to use and modify, so you can fork it on github and release your own with your desired changes. Cheers for the discussion!Wow… Thanks for this!
When testing this script I noticed that the center picture behaviour didn’t work. I solved it by changing
obj.css({‘left’: leftOffset, ‘top’: topOffset}); to obj.css({‘margin-left’: leftOffset, ‘margin-top’: topOffset}); on line 53.
Thanks for the comment John! Using margins is definitely the preferred method of positioning elements like this, so I’ve updated my code.
Hi, first of all, thanks! this is just amazing! I got it to work on firefox, but not in chrome; in chrome it is taking the smallest side of the parents div and not the larger, hence giving me a smaller image, but this happens only if the image has a larger height than a width. If the width is larger, then it works. Any ideas please, thanks a lot!
Fernando, I’ve double checked the script and even done a few tests, however I’m unable to replicate the issue you’re referring to. You can see my tests here: http://jsfiddle.net/fKqBg/, and this works on Chrome 25.0.1364.172. Check to make sure you haven’t got any css properties affecting the positioning, and if it’s still causing you trouble, try creating a jsFiddle like above so that I can take a look and let you know what’s going wrong.
you’re completely right! I had on my css for some reason height:100%; width:100% and that was messing it up. I removed it and now it works like a charm, you’re a genius, thanks!
Glad to hear you got it working!
Really Amazing Plugin! Helped me a LOT! After configuring the CSS correctly, everything just went down smoothly! Thank you so much!
Impressive plugin! – I wonder if this can be used in an responsive example. Say on resize the images reposition themselves according to the parents new width, do you reckon this is possible? Best regards!
It’s definitely possible, you’d need to put the resizing code into a separate function, then call that function when the parent (or window) is resized. Give it a go and see if you can get it working 🙂
Could you please provide a solution to this. My jquery skills are terrible but a fluid solution that truly reflects how the background-cover property works would be greatly appreciated.
Sorry Xevin, but I’m not a not-for-profit rent-a-coder. If you’re not willing to put in the time to learn a bit of jQuery and try and write a solution, then why should I put my time in to write a fully functional responsive plugin for you for free? I’m happy to help people out, but only when they’re willing to learn and give it a shot first.
Hi, thanks for this but it isn’t working as I would expect. I have a square container, images rescale but a wide image ends up with white space at the bottom and a tall image ends up with with white space to the right. I have overflow:hidden on the parent. No obvious errors. Any pointers? (both in Chrome & Firefox)
Hi Alan,
It’s nigh impossible to debug issues without actually seeing them, so if you could provide a demo I’d be able to take a look and try and figure it out. You can head over to http://jsfiddle.net to quickly set up an example.
Christian
Positioning the image to relative or absolute does not center the image. Neither does positioning the parent div. Thoughts?
http://www.shadowfaxdigital.com/cdi
Sorry.
http://www.shadowfaxdigital.com/cdi/events. The first two smaller images under the hero slider are being used with this plugin. It is only showing the top left corner. If the event I wanted to change the centering, say for instance the left middle or bottom center, what would I need to change to do so? Thanks and sorry for the multiple postings!
Hi Chris,
You should always put any jQuery related code inside the document ready function (http://api.jquery.com/ready/), otherwise your code fires before the content is loaded. The shorthand version is always easy to remember: $(function() { // code goes here }
If you want to change the positioning, you’ll be playing with the leftOffset and topOffset variables. Eg: setting topOffset to 0 will position the element top center. Easiest way to position from bottom would be to position the images absolutely, and set the bottom property to 0. You could pass in options to the plugin to determine the positioning. Give it a go and see how you travel with it, if you have any problems, check out http://www.stackoverflow.com and post a question there (great community that will help you out).
Christian
Can’t believe I forgot that… Thanks Christian.
Is there a way to get the image to load and take for on page load rather than after the image loads?
I thought this would be an issue since it took a bit for your demo images to load, but it doesn’t seem to be on my site. should’ve tested first 🙂
The problem is that some browsers don’t report the width/height correctly for images that haven’t loaded yet, which would result in incorrect positioning of the image. In the plugin you’ll see that all the positioning code is wrapped in obj.load(function() {}, which is binding it to the load of the image. You could remove this wrapper function, but it may cause issues in some browsers.
I’m getting an error at `return this.each(function() {`: Uncaught TypeError: Object [object Window] has no method ‘each’
Not sure why you’re getting that problem, ‘this’ should be referring to the jQuery object, not the window. What version of jQuery are you using, and how are you binding the call? Would you be able to create a http://jsfiddle.net emulating the issue?
You mate are a legend! Brilliant demo as well. Searching high and low for something like this. Cheers for sharing.
Jason.
I created a similar plugin myself but it doesn’t work quite so well as yours.
One problem I do have, however, that yours doesn’t solve, is what happens if the image is hidden on page load?
When trying to get the image height, jQuery/Javascript will obviously return 0 if the page is hidden. One technique I came up with us to momentarily ‘show’ the image off screen, then hide it again once we have the image.
How would you do this?
Thanks!
Hi Joe,
If the image is hidden on page load then you do have to do a bit of trickery, but you’re on the money with your solution. I usually clone the element into an absolutely positioned div way off the screen (or with visibility: hidden) to calculate the width/height then remove the cloned element.
It’s a bit of a hack but it works 🙂
Christian
This is impressive! Saved me a lot of time and headache. Thanks for the script!