Floating LI's in IE 6 - html

I'm building a navigation using the simple <ul><li></li><ul> system and floating them to the left side so they appear inline. The follow code works in all browsers except IE 6.
The HTML
<div id="sandbox_container">
<div id="sandbox_modalbox">
<div>
<ul id="sandbox_modalbox_nav">
<li id="Intro" class="modal_active">Item 1</li>
<li id="Queries">Item 2</li>
</ul>
</div>
<!-- more content here -->
</div>
</div>
The CSS
#sandbox_container {
min-height: 385px;
width: 940px;
padding-bottom: 20px
}
#sandbox_modalbox {
width: 940px;
padding-top: 5px;
margin-bottom: -10px;
}
ul#sandbox_modalbox_nav {
width: 936px;
height: 52px;
margin: 0px 2px 0px 2px;
padding-top: 0px;
display: block;
}
ul#sandbox_modalbox_nav li {
height:52px;
float: left;
list-style: none;
padding: 0px;
display: block;
}
ul#sandbox_modalbox_nav li a {
padding: 12px 30px 0px 30px;
height: 52px;
display: block;
}
I also put it up on JSBin.
I understand the problem is that I must define a width for the <li> for IE to float it properly, however I would prefer these remain variable width. Is there anyway to float them properly without restricting the width?

If I am understanding the problem correctly then in browsers other than IE6 the list items appear next to each other, but in IE6 they appear on top of each other.
If this is the case, it may be because the a elements are not floated even though their containing elements are. I would just use a conditional comment and add the following for IE6 only:
ul#sandbox_modalbox_nav li a { float:left; }
Also, Neall is right on track with the whitespace issue, even if it doesn't fix your current display problem it may cause some unwanted space to appear between items later.

Not that I can think of, I can't imagine how to declare a width that can change, except by defining it in ems. If you have a content that you know is likely to be less than ten characters, then width: 11em; padding: 0.5em 1em; is likely to offer enough space for the content while still defining a width.

IE 6 has some bugs with whitespace between <li> elements. Try putting all your list items on the same line with no space between them.
Edit: On further inspection, I don't think the whitespace is your problem. Your example has a lot of extraneous styles - it's hard to tell what the problem is.

I usually solve this by setting the floated list items to width: 0 for IE6. This for one reason or other causes them to have the correct dynamic width.
You can either do this in a conditional comment:
<!--[if lte IE 6]>
<style type="text/css">ul#sandbox_modalbox_nav li { width: 0; }</style>
<![endif]-->
Or simply take advantage of IE's lack of support for CSS selectors, by setting the width to 0, and then back to the default "auto" for modern browsers:
ul#sandbox_modalbox_nav li { width: 0; }
ul#sandbox_modalbox_nav > li { width: auto; }

Related

Line-height differences between Firefox and Safari

This is driving me a bit nuts...I'm working on a site and trying to get a <ul> to render consistently across Safari (v 7.0.1) and Firefox (v 25.0.1). I've simplified the CSS and HTML just about as much as I can... there is still a difference in the distance between the "job title" (the <a> tag) and "location" (the <p> tag) of several pixels between the two browsers.
Fiddle is at http://jsfiddle.net/7BZGU/7/
Here's my code -- is there something obvious I'm doing wrong? I understand browsers render stuff differently, but I'm not sure why two modern browsers have such a difference when dealing with pretty vanilla code...
HTML
<div id="main">
<div id="current-openings">
<h3>Current Openings</h3>
<ul>
<li>
Junior Risk Reporting Analyst
<p>Chicago, IL</p>
</li>
<li>
Trading Data Analyst
<p>Houston, TX</p>
</li>
</ul>
</div>
</div>
CSS
#current-openings {
margin: 30px 0 10px 50px;
font-family: Verdana;
}
#current-openings h3 {
font-size: 25px;
}
#main ul {
margin: 15px 0 0 0;
line-height: 5px;
}
#main ul li {
list-style-type: none;
padding: 4px 0 25px 21px;
}
#main p {
font-size: 11px;
font-style: italic;
}
I did a couple things that helped the spacing be pretty close!
I removed the line height from your ul: having such a low line height will create a jumble of text once the text wraps)
set the paragraph's margin automatically by doing this:
margin: 10px 0px;
I believe what you are trying to do is align the bullet image, correct? To do this it is best to use:
background-position: 0px 10px;
Doing this eliminates the need for line height anyway!
This helps by overriding the initial paragraph styles and setting them specifically, so it works across multiple browsers.
Hope this helps!

Absolutely positioned elements not visible in ie7

Can anyone tell me why the absolutely positioned navigation buttons in the top right corner of this page are not visible in ie7, but are working fine in all other browsers (including ie8 and 9)
Thanks!
For one you are using display:inline-block which isn't properly supported by IE7 or below (sometimes it works, others not -- depends on the element and the situation).
Use display:block and float:left instead as this is more supported (however if you see my first link you can using display:inline too).
Don't forget to include overflow:hidden in the surrounding UL element either otherwise you'll get strange results due to the float.
css:
#navlist {
list-style: none;
margin: 0;
padding: 0;
display: block;
overflow: hidden;
}
#navlist li {
list-style: none;
margin: 0;
padding: 0;
display: block;
float: left;
/* your styles from before */
background-color: #F2F2F2;
border-radius: 5px 5px 5px 5px;
color: black;
height: 20px;
padding-top: 2px;
text-align: center;
width: 20px;
}
markup:
<ul id="navlist">
<li id="li1">
<a id="link1" href="#">1</a>
</li>
<li id="li2">
<a id="link2" href="#">2</a>
</li>
<li id="li3">
<a id="link3" href="#">3</a>
</li>
<li id="li4">
<a id="link4" href="#">4</a>
</li>
</ul>
useful links:
http://aaronrussell.co.uk/legacy/cross-browser-support-for-inline-block/
http://www.quirksmode.org/css/display.html#t03
update:
Another thing you could try (if the above doesn't solve the problem) is to temporarily remove your conditional commented code for IE7 - just to make certain there isn't anything in there causing a problem:
<!--[if IE 7]>
<link rel="stylesheet" type="text/css" href="css/ie7.css" />
<script type="text/javascript" src="Scripts/ie7.js"></script>
<![endif]-->
update:
Now that I've been able to actually test in IE7 the problem shows up if you enable borders - using css borders to debug is always a good idea :) The problem above is being caused by an child element pushing out the width of your parent element innerWrap. This wont affect more modern browsers, but IE7 and older always try and wrap their children no matter where they are placed or what size they are (unless you override this behaviour). Because your child element slideWrap is 3000px wide, it is causing your right positioned elements to vanish off the edge of the screen.
The following css should fix it:
#innerWrap { width: 100%; }
Use left or right properties with it in order to make them visible.

CSS to display unordered list horizontally in IE 6 and 7

I've created a template for WebSVN (see it in action here) and have worked hard to make it use web standards and validate. It looks great in most browsers, but as I feared, IE 6 and IE 7 can't quite hack it. In my case, the problem is that they refuse to render the unordered list for my navigation horizontally — they both display each <li> on a separate line and overflow the allotted vertical space. (IE 8 behaves correctly, and looks very close to Firefox and Safari, which was a pleasant surprise.)
I haven't been able to find a suitable solution on Google or SO. I would prefer a CSS fix, rather than JavaScript or something similar, although that's not entirely off the table. (Also, I don't care about the PNG transparency issue in IE 6 — it doesn't hurt readability at all, and IE 7 and 8 both handle it perfectly.)
Edit: Here are relevant snippets of HTML and CSS:
HTML
<ul id="links">
<li class="diff">Compare with Previous</li>
<li class="rev">Changes</li>
<li class="log">View Log</li>
<li class="download">Download</li>
<li class="svn">SVN</li>
<li class="rss">RSS feed</li>
</ul>
CSS
#links {
padding: 0;
margin: 0;
text-align: center;
background: url(images/bg-gray-light.png) repeat-x 0 top;
border-bottom: solid 1px #a1a5a9;
}
#links li {
font-size: 110%;
display: inline-block;
padding: 5px 5px 4px;
white-space: nowrap;
}
Edit: Now that I've found a solution, the linked page won't (shouldn't?) misbehave any more in this situation, but will continue to be publicly available.
It turns out that IE 6 and 7 don't implement inline-block as expected. Looks like I found a good solution, though... Using the following CSS works for those browsers, and preserves the correct formatting in newer browsers:
#links {
padding: 0 0 4px;
margin: 0;
text-align: center;
background: url(images/bg-gray-light.png) repeat-x 0 top;
border-bottom: solid 1px #a1a5a9;
}
#links li {
font-size: 110%;
display: inline-block;
padding: 5px 5px 0;
white-space: nowrap;
}
* html #links li {
display: inline;
}
I despise IE hacks.... I'm strongly considering including Pushup in my template.
It works fine for me in IE8 with compatability mode.
The only potential problem I can see is you don't specify margins on the list items. Try setting margin:0 and see if that helps.
Assigning float:left to the li elements should work, IIRC.

Different output for IE and the rest

For some reason this class outputs ok in IE but in Firefox the words and the lines ( | ) are not centered:
.horz_list li {
display: inline;
background-color: #CEE3F8;
border-right-style:thin;
padding-right: 4px;
padding-left: 4px;
}
This is the page for the output:
<div id="top_nav">
<ul class="horz_list">
<li>Nuevas</li>
<li>Comentarios</li>
<li class="last">Enviar</li>
</ul> <!-- ul.horz_list -->
</div> <!-- top_nav -->
If anyone know why is this, thanks.
Try changing the li's properties
.horz_list li{
display: block; /* block level */
float: left; /* float them inline to the left */
overflow: hidden; /* this will force the div to stretch to it's contained element */
background-color: #CEE3F8;
border-right-style:thin;
padding-right: 4px;
padding-left: 4px;
}
... or if you want what Ben described, the whole block centred, use
.horz_list {
margin: 0 auto;
}
Ensure it's containing block has a width, even if it's 100%.
If you're trying to get your list items to be horizontally centered, this is accomplished differently in IE vs. other browsers. Try setting margin-left:auto;margin-right;auto on your <ul>:
.horz_list {
margin-left: auto;
margin-right: auto;
}
Probably the reason for the extra spacing in Firefox is that if you set the LI as display:inline, the newline in your HTML code creates an extra space (just like if you type "lorem(newline)ipsum" the words may appear side to side in the page with a space between them).
Try, for example, to stick the <LI> tags together like this <li>....</li><li>.... and I think this will remove the unwanted spaces.
If you don't like to put it all into a single line, alex's suggestion works, but you may have to add a <div style="clear:both"></div> after the closing UL, because of floated elements.

Can you do this HTML layout without using tables?

Ok, I had a simple layout problem a week or two ago. Namely sections of a page needed a header:
+---------------------------------------------------------+
| Title Button |
+---------------------------------------------------------+
Pretty simple stuff. Thing is table hatred seems to have taken over in the Web world, which I was reminded of when I asked Why use definition lists (DL,DD,DT) tags for HTML forms instead of tables? Now the general topic of tables vs divs/CSS has previously been discussed, for example:
DIV vs Table; and
Tables instead of DIVs.
So this isn't intended to be a general discussion about CSS vs tables for layout. This is simply the solution to one problem. I tried various solutions to the above using CSS including:
Float right for the button or a div containing the button;
Position relative for the button; and
Position relative+absolute.
None of these solutions were satisfactory for different reasons. For example the relative positioning resulted in a z-index issue where my dropdown menu appeared under the content.
So I ended up going back to:
<style type="text/css">
.group-header { background-color: yellow; width: 100%; }
.group-header td { padding: 8px; }
.group-title { text-align: left; font-weight: bold; }
.group-buttons { text-align: right; }
</style>
<table class="group-header">
<tr>
<td class="group-title">Title</td>
<td class="group-buttons"><input type="button" name="Button"></td>
</tr>
</table>
And it works perfectly. It's simple, as backward compatibile as it gets (that'll work probably even on IE5) and it just works. No messing about with positioning or floats.
So can anyone do the equivalent without tables?
The requirements are:
Backwards compatible: to FF2 and IE6;
Reasonably consistent: across different browsers;
Vertically centered: the button and title are of different heights; and
Flexible: allow reasonably precise control over positioning (padding and/or margin) and styling.
On a side note, I came across a couple of interesting articles today:
Why CSS should not be used for layout; and
Tables vs CSS: CSS Trolls begone
EDIT: Let me elaborate on the float issue. This sort of works:
<html>
<head>
<title>Layout</title>
<style type="text/css">
.group-header, .group-content { width: 500px; margin: 0 auto; }
.group-header { border: 1px solid red; background: yellow; overflow: hidden; }
.group-content { border: 1px solid black; background: #DDD; }
.group-title { float: left; padding: 8px; }
.group-buttons { float: right; padding: 8px; }
</style>
</head>
<body>
<div class="group-header">
<div class="group-title">This is my title</div>
<div class="group-buttons"><input type="button" value="Collapse"></div>
</div>
<div class="group-content">
<p>And it works perfectly. It's simple, as backward compatibile as it gets (that'll work probably even on IE5) and it just works. No messing about with positioning or floats.</p>
<p>So can anyone do the equivalent without tables that is backwards compatible to at least FF2 and IE6?</p>
<p>On a side note, I came across a couple of interesting articles today:</p>
</div>
</body>
</html>
Thanks to Ant P for the overflow: hidden part (still don't get why though). Here's where the problem comes in. Say I want the title and button to be vertically centered. This is problematic because the elements are of different height. Compare this to:
<html>
<head>
<title>Layout</title>
<style type="text/css">
.group-header, .group-content { width: 500px; margin: 0 auto; }
.group-header { border: 1px solid red; background: yellow; overflow: hidden; }
.group-content { border: 1px solid black; background: #DDD; }
.group-header td { vertical-align: middle; }
.group-title { padding: 8px; }
.group-buttons { text-align: right; }
</style>
</head>
<body>
<table class="group-header">
<tr>
<td class="group-title">This is my title</td>
<td class="group-buttons"><input type="button" value="Collapse"></td>
</tr>
</table>
<div class="group-content">
<p>And it works perfectly. It's simple, as backward compatibile as it gets (that'll work probably even on IE5) and it just works. No messing about with positioning or floats.</p>
<p>So can anyone do the equivalent without tables that is backwards compatible to at least FF2 and IE6?</p>
<p>On a side note, I came across a couple of interesting articles today:</p>
</div>
</body>
</html>
which works perfectly.
There is nothing wrong with using the tools that are available to you to do the job quickly and correctly.
In this case a table worked perfectly.
I personally would have used a table for this.
I think nested tables should be avoided, things can get messy.
Just float left and right and set to clear both and you're done. No need for tables.
Edit: I know that I got a lot of upvotes for this, and I believed I was right. But there are cases where you simply need to have tables. You can try doing everything with CSS and it will work in modern browsers, but if you wish to support older ones... Not to repeat myself, here the related stack overflow thread and rant on my blog.
Edit2: Since older browsers are not that interesting anymore, I'm using Twitter bootstrap for new projects. It's great for most layout needs and does using CSS.
Float title left, float button right, and (here's the part I never knew until recently) - make the container of them both {overflow:hidden}.
That should avoid the z-index problem, anyway. If it doesn't work, and you really need the IE5 support, go ahead and use the table.
This is kind of a trick question: it looks terribly simple until you get to
Say I want the title and button to be vertically centered.
I want to state for the record that yes, vertical centring is difficult in CSS. When people post, and it seems endless on SO, "can you do X in CSS" the answer is almost always "yes" and their whinging seems unjustified. In this case, yes, that one particular thing is hard.
Someone should just edit the entire question down to "is vertical centring problematic in CSS?".
In pure CSS, a working answer will one day be to just use "display:table-cell". Unfortunately that doesn't work across current A-grade browsers, so for all that you might as well use a table if you just want to achieve the same result anyway. At least you'll be sure it works far enough into the past.
Honestly, just use a table if it's easier. It won't hurt.
If the semantics and accessibility of the table element really matter to you, there is a working draft for making your table non-semantic:
http://www.w3.org/TR/wai-aria/#presentation
I think this requires a special DTD beyond XHTML 1.1, which would just stir up the whole text/html vs application/xml debate, so let's not go there.
So, on to your unresolved CSS problem...
To vertically align two elements on their center: it can be done a few different ways, with some obtuse CSS hackery.
If you can fit within the following constraints, then there is a relatively simple way:
The height of the two elements is fixed.
The height of the container is fixed.
The elements will be narrow enough not to overlap (or can be set to a fixed width).
Then you can use absolute positioning with negative margins:
.group-header { height: 50px; position: relative; }
.group-title, .group-buttons { position: absolute; top: 50%; }
# Assuming the height of .group-title is a known 34px
.group-title { left: 0; margin-top: -17px; }
# Assuming the height of .group-buttons is a known 38px
.group-buttons { right: 0; margin-top: -19px; }
But this is pointless in most situations... If you already know the height of the elements, then you can just use floats and add enough margin to position them as needed.
Here is another method which uses the text baseline to vertically align the two columns as inline blocks. The drawback here is that you need to set fixed widths for the columns to fill out the width from the left edge. Because we need to keep the elements locked to a text baseline, we can't just use float:right for the second column. (Instead, we have to make the first column wide enough to push it over.)
<html>
<head>
<title>Layout</title>
<style type="text/css">
.group-header, .group-content { width: 500px; margin: 0 auto; }
.group-header { border: 1px solid red; background: yellow; }
.valign { display: inline-block; vertical-align: middle; }
.group-content { border: 1px solid black; background: #DDD; }
.group-title { padding: 8px; width: 384px; }
.group-buttons { padding: 8px; width: 84px; text-align: right; }
</style>
<!--[if lt IE 8]>
<style type="text/css">
.valign { display: inline; margin-top: -2px; padding-top: 1px; }
</style>
<![endif]-->
</head>
<body>
<div class="group-header">
<div class="valign">
<div class="group-title">This is my title.</div>
</div><!-- avoid whitespace between these! --><div class="valign">
<div class="group-buttons"><input type="button" value="Collapse"></div>
</div>
</div>
<div class="group-content">
<p>And it works perfectly, but mind the hacks.</p>
</div>
</body>
</html>
The HTML: We add .valign wrappers around each column. (Give them a more "semantic" name if it makes you happier.) These need to be kept without whitespace in between or else text spaces will push them apart. (I know it sucks, but that's what you get for being "pure" with the markup and separating it from the presentation layer... Ha!)
The CSS: We use vertical-align:middle to line up the blocks to the text baseline of the group-header element. The different heights of each block will stay vertically centered and push out the height of their container. The widths of the elements need to be calculated to fit the width. Here, they are 400 and 100, minus their horizontal padding.
The IE fixes: Internet Explorer only displays inline-block for natively-inline elements (e.g. span, not div). But, if we give the div hasLayout and then display it inline, it will behave just like inline-block. The margin adjustment is to fix a 1px gap at the top (try adding background colors to the .group-title to see).
I would recommend not using a table in this instance, because that is not tabular data; it's purely presentational to have the button located at the far right. This is what I'd do to duplicate your table structure (change to a different H# to suit where you are in your site's hierarchy):
<style>
.group-header { background: yellow; zoom: 1; padding: 8px; }
.group-header:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; }
/* set width appropriately to allow room for button */
.group-header h3 { float: left; width: 300px; }
/* set line-height or margins to align with h3 baseline or middle */
.group-header input { float: right; }
</style>
<div class="group-header">
<h3>This is my title</h3>
<input type="button" value="Collapse"/>
</div>
If you want true vertical alignment in the middle (ie, if the text wraps the button is still middle-aligned with respect to both lines of text), then you either need to do a table or work something with position: absolute and margins. You can add position: relative to your drop-down menu (or more likely its parent) in order to pull it into the same ordering level as the buttons, allowing you to bump it above them with z-index, if it comes to that.
Note that you don't need width: 100% on the div because it's a block-level element, and zoom: 1 makes the div behave like it has a clearfix in IE (other browsers pick up the actual clearfix). You also don't need all those extraneous classes if you're targeting things a bit more specifically, although you might need a wrapper div or span on the button to make positioning easier.
Do a double float in a div and use the clearfix. http://www.webtoolkit.info/css-clearfix.html Do you have any padding/margin restrictions?
<div class="clearfix">
<div style="float:left">Title</div>
<input type="button" value="Button" style="float:right" />
</div>
<div class="group-header">
<input type="button" name="Button" value="Button" style="float:right" />
<span>Title</span>
</div>
I've chose to use Flexbox, because it made things so much easier.
You basically need to go to the parent of the children you want to align and add display:box (prefixed of course). To make them sit in the sides, use justify-content. Space between is the right thing when you have elements which need to be aligned to the end, like in this case (see link)...
Then the vertical align issue. Because I made the parent of the two elements, you want to align a Flexbox. It's easy now to use align-items: center.
Then I added the styles you wanted before, removed the float from the title and button in the header and added a padding:
.group-header, .group-content {
width: 500px;
margin: 0 auto;
}
.group-header{
border: 1px solid red;
background: yellow;
overflow: hidden;
display: -webkit-box;
display: -moz-box;
display: box;
display: -webkit-flex;
display: -moz-flex;
display: -ms-flexbox;
display: flex;
-webkit-justify-content: space-between;
-moz-justify-content: space-between;
-ms-justify-content: space-between;
-o-justify-content: space-between;
justify-content: space-between;
webkit-align-items: center;
-moz-align-items: center;
-ms-align-items: center;
-o-align-items: center;
align-items: center;
padding: 8px 0;
}
.group-content{
border: 1px solid black;
background: #DDD;
}
.group-title {
padding-left: 8px;
}
.group-buttons {
padding-right: 8px
}
See Demo
I agree that one should really only use tables for tabular data, for the simple reason that tables don't show until they're finished loading (no matter how fast that is; it's slower that the CSS method). I do, however, feel that this is the simplest and most elegant solution:
<html>
<head>
<title>stack header</title>
<style type="text/css">
#stackheader {
background-color: #666;
color: #FFF;
width: 410px;
height: 50px;
}
#title {
color: #FFF;
float: left;
padding: 15px 0 0 15px;
}
#button {
color: #FFF;
float: right;
padding: 15px 15px 0 0;
}
</style>
</head>
<body>
<div id="stackheader">
<div id="title">Title</div>
<div id="button">Button</div>
</div>
</body>
</html>
The button function and any extra detail can be styled from this basic form. Apologies for the bad tags.