Put advanced pseudo class style definitions on their own line

In Internet Explorer 8, if you list a couple of style declarations together and a pseudo class it doesn’t recognize is in that list, it won’t apply the styles from the declarations it does understand. For example:

td:last-child, td.last{border-right:1px solid gray}

In the above example, even if you have a td with a class of last assigned to it, IE8 won’t apply the border style because it chokes on td:last-child. You should do this instead:

td:last-child{border-right:1px solid gray}
td.last{border-right:1px solid gray}

However, it appears that within style declarations, when defining properties, IE will just skip over properties/values it doesn’t recognize. Which is good because then we can mix in all those proprietary -moz, -webkit, etc.declarations.

So, if you are running into unexpected results, this is one more trick to add to your bag.

More IE and inline-block

You didn’t think one posting about IE and inline-block was going to handle all the issues, did you? Did you? The issue I am going to talk about in this post is an oldy but a goody.

Display:inline-block is only supported in IE6 & 7 on elements that are natively inline. Say what?

You’ll find if you add that property to a block element, assuming your element will nicely shrinkwrap, you will be disappointed. The fix is to use display:inline;zoom:1;. Then you will get an element that acts like an inline block.

Source article for this information


IE6 Negative Margin Bug

Negative margins can be really useful for offsetting content from it’s container.  I find them useful when I need to indent most content from the edge of a container but allow certain items to go edge to edge.

But, alas, in certain cases Internet Explorer 6 cuts off the content that is outside the container of the element when that container has layout.

The solution is to also set layout on the element you are trying to offset.  My favorite way of setting hasLayout on an element is to use zoom:1.  It has NO side effects.

According to this article, you also should set position:relative to keep from triggering another bug.

An example always helps:

/* this is our list container, with hasLayout set */

/* this is our list item, with fixes */

Internet Explorer and Opacity

To change the opacity of an item, we can use this CSS declaration:

opacity:0.25; /*the css standard*/
filter:alpha(opacity=25); /*sets opacity in IE*/

Hmmm. IE doesn’t support the CSS standard. Quelle surprise!

Here’s something else. If the element you are trying to make transparent doesn’t have layout in IE, the opacity won’t be set. The solution? Put zoom:1 on the element.

And I haven’t figured this completely out in IE8 standards mode, but I was trying to set opacity on an image wrapped in a link by assigning the opacity to the link itself. Should be inherited, I thought, like in IE8’s predecessors. But it wasn’t. I wound up getting it to work by assigning opacity directly to the image instead of the link.

So in summary, to get opacity to work in Internet Explorer versions 6 – 8:

  • Use filter:alpha(opacity=x), where x is a number from 0 to 100
  • place zoom:1 on the element if needed
  • assign the opacity directly to an image

Negative Margins and IE (prior to version 8)

I haven’t written a post in awhile. But I just came across one of those bugs that kept me poking around the internet and ultimately coming up with some magic combination of styles that happens when you get desperate and start just saying “maybe this will work.” I finally came across the combination that did.

And I always have to document this stuff because 3 months down the road when I bump into it again I have NO idea what I did to fix it.

So, here’s the issue. With negative left and right margins and no width on an element, you can stretch the width of an element. I find this comes in handy when I want to put padding on a div, but there is an occasional element that needs to stretch to the edges of that div. And so I came across a need to stretch an element. Did this:

margin:0 -10px;
padding:0 10px;
border:1px solid gray

The reason I used padding that mirrored the negative margin was that I still wanted the text indented, I just wanted the border to stretch to the edges of the parent div. But you probably already got that.

It looked so beautiful. Until I opened it up in IE6. Well, no surprise there. And then I opened it up in IE7. Broken. Wah? This is the browser that’s supposed to be better. IE8, et tu? Nope, actually, IE8 got it right. There is hope for the future!

I started poking around the web. Found some good articles on this stuff which I’ll actually paste into the bottom of this post. Tried everything they said. Found something about sometimes display:inline will fix IE bugs. We don’t know why, the article said, it just does. I had already tried display:inline-block which also fixes a lot of things but that hadn’t worked. So I tried the display:inline. It actually fixed the indent! However, my border now only stretched the width of the text. Okay, what if I add width:100%, I thought? It might not work because I’m stretching beyond the 100%. But it was worth a shot. And it was the magic combination. I did wind up qualifying it to only IE6 and IE7 using the technique of assigning a class to the body tag via conditional comments that I then use to qualify the styles. I like that technique because it keeps the hacks in the same stylesheet as the rest of the styles.

So, again, here is the fix:

.ie6 .myStretchedElement, .ie7 .myStretchedElement{

It also works for right-to-left display.

Here are those links I promised:

  1. The Definitive Guide to Using Negative Margins (Smashing Magazine)
  2. CSS Float Theory: Things You Should Know (Smashing Magazine)
  3. The Positive Side of Negative Margins

IE 6 min-height fix

Oh I love this. I was all set to use a css expression to fix a min-height bug, and went searching for that code, cause it’s not something most people can remember off the top of their head. And found this, instead.

It’s much less expensive of an operation and WAAAAAAAAAAYYYYYYYYY easier to remember. You do this:

height:auto !important;

You know, in trying to wrap my brain around this, I’m still not sure why it works. Why wouldn’t the auto always kick in? But it doesn’t. It kicks in when the actual height of the element is is greater than the height you set for the min height. Go figure. Sometimes IE’s idiosyncrasies work to our advantage.

It’s called the Min-Height Fast Hack. I love that name.

I thought I’d try the same thing for min-width of my page, but it doesn’t work since the width of the page can be fluid.

CSS programming for right-to-left languages

I am far from an expert in RTL languages. But I do have some experiential knowledge to share in this area from having to make CSS layouts work across browsers in RTL mode. So, if you have to support Hebrew or Arabic, here is what you do.

1. Create a separate RTL version of your stylesheet that has direction:rtl on the body tag. This will be inherited by all the elements. [update: according to the W3C, you should put dir=”rtl” on the html tag rather than direction:rtl in the css of the body tag.]

2. Flip your left/right values in the stylesheet.
If you declare something like margin-left, flip it to margin-right or vice versa.
If you use shortcut notation for margins and padding, flip the left and right values.
In your background positions, swap the left/right values. This gets a little tricky if you have used a pixel offset for a left-aligned element. I have found you can use percentages to get them off of the right-hand edge. So, background-position:4px center becomes background-position:97% center. You’ll have to play with this depending on the width of your UI element.
Seems fairly simple, doesn’t it? Now for the gotchas!

First, Firefox 2:
To deal with a Firefox 2 bug in columnar layouts where the center column is flexible width and the left and/or right columns are floated, put margin-right:auto;margin-left:auto on the center column.

And now, IE (both of em, not just IE 6):
To deal with an IE bug where the UI shifts if you maximize/restore the page, make sure you put position:relative on parent elements of children with position set to relative. More here.

To deal with IE RTL layout issues with floating elements, set direction:rtl on the text elements only (if this is possible). You will need to set direction:ltr on the parent elements to reset the direction:rtl inherited from the body tag. Then set direction:rtl on the text child elements. More here.

IE behaves better in RTL languages when widths are set on elements.

You can always try adding zoom:1 (triggers hasLayout in IE) or setting display of an element to inline-block (two techniques which solve a lot of IE display issues).

If you can’t do some of the techniques described above, you can try converting your complicated UI element to a table. IE usually flips tables nicely. But don’t go here first or you’ll wind up with a UI full of layout tables.

Hope this helps someone else trying to adapt their UI to right-to-left languages.

And here’s a good tutorial for more on this subject. Straight from the W3C’s mouth.