Forum Moderators: not2easy

Message Too Old, No Replies

Known bug in IE rendering...or something else?

any info on this?

         

matthewwithanm

8:32 pm on Jul 5, 2005 (gmt 0)

10+ Year Member



I'm working on some CSS and I think I've stumbled across a rendering bug in IE6. Either that or I'm thinking about CSS wrong.

The goal here is to create a kind of "modifier class" that can be applied to different elements and does different things to each of them. I've constructed a simplified example...


<html>
<head>

<style type="text/css">
.text {
font-family: Arial;
font-size: 15pt;
}
.text.light {
color: pink;
}
.text.dark {
color: red;
}
.bg {
border: 1px black solid;
}
.bg.light {
background-color: pink;
}
.bg.dark {
background-color: red;
}
</style>

</head>
<body>

<div class="light text">light text</div>
<div class="dark text">dark text</div>

<div class="light bg">light background</div>
<div class="dark bg">dark background</div>

</body>
</html>

Ofcourse, in this simple example, you could easily create additional divs and add the child selector...but should you have to..?

FF displays the code as I'd expect. IE6 does something completely different.

Has anybody experienced this before? Am I trying to use CSS in a way other than it was intended? Or is IE just being IE?

As you probably imagined, I was hoping to use this technique to minimalize the amout of markup but this kind of put a kink in the plans.

Thanks for your responses.
matthew

Span

8:55 pm on Jul 5, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Using double class names in mark-up is supported by all modern browsers (not Win/IE5). In CSS selectors, however, you have to separately call them. So you can't do this:

.bg.light {}

You have to separate them with a comma:

.bg, .light {}

matthewwithanm

9:34 pm on Jul 5, 2005 (gmt 0)

10+ Year Member



Now that I've thought about it a few minutes, I've realized that what I actually was trying to do was simulate the child selector in IE. Or more accurately, to apply a rule only if the element was of two classes. I believe one way to do this would be to have multiple instances of a single ID and reference elements like so:

.classname#idname {
/* this style applies only to elements of both class "classname" and id "idname" */
}

That's not proper though. Are there any other ways?

createErrorMsg

3:27 am on Jul 6, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



you can't do this:

.bg.light {}

Interestingly, this is actually not true. Defining multiple classes in the CSS is perfectly legal, and in fact is widely supported. Properly used, multiple classes will function exactly as you want across (AFAIK) all modern browsers.

The problem, and it's the one you've run into, matthew, is that IE has one minor bug that effects the outcome. While IE correctly supports these multiple classes, it incorrectly applies the styles in a multiple selector block to any element on the page containing a call to last of the listed selectors.

From another angle, let's take your selector .bg.light. What you want it to do is apply those styles only to an element with a class name which includes BOTH bg and light. FF does this, displaying only <div class="bg light"> (or, alternately, <div class="light bg">) with a pink background.

IE, however, takes the styles in that block and applies them to any element on the page containing either both classes OR just the "light" class. Thus the first and the third divs get the pink background.

The same thing happens with .bg.dark, resulting in divs 2 and 4 having a red background. Extrapolate it out and you'll see that .text.light and .text.dark are doing the same thing, resulting in two divs with pink text invisible against a pink background and 2 with red text invisible against a red background.

Sadly, there's no workaround, other than avoiding situations in which this occurs.

I've experimented with the idea of, as you put it, "a modifier class," in the past and found that there really wasn't much benefit in using multiple selectors in this way. If you think about it, it's really no different than following Span's suggestion and giving each class it's own seperate style, then combining them, without browser complications, in the markup. After all, you still have to seperately code the .light.text and .light.bg multiple classes, since the text part and the bg part are referring to different properties. in other words, it's not as if you can say...


.light {
pink
}

.dark{
red
}

.text{
color
}

.bg{
background
}

...and expect them to combine .light.bg into a background:pink style rule. CSS doesn't have that sort of variable-like portability. And as long as you have to seperately define that .light.bg having {background:pink;} and .light.text havingin {color:pink;}, you may as well make them individual classes.

cEM

matthewwithanm

4:42 am on Jul 6, 2005 (gmt 0)

10+ Year Member



Thanks cEM. That's exactly what I thought was going on.


I've experimented with the idea of, as you put it, "a modifier class," in the past and found that there really wasn't much benefit in using multiple selectors in this way. If you think about it, it's really no different than following Span's suggestion and giving each class it's own seperate style, then combining them, without browser complications, in the markup...you may as well make them individual classes.

Yes, after staring at the code for a while I began to separate the classes and give each its own style....but I just couldn't for the life of me stomach all the repetition I was seeing. Although it isn't true for the example I gave here (which I stripped down and simplified as much as possible in order to illustrate the problem most clearly), I believed my page really would benefit from keeping the classes separate and maintaining a "modifier class."

However, a few hours ago I had a breakthrough and (although I suppose it isn't a general workaround for this problem per se) was able to come up with something. If you remember, my original intent was to consolidate code and markup by having a single style behave differently depending on context. As usual, the simplest answer was the best...Actually, I feel pretty dumb now for overlooking it.

I realized that one behavior (for example, 'light' refering to the background) always happened within a specific class. Therefore, I could just style it like this:

<html>
<head>

<style type="text/css">
.light {
color: pink;
}

.dark {
color: red;
}

.area1 .light {
color: black;
background: pink;
}

.area1 .dark {
color: black;
background: red;
}

</style>

</head>
<body>

<div class="light">normal light</div>
<div class="dark">normal dark</div>

<div class="area1">
<div class="light">light in area1</div>
<div class="dark">dark in area1</div>
</div>

</body>
</html>

Very simple. There's still one teeny tiny markup-simplification thing I wish I could do but it appears to be impossible. Still, it provides a little insight into how CSS renders classes and IDs. I'd love to discuss it with you but it would require me to send you the page's code (I don't want to post it on the boards - I'm pretty proud of the thing and I'd rather it weren't ripped before I had a chance to use it). If you'd like, I'll mail you the code and an explanation of what I'm talking about.

I hope my stripped-down examples haven't been too stripped down. I'm fairly sure I've reflected the problems of the actual page without actually posting the page. Thanks again for the responses.

matthew