I know that title is horrible, but bear with me. This post is worth reading if you are a novice CSS writer. I hit a CSS bug in IE today that is relatively easy to avoid that involves manipulating an element that has an ID assigned to it by referencing its class.
Some of you may have noticed that I made the site wider by 200 pixels. Well, while doing this, I also decided I would try moving my Adsense banner to the left side on individual blog posts (view an individual post to see this). Here’s what I added in my WordPress code:
<div id=”main” class=”<?php echo (is_single() ? ‘with-ads’ : ‘no-ads’) ?>”>
So basically, when a visitor is viewing a single post, a special class is assigned to the main DIV. So far, simple right? The idea was that on pages without ads, the blog would expand all the way to the left, ensuring no blank gaps in my template (click around to see for yourself). So then I created the following CSS:
.with-ads {
width: 645px;
margin-left: 125px;
}
.no-ads {
width: 765px;
margin-left: 0px;
}
Please note, I don’t claim to be a master-Yoda-CSS-guru and perhaps there’s better ways to do what I did, but also note that my blog integrates with my AJAX code, so I can’t change too many things without breaking other functionality. I used floating columns to do this new formatting (one column on each side of the post), so naturally there are problems when I don’t specify widths. Otherwise, I would just set it to 100%. Anyway, does my CSS work? No:
Many of you have encountered this before, I know. But this one is a tricky bastard. Okay, so I thought maybe the default setting for #main was overwriting the width since #main’s non-blog default is to stretch 100% across the screen. Yes, I use the same CSS file for the entire site so that my AJAX functions correctly (try clicking on the icons at the top of the page). So I changed the CSS to:
#main .with-ads {
width: 645px;
margin-left: 125px;
}
#main .no-ads {
width: 765px;
margin-left: 0px;
}
No effect. Damn.
I banged my head for a long time until I noticed this worked just fine in Opera and Firefox (every good developer tests on at least three browsers! 😉 ). I was scared because this was obviously an IE bug, and I hate doing CSS hacks.
I banged my head for a while until I had the crazy idea of deleting the space between the ID and class. Thus:
#main.with-ads {
width: 645px;
margin-left: 125px;
}
#main.no-ads {
width: 765px;
margin-left: 0px;
}
This worked!
I hit the same bug when trying to make images in my blog have borders except emoticons, which have the CSS class “wp-smiley.” First, the CSS that puts borders:
#rap #main img {
padding: 1px;
border: 1px solid black;
}
Then the CSS for the smiley:
#rap #main img.wp-smiley {
padding: 0px;
border: 1px solid white;
}
Oddly, If I remove that space after “img” or if I take off “#rap #main”, it stops working in all of my browsers. So the first “bug” hit only IE7, but this one hit everything.
Lastly, the whole ID-prefix business seems utterly unnecessary so long as I use a tag ID that is not #main. For example, when I renamed the blog main to use #blog-main, I could correctly modify it with just the class name!
My conclusion is that CSS ID based definitions tends to overwrite class based ones unless that space is omitted. Really, I don’t even know. CSS guru Feed back is appreciated.
Essentially, this isn’t an IE7 bug at all. It’s correctly looking for an element within another element that you specify in your CSS, which doesn’t exist in your HTML.
What Ben is saying, is
#main.with-ads
matches
[div id=main” class=”match”]…
and this
#main .with-ads
matches
[div id=main”][div class=”match”]…
I’m very glad to know both work in IE7 – thanks !
good subjectline on the post too 🙂
*-pike
What Ben is saying, is
#main.with-ads
matches
…
and this
#main .with-ads
matches
…
I’m very glad to know both work in IE7 – thanks !
good subjectline on the post too 🙂
*-pike
I tried to post comments, but your blog marked them as spam, but told me that you’d be able to make them live anyway. I have answers for you in that comment!
#main.with-ads would declare a rule for an element with the id main and class with-ads, eg:
#main .with-ads would declare a rule for an element with the class with-ads, but is a descendant of an element with id of main, eg:
HOWEVER, IE6 doesn’t really handle the combination of class and id one one element properly (#main.with-ads), so it’s best not to use this.
There are many other css selectors, here’s a page on the w3:
http://www.w3.org/TR/REC-CSS2/selector.html