CSS - horizontal suckerfish problem

Z

z

I'm trying to make a horizontal dropdown menu in CSS something like this:
http://www.weblens.org/templates/sample_menu.html

The difference is that I want the secondary menu items to always be flush
with the left side, not starting under the parent list item.

Instead of:

Item1....Item2....Item3
...................Item3-sub1....item3-sub2

I want it like this:

Item1....Item2....Item3
Item3-sub1....item3-sub2

(Periods added in the above example to make sure that the spacing is correct
if you are viewing it in a monospace font.)

Is there a way to do this in CSS?
 
D

dorayme

z said:
I'm trying to make a horizontal dropdown menu in CSS something like this:
http://www.weblens.org/templates/sample_menu.html

The difference is that I want the secondary menu items to always be flush
with the left side, not starting under the parent list item.

Instead of:

Item1....Item2....Item3
..................Item3-sub1....item3-sub2

I want it like this:

Item1....Item2....Item3
Item3-sub1....item3-sub2

(Periods added in the above example to make sure that the spacing is correct
if you are viewing it in a monospace font.)

Is there a way to do this in CSS?

I took a quick look, could not find any css for your class
"inner" and then noticed that the sub menus were disappearing
unexpectedly in Safari while the mouse was over them... and gave
up for now.
 
B

Ben C

I'm trying to make a horizontal dropdown menu in CSS something like this:
http://www.weblens.org/templates/sample_menu.html

The difference is that I want the secondary menu items to always be flush
with the left side, not starting under the parent list item.

Instead of:

Item1....Item2....Item3
..................Item3-sub1....item3-sub2

I want it like this:

Item1....Item2....Item3
Item3-sub1....item3-sub2

(Periods added in the above example to make sure that the spacing is correct
if you are viewing it in a monospace font.)

Is there a way to do this in CSS?

Of course, there are many ways.

It can be achieved with two small changes to the example you posted.

1. Get rid of position: relative from the selector for #mainMenu li

This changes the containing block of the ul.inner from the li above it
to what is now the nearest positioned ancestor which looks like
#mainMenu. #mainMenu is a normal block-level element with its outer
margin edge aligned to the left of its container (the body), not a float
some distance across the page, so this gives us a suitable reference
point for positioning the pop-ups to the left side.

2. Change left: auto in the selector #mainMenu li>ul to left: 0

left: auto here means "go roughly where you would have gone if you'd
been normal flow rather than positioned", which is aligned to the left
of the parent list item since, if we'd been normal flow, the parent list
item would have been our containing block. That's not where we want to
be though, we want to be 0px from the left of our container (now that
we've made our container #mainMenu). So we just change auto to 0.
 
D

dorayme

Ben C said:
Of course, there are many ways.

It can be achieved with two small changes to the example you posted.

1. Get rid of position: relative from the selector for #mainMenu li
2. Change left: auto in the selector #mainMenu li>ul to left: 0


Well done Ben.

There is a most amusing effect (unaffected by Ben's fix for the
submenu) to be seen from
<http://www.weblens.org/templates/sample_menu.html> in iCab. For
all you Mac users, take a look and see if you can keep up with
the marching-down-the-page-menu-bar! Now this is something I
don't think I have ever seen before. Very dynamic!
 
Z

z

Ben said:
On 2006-11-03, z <z> wrote:

Of course, there are many ways.

It can be achieved with two small changes to the example you posted.

1. Get rid of position: relative from the selector for #mainMenu li

This changes the containing block of the ul.inner from the li above it
to what is now the nearest positioned ancestor which looks like
#mainMenu. #mainMenu is a normal block-level element with its outer
margin edge aligned to the left of its container (the body), not a float
some distance across the page, so this gives us a suitable reference
point for positioning the pop-ups to the left side.

2. Change left: auto in the selector #mainMenu li>ul to left: 0

left: auto here means "go roughly where you would have gone if you'd
been normal flow rather than positioned", which is aligned to the left
of the parent list item since, if we'd been normal flow, the parent list
item would have been our containing block. That's not where we want to
be though, we want to be 0px from the left of our container (now that
we've made our container #mainMenu). So we just change auto to 0.

That worked perfectly. Thanks.
 
Z

z

Ben C wrote:


Of course, there are many ways.

One more question... is there a way to put a green line below the top part
of the menu, and have the lower dropdowns appear below the green line?
 
B

Ben C

Ben C wrote:




One more question... is there a way to put a green line below the top part
of the menu, and have the lower dropdowns appear below the green line?

Of course, there are many ways.

I've lost track of your original example, but couldn't you just put
something like border-bottom: 2px solid green on the top part?
 
Z

z

Ben said:
Of course, there are many ways.

I've lost track of your original example, but couldn't you just put
something like border-bottom: 2px solid green on the top part?


I was trying something like this but it isn't working. The border appears
to the right of everything.
ul#nav {
border-bottom: 3px solid green;
}

My version has all the borders removed, with grey on white text for
everything.

Complicated... I'm also trying to put a list-style-image next to only the
top-level items. Haven't been successful with that either.
 
B

Ben C

I was trying something like this but it isn't working. The border appears
to the right of everything.
ul#nav {
border-bottom: 3px solid green;
}

It's because the <li>s inside the <ul> are floats, so they don't
contribute to the <ul>'s height, which is auto and computes as zero. The
border sticks out a bit at the right, for the rest of its length it's
obscured by the "Menu Option" boxes.

If you make ul#nav also float: left, it becomes the "block formatting
context root" for the <li>s and so grows in height to fit them, resulting
in the border being in the right place.

This may not be the best solution in your case though. You'll need to
post a link to your current version.
My version has all the borders removed, with grey on white text for
everything.

Complicated... I'm also trying to put a list-style-image next to only the
top-level items. Haven't been successful with that either.

It should work, but it's up to browser exactly where the list item image
goes. Usually a few pixels off to the left.
 
Z

z

Ben said:
On 2006-11-06, z <z> wrote:

It's because the <li>s inside the <ul> are floats, so they don't
contribute to the <ul>'s height, which is auto and computes as zero. The
border sticks out a bit at the right, for the rest of its length it's
obscured by the "Menu Option" boxes.

If you make ul#nav also float: left, it becomes the "block formatting
context root" for the <li>s and so grows in height to fit them, resulting
in the border being in the right place.

This may not be the best solution in your case though. You'll need to
post a link to your current version.


It should work, but it's up to browser exactly where the list item image
goes. Usually a few pixels off to the left.

You are a CSS genius. The float:left works -- although the rollovers cover
up the border. I am getting inspired to study more advanced CSS.

I'll put a working version online and post the link.

Thanks
 
Z

z

Ben said:
It's because the <li>s inside the <ul> are floats, so they don't
contribute to the <ul>'s height, which is auto and computes as zero. The
border sticks out a bit at the right, for the rest of its length it's
obscured by the "Menu Option" boxes.

If you make ul#nav also float: left, it becomes the "block formatting
context root" for the <li>s and so grows in height to fit them, resulting
in the border being in the right place.

This may not be the best solution in your case though. You'll need to
post a link to your current version.

I don't have a server that I can post it on at the moment. Here is the
entire file though: http://pastebin.ca/raw/241965

Unfortunately the green line gets obscured by the dropdowns. I don't know
if there is a way around that. The list-style-image that I added didn't
seem to work either.

Other than that, it almost looks exactly right. Also need to look into how
to make a delay for the dropdowns with JavaScript if that is possible. So
that when the mouse leaves the sub-menus, there is a momentary delay before
they disappear.
 
B

Ben C

On 2006-11-06 said:
I don't have a server that I can post it on at the moment. Here is the
entire file though: http://pastebin.ca/raw/241965

Unfortunately the green line gets obscured by the dropdowns. I don't know
if there is a way around that.

Just add a margin-top to #mainMenu li ul.
The list-style-image that I added didn't seem to work either.

You don't see the bullets at all, or you see them, but they're in the
wrong place?
Other than that, it almost looks exactly right. Also need to look
into how to make a delay for the dropdowns with JavaScript if that is
possible. So that when the mouse leaves the sub-menus, there is a
momentary delay before they disappear.

Should be able to do that with onmouseout and setTimeout.

A quite nice way to do that kind of thing is rather than set individual
styles in the JS, just change classes.

So where you've now got descendent selectors involving :hover, instead
have

ul.visible
{
display: block;
etc.
}

ul.invisible
{
display: none;
}

Then use onmouseover and onmouseout to change the class attributes of
the elements you're controlling to visible or invisible.

I think it's something like node.setAttribute("class", "visible");

This way all the styling information stays in the CSS, the JS just turns
it on and off.
 
Z

z

Ben said:
Just add a margin-top to #mainMenu li ul.

I had tried that, but I think I put it in the wrong place. I went with
padding-top in the end to keep the menu from disappearing.

You don't see the bullets at all, or you see them, but they're in the
wrong place?

I see the bullets, but they are too far to the left of the list items, and
overlapping with the <li>s to the left. I tried list-style-position:
inside;, but that just put the list items on a line below the bullets.
I'm reading about another way to remove the list-style-image and use a
background image, but haven't tried it yet.

Should be able to do that with onmouseout and setTimeout.

A quite nice way to do that kind of thing is rather than set individual
styles in the JS, just change classes.

I'll look into that.

Thanks for your help. This is the most difficult thing I've ever tried to
do in CSS. I wouldn't have thought it possible. I am impressed with your
knowledge of CSS. Is there a book on CSS that you could recommend that
would explain these things clearly? I have a couple of CSS books already,
but not impressed with them. I like computer books that get to the point
really fast.
 
B

Ben C

I see the bullets, but they are too far to the left of the list items, and
overlapping with the <li>s to the left.

Understandable-- the browser just offsets the bullets to the left of the
list items. This works OK most of the time, but not if the list items
are floated.
I tried list-style-position: inside;, but that just put the list items
on a line below the bullets.

Interesting, I suppose it didn't float them. One way to implement
list-style-position: inside is for the browser to pretend the bullets
were display: inline and insert them before the list item content. That
might account for the behaviour you're seeing. Anyway, it's not
something you can control precisely.
I'm reading about another way to remove the list-style-image and use a
background image, but haven't tried it yet.

That sounds like a better approach. You could give them a bit of left
padding and a background image positioned at the left.

[snip]
Thanks for your help. This is the most difficult thing I've ever
tried to do in CSS. I wouldn't have thought it possible. I am
impressed with your knowledge of CSS. Is there a book on CSS that you
could recommend that would explain these things clearly? I have a
couple of CSS books already, but not impressed with them. I like
computer books that get to the point really fast.

I don't know of any, but I'm sure there are good books. I just read the
CSS 2.1 spec, which is clear, comes from the horse's mouth and certainly
gets to the point fast. But it's not always the most readable thing. You
can get it from here: http://www.w3.org/TR/CSS21/
 
Z

z

That sounds like a better approach. You could give them a bit of left
padding and a background image positioned at the left.

The background-image solution worked well.


I don't know of any, but I'm sure there are good books. I just read the
CSS 2.1 spec, which is clear, comes from the horse's mouth and certainly
gets to the point fast. But it's not always the most readable thing. You

Thanks, I bookmarked it for later.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top