Monday, February 23, 2009

Damn IE7 and inline-block

Damn you Microsoft damn you to hell you are just seriously ticking me off now. Still working on this charity website and I've set the menu bar up using list elements, this is a neat way of doing things as they lend themselves well to orientation for non-visual browsers as well as being easy to shift around. However by default they line up vertically one atop another, if you want them to line up horizontally you can do one of two things - you can either float them or you can make them inline.

Float seems to be the first option of many coders, but it comes with a price - the element you're floating is removed from the default ordering system it's 'floated' over the top of them. So if you want more than one element side-by-side you have to float them all and to keep them straight enclose them in their own container; not pretty.

The other better method is to use make them inline, inline is simply what you're seeing now as you read, each word naturally follows the other in a horizontal line; however the reason most people use float is because an inline element grows and shrinks according to its contents, fine if that's what you want, not good if you want to create a fixed height/width 'block'.

So the solution is to use a new property called inline-block, this has all the advantages of the inline property while allowing you to apply block properties to it - yay!

Except IE7 doesn't understand inline-block properly.

It's to do with a hidden property called hasLayout the mention of which can cause seasoned web developers to tear their hair out, see you can't set it explicitly no such thing as hasLayout: on; it's set when other properties get applied and surprise surprise it's an IE only creation.

So to call this elusive hasLayout you need to set a property of "zoom:1;" to any element you want to work correctly. It doesn't do anything; if you set it to 2 it'll make things twice as large, but 1 nowt.

So that's that - nope, see if you set hasLayout as above for an element that is by default a block and then try to make it an inline-block IE7 still ignores it. So you need to add in one extra little snippet "*display: inline;" the star is important as every other correct browser will ignore that item, but dumb-old Internet Explorer won't and amusingly despite setting it to plain old inline it'll happily apply block properties to it too.

So is that all - still nope, because although that fixes IE7 it won't fix IE6 which requires a height be set to the element and that's added by "_height: 30px;" yep another funny character in front of the property this time one that IE7 and proper browsers ignore yet IE6 will apply.

So to get inline-block working for any element in Internet Explorer simply add "zoom:1; *display: inline; _height: 30px;" to the end of that elements style oh and yes change the height to whatever you need.

145 comments:

Tuopillinen (Jouni Koskinen) said...

Thank you so much! I was ready to mailbomb MS offices.

FlipC said...

De nada, to an extent this was an aide-mémoire so I won't tear my hair out everytime I come across it.

Coincidently I've just added an a similar memo about a:hover for IE and CSS image-swapping that you might also find useful.

Anonymous said...

Thanks really help me out just lost too many hours messing with inline-block and IE

Axel said...

thank you thank you thank you thank you thank you thank you !!!

Just wasted more than half a day in VisualStudio 2005 because I couldn't believe you can't achieve this without tables. IE is really some crock of sh!t.

Anonymous said...

I think you just saved me pulling the rest of my hair out!

Thank you for posting this info it was a great help.

Dear Microsft, please kill off IE and I do mean all versions, and never enter the marketplace with another browser EVER!

Ryan Mitchell said...

Just to throw something in there, you would be better targeting IE6 and 7 with conditional comments than the hacks. Also my understanding is that height and width are interchangeable.

FlipC said...

Ryan - To work your comment backwards.

Makes sense, I can understand if height and width were interchangeable they're both structural components. Thanks for that point.

As for conditional comments... if you find that a ton of your CSS is beginning with * or _ then stuffing in a <!--[if IE]>ie-only stylesheet<![endif]--> makes sense. For the odd 'Just bloody work' the hassle of maintaining two, three or more stylesheets which are essentially duplicating and overriding styles is just too much hassle from my point of view. Sure your CSS won't validate, but who gives a [beep] what the W3C thinks if it works?

One important fact though is that conditional comments are the only approved method of discriminating IE versions. So when IE8 hits with all its new bugs (yeah like it's not going to have any) using these may become the only way to target that version directly, as such adding in specific IE6 and IE7 conditional comments simply becomes something to tag on at the same time; so it's definitely something to consider.

Butter said...

Thx Dude. Really works. But I still don`t get the haslayout thing.

FlipC said...

hasLayout is an internal switch for IE that alters or allows other parameters to function.

Think of it as not being able to turn on the foglights for your car unless the main headlights are also on, but without having a switch for the headlights ;-)

Dan Costalis said...

You sir, have saved my life.

I thank you, and viniki.com thanks you.

Anonymous said...

/hug

Anonymous said...

Immense! This worked for me. THANK YOU.

Anonymous said...

Thanks a ton, really helped me out...

Mark Schlaudraff (SlawDog) said...

Hey Mad Ranter... Thank you for putting a solution out that everyone can understand and works.

I have been looking for a solution for the past 4 hours and I find your blog on it and bang it works.

Thank you again.

Suzanne said...

Kudos for a way better explanation than some of these other sites. The #1 result for this Google search reads like a bunch of blah blah blah. You get right to the solution - much appreciated!

Max van der Stam said...

Thanks a lot man, I'm sure that there are webdevelopers all over the world who wait for the day where people stop using IE. Until that day comes, we're stuck with using hacks like these so websites work in a normal fashion.

Let's hope that IE9 will be standard compliant, like all of the other browsers on the market. Damn you M$!

Again, thanks a bunch!

FlipC said...

Da nada, I find it amusing that what essentially was a reminder for me is the most visited page on my blog.

As for IE9 well I gotta say that we'll still get the same calls that we are since IE8's release "A lot of people still use IE7 so make sure it works in that"

Aaaahhhhhh!

Anonymous said...

Thanks, you've saved me a bunch of time and hair.

chyro said...

Thanks a million. I had the problem before, and solved it in this exact same way, but whadaryagonado, I can't seem to remember every single IE bug and the matching solution. You ended my bug-solving session, and for that I thank you.
Onwards to the next bug-solving!

Anonymous said...

Another very happy developer! Thank you very much. Please M$, stop it! I will be happily to tell customers to us IE if it was standard compliant, and generally a good product.

I work very hard to convince clients to use use anything else. You will loose. Just give up.

FlipC said...

Yesterday I had a client asking me why a footer div was now so tall on the page; it looked fine in Firefox/Opera/Safari but not IE6/7. Turns out I'd altered some other attribute on its container and it had ballsed it up, just for IE mind.

IE8 handled it though so they have gotten better, but that has it's own kinks.

Alex said...

Dude, awesome fix. Don't know how you figured it out, but god bless you.

sander1 said...

Thank you so much! I've read a couple of other websites covering this topic, but yours is simply the best and easiest to understand!

Unknown said...

The problem's not MS or IE, folks... it's users that won't upgrade. People who sit on their Pentium III running Windows 2000 with IE6 and expecting that everything is going to work fine for them. Personally, I just ignore them. I build pages for IE7+, FF3+, and Chrome (and sometimes I test on Opera and Safari) - but I don't go any lower than that. People coming in on an unsupported browser are redirected to a series of upgrade links. When IE9 launches, I'll add IE7 to the list of unsupported browsers. You can't coddle these people.

FlipC said...

No at times it's companies that sit on their Pentium III's running Windows 2000 with IE6 because that's what their internal software works on. As it still works why should they fork out to on a new OS and a new computer to run it at a comparable speed just to get rounded corners?

It's fine to say "You should upgrade, I'm not supporting you", but if you're developing a business site and the MD is still running IE6 you're going to get a phone call asking why it doesn't 'work'. Try using that line on them.

Anonymous said...

thanks!

Anonymous said...

Just one more THANK YOU from Dublin!

Anonymous said...

Nice work!

Unknown said...

Wow, thank you so much for explaining this! I was at my wits end, and this fix, while unintuitive (on IE's part, not yours) was very simple and worked perfectly. Thanks!

Richard Uren said...

Dude ! That is awesome ! Thanks for posting.

Glen Appleton said...

Nice work! I know you keep hearing this same comment, but you just saved me hours.

Sir, you ROCK!

Klementz said...

Thanks, that helped me out a lot.

Tom James said...

Great little hack, definitely saved me some time there, Thanks!!

Tom

Anonymous said...

A+ Great tips.

Anonymous said...

Super man comes to the rescue

Thanks

Craig said...

Thank you... You just saved me hours of debugging.

Anonymous said...

Thanks a bunch... I'm gonna spread the word! :)

Beth said...

Coming really late to the party, but you just saved me from pulling my hair out. Thanks!!!!!

Orphi said...

At 38 comments, I nominate this for the award of “most popular post in your entire blog”. :-P

FlipC said...

Roughly a third of all my traffic for this month, glad people find it useful even if I did only put it up to remind myself what's going on :-)

Looking at it now there's a shorter method that fixes the problem but it might only work for IE7 not 6 or 5. It seems "display: inline-block" triggers hasLayout in IE despite not being recognised, but that in turns makes "display: inline" accept block properties.

So in theory display: inline; display: inline-block" should make all the proper browsers work while making IE7 also behave properly. Not tested yet though.

Orphi said...

And Tchaikovsky hated the Nutcracker Suite, which is practically the single most popular thing he ever wrote! ;-)

Anonymous said...

Indeed, thank you so much for this concise explanation of IE7's stupid shortcomings. I'll add this to a separate stylesheet for IE browsers. Damn M$.

Anonymous said...

Thank you. that has saved me an awful lot of bother!

Merayen said...

Thank you for solving this ultradumb problem with IE6-7. Thank you!

Okko said...

Thanks for this very clear and useful tips.
It save my day !

ChrisWalker said...

Thanks so much for this. I used this link in my Bugzilla resolution for a reported problem. Your first sentence says it all.

Anonymous said...

the * hack doesn't seem to work on IE7 anymore

FlipC said...

Ah be careful there's a "Star Hack" and a "Star HTML hack".

It all depends on where you put the *. Put it in front of an element such as * p{} and it'll only be read by IE4-6. Put it in front of a property p{ *zoom:1} and it'll only be read by IE4-7.

I will check, but the posts here suggest it still works.

Rui Figueiredo said...

Thank you! It worked like a charm.

You're definitely a life saver!

Unknown said...

Thank you so much. Both for the solution, and for explaining it so well.

Andrew said...

Thanks for the post. Well over a year later and still helping people. Appreciate it.

Alain Juteau said...

Great post, it summarize well the situation and all possible outcomes

Anonymous said...

Awesome thank you. You really helped out.

Mehdi said...

Thanks man

David said...

Thanks a lot for this tip.
"zoom:1; *display: inline;" solved my problem nicely.

m(__)m

David

Andy Stewart said...

Thank you! You saved me lots of time.

Anonymous said...

i love u

streetfoodie said...

Thank you!

Anonymous said...

Thanks man, works great!

Peter said...

Dude, you are my hero! ;)

Anonymous said...

wow it works! the world would be a better place w/o ie

vitamin said...

yet another thanks. :) What is the deal with IE!? I wonder if they sit back and enjoy the controversy that surrounds them...

What a waste of time! Pray that Mozilla, Chrome, Safari and alike, take over!

cheers!

Andy Thornton said...

Genius! Thank you!

carl87gt said...

Worked like a charm - thanks!

Jasper said...

Thanks a billion!

Silvia said...

Thank you a million! Complete novice to web coding, trying to update my son's pre-school website rescuing it from the depths of Dreamweaver tables for layout, decided to go CSS, and you just sorted the main problem I had with making the layout work cross-browser for me: THANKS!

IE is evil, IE must die.

Anonymous said...

YTMND!

herbudaman said...

Thanks Man,

Saved me a ton of time with this fix!

Ppvl007 said...

I'm surpised that this had helped me so much for my own company. Thank you!

~ Ppvl007

AFine said...

I'm still confused. My horizontal navigation bar is vertical right now in IE7 and IE6. Can someone take a look at let me know exactly what to do to make it vertical? Here is the site: http://www.slimekids.com/

FlipC said...

@AFine - try setting a width for your #nav element.

Floated elements are taken off the normal drawing procedure. With your set of floated li elements IE only draws the containing box wide enough to accommodate just the one; so all the others stack rather than expand the box.

Anonymous said...

*display:inline; - Didn't know about the *, worked perfectly! Cheers :)

Unknown said...

Thanks. Apparently setting a width for the #nav element was all I had to do. For whatever reason, I didn't have to bother with all of that display: inline-block, display: inline stuff. I set the width long enough to make it horizontal in IE7, and I think I could've set it a little longer to make IE6 work as well, but I'm not sure if it's worth making the effort for people who still use IE6.

FlipC said...

@Andy - That's because you're using floated elements; my piece was for those who wanted to use inline-blocks in IE :-)

There's nothing wrong with using floats, they can just be a little more restrictive and, as you've discovered, IE can still behave in unexpected ways when using them.

Alex said...

You are a King! Thank you very match!

Bojan said...

Thanks a thousand times!!! Worked great for me!

impelmedia said...

You're amazing!! Thank you so much!

monkeydeus said...

I came across this issue secondary to the real one I was debugging. When you are using ie8 in the enterprise, by default all *intra*net sites are rendered with document mode ie7 standards. So after getting THAT fixed, it prompted me to wonder WTF with display-inline in ie7. Thanks a lot for this.

FlipC said...

@MonkeyDeus - if I recall correctly in an enterprise environment this can be changed via a group policy... tum te tum... ah here it is "Turn on Internet Explorer Standards Mode for Local Intranet" - "This setting disables Compatibility View (enables Standards Mode) for all intranet websites."

Anonymous said...

I LOVE YOU!!! god i hate internet explorer.

Bhupendra mankar said...

Thanks.. Its working.. I spend my whole day... but this soln worked.. :)

Tee Jay said...

Hey guys
I have this template on my site at pornporn.ca (NO the name does not imply its a porn site haha). just a random template i uploaded.
The problem is, the site looks good in Firefox but in Chrome and IE, the top header DOES NOT show.

Can someone pleaseeeee help me?
Please tell me what I need to modify or remove or add.

Thanks a million!!

I will even paypal you something for your troubles.

Thanks a lotttttt

FlipC said...

@Tee Jay

You're going to kick yourself.

Remove the quote marks in layout.css from header-tail.gif so it reads

#header {
background:url(header-tail.gif) repeat-x left top;
}

IE and Chrome now work.

JB said...

You are a god among men.

JJA said...

Please allow me to add to the chorus of praise. Thank you for posting this fix!

logvi said...

Thank you!!!

Udo Trappe said...

Thank you so much!!

Paul said...

Thanks! It worked perfectly.

Anonymous said...

Anyone been able to get this to work on nested list elements without declaring a doctype (HTML5) and specifying min/max width on the first child UL that contains inline-block second level child LI tags?

FlipC said...

@Anonyomous 20/7: Given that IE7 doesn't support HTML 5 specifying any doctype simply forces it out of quirks mode and into standard/compliance mode.

It's always a good idea to do this anyway as at least it tends to provide a consistent set of problems to work around :-)

As for nested list elements without a sample or link to a page all I can do is generalise as to what effect you are trying to achieve. To that end remember that both UL and LI are block level elements; have you applied this to both?

Anonymous said...

Longest comments thread ever!

Uffe said...

_THANK YOU_

Anonymous said...

Informative and well written. Thanks!

daemonl said...

Mate... There's a special in the good book just for people like you :-)

Thanks!

Lupo Montero said...

This post just saved me a lot of head scratching. Im writing a jQuery plugin (http://demos.e-noise.com/jQuery.locationPicker/ , shameless plug) and I was going mad trying to make it work on IE.

Thanks for sharing!

Matt Stein said...

Thanks for this angry rant – headache averted!

Anonymous said...

Instead of hacking CSS, I would suggest using this instead. Then you rip out all the IE specific stuff when you don't need it anyore. Also give you a lot of other great tools:

http://www.modernizr.com/

FlipC said...

It appears to be a good time saver in creating an HTML5+CSS3 site and then forcing older browsers to display the same thing.

Of course it depends on javascript being turned on and as it says running multiple scripts can impact on performance.

As such if it's just a little tweak that's required CSS 'hacking' is still the quickest and best method.

nicola said...

YADDTU

Yet Another Desperated Developer Thanks You :).

buy cheap viagra said...
This comment has been removed by a blog administrator.
Gregir said...

Oh. My. GOD. You saved my bacon. I built an entire site that relied on inline-block elements. Client came back and wanted IE7 compatibility. I freaked out...until I saw this. Thank you so much for sharing it.

Anonymous said...

Thank you so much! You've saved me lots of de-bugging...Fuck IE and all off-shore dumb ass coders of Microsoft!

Mlo Designs said...
This comment has been removed by the author.
Mlo Designs said...

Hello: I've been searchin for hours how to fix this and came across your post. I wish I can say you save me but for some reason it wont work for me. can you take a look at my page and see if you can find why is not working the F**** IE 7 inline-block is driving me nuts.

Here is the page:
http://test.e-zrentacar.com/vehicles-Orlandomco-Florida.html

I am trying to get those links to display horizontally.

FlipC said...

@MLO Designs: In your IF IE 7 block you're applying the fix to the UL Block not the LI (i.e. you'd have a set of lists displayed inline)

Replace your .menu style with:

ul.menu li{display: inline-block; zoom:1; display: inline; _height: 30px;}

That seems to do the trick.

ie7 Hater said...

Don´t missunderstand! ... but ... love ya! :-)

Anonymous said...

THANK YOU!!!

Unknown said...

Can I give you money?
You da man.

Anonymous said...

Thanks bro

Omer Bonfil said...

Thank you so very much, was about to shoot myself.. Hate IE7!!

Anonymous said...

Thank you!

Chris said...

Thanks for publishing these fixes. IE still makes me want to club baby seals, though. *rant*

Anonymous said...

Like magic... magic that makes no logical sense, but still magic. Thanks for posting!

Anonymous said...

You're a legend, mate. That was driving me mad. IE needs to be culled.

@PoorbandTony said...

Thanks mate - just had exactly the same issue with a category page which included sub categories. Inline-block just wouldn't behave in IE 7 - thanks very much for taking the time to post this.

Anonymous said...

Many, many thanks from me also - you saved my weekend.

May all IE developers burn in hell.

Anonymous said...

thank you!

Neil said...

Man, you are such a dude! I don't know what I would have done without that! Thank you thank you thank you!!!!

Anonymous said...

Thanks a lot for this tip, was starting to doubt my sanity!

Anonymous said...

You are a genius. Thank you so much for this! IE make me want to shoot myself in the face.

Shifty said...

Brilliant! That was bugging me for the past hour or so. All those hours IE has ate out my life... damn!

Barbara Tallent said...

Thank you so much for posting this! You have made life so much easier for us mere mortals - it is greatly appreciated.

Alex said...

This is the damn best thing man! THANKS A MILLION TIMES... Yo make my day!

Elijah said...

Thanks a ton for the fix! I knew there was an issue with inline-block on IE7, and luckily your blog came up at the top of my search! :)

Anonymous said...

Thanks a lot!

Ian Neubert said...

I'm trying to get 2 divs to sit next to each other in IE7. In other browsers the display:inline-block; setting works just fine.

I seem to be unable to get this to work though, even with the fix suggested.

This may be a different issue, but would anyone mind giving it a shot?

https://gist.github.com/c03ee0023dbd72070f9d

This is a simple test, in my production env I am unable to edit the HTML, so I cannot put the .left div first in the DOM. :-(

FlipC said...

It is indeed a DOM ordering problem. IE draws in the right div then draws the left div and "floats" it to the left.

As such to me the suggestion is to drop the float and have the browsers display them as inline-block "right" then "left" then use position: relative to shift them + and - respectively. Or use position absolute and shift only the "right" div; though that will lose the container height unless set specifically.

Make sure the container has sufficient width to accommodate both left and right divs though or the left will be pushed off the page.

Ian Neubert said...

@FlipC - Thanks! That worked perfectly. Thanks for posting this article as well!

FlipC said...

To continue from the last using the relative method gaps may appear in non-IE browsers to eliminate them sent the font-size of the div to 0 and then explicitly set a font-size for any text contained within them by placing them in spans with an appropriate class.

The CSS:

div {
display:inline-block;
zoom:1; *display: inline;
height: 30px;
font-size: 0;
}

.container {
width:190px;
border:1px solid black;
}

.left {
width:95px;
position:relative; left:-95px;
background-color:gray;
}

.right {
width:95px;
position:relative; left:95px;
background-color:red;
}

.indiv {
font-size: 12pt;
}

With the alteration of the div elements such that:

<div class="right"><span class="indiv">On the right</span></div>
<div class="left"><span class="indiv">On the left</span></div>

Tested in FF, Opera, Chrome, IE7

technicallyblue said...

I have to give you props for this article. You wrote it 3 years ago and still helping out. Thank you so very much. I had no idea what my client was talking about till I dusted off IE8 and clicked the "compatibility view". You rock, again, some more.

Martín Ferrari said...

THANK YOU!!THANK YOU!!THANK YOU!!THANK YOU!!THANK YOU!!THANK YOU!!THANK YOU!!THANK YOU!!THANK YOU!!THANK YOU!!THANK YOU!!THANK YOU!!THANK YOU!!THANK YOU!!THANK YOU!!THANK YOU!!THANK YOU!!THANK YOU!!!!!!!!!!

howard said...

Thank you very much.

Anonymous said...

THANK YOU!

U saved MANY lifes at the local MS office with this post!

Wes said...

Thanks for posting this. Spent a few days working on a page at work, only to discover that it looked crap in IE7 (which is what most of the PCs user here! THANKS!

Anonymous said...

You are a life saver!!!!

Hgulf said...

Thank you, sir!

Anonymous said...

You just saved me a lot of time!
Thank you very much!
We all love to hate IE :-)

Becky said...

Oh, perfect. Thank you!!

Sneak-Peak said...
This comment has been removed by the author.
Anonymous said...

You are the real, Man!!!

Anonymous said...

Thanks! Really helpful!

Anonymous said...

extremely helpful. can't believe it worked perfectly after i added that.

Pippo said...

Thank You from Italy!
"Sei un grande"
;-)

sagarsane said...

Thanks a lot man!!! \m/

Anonymous said...

Thanks Dear