Forum Moderators: not2easy
first of all I'd like to say I'm new to this site, so just a quick hi.
I'm trying to create a site header within <div> fields. The header contains 3 elements, a header image, on the left of the div, a login module: $login and another module: $module2 both on the right side of the div. The header image should align to the bottom of the header box, and the $login module should be on a layer above $module2. this is so the $module2 is only visible when $login isn't active.
Ok, my problem is I want the div height to grow and shrink depending on what's in the box, but puting the height of the div as 100% doesn't seem to work when I'm giving my <div>s absolute positions. The div doesn't think there's anything in it. If I set the header to 150px it works, but it looks majorly ugly when the login box isn't there.
So the question is, how can I get Firefox and IE5+ to bottom align two items and left align one, and right align the other while growing and shrinking depending on how big the items are.
Any help would be appreciated.
Here is my CSS:
DTD HTML 4.01 Transitional//EN
<style="text/css">
#Header
{
display:block;
padding:0em 0em 0em 0em;
position:relative;
height:100%;
/* height:150px */
}
#LeftDiv
{
width:678px;
text-align:left;
position:absolute;
bottom:0px;
left:0px;
height:89px;
}
#RightDiv
{
display:block;
width:240px;
text-align:right;
float:right;
position:absolute;
right:1em;
bottom:0px;
z-index:20000;
}
</style>
<div id="Header">
<div id="LeftDiv"> <img> </div>
$module2
<div id="RightDiv">$login</div>
</div>
Some points:
- No point in having ultra-high z-indexes like that. Make sure objects you want handled with z-indexes are in the same stacking context... that they have the same parent.
- display: block is redundant. all divs are by default block level elements.
- padding:0 is all you need if you want it 0 on all sides. You do not need a unit for zero values.
- unless some other parent of header had a value for text-align other than left, that too is redundant since it's the default alignment for the body (which gets inherited by the children).
You cannot float and absolute position simultaniously. This W3C rule: [w3.org...] explains it.
I'm not sure what you're trying to accomplish there... float it to the right, but leave 1 em space to the right? one thing you could do is just simply give it 1em right padding/margin. Another thing you could do similar to what you were doing, but is not a preferable option compared to the padding solution is: add position:relative;top:0;right:1em
as you may know though, floating the guy will not align it vertically to the bottom of it's container. To do that, just use position:absolute;right0;bottom:0; and have NO float. You will then need to add 1em right PADDING (margin won't work for absolutely positioned) if you didn't want it against the side. You could also just give the CONTAINER 1em padding-right though too.
one last thing: in your code you just put module 2 in your header, in no container div or anything. It won't right align if you have it like that, so it's necessary to put it in another div (with 1 zindex lower than the one that's supposed to be on top) perhaps named rightdiv2, with the same positioning styles as in rightdiv.
If you put the padding-right on the header, you won't need to add a padding for both the other two elements.
I did not cover the trickiest part, the fact that the header size must increase based on the size of it's contents.
because absolute positioned elements must be given both a height and a width this makes it impossible.
Using floats instead it's possible, but it won't guarentee they are all aligned to the bottom of the div.
I couldn't help you with the main thing you probably wanted, but I did fix many mistakes you made.
Basicly there's two ways to go that I can think of: one: don't specify a height for your absolutely positioned elements. This is by far the easiest solution. The problem is that browsers are not OBLIGED to fit the content into the div if it's not given a width. It could in theory give a width of 0. Neither IE or firefox do that though, so you should be safe.
The other option would be to use tables vertical align property, or have the things ACT like table cells (which isn't supported by IE(6)).
[edited by: Xapti at 1:51 am (utc) on June 16, 2007]
I'm editing some old code, and the other object had a very high z-index, so decided to work with it rather than messing it around too much.
I'm not having a problem with the width, it's the height that's the issue. If I just float the items, then the header recognises the heights of the items, so making the header height:100% works fine.
The problem is as soon as I position them, unless I make the height an absolute size: height:150px, browsers don't seem to register that the object is within the div, so the div height ends up being 0px and the objects jump up above the browser window. If I just float the objects, then the height:100% works, but I can't bottom align the objects.
I've tried using tables, but for some reason, that seems to conflict with the CMS software, but I may have to work that out as it seems to be my only option at the moment.
thanks for your help,
Chris
I'm not having a problem with the width, it's the height that's the issue. If I just float the items, then the header recognizes the heights of the items, so making the header height:100% works fine.
What is the header taking 100% height of? the body?
I don't think you understand how height:100% works. height:100% means that the div will assume the full height of it's containing box. If none of it's ancestors (containers) have any heights specified, giving height:100% is inappropriate (it will just size the element normally as if there was no height specified)
[w3.org...]
"Containing box" is a somewhat tricky term which is defined here:
[w3.org...]
_________________
And I have some fixes/edits for my previous post:
"You will then need to add 1em right PADDING (margin won't work for absolutely positioned) if you didn't want it against the side. You could also just give the CONTAINER 1em padding-right though too." this is incorrect. I meant to swap margin and padding
"one thing you could do is just simply give it 1em right padding/margin." my mistake, this doesn't work. Still plenty of options though.
"Basicly there's [a way] I can think of: [...] don't specify a height for your absolutely positioned elements. This is by far the easiest solution." Ignore what I said. Not only is it what you did already, but it doesn't really apply, since everything inside is absolutely positioned, and will not auto-size the div.
The problem still remains. You cannot, as far as I know, absolutely position everything to the bottom while still having natural flow size. Not without using tables, anyway. In which case it'd be easy using the valign attribute.
Question though: Why even bother having them align to the bottom? it's not even very natural... typically people read top to bottom, left to right. Leaving a gap at the top seems pretty silly, especially for a HEADER element, where it'd probably look the worst.
[edited by: Xapti at 3:55 am (utc) on June 18, 2007]
what I think we need here is the generated source code, both of them, one with the "login" and one with "module2" and can you also give us the height of your header image and approximate heights of the 2 x modules
I would hazard a guess that the best way to dictate whether login or module2 is displayed (i.e. detect whether visitor is logged in) is via the PHP? script, - once detected you could either add a class name to the header div or generate different class names for the right div depending on "state" , either way you could then write your CSS accordingly without the need for layered divs.
If it's the right side div that needs to be the dictator of the height of the header div, you can't absolutely position them, as you've found out. You can though use a z-index with relative positioning so that might be an option. If any positioning is to be used I would be more inclined to absolutely position the left image to bottom left of the header, it can be placed at the bottom of the header div once the header's height is known by the browser. (i.e. once it has stretched to contain whichever right module)
anyway if you give us some more source it might help, and left us know if you can add/amend class names based on the logged in status of user
Suzy