MaxSide: jQuery Plugin (and How-To)

Abstraction is an important concept in any language. You can think of CSS as a way of abstracting the design away from the content of a site. This makes the code for both much easier to read, understand and maintain. Javascript is a way of abstracting away the functionality of a site, and jQuery a further abstraction making common tasks much much easier. Writing plugins for jQuery is yet another deeper abstraction which makes your jQuery easier to write and understand.
To illustrate this idea, let’s build an jQuery plugin. While we’re at it, it might as well be something useful! We’re going to call it MaxSide. The idea here is to take any page element and resize it, making the length of its longest side a value you determine. For example, if you have an image that is 300×180px you could call MaxSide on it with a value of 100 and the resulting image would be 100×60px (it maintains its ratio).
Let’s get to it.
Doing it Without a Plugin
Let’s put three images on the page, one 200×200px, one 200×50px, and one 50×200px.
<body>
<img src="images/200x200.jpg" alt="" />
<img src="images/200x50.jpg" alt="" />
<img src="images/50x200.jpg" alt="" />
</body>
We want to run some jQuery on these images so that each of their longest sides becomes 100. 200×200px becomes 100×100px, 200×50px becomes 100×25px, and 50×200px becomes 25×100px.
Let’s include jQuery on our page (in the <head> section) and write the code that will make this happen:
<script type="text/javascript" src="../jquery-1.2.6.min.js"></script>
<script type="text/javascript">
// don't run until all images are loaded
$(window).bind("load", function() {
// run on every image on the page
$("img").each(function(){
// set a variable for this, quicker
var $this = $(this);
// maximum length is hard-coded here
var $maximum = 100;
// jQuery 1.2.6 has "dimensions" built-in
var $thewidth = $(this).width();
var $theheight = $(this).height();
if ($thewidth >= $theheight) {
if ($thewidth >= $maximum) {
$(this).attr({
width: $maximum
});
}
}
if ($theheight >= $thewidth) {
if ($theheight >= $maximum) {
$(this).attr({
height: $maximum
});
}
}
});
});
</script>
In plain English, this reads: “Look at every image on the page. If it is wider than it is tall, make it’s width 100. If it’s taller than it is wide, make it’s height 100.”
Works like a charm, see the example without the plugin.
Doing it With a Plugin
There are a couple of problems with doing the “without the plugin” way. For one, it really dirties up our page. We should really get all that code off of our HTML file, as that is where our content lives and we are trying to abstract here. Two, the “MaxSide” is hard-coded here. What if we want to use this same bit on the page but use a different MaxSide value. We would have to repeat very similar code. Never a good idea.
jQuery makes it easy for us to write our own functions in the form of plugins, to abstract away code like this. Take a look at the new code in our header, using the plugin:
<script type="text/javascript" src="jquery-1.2.6.min.js"></script>
<script type="text/javascript" src="jquery.maxside.js"></script>
<script type="text/javascript">
$(window).bind("load", function() {
$("img").maxSide({ maxSide: "100" });
});
</script>
A lot simpler, eh? But not only simpler, but now we could call the maxSide function on different page elements and with different values to boot.
jQuery.fn.maxSide = function(settings) {
// if no paramaters supplied...
settings = jQuery.extend({
maxSide: 100
}, settings);
return this.each(function(){
var maximum = settings.maxSide;
var thing = jQuery(this);
var thewidth = thing.width();
var theheight = thing.height();
if (thewidth >= theheight) {
if (thewidth >= maximum) {
thing.attr({
width: maximum
});
}
}
if (theheight >= thewidth) {
if (theheight >= maximum) {
thing.attr({
height: maximum
});
}
}
});
};
Notice the code really isn’t all that different here. There are a couple of important things to note though.
- This plugin is built to do its thing on every page element that matches what you call it on. Hence the “each” function. If you wish to write a plugin which only effects a single page element, it is even easier. Omit the “each” function and write regular ol’ jQuery but include a “return this;” line at the end.
- The “settings” bit at the beginning of the function handles the event in which the function is given no parameter (it defaults to 100px). You could technically call this function with just .maxSide(); if you wanted.
- If you are using this function on images, it should only be called after the window load event. Many jQuery functions are called when the DOM is ready instead, which is much faster, but the width and height calculations will fail if the images are not fully loaded yet (very probable).
- Variables inside the plugin don’t need the “$”.

















1
Clean and concise. Excellent tut on authoring plugins.
Comment by Joe McCann — June 18, 2008 @ 6:36 am
2
$(window).bind(”load”, function() {
//something happens here
}
I need to the something that happens to happen after the images had loaded, as u have stated,
but in firefox it’s just happening after the DOM have been loaded (before the images had).
I mainly use opera and its OK there.
PS:the difrence in my code is that i use images as background with css, so apperantly opera takes them into account, but firefox not
Comment by Mit — June 19, 2008 @ 2:47 am
3
If you want to do something when the DOM is ready:
If you want to do something when the page is loaded:
Are you saying that even while using the second option here that it’s firing too early? If that’s the case, that’s an interesting problem I’ve never run across.
Comment by Chris Coyier — June 19, 2008 @ 6:47 am
4
yep, it too early.
But only in firefox, Opera and IE are fine. And i guess it only for the images that a background (and in my sites usually nearly all the images are background ).
And i still haven’t updated Firefox –I kinda don’t like it
Comment by Mit — June 19, 2008 @ 10:57 am
5
Hah, it’s fixed in Firefox3.
Ok , that’s good … I won’t have to write some weird solution.
Sorry for the spelling of the last comment
Comment by Mit — June 19, 2008 @ 11:17 am
6
Nice for this plugin. Please note that actually the download page give a 404 error. I had to download the js from the sample page.
A little usage advice: Since I tried with a big logo, imaging to use this plugin where there’s a logo that can’t be resized before uploading and can be very large… When loading the page, the big image version first appars, then resizes to the right value thanks to the plugin. If you give a display:none and add a $(”#logo”).show(); after $(”#logo”).maxSide({ maxSide: “xx” }); your logo will stay hidden until resized
Comment by Tinny — August 1, 2008 @ 6:54 am
7
@Tinny: Sure, that’s one way you could fix that problem. The problem arises though if the user has Javascript turned off, they won’t see the images period then. That would be at your discretion, but generally a bad idea. Another way to do it would be to hide the image when the DOM is ready, but then only call maxSize when the page is loaded.
Comment by Chris Coyier — August 1, 2008 @ 9:01 am
8
It’ true. With your solution it would be perfect. Maybe the maxside function before the show can be even better (talking about milliseconds…)
A nice feature would be a different maximum for width and height.
Comment by Tinny — August 1, 2008 @ 11:42 am