homepage Welcome to WebmasterWorld Guest from 23.20.63.27
register, free tools, login, search, pro membership, help, library, announcements, recent posts, open posts,
Become a Pro Member
Visit PubCon.com
Home / Forums Index / Code, Content, and Presentation / CSS
Forum Library, Charter, Moderators: not2easy

CSS Forum

    
Div won't expand to CSS percentage
inline-block and ul
TheStranger




msg:4268371
 11:41 am on Feb 17, 2011 (gmt 0)

Hello,

I'm trying to make a centered expanding horizontal Navbar with an unknown width.
I've managed to get my horizontal Navbar to work by using an unordered list with div's around the content inside the <ul>.
With display: inline-block on the div's inside the <ul>, I can set specific widths and heights to the individual div's. However, when using a percentage for .NavBarContent, it won't expand.
The fixed width div's are fine, but for some reason it won't work with percentages.


CSS:

<style type="text/css">
#content {
position: relative;
min-width: 790px;
padding: 0px;
margin-top: 0px;
margin-right: auto;
margin-bottom: 0px;
margin-left: auto;
}
body {
margin: 0px;
padding: 0px;
}
#Navbar {
margin: 0px;
padding: 0px;
}
#Navbar ul {
margin: 0px;
padding: 0px;
text-align: center;
}
#Navbar li {
vertical-align: top;
display: inline-block;
display:-moz-inline-stack;
zoom:1;
*display:inline;
list-style-type: none;
margin: 0px;
padding: 0px;
}
#NavbarL {
width: 102px;
padding-top: 10px;
padding-bottom: 10px;
font-size: 110%;
margin: 0px;
padding-right: 0px;
padding-left: 0px;
background-color: #060;
display: inline-block;
display:-moz-inline-stack;
zoom:1;
*display:inline;
}
.NavbarInset {
background-color: #090;
width: 139px;
padding-top: 10px;
padding-bottom: 10px;
font-size: 110%;
margin: 0px;
padding-right: 0px;
padding-left: 0px;
display: inline-block;
display:-moz-inline-stack;
zoom:1;
*display:inline;
}
.NavbarContent {
background-color: #0C0;
min-width: 74px;
width: 12%;
vertical-align: top;
padding-top: 10px;
color: #F5F5F5;
padding-bottom: 10px;
font-size: 110%;
background-repeat: repeat-x;
margin: 0px;
padding-right: 0px;
padding-left: 0px;
display: inline-block;
display:-moz-inline-stack;
zoom:1;
*display:inline;
}
#NavbarR {
width: 102px;
padding-top: 10px;
padding-bottom: 10px;
font-size: 110%;
margin: 0px;
padding-right: 0px;
padding-left: 0px;
background-color: #060;
display: inline-block;
display:-moz-inline-stack;
zoom:1;
*display:inline;
}
</style>


HTML:

<body>
<div id="content">
<div id="Navbar">
<ul>
<li><div id="NavbarL">&nbsp;</div></li><!--
--><li><div class="NavbarInset">&nbsp;</div></li><!--
--><li><div class="NavbarContent">Home</div></li><!--
--><li><div class="NavbarContent">Something</div></li><!--
--><li><div class="NavbarContent">About</div></li><!--
--><li><div class="NavbarContent">Contact</div></li><!--
--><li><div class="NavbarInset">&nbsp;</div></li><!--
--><li><div id="NavbarR">&nbsp;</div></li>
</ul>
</div>
</div>
</body>


Any help would be much appreciated :D .

*Note. I tried doing this without the <ul>, and it worked. However, I couldn't center it, and the inline-blocks wouldn't line up properly (even with adding vertical-align: top, and text-align: center to each individual div).

 

SuzyUK




msg:4268757
 12:22 am on Feb 18, 2011 (gmt 0)

Hi TheStranger and Welcome to WebmasterWorld!

I think there's a touch of divitis going on here and those extra li's to get a "padded" effect.. ouch ;)

I am basing this that those items inside the lists will be links eventually and that there will be yet another element added to the mix

This can be done without any class names or extra list items & using the existing wrapper element you have

HTML:

<div id="wrapper">

<div id="Navbar">
<ul>
<li><a href="#">Home</a></li>
<li><a href="#">Something</a></li>
<li><a href="#">About</a></li>
<li><a href="#">Contact</a></li>
</ul>
</div>

</div>


The "wrapper" element is only there to give the whole navbar a width to work from, which I think may be your content div?.. I couljd have left it tto default to the page width.. the pixel width is not important - however a wrapper div is not a bad thing to use if you want the whole site centered as you can put the content div inside it and it will take the same width.

The following widths are guesstimates you can tweak them as long as all the sums add up to 100% :)

The idea is to make the #Navbar div 100% wide but with left and right padding to give the outer dark green effect, and rembering that width = content width + padding - I made the #Navbar 80% wide with 10% left and 10% right padding = 100%

the <ul> then sits inside the 80%, content width, part of the above div - and the UL stays @ 100% wide, it doesn't need padding as the inline-blocks (now the li's) are already centered inside it..

.. so I then made the width of the li items add up to 80% (4 <li>'s @ 20% = 80%) - this leaves 20% space inside the <ul> which is distributed evenly on both sides because the <li>'s are centered.

Nice HUH!

OK in code:
html, body {margin: 0; padding: 0;}

#wrapper {
width: 960px;
margin: 0 auto;
}

#Navbar {
width: 80%;
padding: 0 10%; /* width + padding = 100% = 960px width of container */
background: #060;
text-align: center;
}

#Navbar ul {
background: #090;
width: 100%;
word-spacing: -4px; /* to make inline-blocks have no space between them */
}

#Navbar ul, #Navbar li {
list-style: none;
margin: 0;
padding: 0;
}


#Navbar li {
vertical-align: top;
color: #F5F5F5;
background-color: #0C0;
width: 20%; /* 4 links x 20% = 80% which leaves 10% either side for effect */
min-width: 100px;
font-size: 110%;

display: inline-block;
word-spacing: 0; /* reset for text inside list items */
}

#Navbar li { /* for IE 6 & 7 - asterisk before the rule is the hack */
*display: inline;
}

#Navbar li a {
padding: 10px 0;
display: block;
color: #f5f5f5;
background-color: #0C0;
text-decoration: none;
}

#Navbar li a:hover {
color: #000;
background: orange;
}


Notes:
real live inline blocks (as in not the IE6/7 version) have whitespace between them, like words in a sentence, so the word-spacing work around is for that, the negative value on the ul removes the space between the the li items, the 0 value on the li items restores the default so the text inside them has default word spacing again.

moz doesn't need the inline-stack workaround anymore and if you do need to support on older version there's more to it than that.. can look it up if you need it.

the IE inline-block hack is separated out into it's own rule for clarity, and another advantage, by separating the display:inline rules into a separate ruleset you no longer need the zoom:1; part of the hack

HTH
Suzy

TheStranger




msg:4268956
 11:08 am on Feb 18, 2011 (gmt 0)

Thanks for the reply Suzy. Very nice work indeed, however I should of made myself clearer on my websites design (aplogises).

I hope this image helps to show how I would like my site:
[img517.imageshack.us ]
(the coloured borders and text are just for show, not part of the design)

Basically I would like a centred parent div with images either side of an expanding middle section (.NavBarContent).

I know this could be accomplished very simply by either having a Fixed Width, or by using a Table for my NavBar, but Tables are deprecated, resulting in the use of them for anything except tabular data being somewhat frowned upon.

I should really combine the images for #NavBarL & R with .NavBarInset, but for some reason the total of the file sizes for them being separate are smaller than the total of them combined.

Also, thanks for pointing out that I no longer need to use inline-stack, and for the IE inline tip.

SuzyUK




msg:4269001
 1:15 pm on Feb 18, 2011 (gmt 0)

ah I did wonder.. however that's no problem, the theory is still the same only with less sums ;)

rounded corner tabs aka the sliding door technique is what you need.. combine the rightmost two images with the middle content image making the right "image" as big as you need plus some.. i.e. the image itself will be 102+139+whatever the maximum width you're ever likely to need px wide

Then combine the left two images 102+139px - you will then have two images a very wide one for the right and a very precise one for the left .. use the right image as the background to the #navbar div, remove the padding off the #navbar div, in the code above, as you want the ul to fill the space now.. and position the background image top right, it will, because you have made it wide enough, cover the whole width of the #navbar and have the rounded corner on the right side.. this rounded corner can be transparent png/gif

There's already no padding on the #navbar ul so it too now covers the whole width of the #navbar - put the left image as a background to the ul, positioned top left no repeat and transparent as the background color - here you will likely have to incorporate your page background color into the new left corner image, i.e. in your linked example you would need to build white into the corner - if the rounded corner bit is a transparent png/gif the image underneath, the extended right side image will show through.. (this is now so much easier to do in browsers that support multiple background images!)

now no matter how wide the whole navbar gets the left image "slides" over the right, hiding the extra bit and giving the fluid effect

then finally the centering of the li's should still take care of leaving the sides free, but now you could put 241px (or more or less as required) of padding onto the ul - no explicit width on the ul though, it's already using 100% of the navbar - from here you can then make the li's percentages add up to 100% i.e. if 4 of them make them 25% to fill the content width of the ul, the padding on the ul should ensure they don't encroach on the required area of your design, or you could leave the li's at the slightly lesser sum for more effect or you could use less padding on the ul for a different effect, allowing the li's to slightly overlap the fading design of the corner images.. you choose :)

NOTE: if the page background is patterned and you can't build it into the left sliding image this might need a rethink or an extra wrapper but it should still be possible by combining those background images as suggested.. if you have to leave the left rounded corner transparent or don't understand what I'm trying to explain (possible as it's not easy to describe an effect that you can see in your head! :o) give me a shout back and I'll provide some more code..

but do make those images ;) don't worry about the file size totals.. smaller images are not necessarily better, more images = more http requests which is the bigger speed problem - bigger images (this included CSS sprites) as well as being less http requests actually often download quicker anyway due to packet size or something like that!

e.g. did you know that when creating a repeating background image it's better for it to be 100px by 100px or even 20px by 20px rather than 1px by 1px something to do with the amount of repeat work and packet size.. so don't be worrying about image size (there are great image smushers if you want to run your images through them when you get the effect working).. more worry about not using extra unnecessary elements, whether table cells or extra <li>'s, to create a display effect ;)

TheStranger




msg:4269437
 1:36 pm on Feb 19, 2011 (gmt 0)

Thanks Suzy, you explained it fine...However, a few complications have arised.

  1. The Right image really does need to be transparent, so I did as you suggested (make another wrapper, of sorts). It works, but in IE7 the Left (extremely long) image doesn't show up (I expect I bodged the coding up somehow).

  2. Unfortunately, my original problem of the li's not expanding and shrinking based on there percentages, is still there.
    *Note. Expands in Opera and Google Chrome, but not FireFox, Safari, or IE.

  3. In IE7 there is no space between the li's,.

  4. I have centered the Navbar using 2 div's: 1 Floating left with position: relative, and Left 50%, the other with position: relative, Left -50%. However for some reason this does not work in Opera.


I expect problem 2 is somewhat caused by problem 4, because if I remove the float and positions, and gave back #wrapper a width (such as 100%), the li's will expand and shrink, but then I can't centre #wrapper (well, to be more precise, I haven't found a way to...yet).

Here is my code now.

CSS:

<style type="text/css">
html, body {
margin: 0;
padding: 0;
}

#wrapper {
margin-top: 0;
margin-right: auto;
margin-bottom: 0;
margin-left: auto;
float: left;
position: relative;
left: 50%;
}

#Navbar {
width: 80%;
min-width: 790px;
min-height: 41px;
text-align: center;
background-image: url(http://img151.imageshack.us/img151/2232/examplerd.png); /* Temporary external image, for ease of your editing*/
background-repeat: no-repeat;
background-position: right top;
left: -50%;
position: relative;
}
#NavMiddle {
min-height: 41px;
background-image: url(http://img27.imageshack.us/img27/2603/examplelwh.png); /* Temporary external image, for ease of your editing*/
background-position: left top;
background-repeat: no-repeat;
margin-right: 241px;
}
#NavInner {
margin-right: -241px; /* Found it was necessary to get Right image to show */
}

#Navbar ul {
width: 100%;
word-spacing: -4px;
margin-left: 241px;
}

#Navbar ul, #Navbar li {
list-style: none;
margin: 0;
padding: 0;
}


#Navbar li {
vertical-align: top;
color: #F5F5F5;
width: 14%;
font-size: 110%;
display: inline-block;
word-spacing: 0;
}
#Navbar li { /* for IE 6 & 7 - asterisk before the rule is the hack */
*display: inline;
}
#Navbar li a {
display: block;
color: #f5f5f5;
text-decoration: none;
padding-top: 10px;
padding-right: 0;
padding-bottom: 10px;
padding-left: 0;
}

#Navbar li a:hover {
color: #000;
background-color: #CCC;
}
</style>


HTML:
<div id="wrapper">

<div id="Navbar">
<div id="NavMiddle">
<div id="NavInner">
<ul>
<li><a href="#">Home</a></li><!--
--><li><a href="#">Something</a></li><!--
--><li><a href="#">About</a></li><!--
--><li><a href="#">Contact</a></li>
</ul>
</div>
</div>
</div>

</div>

SuzyUK




msg:4269489
 4:19 pm on Feb 19, 2011 (gmt 0)

# The Right image really does need to be transparent, so I did as you suggested (make another wrapper, of sorts). It works, but in IE7 the Left (extremely long) image doesn't show up (I expect I bodged the coding up somehow).


OK it's not a problem, and thanks for including the images it does indeed make it easier to edit.. you've done it the opposite way to what I suggested, but that doesn't matter at all.. the left, long image wasn't showing because of some extra float/positioning, it's not necessary.. see updated code below

You did right with the how you made the long image clear the short image but you don't need an extra wrapper to do it.. that's my fault I was thinking out loud after the fact.. however I've redone it in the code below

redoing it so that your clearing margin is on the <ul> means the ul itself is not perfectly centered any more therefore then the centering of the inline-blocks were affected.. this is easily compensated for my putting 241px of left padding on the UL to match the 241px right margin :) This leaves a centered content area again

# Unfortunately, my original problem of the li's not expanding and shrinking based on there percentages, is still there.

*Note. Expands in Opera and Google Chrome, but not FireFox, Safari, or IE.

Ok not understanding that one, but perhaps it was related to the fixes I made for the basic centering.. how does it work now (see code below)

# In IE7 there is no space between the li's,.

I know that's why I introduced the word-spacing workaround for the other browsers rather than using a negative right margin, which would have affected IE as well. There should be spacing between inline blocks that is their default behaviour, but there is no space between inline-blocks in IE7 and below because they're not really inline blocks, they're hacked inline boxes.. IE got in wrong again in the past, it was only able to apply
display: inline-block; to inline elements.. i.e. elements that would normally have that default word-spacing in the first place.. the hack in your code actually makes IE display the li elements as inline, and in normal circumstances you wouldn't be able to apply a width or height to them.. which is what you want by choosing inline-block.. however IE will give an inline element height and width honoring capabilities if it's hasLayout trigger is set to true.. zoom: 1; in your previous hack was doing that.. in my version display: inline-block is actually doing that5 but only if it's not in the same rule as the other display property

# I have centered the Navbar using 2 div's: 1 Floating left with position: relative, and Left 50%, the other with position: relative, Left -50%. However for some reason this does not work in Opera.


I think this method was not quite right or required.. see point one above and code below to see if it's clearer

I've amended the wrapper div to 100% to remove all reference to px widths.. I see you've chosen to give the navbar 80% width so I've added the
margin: 0 auto; centering code to it too, you can change the width of the wrapper to see the effect of the overall centering .. like if your overall container has a width of it's own in all you should not need floats or relative positioning to center any of this :)

I've removed the HTML comments from between the li's.. these are an old bug fix for when IE6? would put whitespace between lists, but the hasLayout fix for the same bug is incorporated with the inline-block hack as explained above

If you want whitespace between your lists items you should margin them, now that the word-spacing workaround brings all browsers to the same 0 default

<div id="wrapper">

<div id="Navbar">
<ul>
<li><a href="#">Home</a></li>
<li><a href="#">Something</a></li>
<li><a href="#">About</a></li>
<li><a href="#">Contact</a></li>
</ul>
</div>

</div>



html, body {
margin: 0;
padding: 0;
}

#wrapper {
margin: 0 auto;
width: 960px;
width: 100%;
}

#Navbar {
width: 80%;
margin: 0 auto; /* center this too if it's less width than the container */
min-width: 790px;
min-height: 41px;
text-align: center;
background-image: url(http://img151.imageshack.us/img151/2232/examplerd.png);
background-repeat: no-repeat;
background-position: right top;
}

#Navbar ul, #Navbar li { /* general reset though some margins are redeclared later */
list-style: none;
margin: 0;
padding: 0;
}

#Navbar ul {
min-height: 41px;
background-image: url(http://img27.imageshack.us/img27/2603/examplelwh.png);
background-position: left top;
background-repeat: no-repeat;
margin-right: 241px; /* this is good and the way to be able to use a transparent corner image */
/* width: 100%; */ /* but no explicit width here! or the margin above this is doing nothin.. the ul is already 100% by default */
word-spacing: -4px;
text-align: center; /* add this.. it won't center the blocks any more because of the margin above but add an equivalent of padding the other side to simmulate */
padding-left: 241px; /* add this to even up the size of the ul's content area */
}


#Navbar li {
vertical-align: top;
color: #F5F5F5;
width: 20%; /* increase this a bit there wasn't enough room for the text and it's still leaving a bit of extra space */
font-size: 110%;
display: inline-block;
word-spacing: 0;
}
#Navbar li { /* for IE 6 & 7 - asterisk before the rule is the hack */
*display: inline;
}
#Navbar li a {
display: block;
color: #f5f5f5;
text-decoration: none;
padding-top: 10px;
padding-right: 0;
padding-bottom: 10px;
padding-left: 0;
}

#Navbar li a:hover {
color: #000;
background-color: #CCC;
}


I increased the size of the inline-blocks because at 14% there wasn't enough room for the text in one of them so they only looked like they were not evenly spaced due to the text overflowing.. this is still happening at my 20% if you reduce the browser size.. it's not that the percentages aren't working it's that they're not enough to contain the text.. this will be trial and error to get the optimal solution for when your menu is actually complete.. if it were me I would try to make the total add up to 100% especially if there is to more than 4 items.. in this menu for example if you increase them to 25% they look a little to spaced out at normal resolution, but they will stay looking equally space longer as you narrow your browser window

I moved the general list reset (see CSS comments) above the rest of the ul and li code, it needs to be first to reset the values so the cascade then means ul goes on to override this general reset by setting a right margin

notes in the CSS what was added changed and why.. Hows that now?

Suzy

TheStranger




msg:4269511
 5:40 pm on Feb 19, 2011 (gmt 0)

.. Hows that now?

Absolutely brilliant :D . Works well. Thanks so very much for your help :D



# Unfortunately, my original problem of the li's not expanding and shrinking based on there percentages, is still there.

*Note. Expands in Opera and Google Chrome, but not FireFox, Safari, or IE.

Ok not understanding that one, but perhaps it was related to the fixes I made for the basic centering.

You are correct.
I think it had something to do with I didn't have a width on #wrapper, which caused a problem with FF, Safari, and IE.
Your revised coding worked :)


I increased the size of the inline-blocks because at 14% there wasn't enough room for the text in one of them so they only looked like they were not evenly spaced due to the text overflowing.. this is still happening at my 20% if you reduce the browser size.. it's not that the percentages aren't working it's that they're not enough to contain the text.. this will be trial and error to get the optimal solution for when your menu is actually complete.. if it were me I would try to make the total add up to 100% especially if there is to more than 4 items.. in this menu for example if you increase them to 25% they look a little to spaced out at normal resolution, but they will stay looking equally space longer as you narrow your browser window.
I've enlarged the percentages, and also added a min-width to the li, works well now.

Thanks again Suzy :D .

SuzyUK




msg:4269551
 7:57 pm on Feb 19, 2011 (gmt 0)

You are very welcome, .. your code samples were great, tried and tested.. so I'm happy to be your second pair of eyes and glad to have been of some help

now, don't live up to your name, don't be a Stranger! :)

Global Options:
 top home search open messages active posts  
 

Home / Forums Index / Code, Content, and Presentation / CSS
rss feed

All trademarks and copyrights held by respective owners. Member comments are owned by the poster.
Home ¦ Free Tools ¦ Terms of Service ¦ Privacy Policy ¦ Report Problem ¦ About ¦ Library ¦ Newsletter
WebmasterWorld is a Developer Shed Community owned by Jim Boykin.
© Webmaster World 1996-2014 all rights reserved