Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 11 of 11
  1. #1
    Regular Coder
    Join Date
    Aug 2002
    Location
    Silicon Valley, CA
    Posts
    980
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Exclamation Advanced: Force container to autofit to its contents. Looking for a semantic solution

    The goal that I'm trying to accomplish is to build my page navigation with an unordered list, allow each LI to have a variable width, and have the menu items push off from the right side of my header while being semantically sound.

    Here's the setup:
    • UL is display:block;
    • Each LI is display:block; float:left; so that they all line up horizontally and can have padding applied (for a:hover, etc.).
    • UL is float:right in an effort to get the menu to the right side of the header. The problem is display:block makes the width 100% by default, so floating it to the right doesn't help without an explicit width. text-align:right doesn't affect block-level items.


    "So set an explicit width and be done with it." I'd rather have the UL width be variable to contain the LI's, which are also variable width (based on how many letters are in the word, etc.).

    I could set a an explicit width and then apply margin-left to push the menu over from the left. I'd rather have the menu push off from the right (e.g. in cases where people change their font size settings in their browser, I don't want the menu to wrap to the next line (and aligned to the left) because of some hard-coded width).

    I know that I could wrap the UL in a TABLE (which will automatically reduce its width to fit whatever its contents are), and align that table to the right... which would work, but it's not a semantic way of approaching the problem.

    I could probably also come up with a solution using JavaScript to calculate the widths of the LI's, but again, I shouldn't have to misuse a tool (behavior to solve presentation) to solve this problem.

    A last-resort fallback would be to float all of the list items to the right, but that has the unfortunate consequence of the list items being in reverse order when CSS is disabled (we're also serving this page without CSS to mobile devices).

    It's an interesting problem. Any ideas? A similar solution could be applied to centering these same navigation items (which I know is a popular layout for menu items).

  • #2
    The fat guy next door VIPStephan's Avatar
    Join Date
    Jan 2006
    Location
    Halle (Saale), Germany
    Posts
    8,696
    Thanks
    6
    Thanked 1,011 Times in 984 Posts
    Quote Originally Posted by Skyzyx View Post
    UL is display:block;
    1. Lists are block-level elements by default and usually don’t need to be set explicitly (except to revert a former display: inline;).
    2. float: right; applied to the list should do exactly what you want: Shrink the list to the width of its content. I don’t see what your problem is.


    Show us your code/page and we might see what you are doing wrong.
    Alternatively position: absolute; will make the list shrink to the size of its content as well but should only be used if you know exactly what you are doing and how to do it correctly.

  • #3
    Regular Coder
    Join Date
    Aug 2002
    Location
    Silicon Valley, CA
    Posts
    980
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Quote Originally Posted by VIPStephan View Post
    float: right; applied to the list should do exactly what you want: Shrink the list to the width of its content. I don’t see what your problem is.
    I'm stupid. I spent an hour working on this and couldn't get it to work. Maybe I was overcomplicating something. Stripping down some code, I applied float:right to the UL and it works. I've been designing with XHTML+CSS for five years, and I completely overlooked this. *headsmack*

    However, there's another website where I have an identical issue... the only difference is that instead of aligning to the right, it needs to be centered.

    At the moment, I have the list wrapped in a single-celled table because the table will shrink to fit the contents, and you can center it. Is there a more semantic solution?

  • #4
    Senior Coder
    Join Date
    Nov 2003
    Location
    Minneapolis, MN
    Posts
    2,879
    Thanks
    2
    Thanked 65 Times in 56 Posts
    Quote Originally Posted by Skyzyx View Post
    However, there's another website where I have an identical issue... the only difference is that instead of aligning to the right, it needs to be centered.

    At the moment, I have the list wrapped in a single-celled table because the table will shrink to fit the contents, and you can center it. Is there a more semantic solution?
    Long time no see around here, Skyzyx.

    You should be able to get that effect just by declaring the list items and list "display: inline" and styling UL with "text-align: center". Would that work?

  • #5
    Regular Coder
    Join Date
    Aug 2002
    Location
    Silicon Valley, CA
    Posts
    980
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Quote Originally Posted by rmedek View Post
    Long time no see around here, Skyzyx.
    I know it's been a while. Life gets busy and you start working on other projects. Poor old CF falls by the wayside. In a very, very strange way this place feels like (virtual) home for me. Weird.

    Quote Originally Posted by rmedek View Post
    You should be able to get that effect just by declaring the list items and list "display: inline" and styling UL with "text-align: center". Would that work?
    You could get the menu centered that way, but then you lose control over padding and margins -- they go a bit wonky on inline elements. I've also thought about setting the LI's to inline and the inner A's to block, but -- naturally -- you can't have a block element inside an inline element.

    Ideally, I'm hoping something like float:center or width:auto-fit will magically appear in a CSS spec and a browser implementation somewhere... At the moment, a table element is the only thing I can think of with box model rules that just work. I feel dirty just thinking about it...

    How's the music world treating you?
    Last edited by Skyzyx; 05-10-2007 at 07:04 AM.

  • #6
    Senior Coder
    Join Date
    Nov 2003
    Location
    Minneapolis, MN
    Posts
    2,879
    Thanks
    2
    Thanked 65 Times in 56 Posts
    Quote Originally Posted by Skyzyx View Post
    How's the music world treating you?
    It's good, although now I'm doing web design full time and music a little less. Still playing, just more of a quality over quantity thing (or so I like to think ).

    I've been trying a few approaches that I'm sure don't work in IE with getting floated items to center horizontally in a block level element. It's a lot trickier than I thought using floats, unless I'm missing something obvious. If I come up with anything I'll be sure to post it!

  • #7
    The fat guy next door VIPStephan's Avatar
    Join Date
    Jan 2006
    Location
    Halle (Saale), Germany
    Posts
    8,696
    Thanks
    6
    Thanked 1,011 Times in 984 Posts
    Quote Originally Posted by rmedek View Post
    It's good, although now I'm doing web design full time and music a little less. Still playing, just more of a quality over quantity thing (or so I like to think ).
    I know how that is… although you shouldn’t neglect music too much because quality needs to be abided. I always notice how much I’ve missed it to make music if I had longer periods of lonesome web programming at home and suddenly I can/have to play jazz (which you have to get into again at first).

    OK, back to the topic: display: table or table-cell; or inline-block may be an option but there are compatibility issues (major testing adivsed).

  • #8
    Regular Coder
    Join Date
    Aug 2002
    Location
    Silicon Valley, CA
    Posts
    980
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Quote Originally Posted by rmedek View Post
    It's a lot trickier than I thought using floats, unless I'm missing something obvious.
    I must be missing the same obvious thing. I'm open to exploring something besides floats, but it's the only way I know to convert an unordered list into "inline" navigation.

    Quote Originally Posted by VIPStephan View Post
    display: table or table-cell; or inline-block may be an option but there are compatibility issues (major testing adivsed).
    I'll look into those. The single-celled table has been a decent stop-gap solution for the moment, but the only real problem (other than having to misuse a table) is that the currently-shipping version of Safari 2.0.x will display incorrectly the first time I load the page after making a change (HTTP 200), but will work just fine if I reload the page after that (HTTP 304).

    The currently nightly build doesn't have this issue, so it'll likely be fixed for Safari 3 when it debuts with Leopard.

    Thanks again guys!

  • #9
    Senior Coder koyama's Avatar
    Join Date
    Dec 2006
    Location
    Copenhagen, Denmark
    Posts
    1,246
    Thanks
    1
    Thanked 5 Times in 5 Posts
    Quote Originally Posted by Skyzyx View Post
    I've also thought about setting the LI's to inline and the inner A's to block, but -- naturally -- you can't have a block element inside an inline element.
    Actually, you can perfectly nest an element with display: block within a element with display: inline. CSS 2.1 Working Draft, Section 9.2.1.1 explains how rendering should look like. However, this wouldn't give the desired effect.

    Quote Originally Posted by Skyzyx View Post
    At the moment, I have the list wrapped in a single-celled table because the table will shrink to fit the contents, and you can center it. Is there a more semantic solution?
    As VIPstephan says there exist semantic solutions. There are many canditates for display property of the ul element. Arbitrator has compiled a list of properties/values having the shrink effect. Not all can be centered, but some can. The problem is rather browser support. Mostly in IE.

    For Firefox 2, display: table could be used, but not display: inline-block. Only in Firefox 3 will that be possible.

    IE7 still only supports display: inline-block on naturally inline elements such as the span element. So this excludes that one could apply that display property directly on the ul element. It turns out that one can wrap the ul in a span and then apply span {display: inline-block}. This is invalid code, but one could solve this by hiding the span element in an IE conditional comment. Alternatively, Stu Nicholls suggests that one uses the del element (which allows block-level children) so one wouldn't have to hide it using conditional comments. However, I believe this instead violates semantics.

  • #10
    Senior Coder koyama's Avatar
    Join Date
    Dec 2006
    Location
    Copenhagen, Denmark
    Posts
    1,246
    Thanks
    1
    Thanked 5 Times in 5 Posts
    It appears that Bruno Fassino has found a more general method for emulating display: inline-block in IE/Win.

    The method may also be used for naturally block-level elements and involves setting display: inline together with triggering hasLayout using zoom: 1. He has created a cross-browser example illustrating the technique.

    The code may not be easy to overview because it is somewhat cluttered by the CSS hacks and conditional comments for browser style branching. So below is a stripped down example showing his technique that one might use for IE. It appears to be working in at least IE6 and IE7. Note that this example is not cross-browser compatible. It only illustrates the technique for IE6/7 since these are the tricky browsers. The styles below should be fed to IE using e.g. conditional comments. Other browsers should be fed with separate styles using a centering technique based on CSS standards.
    Code:
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
    "http://www.w3.org/TR/REC-html40/strict.dtd">
    <html>
    <head>
    <title>Centering ul menu of unknown width in IE6 and IE7</title>
    <style type="text/css">
    body {
    }
    div {
    	text-align: center;
    }
    ul {
    	display: inline;
    	zoom: 1;
    	border: 5px solid blue;
    	text-align: left;
    }
    li {
    	float: left;
    	display: block;
    	background: red;
    	border: 5px solid black;
    }
    </style>
    </head>
    <body>
    <div><ul><li>Alpha</li><li>Beta</li><li>Gamma</li></ul></div>
    </body>
    </html>
    Still, I'm not sure if this is a safe method when it comes to forward compatibility with future versions of IE. There is no guarantee that it will be working in IE8. I think that one should wait using this kind of code until we get an IE version that supports either display: inline-block or display: table for the ul element. On the other hand when that happens, we can implement the above code as a hack for IE6 and IE7.

    Until then, I think that I would wrap the ul in a table element – or not center it.
    Last edited by koyama; 05-11-2007 at 04:56 PM.

  • #11
    Regular Coder
    Join Date
    Aug 2002
    Location
    Silicon Valley, CA
    Posts
    980
    Thanks
    0
    Thanked 0 Times in 0 Posts
    According to Quirksmode, there is also the display:compact property, but it's only reliably supported by Opera. This might be that holy grail that would allow this kind of navigation layout.

    Re: IE8, Chris Wilson (program manager for Internet Explorer) talked about HTML5 and IE8's opt-in-to-standards method, which may be an interesting read for those interested in the future of standards ("standards" meaning the way things are done, not necessarily the way a piece of paper says they should be).

    I had put all of my CSS know-how to the test trying to come up with a solution before posting here, and the most (a) reliable and (b) semantically-pure solution I could come up with was a centered, single-celled table. I might lose points with standards purists over the table, but I'd probably lose more points with my customers with a less reliable, CSS-based "let's hack the hell out of it" solution. I'll err on the side of my customers, and apologize to the purists (after having explored all reasonable avenues).

    Thanks for the tech-talk guys. I appreciate the help.


  •  

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •