Thursday, February 15, 2007

CSS Positioning IE vs Firefox/Mozilla

I've spent the past two days figuring out how to vertically align elements so that it would show up in Internet Explorer as well as Firefox. There are two methods that I'm going to post here, and they're not very pretty. But they've both worked.



In example 1, I had a set of images. Small images. I wanted to line them up vertically centered (middle) of a black strip. Here's what I wanted.




There are seven small images. I used the following CSS that worked for both IE7 and Firefox 2.0


#indexBanner {
clear: both;
width: 700px;
height: 90px;
margin: 0;
padding: 0;
line-height: 90px;
background-color: black;
text-align: center;
font-size: 90px;
}


That sets up the banner that's going to hold the images. It's 700 pixels wide and 90 pixels high. It has no margins and no padding. I've also coloured it black. Now the interesting things. The line that reads:


text-align: center;


will make sure that the images are placed in the center of that DIV. That's right. They won't be placed left-to-right as would be normal. This is because, I wanted extra black space at both ends equally, and not all of it on the right side. Got it?


The next two lines that read:


line-height: 90px;
font-size: 90px;


are there to make IE happy. Basically, I have no text in that DIV, therefore IE will not align the images to the middle of the DIV. It will align them at the top. If I had text, this would be a different issue since I could use a vertical-align: middle; statement to align the text properly to the middle of the DIV and then the image would behave properly.


It's an IE thing.


Since the default font is about 10pt, the image ends up at the top. So, I made the height of a line of text equal to the height of the DIV. In addition, I made the font size the height of the DIV. Now IE will correctly align the image to the middle (vertically) of the DIV.


But we're not done yet, the images will still align to the top since we haven't told them to go to the middle, vertically. So we have a couple more things to do. We use the following to adjust the image positioning.


*>#indexBanner {
font-size: 12pt;
}


This fixes the problem with the font for other browsers. IE doesn't understand the *> directive, so it will ignore this line completely. And then:


#indexBanner img {
margin: 0 -15px;
padding: 0;
vertical-align: middle;
}


What this does is allow the image to align vertically. The vertical-align directive only works for inline elements, not block elements. The margin for each image is moved because IE has a habit of padding extra pixels around images. And removing the padding is a good precaution.


*>#indexBanner img {
margin: 0 -1px;
}


This last directive will fix margins for other browsers (Firefox). Even though the additional space that the browser puts is little, (about 2 pixels around which means 4 pixels between pictures) they look better when they're spaced tighter.


So, in your HTML, you just put img tags for each image between the div with an ID of indexBanner.



Here's the second solution...


I actually tried to replicate this in a different case. Here's the effect that I wanted.




In this example, you see a very simple, and common, web layout. We have a logo at the top left of a bar that could potentially contain some interesting image and a menu directly below it. Creating the backdrop is easy. It's positioning the LOGO, to the left and vertically in the middle that's problematic between browsers. Here's the CSS I used to make this work in IE7 and Firefox 2.x

#header {
clear: both;
width: 650px;
height: 77px;
margin: 0;
padding: 0;
background: url('greenmarbly.jpg') repeat;
line-height: 77px;
font-size: 70px;
}

I'm sure you noticed the IE fix with the line-height and the font-size. Notice that the font-size is not the exact same height as the DIV that I'll create. I found that If I made the font-size the same width as the DIV, the DIV would actually grow bigger than 77 pixels. And only by experimenting with the font-size did I arrive at this size. Here's where the vertical alignment instructions are:

#header img {
margin-left: 20px;
vertical-align: middle;
}

Notice that the image will push itself 20 pixels away from the left margin. In Firefox, this would have worked with setting a padding width also, but IE won't respect it. And finally, the fix for the font size:

*>#header {
font-size: 10pt;
}

IE will ignore this instruction since it doesn't understand it. All other browsers will override the 70 pixel font size we gave this element earlier. And this code works for both IE and Firefox.

A couple of final points. The vertical-align instruction only works for inline elements. It does not work for block elements that's why we had to modify the img tag. Secondly, it helps if you have text in the DIV. If you have text, some of the IE work arounds are not necessary. Remember, images align themselves to text. So if there's no text, then the browser is free to do whatever it wants. So I actually cheated a bit. I put some text in the HTML in order for Firefox (which wouldn't obey these rules) to work properly. The HTML looks like this:

<div id="header">
<img src="myLogo" />
</div>

Notice the non-breaking space that I put at the end of the image declaration. This non-breaking space will be aligned properly vertically centered by Firefox and so the image will be aligned in the middle of it.

It's a strange world. I wish I didn't care about all these subtleties.

Monday, February 12, 2007

The Prayer

Dear God, I thank you that you have given me over forty years of life. I thank you for your graciousness and good health that I have been able to enjoy, and continue to enjoy. Most of all, I thank you for the loving company of good people. People who have cared for me all my life without whom I would not be able to enjoy living and continuing to learn.

Lord, I have not been the most gracious of people. In fact, I normally don't notice that you are there walking beside me. I care too much for my own pleasures and have a tendency to hurt others. Despite all this, you continue to love and watch over me and my family. No matter what the issues are and no matter how far I try to stray, you are always willing to pick me up when I fall.

Lord, I thank you for my wife and children. You alone know that I really don't deserve them and perhaps they don't deserve me. But you chose to give them to me. Perhaps this was your way of making sure that I was watched over and taken care of.

I acknowledge your presence and your wonder. I believe that you have always been there for me and continue to ensure that I don't make decisions that are too disastrous for me. For this I can never be thankful enough.

I ask that you continue to take care of me and watch over me. I know that I will continue to waver, but I understand your commitment to me and bow down to your authority over me. I also ask even more that you watch and take care of my loving wife and children. That they may never be distressed or know pain. I know that on this earthly world, that is almost an impossibility, but I would graciously ask that you teach them to understand what it is and how to deal with it. That they may emulate their mother in compassion and fortitude. That they may grow into adults who will contribute to the wealth of mankind and leave this world a better place than they found it.

In Jesus' name, your loving son who died for us all I pray.

Amen.