Welcome to AspAdvice Sign in | Join | Help

.Net Discoveries

An attempt to pass along some answers I have discovered in my .Net coding.
More Page Layout Snafu's or More Stupid CSS Tricks

Prologue

I wanted to document a couple new CSS snafu's that I found in the midst of my work. If you've ever used CSS, you'll realize what a pain it can get to be if you have a lot of nested stuff. The website redesign I was (the company is opting to change their name, logo, color scheme, the works.. so I stopped redesigning) contains a multitude of nested elements. I've found it quite frustrating trying to get the CSS to display the same in both IE and in Firefox (and for that matter, IE6 and IE7 don't always agree). In fact, most of the snafu's here were found as a result of attempting to achieve cross-browser compliance. So with no further ado, here are some snafu's and how to work around them.

Problem

Creating and working with CSS in Visual Studio is getting easier, it tests well in IE, but then if you turn around and test it in Firefox, it doesn't work. Most of what I'm sharing worked in one but not the other, so I had to find a work around for the CSS so it would work in both. (as a side note, I can't wait for VS '08 and their improved CSS features!)

Solution

We'll actually build on one file for most of this post so let's get started...

How Do I Horizontally Center in Firefox?

Ok for this one, create an HTML file and add the following to the header section:

<style type="text/css">
   body
   {
   }
   .header
   {
      border: solid 1px red;
      height: 100px;
      width: 607px;
   }
</style>

Ok, now add a DIV section to the body as follows:

<div class="header">I want this section centered</div>

Now bring it up in both IE and FireFox. Notice that our red DIV section is NOT centered. How do we go about centering it horizontally? Let's try the wrong way first. Add the following to your body section of the CSS:

text-align: center;

Now refresh IE an see what happens. IE works like a charm. Notice that all text has been centered, AND the DIV as well. Now refresh it in FireFox. What happens? All the text centers, but because the DIV isn't text, it doesn't center. So how to do it? It took me a while, but I found an article that told me how to do it. There is apparently something in the specifications for CSS that says margins should fill up all the remaining space in the enclosing element (in this case, the body is the enclosing element to our DIV). So in the DIV's style section, add another line as follows:

margin: auto;

Now refresh both IE and FireFox. Works in both. What about the text-align:center in the body? Well, you can leave it if you want because older IE versions will use the text-align. That is if you are ok with the text in your body being centered. This margin: auto method can also center other elements in your code. Let's say you wanted to center a table in a span, how do you horizontally center, again use the margin: auto on your table and it'll center.

Set a Height, But Let it Grow

Another issue that I ran into was that I created a section, and it needed to be AT LEAST a certain height, but also needed to allow it to automatically grow longer if there were more text in it. Till this project, I'd done nearly all my development in IE and it works by default there, but FireFox isn't quite as straight forward. Let's continue with our current file and keep adding to it. In your DIV section, add a span section and some text as follows:

<span class="leftCol">
   I want to<br />
   put a lot of<br />
   text here<br />
   so that it <br />
   will go <br />
   down past<br />
   the bottom <br />
   of the <br />
   enclosing <br />
   container.
</span>

(yes, leave the unused class designation for now, we'll use it later) Ok, now refresh both IE and FireFox. What happens? Well, in IE your DIV grows but FireFox, it just stays the same and the text flows right out of it. How to fix it? Well, let's try a couple of things that are a little less effective on our way to the right answer. First, lets specify that we want the height to adjust automatically. So at the end of your .header style definition, add:

height: auto;

and refresh in both browsers. Now they're both appear to be working, but take the text out of your span, save and refresh. It's not really working as desired, it doesn't retain it's minimum height. Since we have two height: statements in our definition, the last one wins. So how do we maintain a minimum height, but let it grow? There is a min-height: CSS attribute that we can use, so replace your height: auto with it as follows:

min-height: 100px;

Now let's see what happens when we refresh. IE's working fine, but FireFox still isn't growing. Pretty much we've just come back to where we were before we started. Ok, lets think it through just a little from the specifications point of view (I don't know em, I just read about em). We need a minimum height, but min-height doesn't work in IE, it does in FireFox though. If we specify to do auto with the height, then both browsers will shrink too small. If I put a height in, IE will grow but FireFox won't. How can we combine all three to make it work? We start with a minimum height. Then we tell FireFox that we want the height to be auto. We can just tell IE a height and it'll take care of itself. Ok, so take out the stuff below your min-height statement, add the following 2 lines:

height: auto !important;
height: 100px;

Now refresh both and see what happens, now take the text out of your span and see what happens. Both are working as we want. How did we do it? It works like this. Since CSS is read from the top down, whatever is last is what's used. So we tell the browser that we need a min-height, Firefox complies, IE will ignore it. Then we tell the browser, that we want the height to be automatic (but with a minimum from the min-height line) AND that we want it to be the most important height statement (using the !important statement). FireFox says, ok, min-height and it's important to be auto height. IE, ignores the !important statement and the min-height statement and just sees the next line and sets its height. FireFox downplays the next line because of the !important statement, and all's well (note: IE7 seems to use the min-height statement, but IE6 and below will disregard it).

Basically, we're getting IE6 to do it's default behavior, the only line that really gets used is the height:auto. With Firefox, we're telling it to set a min-height, then telling it a priority on height statements. Simple and elegent, you just have to know how to do it. There are some pretty complex CSS hacks to get around this out there, but I liked this one for a number of reasons. I read the article and it made sense to me to use 3 lines of CSS rather than a lot of other html elements to force what we need. Anyhow, its clean and it works.

My Float's Sticking Out

I used floats in my layout so that I could get the HTML code to put certain text ahead of others (for search engine optimization purposes), but display the content in a different order (see my previous post's section on using a float to change the html text flow). Well, then I ran into the issue that my floated section didn't cause the floated element's containing element to automatically grow and encapsulate the entire floated element. In our example, we'll continue with what we have. The header DIV may represent a background to a section, and the SPAN inside the text that may be inside it (in real life I had a DIV as a background (with color) and the SPANs inside with text, that were floated as I wanted them. The Div should grow with the text so that the background extended to the end of the text.). But in FireFox, the background didn't extend down past the end of the floated internal element.

To begin, we need to add some stuff to our page. Add two more spans inside our DIV as follows:

<span class="midCol">b</span>
<span class="rightCol">c</span>

Now, we also need to add style definitions for our column spans, so add the following to the style section:

.leftCol
{
   width: 200px;
   border: solid 1px green;
   float: right;
   display: inline-block;
   position: relative;
}
.rightCol
{
   width: 200px;
   border: solid 1px green;
   float: left;
   display: inline-block;
   position: relative;
}
.midCol
{
   width: 200px;
   border: solid 1px green;
   float: right;
   display: inline-block;
   position: relative;
}

Now, refresh and see what I'm talking about, IE actually has our red DIV section enlarge to fit the floated SPAN, but FireFox does not. What's the deal? Well, actually Firefox is doing it the way it's supposed to work. If it didn't work this way, then things wouldn't wrap around stuff like pictures like they should (again I read it in an article). The question though, is how to fix it. The simple solution lies in adding something in the flow AFTER the floated element that isn't floating, something that the parent element WILL have to wrap around. So add another DIV after all our SPANS as follows:

<div class="floatHack"></div>

and add another section to our style section as follows:

.floatHack
{
}

Notice that the floatHack DIV is empty, it doesn't need any content, we just need something invisible to force the flow differently. So what do we do to fix the problem. Well, we need an item that ISN'T affected BY the floats to be placed AFTER the floats. To do that, we use the clear: CSS attribute. We can have it clear right, left or both floats. In our example, it's the right float that's causing the problem, so we can choose either right or both, I'll choose both. Add the following to your .floatHack style definition:

clear: both;

Now refresh and see what happens. Viola, our problem fixed. As a side note, you can use any block level element to do this hack. Now, let me give you a little side note of warning, though. Add the following to our leftCol style definition and see what happens:

top: 40px;

Refresh and see what happens, our container doesn't grow to fit. What happened? Well, we're moving our float out of it's position. Workaround? I don't have one.

Turn Off Double Spacing in an HTML List

Ok one more then I'll call it quits. Have you ever noticed that when you create a list in HTML using the UL tag, that it puts a space between the header and the first item (and one after the list for that matter)? How do we get rid of that unsightly annoyance?

This exercise doesn't continue where we left off, so you may want to create a new html file for it. Create a style section, but don't put any definitions in it. Then in the body of the HTML, create a UL as follows:

My unordered list
<ul>
   <li>first item</li>
   <li>second item</li>
   <li>etc.</li>
</ul>
The line after

Pretty standard, and when we render it in the browser, it puts a space between the title and the first item, and a space between the last item and the next line of text. To get rid of it, I'm using some CSS from another article that I read. All we need to do is turn off the top and bottom margins for the UL element. So, add the following to your style section in the header:

ul
{
   margin-top: 0px;
   margin-bottom: 0px;
}

Now refresh both browsers and we've eliminated the nasty spaces. We can now put spaces where WE want them instead of where the HTML wants them.

Epilogue

Here's what I found. Test your web apps in IE6, IE7 and FireFox. They are all different animals, and will all display differently. Then try not to pull your hair out trying to fix it when they don't exactly work the same.

Sponsor
Posted: Thursday, July 26, 2007 11:12 AM by Yougotiger
Filed under:

Comments

foreachdev said:

I enjoyed your css article. Thanks for posting
# July 27, 2007 8:44 AM
Leave a Comment

(required) 

(required) 

(optional)

(required) 

Enter the code you see below

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS