views:

66

answers:

3

I've written the following code to create a three-column layout where the first and last columns have no left and right margins respectively (by definition, the three columns will have the exact same class as they're dynamically generated--see last paragraph):

#content {
    background-color:#edeff4;
    margin:0 auto 30px auto;
    padding:0 30px 30px 30px;
    width:900px;
}
    .column {
        float:left;
        margin:0 20px;
    }
    #content .column:nth-child(1) {
        margin-left:0;
    }
    #content .column:nth-child(3) {
        margin-right:0;
    }

.width_33 {
    width:273px;
}

HMTL:

<div id="content">
    <cfoutput query="IndexView" group="pName"> <!--loop one to create the columns -->
        <div class="column width_33"> <!-- Columns -->
            <h3>#IndexView.pName#</h3>
            <ul>
            <!---LOOP two--->
            <cfoutput>
                <li>
                    #IndexView.titles#
                </li>
            </cfoutput>
        </div>
    </cfoutput>
</div>

The problem is that this code does not work in Internet Explorer 7 and 8? The only pseudo class I can use with IE (in this case) would be "first-child," but this does not eliminate the right margin on the third and last column. Does anyone know of a way I can make this code work on IE 7/8?

A important side note: The three columns are being generated dynamically through a query loop, and therefore the class attribute for each column will be identical.

+1  A: 

You could try something like ie7.js. which uses javascript to make these things work.

Short of that, it doesn't look like ie8/ie7 support it.

Koobz
+1  A: 

I hate to say it, but since IE doens't have proper support for the pseudo classes you're trying to use, you might have to resort to Javascript to solve your problem.

You could write a pretty simple jQuery function that runs on document.ready() that matches your psuedo classes and adds the proper styling to them. Load the Javascript file in an IE Conditional Comment and you're good to go.

Justin Niessner
Justin, if you mean to try the method Anthony suggested, then I run into the problem of classification. The columns are generated dynamically from a single block which has a class. Therefore, all three columns will have an identical class; this is why I'm resorting to using pseudo-classes to begin with.
Mel
Mel, our method does not depend on you having classes pre-set on the HTML. The javascript adds the classes after the page loads based on the same CSS selector rules in your stylesheet. You could have 0 classes or IDs in the HTML and the javascript would add them based on the selector rules.
Anthony
+2  A: 

I would use jquery. You could even wrap the call to the script in a conditional comment. jquery 1.4 is fully CSS 3 compliant in terms of selectors, so you can use the same selectors and then assign a class to the elements you want to style. Something like:

This is the jquery code:
 <!--[if IE]>  
 <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"&gt;&lt;/script&gt;
 <script type="text/javascript"> 
    $(function() {
     $("#content .column:nth-child(1)").addClass("childone");
     $("#content .column:nth-child(3)").addClass("childthree");
    });
 </script>
 <![endif]-->
This is your CSS, with the new classes for IE support:

 #content .column:nth-child(1), .childone {
    margin-left:0;
 }
 #content .column:nth-child(3), .childthree {
    margin-right:0;
 }

Edit

The above will work but you are not familiar with jquery or how to make changes like adding classes dynamically, I can understand your confusion and resistance to the solution. Here is a slightly modified version that may make things a bit clearer:

 <!--[if IE]>  
 <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"&gt;&lt;/script&gt;
 <script type="text/javascript"> 
     $("#content .column:nth-child(1)").css("margin-left","0");
     $("#content .column:nth-child(3)").css("margin-right","0");
 </script>
 <![endif]-->

In this case, instead of using dummy classes that you can add into your stylesheet, the script simple adds the same style rules you want to the same CSS selectors. I prefer to use dummy classes because it allows me to have several style rules for that same class without clogging up the script, but since you only have one rule for each selector, this makes a nice example of how jquery is working, whichever method you go in.

Anthony
Thanks Anthony, but I can't do that because the three columns are dynamically created from a single block, and as such will be identical clones of one another, and as such their classes.
Mel
It doesn't matter, if I read your question right. You want to use pseudo-classes in IE. Well if those pseudo-classes work in Firefox, this will work in IE. You are just making up a dummy class that corresponds to the pseudo-classes, you aren't actually setting the classes when you output the HTML. Jquery assigns all elements that match up to the pseudo-class rule you already have in your CSS, it then gives all of those elements the class "child1" or "MellovesCSS", it really doesn't matter. what matters is that your CSS rule is set to that dummy class as well as to the pseudo-class already...
Anthony
set up. Just imagine if you could instead of using `#content .column:nth-child(1)` for the CSS, you could say `X = #content .column:nth-child(1)`. and then reuse X over and over. Basically, you are saying the same thing: `#content .column:nth-child(1), .childone`. there are no elements with the class .childone, but jquery goes and finds all elements that match up to `#content .column:nth-child(1)` and gives them a class of `childone`. Which means your rule will apply to them even if you use IE.
Anthony
And another nice part is that by putting in those conditional comments, you only force IE to use this solution, while Firefox and company will just use the CSS. Let me put in another way: try it, if it doesn't work, I'll personally debug the whole thing.
Anthony
Sorry, I'm a bit chatty tonight. I went ahead and updated my code so that jquery script call points to Google's jquery source, so you don't even have to download anything, just copy and paste to test my answer.
Anthony
Nothing to be sorry about. I completely misunderstood your initial explanation because I know almost nothing about jQuery. Thanks for taking the time to explain this to me. I appreciate it!
Mel
I tried it and it did not work. IE was still inheriting the margin:0 20px; from column. Let me update my full code to see what I mean.
Mel
Updated my code! What am I doing wrong?
Mel
3 things: 1, I had a typo at one point and fixed it, maybe you didn't get the fixed version. 2, Did IE give you any kind of potential threat warning? Because I tested my own theory (with the external google version) and it threw an alert and I had to say it was okay (it's because you're pulling javascript from an external source), 3, do you want to give me a link to the earlier version you have without my idea, so I can take a quick whack at it?
Anthony
Also, I was just reading over how `:nth-child` works. Suppose you have an unordered list with three list items. if you use `:nth-child(1)` the style goes to the first list item. Fairly obvious. But not let's suppose you have a `div` with an id of `main`, and in that div, the first three children are paragraphs (`p`) and the next three children are `img` tags. And you have a rule `#main img:nth-child(3)`. CSS actually starts at the first child in the main div, not the first `img`, and it counts down to the 3rd child, which is a `p`. Since it's not an `img`, the rule doesn't get applied. Crazy!
Anthony
So I believe in your case you should be fine, since I'm guessing you already tested in Either Firefox or Chrome or whatever, but in case you haven't make sure you double check. Jquery has a selector that actually counts the number of the elements before the pseudo-class (the part before the `:`) so that it only counts the number of `imgs` or `p` or whatever you want the nth of. But I'm still looking to see if this is a CSS pseudo-class or if it's jquery exclusive. If that's the case, it may be easier to use it for all browsers.
Anthony
One last update then you'll either catch me tonight or tomorrow after sleep: Just in case you are having trouble as a result of the weird `nth-child` mechanics (which were created by the w3c, not jquery or anybody else), there is a pseudo-class called `nth-of-type`. The main creator of jquery refuses to include it into jquery as it's on a very short list of selectors he thinks are just stupid. However, jquery does have custom selector (mentioned in last comment) called `eq()`. I can't tell the real difference other than...
Anthony
The jquery version goes the `nth` number given of whatever the jquery selector returns. Which means if you had a jquery selector for all `img` and `p` (which isn't really doable in with just CSS), and then said `:eq(5)` it would go to the 5th in that group (assuming, say 15 total of img and p, and the first five on the page were: img, img, p, img, p, it would go to that p as it's 5th on the list). But I digress. Point is, for your purposes, if you used `:nth-of-type()` (if need be) in the CSS, then `:eq()` should cover it in jquery. Still up for seeing the original code.
Anthony
Ack! Mel, you must forgive me, I've wasted hours of your night (or day, depending on where you are). It's like I gave you a brand new Mercedes but left the parking-brake on! I spent the last 45 minutes doing a real dumb down version of your goal, with not only IE but Firefox and every other browser not working. I finally realized I forgot in my example code to wrap the script in the "on page load" event trigger. Which basically means the javascript ran before the page loaded, so of course it didn't add the classes, as it had nothing to search. I've fixed it, and tested it. Here's proof:
Anthony
http://tony.thedayjob.net/sandbox/columns.htmlI will admit, I can't make it work with classes. I'm sure this is something really simple I'm over looking, but I was able to change the css directly using the same pseudo-selectors. Anyways, I'm far past my bedtime. I hope this is helpful. Sorry it wasn't quite as perfect as I promised, but I am almost certain the flaw is with me being tired, not with jquery's ability to do what i said it could.
Anthony
Oh lord, still awake. It had nothing to do with IE not liking jquery or refusing to change style even though I could see in the dev toolbar that the class add been added. It has to do with how IE is super fussy about dealing with commas in css selectors. Go back to my test page and you'll see that all i've done is put the dummy classes below the pseudo-classes, but with the same rules. works fine. tony.thedayjob.net/sandbox/columns.html
Anthony
Magic! It works. Thanks Anthony. So a short way to say this: jQuery figures out/interprets the nth-child selectors for IE because IE can't do it itself? This has opened up a brand new world of possibilities for me. Thanks again!
Mel