Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Menu, fills out in width, equal padding

Status
Not open for further replies.

ThomasJSmart

Programmer
Sep 16, 2002
634
0
0
Hi

I am trying to put together a menu but it is proving difficult.

The situation is as follows:
I have a fixed space for the menu: 960pixels wide.
The number of menus is dynamic
The contents (menu titles) are dynamic

The menus have a graphic left and right, a content section and a pull-down menu on hover.

I am looking for a way to dynamically size the menus so they always fill out the available 960px nicely. Currently I am achieving this with static padding in the css file. But the menu falls apart when anything is changed. A CSS solution would be great but if it can only be done with JS then preferably a jQuery solution. I know it can be done with tables but i would prefer not to have to resort to that ;)


The following is a very simplified (JS and image free) version of the code that is enough to demonstrate this issue and hopefully find a solution. Note that even if you add 1 character to the menu titles the menu 6 wraps to the next line. And if you remove a character (or menu) then there is a big gap on the right.



html:
Code:
<html>
<head>
<style>
.menuholder{
	height:37px; width:960px;
	background:#999;
	background-repeat:repeat-x;
	clear: both;
}
.menuitem{
	position:relative;
	float:left; _width: 0px;
	height:37px; top:0px;
}
.menuitem:hover{
	background-color:#CCC;
}
.menuitemleft, .menuitemright{
	width:1px; height:37px;
}
.menuitemright{
	background-color:#333;
}
.menuitemleft{
	background-color:#fff;	
}
.menuitemleft, .menuitemright, .menuitemmid{
	float:left;
}
.menuitemmid{
    text-align:center;
    height:25px;
	padding-top:12px;
	padding-left:60px;
	padding-right:60px;
}
.submenuholder{
	background-color:#CCC;
	position:absolute; top:36px;
	left:1px;right:1px;
	display:none;
}
.menuitem:hover .submenuholder{
	display:block;
}
</style>
</head>
<body>
<div class="menuholder">
  <div class="menuitem">
    <div class="menuitemleft"></div>
    <div class="menuitemmid">Title 1</div>
    <div class="menuitemright"></div>
    <div class="submenuholder">
      <ul>
        <li>Subitem 1-1</li>
        <li>Subitem 1-2</li>
        <li>Subitem 1-3</li>
      </ul>
    </div>
  </div>
  <div class="menuitem">
    <div class="menuitemleft"></div>
    <div class="menuitemmid">Title 2</div>
    <div class="menuitemright"></div>
    <div class="submenuholder">
      <ul>
        <li>Subitem 2-1</li>
        <li>Subitem 2-2</li>
        <li>Subitem 2-3</li>
      </ul>
    </div>
  </div>
  <div class="menuitem">
    <div class="menuitemleft"></div>
    <div class="menuitemmid">Title 3</div>
    <div class="menuitemright"></div>
    <div class="submenuholder">
      <ul>
        <li>Subitem 3-1</li>
        <li>Subitem 3-2</li>
        <li>Subitem 3-3</li>
      </ul>
    </div>
  </div>
  <div class="menuitem">
    <div class="menuitemleft"></div>
    <div class="menuitemmid">Title 4</div>
    <div class="menuitemright"></div>
    <div class="submenuholder">
      <ul>
        <li>Subitem 4-1</li>
        <li>Subitem 4-2</li>
        <li>Subitem 4-3</li>
      </ul>
    </div>
  </div>
  <div class="menuitem">
    <div class="menuitemleft"></div>
    <div class="menuitemmid">Title 5</div>
    <div class="menuitemright"></div>
    <div class="submenuholder">
      <ul>
        <li>Subitem 5-1</li>
        <li>Subitem 5-2</li>
        <li>Subitem 5-3</li>
      </ul>
    </div>
  </div>
  <div class="menuitem">
    <div class="menuitemleft"></div>
    <div class="menuitemmid">Title 6</div>
    <div class="menuitemright"></div>
    <div class="submenuholder">
      <ul>
        <li>Subitem 6-1</li>
        <li>Subitem 6-2</li>
        <li>Subitem 6-3</li>
      </ul>
    </div>
  </div>
</div>
</body>
</html>

Suggestions are most appreciated, thank you for your time. :)



site | blog | iphones |
 
the contents will be managed by third parties and so out of my control. I cant have them calling me up every time they want to change a menu title or add/remove an item.

Infinite doesn't need to be supported but between 3 and 10 is realistic.


site | / blog |
 
ps. the main issue isnt really the menu items, like you say its not infinite and for a realistic range i could easy put together an if/else kind of thing. The main issue is with the menu text, just adding 1 letter to any menu causes it all to break, too fragile :(


site | / blog |
 
There are so many possibilities for content that you could never cover them all.

The only solution I can think of is to have a fixed number of menus items across the top of the page.

If more menu items are required, introduce a vertical menu down the side. The vertical menu could contain as many items as the user requires, giving them more flexibility.


Keith
 
For now i have resorted to a JS fix, not the best option - it doesn't degrade very nicely, but it works.

i lowered the left/right padding in .menuitemmid{} to a minimum value of 10, added a first/last class for the first and last menu items with an additional 2 px padding left on first and right on last, and then (with jquery):

Code:
// when dom is ready:
$(document).ready(function(){

// get the used width and total menus
var usedWidth=0; var totalMenus=0;
$('.menuitem').each(function(){
  usedWidth+=$(this).width();
  totalMenus++;
});

// calcualte the default padding value
var defaultPadding = (totalMenus*10)+4

// calculate the real remaining with (without default padding)
var remainingWidth = 958-usedWidth+defaultPadding;

// calculate the proper padding to fill it out nicely
var padding = Math.floor((remainingWidth/totalMenus)/2);

// "left-over" padding is applied the first and last menu item
var leftXpad = Math.ceil((remainingWidth-((padding*totalMenus)*2))/2);
var rightXpad = remainingWidth-((padding*totalMenus)*2)-leftXpad;

// apply padding to each menu item
$('.menuitem').each(function(){
  $(this).find('.menuitemmid').css('padding-left',padding).css('padding-right',padding);
});

// apply left-over padding to first/last menu items
$('.menuitemFirst').find('.menuitemmid').css('padding-left',(padding+leftXpad));
$('.menuitemLast').find('.menuitemmid').css('padding-right',(padding+rightXpad));
});


site | / blog |
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top