Hi gang!
I'm trying to build a striaghtforward (?) Suckerfish dropdown (and while I'm at it this time, REALLY wrapping my head around what each bit of the code does and why. Thus the heavily commented menu code in the css.)
Thus my frustration that the dropdowns are sticking to the left of the content area, not remaining under their parent list item.
Actually, I've stared at the Suckerfish example here until my eyes cross:
http://www.htmldog.com/articles/suckerfish/dropdowns/example/bones1.html
and can't for the life of me figure out how the subs are "told" to stay with their parent list item. Or what I'm doing differently that's screwing things up.
I'm having issues quoting the code here, so I'll give links instead (sorry):
Here's the HTML:
http://royalcitymusicaltheatre.com/indexNEW.html
...and here's the CSS:
http://royalcitymusicaltheatre.com/rcmt2008.css
I'm sure it's something super-simple and obvious but I just can't see it.
Thanks!
adam
the difference is..
Your first level li's are display:inline, SF's are display: block; that's the default, for an li but is also enforced courtesy of the float (a floated element automatically becomes a block element)
and because you said you wanted to really wanted to wrap your head around this (though you may regret this ) here goes my attempt at describing what's happening:
The absolutely positioned child/second level list will be positioned in respect to its containing block a containing block for positioning purposes is not necessarily the same as the "parent element" (though you can make it that way to help gain control** see below about relative positioning the parent)
There is actually no specified containing block in the SF menu code so the position of the drops will be calculated from the initial containing block which is the root (viewport)
Then the rules for the auto keywords Calculating Box Offsets are important for determining what the base of the containing block
"Note: For absolutely positioned elements whose containing block is based on a block-level element, this property is an offset from the padding edge of that element."
although the containing block for both the inline li and the block li is the root, the element that it's based on is different in the two cases, the base is the nearest block level ancestor to the absolutely positioned element. In the case of the SF code, that nearest block level ancestor to the AP drop list is the parent li (as described above), in your case it's the master UL (ul class="nav") itself.
So the 'padding edge' from which the auto value calculates as per the above rule is different in the two cases : in SF it's the parent li's left padding edge, in yours it's the parent ul's left padding edge!
now is that any clearer or do you wish you'd not asked
best way to fix it for you? go the float route, and you could if you like which SF hasn't done also specify position:relative on the parent li, this will remove any need for using that auto value anyway because by doing this you are taking control and saying you want the li specifically to be the containing block as well as the parent - you would then likely need to use the values left: 0; and top: 100%; for positioning the drop list - this is saying 0 from the left of the containing block (the parent li) and 100% from the top of it (which is the bottom of it)
or you could just copy SF literally.. but note that when you make the "li" and the "a" into block elements you will likely need to adjust your padding. You can't set a width on an inline element (in your code that's both the li and the a) so that bit of your code where you're telling the <a> element to be 10em wide is not doing anything for you.. it will if you turn the anchor into a block too though, and will likely mean you don't need left/right padding at all, just text-align:center; within your required width to get "equal" padding perhaps?
there's a few different ways to achieve the look and I think it depends on which way you would rather do it, so you understand it, as to which advice would be best, so hope some of that helps and doesn't put you off
btw if you really are using SF's javascript to get IE6 and below to do the hovers you would need to change ul class="nav" to ul id="nav" and change every instance .nav to #nav in the styles, the sf javascript is based on targetting the element by ID.
Getting there, but....
Suzy - thank you SO much for your detailed response, it is tremendously appreciated!
I actually think I understand most of your reply (though I did have to re-read it many times... and although my brain hurt for a while, gradually it all seems to be making sense).
For the moment, I'm trying the approach of exactly duplicating the SF code.
But...
The submenu has now disappeared! I keep going over it and can't see why.
One other point: I do want this menu to be centered, overall - and though I could fake it with a left margin, I'd rather it was truly centered. I take it that will add a whole new layer of complexity....?
Still, my main concern is the vanished submenu.
Here again are the links:
http://royalcitymusicaltheatre.com/indexNEW.html
http://royalcitymusicaltheatre.com/rcmt2008.css
Once again, many thanks for your help and hopefully I'm nearly out of the woods!
adam
disappearing sub
re: disappearing sub, in your code you have li:sfhover ul, the "sfhover" is a class created by the javascript so it should read
li.sfhover ul (note dot not colon)
this is causing FF not to work too because it's ignoring the rule following this selector by way of dealing with a parse error.
re:centering the menu - I would cheat! the pros outweigh the cons when using floats (instead of display inline) your menu is quite precise so I would simply margin the top level list on the left by about 45px to give the "centered" look
you would be about to hit another problem which is the whitespace in lists for the drop menus, as I presume you want the yellow rollover to fill the width of the drop list?
anyway it's Sunday so I did the code, and I added comments like you have to hopefully help explain why
#menu {
width: 700px;
height: 34px;
background-color: #660000;
}
/* THE MENU */
#nav, #nav ul { /* TOP AND NESTED LISTS */
padding: 0; margin: 0; /* CLEAR UNWANTED BROWSER DEFAULT INDENTS */
list-style: none; /* NO BULLETS (Underlining is on 'a' tag, not here) */
font-family: 'Arial Narrow'; /* FONT STYLES EXCEPT COLOUR (that's also in 'a' tag) */
font-size: 14px;
font-weight: bold;
}
#nav { /* center cheat! */
margin-left: 45px; /* adjust this to move whole menu over a bit to make it look like it's centering */
}
#nav li {/* all list items */
float: left; /* side by side for top level */
margin-right: 10px; /* space out top level buttons here */
}
#nav li li { /* overrules for second level drop lists */
width: 100%;
/* takes width from parent ul - set below -
it's best for IE to leave the second level
list items floated too - for the whitespace in lists problem
so this time if you don't want them to 'shrinkwrap' but fill the
list instead they need a width and this is simply telling them to be
100% of whatever width you decide to give the parent list below */
margin: 0; /* overrule any button spacing given in previous rule not necessary for the drops */
}
#nav li a { /* all links */
display: block;
text-decoration: none; /* REMOVE UNDERLINE */
color: white;
padding: 0 10px; /* don't use top/bottom padding here see line-height below */
/* THIS ONLY APPLIES TO BORDERS/BKGDS, NOT THE TEXT.
ADD UPPER/LOWER PADDING TO THE
- TAG TO EXPAND IT TO MATCH.
ADD THE AMOUNT OF PADDING, PLUS ANY BORDERS, YOU ADDED HERE. */
line-height: 34px;
/* make the line-height the same as the menu div height
so link text centers vertically and positioning of the drop is precise
using top/bottom padding can result in 1px rounding difference
font-size + natural leading = normal line-height
normal line-height + top/bottom padding can be quite hard to get
the height very precise, it's the height which is important for
accurate top positioning of the dropdown */
}
#nav li li a { /* overrules for second-level links */
line-height: normal; /* return line-height to normal value for child lists
this is to avoid wrapping links spacing out vertically too much - and use padding again if required */
padding: 8px 10px; /* adjust to suit spacing of text in drop menus */
}
#nav li a:hover {
font-weight: bold;
color: black;
background-color: #FFCC66;
}
#nav ul { /* THE AT-REST SUBMENUS */
position: absolute;
left: -999em;
width: 9em; /* adjust to suit but don't make it too small
this is the bit that the 100% wide li above takes its width from */
}
#nav li:hover {position: relative; z-index: 1;} /* helps avoid any stacking issues by making sure drop stays on top */
/* the sfhover class which the SF js generates is a class so needs the . */
#nav li:hover ul,
#nav li.sfhover ul { /* THE ACTIVATED SUBMENUS */
left: auto; /* THIS "REVEALS" THE MENU */
background-color: #660000;
}
hopefully all explained OK, you can't really copy SF directly if you want those full block rollovers in the drop lists as that starts to trigger IE oddities (namely whitespace in lists) - however the main ingredients to get around that where to leave the second level lists floated, give them a width so they no longer shrink to fit the text, I used 100% so it takes it's width from the parent UL for the drop list which also needs a width for IE.
hth have fun!
Hi Suzy, re: the whitespace
Hi Suzy,
re: the whitespace bug.
I wrote about this ≈3 years ago, and just republished, IE white space bug.
It's another one of those hasLayout issues. (Aren't they all?) Pray for a speedy rollout of IE8.
cheers,
gary
nice!
nice article Gary :thumbsup:
yes it's the same old same old, however I must be getting old , when whitespace in lists first appeared it was in IE5, it quietened down a bit in IE5.5/6 but reared its ugly head again in 7. The "fix" for IE5 was to float the li's so that's always still my first line of defence (sad remebering that far back no?) and I didn't want to add any hasLayout hacks into this code for poor cosmocanuck, I know I discovered one of them but I still don't like using one unless I absolutely have to
as you wrote, a hasLayout hack on the anchor would've worked in this case too *if* the width of them weren't important (there's padding on them too), but as the whole thing (evenly sized rollovers is what *I think* cosmocanuck wants, but sf doesn't do) depends on there being a width on the ul in the first place it worked just as well keeping the float on the nested li's and getting them to "take responsibility" for the layout of the links - the float and the width on the li are both triggering layout and taking care of that
it works and is logical I hope
roll on IE8, too true - but with the 'opt in' for 8 "support" I think we could well be dealing with 7 for a very long time!
I've only scanned lightly
I've only scanned lightly over the thread, so ….
Put any padding (why pad? wasn't there mention of text-aligning text?) on the li, and make a {width: 100%;}. The width property will set hasLayout.
This might all be wrong. I've never used SuckerFish, unless by accident.
cheers,
gary
"Oh, bother!" said Pooh...
Suzy, I inserted your code, but I'm still in some trouble here as you can see.
http://royalcitymusicaltheatre.com/indexNEW.html
What happened? Everything in your code makes sense but many things are not working - list-style for starters, and vertical spacing...
Here's the code link:
http://royalcitymusicaltheatre.com/rcmt2008.css
I'm sure I've botched things somewhere but I can't find anything I copied incorrectly. Maybe I am simply too close to see it...!
Thanks,
adam
strange..
when I view your stylesheet it's full of strange characters..
Ê line-height: 34px;Ê
ÊÊÊÊÊÊÊÊ /* make the line-height the SAME AS THE MENU DIV HEIGHT
ÊÊÊÊÊÊÊÊÊÊ so link text centers vertically and positioning of the drop is precise
ÊÊÊÊÊÊÊÊÊÊ using top/bottom padding can result in 1px rounding difference
ÊÊÊÊÊÊÊÊÊÊ font-size + natural leading = normal line-height
ÊÊÊÊÊÊÊÊÊÊ normal line-height + top/bottom padding can be quite hard to
perhaps it's the copy/paste from the forum? then there's the upload method, not sure about the technical terms for this perhaps someone else can weigh in
- copy the original code to a text document, e.g. notepad, not word or your editor, first then copy/paste into your stylesheet..
That was it! Oh, the
That was it! Oh, the pitfalls that await us newbie coders... or even semi-experienced coders!
Thanks!
adam
gary.turner wrote:I've only
I've only scanned lightly over the thread, so ….
Put any padding (why pad? wasn't there mention of text-aligning text?) on the li, and make a {width: 100%;}. The width property will set hasLayout.
This might all be wrong. I've never used SuckerFish, unless by accident.
cheers,
gary
Gary,
Many thanks for the quick blurb you mentioned above. I was fighting with Suckerfish for a while in that shorter <li> bits within the first level dropdown were being packed 'two to a line.' Your width comment above worked like a charm when applied to the submenus' <li>.
Your new site looks clean and refreshing, BTW. It's a nice change from the standard, noisy collaborative web designer's project...
Kindest regards,
Chris
Hi Chris, Welcome to
Hi Chris,
Welcome to CSSCreator.
I edited your post to escape the < characters. This forum allows some html, so to show a tag, be sure to use the alpha/numeric entity for at least the left angle bracket (<).
Thanks for the good words on my site. My graphics consultant hasn't got to it yet. The pages are basically wire-frames based on information architecture considerations. I once used a signature line, "Anyone can create a usable web site. It takes a graphic designer to make it slow, confusing and painful to use."
cheers,
gary
Thank goodness for forums!
:thumbsup:
Hey CSS gurus! I was searching for a fix for IE. I am using the SF and PVII drop-down code and could not figure out why the drop down stopped working in IE (I had also inserted AJAX function).
The very last line in Suzy's fix for cosmo was my fix. :
#nav li:hover ul, #nav li.hvr ul {
left: auto; /*reveals the menu */
}
I beleive I will be reading more on this site! Definitely want to improve my CSS skills!
Peace,
astro
space between vertical rollover menus
Thank you Susy,
I had the same problem, the white space between nested li for rollover menus, It helped when I wrote line-height:10px;
thanks.
Mauricio
Ah, but...
I heard from Paul O'Brien that IE7 really doesn't like left: auto;
#nav li:hover ul, #nav li.hvr ul {
left: auto; /*reveals the menu */
}
And what he did was keep left: 0 for IE7 while also using marging-left in place of left as well-- both left and margin-left work to move the subs around but apparently IE7 can ger squirrely with left: auto.
And, I've always wondered what that Opera bug was when you didn't set a width on the top-level li's was. Someone on another forum ended up tripping this bug! It was interesting to watch. The subs would usually appear on :hover but they'd flicker and be off-centered. However, there are times when you want to float something and use padding to keep some sides on the menu items and otherwise let the float shrink-wrap... can we do this?
have u tried suckerfish on
have u tried suckerfish on the IE8 beta versions?
yeh, let's hope they wait another 7 years before releasing that bugged pita
basicly, even if u put z-index to a million, the background text will still display in front of ur suckerfish dropdown, so u can only use it on a clean background with no text or images behind it
which sorta kills the functionality
IE8 has bugs-- the beta is
IE8 has bugs-- the beta is out so developers can send bug reports to the development team.
IE7 and IE6 do have a z-index bug where setting the z-index on the Menu instead of the subs is needed. I'm actually not sure if IE7 had this, I've only run into this bug once.
If it's the same IE bug, they need to be notified of it so it can be fixed.
Great Explanation...but I'm still a little bit stuck
Hi Suzy,
Thank you _so_ much for posting that detailed explanation. It's exactly what I wasn't finding anywhere else.
I'm this |----| close to being happy w/ the "suckerfish" menu I'm using for a new non-profit's website. Unfortunately, the problem I'm having is that I can't get the width of the second-level list items to extend to the width of the second-level list, and though I think I'm starting to understand your explanation about which controls -- the parent or the containing block -- I'm still a bit stuck. It's easier to show than explain:
I've set a border around the second-level list (ul), and then a top border on each second-level list item (li). I've also set the hover pseudoclass for the second level list items to trigger a change of each item's background color.
As you'll see, neither the top border nor the background color change span the whole width of the list; they stop @ the width of each list item, as determined by the width of the text inside. Changing the second-level list items' width to 100% really screws things up, as the list items far overshoot the width of the list. (This I think I understand now.)
I've posted the relevant section of my css below, & I'd really appreciate a hand in figuring this out the rest of the way. I'm sure it's something simple that I'm overlooking, but despite hours of trying (& googling & trying again...), I'm still stuck with this almost-finished nav list!
Thank you, kind coders!
Shane
#nav { margin: 0 0 1em 0; font-size: 1.2em; width: 100%; height: 1.6em; background-color: #8aa1b1; border-bottom: 1px #333333 solid; border-top: 1px #333333 solid; } #nav a { text-decoration: none; color: #000000; } #nav ul { list-style: none; padding: 0; margin: 0; width: auto; } #nav li { padding: 1px 13px 4px 13px; border-right: 1px #333333 solid; float: left; position: relative; width: auto; } #nav li ul { display: none; position: absolute; top: 1em; left: -14px; /* aligned to the left edge of their parent, minus the amount of left padding of the parent (minus one more for the border of the child). Otherwise, this will line up w/ the left edge of the text; not the left edge of the parent's area that changes color on hover */ background-color: #8aa1b1; border-top: none; border-left: 1px black solid; border-bottom: 1px black solid; border-right: 1px black solid; } #nav li > ul { top: auto; left: 0; margin-top: 4px; margin-left: -1px; } #nav li ul li { border-top: 1px black solid; border-left: none; border-bottom: none; border-right: none; padding: 2px 13px 4px 13px; /* width: 100%;*/ } #nav li:hover { background-color: #b2cfe3; /*background-color: #78abdd;*/ } #nav li:hover ul { display: block; }
Shane, first of all, I'd
Shane,
first of all, I'd advise to stay with Suckerfish's version of showing and hiding the subs-- until the screenreader developers get their bugs fixed, and esp with this being a non-profit web site (might you fall under section 508 of the US?) so use left: -abazillionunits and then left: 0 (or margins, if it makes IE7 happier) to show (that's the only reason there are coordinates on the Suckerfish; not sure why you have left:whatever in your code since you're currently using the changing display states to hide and show the subs). Since screen readers for some unknown reason acknowledge display: none, the submenus are not read out loud and so they are never available to web listeners.
Second, I think what you want to make your borders and background colours stretch all the way across is to make your a's display: block and move your hover characteristics over to the a's. Blocks can has widths : ) but currently, it seems that your li's are getting the :hover characteristics but remain at the width of the a's (which are inlines, meaning they cannot have width greater than their characters + horizontal padding and cannot have height greater than their line-height + vertical padding). By floating the li's and then saying width: auto, you're letting the li's shrinkwrap I think. If you did width: 100% then you couldn't also have side padding cause that's 100% + padding and you can't eat 100% of your candybar and then eat more.
So, change your hide/show model to use the pushing off-side technique (instead of display: none, display: block), leave the li's floated and auto width (for the main-level li's) but for the sub-li's, keep them floated left and width 100% but no side padding, and move your hover colour and border changes to the sub a's, which you'll make display: block (and cause they're not floats, they'll naturally try to be 100% width so you can set padding and not have to say a width!) and that oughtta do it.