You might think to yourself, “What is all the fuss with jQuery? You have to download a bunch of plugins to even make the library worth while.”. First, that isn’t true. Second, the jQuery library was specifically designed for that very purpose. By keeping the core library as small as possible – about 16 kb – users can then apply additional plugins at their own discretion. Today, I’ll teach you how to build your first “Center” plugin from scratch. Let’s get started!
Our Objective
We want to create a plugin that will dynamically adjust the styling of a specified element in order to keep it vertically and horizontally centered on the page at all times – even when the browser window is resized. Very little is required up front. You only need to make sure that you have the jQuery library downloaded.
The Screencast
Step 1
The first step when creating a plugin is to add a blank Javascript file. Naming conventions state that the file should be named “YourPluginName.jQuery.js”. Once you’ve created this file, make sure that you create a reference to it in your document.
<head>
<script src="jquery-1.2.6.pack.js" type="text/javascript">
<script src="center.jQuery.js" type="text/javascript">
</head>
Step 2
Next, paste in the following code.
(function($){
$.fn.center = function(){
var element = this;
$(element).load(function(){
changeCss();
$(window).bind("resize", function(){
changeCss();
});
function changeCss(){
var imageHeight = $(element).height();
var imageWidth = $(element).width();
var windowWidth = $(window).width();
var windowHeight = $(window).height();
$(element).css({
"position" : "absolute",
"left" : windowWidth / 2 - imageWidth / 2,
"top" : windowHeight /2 - imageHeight / 2
});
};
});
};
})(jQuery);
I go into much greater detail in the video, however, I’d still like to go over a few key points. Any time that you create a plugin, it must be wrapped with:
$.fn.center = function(){};
“Center” should be replaced with whatever your plugin’s name is. This lets jQuery know that you’re extending its methods. Now, though it does absolutely nothing, we can call our center method with:
$(function(){
$("#someElement").center();
});
Step 3
You must understand how to manually center an image on a page before creating the plugin. First, your element must be positioned absolutely. Otherwise, it obviously won’t budge when we alter the “left” and “top” values. Next, the image needs to be shifted 50% of the browser’s width to the left. Finally, in order to compensate for the image’s width, we need to subtract one half of the image’s width.
function changeCss(){
var imageHeight = $(element).height();
var imageWidth = $(element).width();
var windowWidth = $(window).width();
var windowHeight = $(window).height();
$(element).css({
"position" : "absolute",
"left" : windowWidth / 2 - imageWidth / 2,
"top" : windowHeight /2 - imageHeight / 2
});
};
This will perfectly place the center of the image in the center of the page. It’s a bit hard to explain with text. Be sure to watch the video for a greater explanation.
Step 4
Continuing on, we need to create a listener for when the browser window is resized.
$(window).bind("resize", function(){
changeCss();
});
“ChangeCss()” is a function that adjusts the left and top values of our image. By calling it again when the window is resized, jQuery will recalulate those values.
You’re Done!
If you have any questions, please feel free to leave a comment and I’ll make sure that I respond. As always, this might not be “real world ready”. What happens if the user has Javascript turned off? And of course, there are some ways to do this using pure CSS – but I digress.
Subscribe to the Weekly Screencasts
You can add our RSS feed to your ITUNES podcasts by doing the following:
- Once ITUNES has loaded, clicked the “Advanced Tab”
- Choose “Subscribe to Podcast”
- Enter “http://feeds.feedburner.com/NETTUTSVideos”
That should do it! The screencast will also be searchable on ITUNES in the next twenty four hours.
- Subscribe to the NETTUTS RSS Feed for more daily web development tuts and articles.



Nice Tutorial! :)
AWESOME! looking forward to many more screencasts, glad to see nettuts is still growing!
Nice intro Jeffrey! Looking forward to more videos =)
I’m far from an expert, but I read something in jQuery in Action (pg. 189) that is probably relevant here. They say you should wrap your plugins in a function that passes in the “$” as a parameter, then you are 100% safe to use “$” within your plugin. Otherwise, if the user of the plugin uses $.noConflict(); or otherwise re-defines “$”, it could break your plugin.
(function($) {
// Plugin definition
$.yourFunction = function(params) {
// Plugin stuff
}
})(jQuery);
WOW! That’s great..
@Chris – Very good point. It helps to ensure that jQuery doesn’t conflict with other libraries. I decided not to add that part at that last minute…just to make sure that everyone could understand it. I’m planning on doing a more advanced screencast in the coming weeks that will go over this very thing.
Great suggestion, though. To everyone reading the comments, Chris is absolutely right. Make sure that you pass in “$”. It’s not required – but is generally considered to be a best practice….and can save you some potential headaches.
“Make sure that you pass in “$”. It’s not required – but is generally considered to be a best practice”
Chris, can’t you just update the tut to show us?
Very nice video. It’s great that you guys are starting to make podcasts ! My minor gripe is that the sound quality is very low you may want to check that in the future (as it can be annoying at times). Looking forward the next ones !
PLUGINS RULE. This should be a lesson to any one in software development. Firefox, WordPress and Jquery are only successful because the creators made them to be extensible. Facebook and Twiter are prime time because they provide an open API. So if you want to make the next big thing always keep these things in mind.
Nice tut BTW. Thanks.
@hcabbos and everyone else – I went ahead and updated the code to help you.
Doesn’t work on FireFox 3.0.1 for Mac… Glad to see video tutorials on the site now!
GREAT!!!! More Screencast vidoes ;D!
Great tutorial, love the screencast form of tutorials :]
One small thing that annoys me a bit is the yellow ring following your mouse but that’s just my personal preference.
Keep up the fantastic work Nettuts team!
@Molitor – Are you sure? I just checked Firefox on the Mac and it’s working just fine.
@span – Yeah, I agree. I’ve been out of town the last few days. So, I had to record this using my laptop. We’ll make sure that the audio quality of next week’s screencasts is much better.
Heavens yes! This solves a huge problem I’ve had for the longest time. I was actually asked this question recently at an interview. Now I have the answer.
MooTools version – not a plug in, and neither version handles page scrolling, but here it is:
var x;
window.addEvents({
‘domready’: function(){
x = func.bind($(‘test’));
x();
},
‘resize’: function(){
x();
}
});
function func(){
var window_size = window.getSize();
var ele_size = this.getSize();
this.setStyles({
‘top’: (window_size.y – ele_size.y) / 2,
‘left’: (window_size.x – ele_size.x) / 2
});
}
Fantastic, the screencast is great :) By the way, I swear your constanly saying netflix, not nettuts ;)
It’s possible to do this with just CSS though and you don’t get the awkward jerking action whilst the styling updates. Or am I missing something?
Whooo, very cool screencast ! Thanks!
Uah, I never used jQuery, but after seeing that, I’m glad I didn’t. I really don’t get the logic behind this whole stuff, like function-naming etc. MooTools does it a hell of a lot better. Nice tutorial though, I’d like to see more MooTools stuff from you guys.
Love to see screencasts! Keep going and I love You doing that! Thanks!
That was great! Keep up the good work.
Great job (necessary fluff) but (meat of my comment) I have a few issues…
First, plugin naming syntax is not “myplugin.jQuery.js” it’s “jquery.myplugin.js” — almost always in full lowercase. Check the jQuery plugins repository if you’re not certain this is true.
Second, there’s no need to define “element”. In both contexts of “this” you will be referring to the proper element.
Third, there isn’t any element iteration or return. If multiple items are selected (say, “$(‘p’)”) they are not iterated over, and the method chaining jQuery is known for will break because they’re not returned. The entire contents of this plugin inside of “$.fn.center = function() {…}” should be wrapped with “this.each(function() { … }” and at the very end inside of the “each()” iteration should be a “return this;”.
I understand the desire to make things easy for new plugin authors, but teaching someone just getting started the wrong way to go about things can be a serious problem later on.
@Michael – You are right about the naming. I just had a brain freeze. Sorry about that! :)
Second, I’ve found that assigning “this” to a variable is generally a good practice. When your plugins start becoming more advanced, this almost always becomes a requirement – at least in my case.
In response to your last criticism, you are correct. But, try to remember that this is a “creating your FIRST plugin” tutorial. If it becomes too complicated, it’ll go over a beginner’s head. This was meant to manipulate a single element. But sure, if you’ll be calling the “center” method from a wrapped set, you should use a for statement.
No need to get too complicated in this introductory tut. I’ll go into much greater detail in Part 2 of this screencast.
Thank you very much for your thoughts though. Very good, and true arguments.
Doesn’t work on google chrome
@Taylor – I’m using Chrome right now. I just checked the demo. It works just fine.
Taylor it works better in chrome than it does in FF3 (PC) as it’s not so jumpy.
I’m liking the vodcast. I heard you mention finding it on iTunes, but I did a search and cant find the feed – nor subscribe obviously. Maybe it hasn’t propagated through their system yet?
Hi, Really Very Happy to see you working in Visual Studio2008, i am keeping my finger cross in hope to see some really great asp.net tutorial.
thanks for sharing this jquery,
My apologies for not seeing that last note on the podcast. Disregard my comment.
YOU DONT HAVE TO name the javascript jquery.classname.js, it doesnt matter at all, jQuery is just trying to have a standard, who cares.
Anyways very simple and straight forward, ive written a couple myself.
Nice Tutorial………..
…………….. Great Job
Keep it up…………….
nice to hear that nettuts having screen cast. and great tutorial too.
im so undecided between jquery and mootools.
Need a good comparison article.
thanks for sharing this, very useful!!
Thanks for the tutorial, i was looking a tutorial like this for starting JQuery from the scratch.
Nice tutorial! I like it :D
Some good points made along the way Jeffrey. I’ve written a few jQuery plugins for a project that I’m currently working on, and find the simplicity of using them a real joy, and makes their development really fun.
This is a good, simple example of how to create a plugin. Thanks for posting.
Nice video Jeffrey!
If this is going to become a weekly occurance can we spruce it up a bit? How about a really nice mic like Chris’ -> http://css-tricks.com/screencasting-setup/
@James – Definitely. I’ll be investing in a nice condenser mic sometime this week.
Thank you sir, may I have another?
I really like this website because I am learning a lot`s of things. Thanks for posting Jeffrey !
While I really like jQuery and am working to include it in my designs, I think we should use it for things that (X)HTML/CSS can’t do. This is actually quite easily done in CSS and as someone else pointed out – it works smoother (not to mention much smaller page size).
For those wondering how to do this in CSS:
Basically, you absolutely position the image with top: 50%; and left: 50%.
Then apply a negative margin to the top that is 1/2 the height of the object and a negative margin to the left that is 1/2 the width. Done.
@JeffreyWay I am trying to use this plugin with a div instead of an image. It does not seem to be working though. I changed the code to $(‘#divId’).center(); and then in the jQuery.center.js I changed it to
$(element).css({
“position” : “absolute”,
“left” : windowWidth / 2 – 375,
“top” : windowHeight / 2 – 255
Because I know the size of the div will not be changing.
Thanks for any help.
Hey Michael. Remove the “$(element).load(function();” wrap. In the case of this div, there isn’t anything to load. Remove it (and the closing brackets) and it will work just fine on a div element.
Hope this helps!
@JeffreyWay Thanks worked great!
@mattems – Its simple. jQuery = functionality, Mootools = animations.
@Darin – THis is true, but I think he just wanted to show off HOW TO make a plugin… not this actual plugin itself. I dont think its necessary to write a full blown plugin, this is fine.
Let’s try…
Hi Jefferey,
I try to apply on div, but just couldn’t get it work…
my html is:
Hello
jQuery.center.js is:
(function($){
$.fn.center = function(){
var element = this;
function(){
changeCss();
$(window).bind(“resize”, function(){
changeCss();
};
function changeCss(){
var imageHeight = $(element).height();
var imageWidth = $(element).width();
var windowWidth = $(window).width();
var windowHeight = $(window).height();
$(element).css({
“position” : “absolute”,
“left” : windowWidth / 2 – imageWidth / 2,
“top” : windowHeight /2 – imageHeight / 2
});
};
});
};
})(jQuery);
Have i done anything wrong?
Since I see some mootools comparison in here I will post an example of how I would do this with mootools. In this case I would probably just implement some more functionality on to Element but you could also write a class to do it.
You can pin and unpin any element using the following syntax.
$(‘some-element’).pinCenter();
$(‘some-element’).unPinCenter();
Element.implement({
pinCenter: function(){
this.setStyle(‘position’, ‘absolute’);
this.center();
this.pinEvent = window.addEvent(‘resize’, this.center.bind(this));
},
unPinCenter: function(){
this.setStyle(‘position’, ‘static’);
this.removeEvent(this.pinEvent);
},
center: function(){
var windowSize = window.getSize();
this.setStyles({
top: (windowSize.y / 2) – (this.offsetHeight / 2),
left: (windowSize.x / 2) – (this.offsetHeight / 2)
});
}
});
Evan I like your implementation. You’ve given all of the elements (that go through mootools selection) the ability to be centered in the page, good stuff.
you have an error in your left calculation though, you’re using offsetHeight
I tested this on my other mac and it’s working now. Awesome!