purchase photoshop cs5 buy visual studio online student discount microsoft office mac buy office 2007 upgrade discount microsoft office download download propellerhead reason 4 cheap windows 7 for college students mappoint europe 2010 buy microsoft word 2007 download buy adobe cs4 production premium buy windows 7 activation buy office 2007 small business edition quarkxpress 8 activation best price microsoft project 2007 can you buy windows 7 starter edition buy adobe illustrator cs5 adobe contribute cs3 download adobe premiere pro cs5 cheap microsoft outlook cheap buy windows 2000 server cheapest final cut studio buy adobe photoshop 7 windows xp buy product key buy autodesk mudbox 2010 buy windows xp student buy office 2010 online download microsoft mappoint cheap autodesk maya 2009 download acronis true image 11 dreamweaver cs4 for mac buy windows xp sp3 download windows xp home edition buy adobe illustrator cs3 buy windows xp cd key microsoft access 2007 buy online buy windows xp home edition buy microsoft office groove purchase acrobat 9 photoshop cs4 purchase cheap windows 7 pro best price photoshop cs4 upgrade used adobe cs3 buy symantec ghost solution suite steinberg cubase 4 download dreamweaver mac download cheap microsoft office 2007 software corel draw 12 mac master collection cs3 download buy excel 2007 download buy windows 7 home premium upgrade family pack cheap pdf software cheap windows 7 ireland buy windows 2003 standard buy adobe acrobat pro extended buy office 2007 student used windows xp professional buy matlab download purchase office 2003 professional student discount adobe illustrator photoshop elements 8 purchase download autodesk 3ds max 2009 buy zbrush autodesk 3ds max 2010 system requirements buy autocad 2010 online price of windows 7 license purchase windows xp installation disc buy windows 7 upgrade windows 7 professional cheapest price purchase microsoft office 2003 product key download nero suite discount microsoft office 2007 buy indesign purchase photoshop elements 7 buy photoshop elements 7 cheap dragon naturallyspeaking 10 buy windows xp tablet pc edition buy windows 7 oem online buy acronis disk director suite 10 download adobe photoshop full version download streets and trips 2007 dreamweaver cs3 price microsoft office 2003 discount cheap parallels desktop 5 buy office 2007 download microsoft office price singapore cheap windows 2003 enterprise where can i buy microsoft office cheap windows 7 discount turbo tax 2009 download price windows xp home edition buy photoshop cs4 online download autodesk maya 2010 best price microsoft office 2007 professional adobe illustrator buy online buy windows xp original buy microsoft access 2002 buy photoshop 5.0 windows vista download buy adobe acrobat writer what is the price of windows 7 home premium buy windows 7 from us used dreamweaver cs4 microsoft office discount students solidworks 2009 price purchase photoshop online adobe captivate demo buy autodesk inventor 2008 price of microsoft office 2007 professional windows 7 pro price comparison buy adobe cs4 uk windows 7 price dubai download microsoft powerpoint 2003 adobe after effects download ptc mathcad download buy quicken 2010 software buy windows xp 2010 microsoft office price australia mathcad price adobe illustrator cs5 direct download access 2007 purchase order how much does adobe photoshop cs4 cost price of microsoft office home and student 2007 adobe photoshop cs2 cost download microsoft excel 2003 price autodesk maya download windows 7 discount for military buy windows 7 key only indesign software download cheap rosetta stone spanish latin america buy windows 7 64 bit ultimate buy adobe captivate 3 / 4 buy pinnacle station nero discounts buy sony vegas pro 9 navisworks manage 2009 student discount microsoft project where can i buy windows 7 download buy windows 7 for 3 computers omnipage coupon student discount windows 7 home purchase office 2003 license buy photoimpact x3 purchase windows vista basic buy windows xp cd purchase office 2007 trial download adobe soundbooth cs5 pdf converter professional 6 download buy microsoft office for xp download windows 7 ultimate operating system how much does microsoft excel cost buy adobe photoshop 7 for mac download windows 7 professional buy microsoft office 2007 online cheapest microsoft office 2007 standard buy windows 7 switzerland ms office 2010 cheap buy office 2003 oem buy matlab r2010a buy office 2003 standard pctools spyware doctor 5.5 download buy matlab cheap cheap adobe illustrator cs4 buy office 2003 cheap windows vista business oem download windows xp professional discount photoshop cs5 discount code adobe photoshop cs4 used purchase office 2007 professional purchase windows 7 upgrade family pack cheap indesign cs3 download indesign cs4 buy windows 7 cheap student dreamweaver cs4 demo buy office 2007 enterprise edition buy excel online buy adobe fireworks cs5 purchase sql server 2005 office 2010 home and business price autodesk inventor professional 2008 download download adobe soundbooth cs5 mac buy adobe flash cs4 for mac buying photoshop cs4 buy onenote 2010 office ultimate 2007 download full buy office 2010 buy windows 7 ultimate license key buy windows xp installation cd microsoft excel 2003 product key download cheap outlook 2007 purchase adobe cs3 design premium microsoft visio 2007 prices buy windows xp pro product key where to buy streets and trips 2010 autoroute 2007 download buy windows 7 oem ultimate download solidworks 2009 buy adobe flash 8 how much does guitar pro cost buy windows 7 for students student discount visual studio purchase adobe dreamweaver cs4 teacher discount office 2007 adobe photoshop cs4 oem download download adobe photoshop cs3 buy microsoft frontpage 2007 purchase windows 7 online australia buy photoshop online student discount microsoft office uk photoshop cs4 student pricing buy photoshop cs2 download buy windows xp professional license buy corel draw 12 adobe indesign cs3 price cost of rosetta stone spanish download microsoft expression web 3 cheap ms access 2007 purchase windows 7 ultimate photoshop licensing for this product has expired buy photoshop cs5 extended buy microsoft office picture manager buy cs3 master collection buy microsoft office 2007 home and student edition where can i buy windows xp for cheap where to buy corel videostudio pro x3 cheap windows vista 32 bit military discount adobe photoshop powerpoint 2010 price best price adobe after effects for mac photoshop for sale dreamweaver for mac price download wordperfect x5 buy windows 7 in uk vmware workstation 6.5 price autocad 2010 pricing buy windows 7 professional 64 rosetta stone spanish discount cs4 master collection demo download windows 7 full version buy adobe premiere pro cs5 mac price of windows 7 for students where can i buy windows 7 cheapest microsoft visio 2003 price buy mathworks windows 7 home premium license only sony vegas cheap buy cakewalk sonar 8 microsoft office price comparison adobe photoshop cs4 best buy install excel 2007 only price of matlab software buy quicken 2009 windows xp home edition download buy adobe flash player 10 windows xp price canada discount outlook 2007 cheap windows xp home edition cheap adobe creative suite cs4 download windows xp professional full version cheap windows 7 full version buy corel wordperfect cheap adobe fireworks cs4 best price windows 7 ultimate upgrade buy nero online purchase windows xp pro license buy microsoft office project 2003 download ms access 2007 microsoft office discount coupon windows 7 enterprise download discount adobe illustrator cs2 microsoft office 2008 for mac license where to buy windows 7 hong kong buy office 2007 pro windows xp professional cheapest microsoft windows 7 starter download cheap maya software office 2003 for sale windows 7 pro deals buy adobe premiere pro cs5 rosetta stone at costco buy microsoft office word 2007 purchase microsoft office windows 7 professional full version cheap cubase 5 windows 7 professional sale price buy photoshop cs5 student cost of microsoft excel 2003 / 2007 / 2010 windows 7 professional purchase cheap photoshop for mac purchase windows vista ultimate 64 bit adobe dreamweaver cs5 buy buy microsoft office for students purchase photoshop 7.0 buy frontpage 2003 upgrade cost of dreamweaver software buy mathcad 13 buy illustrator for mac buy premiere elements 8 adobe fireworks cs5 mac pricing student discount adobe lightroom buy rosetta stone online buy outlook product key download autocad electrical 2009 buy windows xp 64 pro buy microsoft visual studio 2005 buy office 2007 rosetta stone spanish price comparison best price windows 7 update nero 8 ultra edition download download abbyy finereader 8 cheap adobe cs5 web premium adobe cs4 mac oem buy microsoft word 2000 buy photoshop canada buy microsoft office student version cheap photoshop elements 7 buy adobe cs3 web premium buy rosetta stone persian buy sony vegas pro 9.0 buy adobe premiere quarkxpress for mac download turbotax pricing buy final cut express 3.5 buy office 2007 language pack buy vmware fusion 3 adobe illustrator cs5 mac download buy windows 7 product key microsoft word for mac purchase buy windows 7 download canada buy photoshop elements online buy windows 7 pro oem microsoft office 2008 price price vista business price of photoshop elements buy office cheap adobe photoshop cs4 mac download purchase office 2007 product key disk director 10 price of adobe acrobat photoshop cs4 download full version buy sony vegas cheap how to purchase solidworks buy windows vista full version download autodesk maya 64-bit buy windows 7 pro price of autocad 2008 adobe dreamweaver cs4 buy buy windows 7 operating system buy photoshop australia best price office 2007 home and student price of cubase purchase adobe photoshop cs3

Distributing Elements Within a Container

Posted September 6th, 2006

One aspect of HTML and CSS I’ve always felt is lacking is the ability to distribute elements evenly within its container. Using the CSS rule text-align:'justify', you are able to justify lines of text within their container, but there’s really no equivalent for non-text elements.

This became a problem a few weeks ago when a client requested that their site menu span the entire width of the page. Before discovering CSS, I would accomplish this using tables and images. But since then, I’ve learned that images are quite inaccessible and can be very difficult to maintain when the menu changes, and since this site was being built using CSS, I wanted to keep tables out of the design as much as possible. So, for the time being, I created something like the following.

1
2
3
4
5
6
7
8
9
10
11
<html>
	<body>
		<ul id="container">
			<li>Home</li>
			<li>About Us</li>
			<li>Services</li>
			<li>Resources</li>
			<li>Contact Us</li>
		</ul>
	</body>
</html>

distribute_noscript.gif

That was all well and good, but it wasn’t going to fly with the client.

After digging through CSS documentation and finding little that addresses this problem, I decided the best way to accomplish this effect was to use javascript to dynamically generate CSS. I’m hoping a feature is added to CSS soon since I’m not a big fan of using javascript for design.

While scripting this method, I made a list of characteristics I’d like to see it have.

  1. Utility
  2. Scalability
  3. Simplicity

With those goals in mind, I came up with this frame for the method.

distribute(container, elements, [direction = 'horizontal', className = null])

Container (required)
The id attribute or HTML object of the container.

Elements (required)
The tag name of the element(s) you want to distribute within container (e.g. ‘li’, ‘img’, ‘div’).

Direction (optional)
The direction you wish to distribute elements. This can either be ‘horizontal’ (default) or ‘vertical’.

ClassName (optional)
If you have multiple instances of elements and only want to distribute certain elements, you may attach a class to those tags and pass that to the method. This property is null by default.

Let’s take a look at the script (the following script was written with Prototype).

1
2
3
4
5
6
7
8
9
10
11
12
13
var containerDimen = Element.getDimensions(container);
var element = $A($(container).getElementsByTagName(elements));
 
if (direction == 'vertical') {
	var containerHeight = containerDimen.height;
	containerHeight -= 
	(parseInt(Element.getStyle(container, 'padding-top')) 
	+ parseInt(Element.getStyle(container, 'padding-bottom')));
} else {
	var containerWidth = containerDimen.width;
	containerWidth -= 
	(parseInt(Element.getStyle(container, 'padding-left')) 
	+ parseInt(Element.getStyle(container, 'padding-right')));

The first thing we need to do is collect all elements within the container. We’re using the $A() method to make the results Enumberable so we can run them through an each() loop a little later. After we’ve gathered all the elements, we need to calculate the container width or height (depending whether direction is set for ‘horizontal’ or ‘vertical’). Since the box model calculates width as the sum of width and padding, we have to subtract the padding from the width to get the real width of the container.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
var elementWidth = 0;
var elementHeight = 0;
var i = 0;
 
element.each(function (e) {
	if ((className == null) || ((className != null) 
		&& (Element.hasClassName(e, className)))) {
		i++;
		var elemDimen = Element.getDimensions(e);
		if (direction == 'vertical') {
			elementHeight += elemDimen.height;
			Element.setStyle(e, { 
				marginTop: 0, 
				marginBottom: 0 
			});
		} else {
			elementWidth += elemDimen.width;
			Element.setStyle(e, { 
				marginLeft: 0, 
				marginRight: 0 
			});
		}
	}
});

Now that we have the container width (or height), we need to calculate the total width (elementWidth) of all the elements. If there were any margins applied to the elements for a noscript version, we remove them. i is used to count how many elements match the search criteria since className may or may not be null.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
if (direction == 'vertical')
	var leftover = containerHeight - elementHeight;
else
	var leftover = containerWidth - elementWidth;
 
var marginNum = i - 1;
var margin = Math.floor(leftover / marginNum);
 
element.each(function (e) {
	if ((className == null) || ((className != null) 
		&& (Element.hasClassName(e, className)))) {
		if (direction == 'vertical') {
			if (e != element[element.length - 1])
				Element.setStyle(e, {
					marginBottom: margin + 'px'
				});
		} else {
			if (e != element[element.length - 1])
				Element.setStyle(e, {
					marginRight: margin + 'px'
				});
		}
	}
});

We’re just about done! With the elements and container width calculated, we figure out how much space is leftover. The leftover space is divided by i minus one (we’ll only be applying margins to the right side of elements) to figure out how much space should be between each element. All that’s left to do after that is to place those margins on each of the elements.

With the javascript written, all that’s left to do is make a little modification to the HTML.

1
2
3
4
5
6
7
8
9
10
11
<html>
	<body onload="distribute('container', 'li')">
		<ul id="container">
			<li>Home</li>
			<li>About Us</li>
			<li>Services</li>
			<li>Resources</li>
			<li>Contact Us</li>
		</ul>
	</body>
</html>

distribute.gif

That’s it. It’s probably a good idea to add default margins to the elements for users with javascript disabled (any default margins get removed by the script). Enjoy!

Resources

The script in this post uses Sam Stephenson’s Prototype library. There’s some very good documentation for Prototype written by Sergio Pereira and over at script.aculo.us (another great javascript library).

Download the Source

All source code is provided under the Creative Commons Attribution-Sharealike License. If you agree to these terms, please view and download the entire source now.



Leave a Reply


11 Responses to “Distributing Elements Within a Container”

Oh my dear Garrett,
;)
use an unordered list or two for this problem, and you have no *div* soup or anything else to code.

pure css is always better.

have a nice day and read http://www.cssplay.co.uk/index.html Stu is a one of the best in css for me.

Monika

Garrett Murphey
October 11, 2006

Hi Monika: There’s no solution to this problem on the site you provided.

From what I’ve seen, there’s no way to tell CSS to distribute elements within their containers. That’s why I wrote the javascript.

If anyone has a pure CSS solution, please share it. I’d much rather not have to use javascript for these kind of things.

Thanks for posting your tutorial — it seems like it should be such an easy thing that a lot of people are doing, but yours is the only answer that google can find for me!

I still can’t get it to work, though. I’ve copy and pasted the html and linked to the js file, but that doesnt fix the problem. Is there some CSS component that I am missing, or another js file that it is dependent upon?

Thanks man, worked like a charm. Much better than my own solution I brewed up a year or so ago.

I have some issues with this.

Total js payload is around 130 KB, seems overkill for a small tweak. Not good for dialup visitors.

On FF 3.0.5 I ran into out of memory errors. I didn’t check on IE.

Also, Garrett, you might explain to newbies that they need to include two lines in their page header:

<script src="path/to/js/prototype-1.6.0.3.js" type="text/javascript"></script>
<script src="path/to/js/distribute.js" type="text/javascript"></script>

Has anyone else checked this on Firefox?

Чот не так себе, пойду ещё что нить зачту