Css3pie messes up DOM, leads to jQuery selection errors

To get CSS3 effects (border-radius, box-shadow ...) in IE 6/7/8, I use css3pie .

However, css3pie generates css3-container (v1) / css3pie (v2) tags in the DOM, which violates the expected architecture. Here is an example:

CSS

 pre { border: 1px solid #aaa; border-radius: 5px; behavior: url(pie.htc); } 

HTML

 <div class="foo">bar</div> <p class="getme">paragraph</p> <pre>preformatted</pre> 

JQuery

 // undefined expected: getme alert($("pre").prev().attr("class")); // css3-container expected: p alert($("pre").prev()[0].tagName); // getme expected: foo alert($("pre").prev().prev().attr("class")); // 4 expected: 3 alert($("body").children().size()); // will not set expected: Impact $("p+pre").css({fontFamily: "Impact"}); // it almost affects all such jQuery selctors 

The actual generated source is as follows:

 <DIV class="foo">bar</DIV> <P class="paragraph">paragraph</P> <css3-container...> <border...> <shape...><stroke></stroke><stroke></stroke></shape> </border> </css3-container> <PRE>preformatted</PRE> 

Has anyone encountered such problems? Any workaround? Is there an alternative to css3pie to make CSS3 work with IE 6/7/8?

+6
source share
5 answers

I also tried using CSS3PIE and ran into similar issues (mainly with jquery and mediaqueries). In fact, I did not find an easy / practical solution to all the problems that it causes.

My advice would be to use Modernizr load to gradually improve the older IE user interface. This requires a more complex / lengthy process, since you must configure one polyfill for each CSS3 function. As mario.tco has already reported, there is a list of cross-browser polygons on the Modernizr repository. And here is a list of feature detection .

Also see html5please and caniuse .

Regarding IE6 and 7, if your siteโ€™s statistics do not indicate anything else, usage rates are below 1% on average (with some exceptions, check ie6countdown ), so you can almost ignore them. However, with conditional comments, you can target each version of IE <10 using specific backups.

Keep in mind that you really donโ€™t need box shadows and other visual decorations (if they are not needed for ease of use) in IE <9. Indeed, any failure can cause a huge performance problem (think about what equipment an IE7 user might have ) Websites should not look the same in any browser .

+3
source

CSS3PIE is a very useful and powerful way to simulate CSS3 rounded corners - and at my company we chose this, but there are many other ways to do this.

As CSS3PIE creates rounded corners, it will create the <css3-container> as the previous sibling that has a behavior attribute, so it will change the DOM structure and break your prev() calls. The css container is important because it is a VML drawing of a rounded background behind the <pre> .

One way to do this is to wrap the <pre> in something like <div> , and then use <div> to navigate the DOM using the prev() function.

Another way you could do this is to create a jQuery plugin like this

 /* This adds a plugin prevPie and nextPie - it is the same as the existing prev and next, but it will ignore css3-containers. */ (function($){ function addPlugin(name) { $.fn[name + 'Pie'] = function() { var result = []; this[name]().each(function(i,el){ if (el.tagName == 'css3-container') { var val = $(el)[name]()[0]; val && result.push(val); } else { result.push(el); } }); return $(result); } } addPlugin('prev'); addPlugin('next'); })(jQuery); 

Now the following should work the way you want it to be in all browsers.

 // undefined expected: getme alert($("pre").prevPie().attr("class")); // css3-container expected: p alert($("pre").prevPie()[0].tagName); // getme expected: foo alert($("pre").prevPie().prevPie().attr("class")); // P expected: div alert($("pre").prevPie().prevPie()[0].tagName)); 
+2
source

This is probably not the answer you are looking for, but instead of trying to get jQuery to ignore elements embedded in the PIE, I recommend (re) writing your jQuery to make more use of classes / identifiers and be less dependent on the structure of the page. This allows you to make your code more resistant to other changes in the page structure, as well as make your code more portable and reusable.

When you must cross the DOM, most (if not all) jQuery workarounds include a filter selector argument that you can use to exclude PIE elements, for example:

 $("pre").prevUntil('*', 'not(css3-container)') $("body").children('not(css3-container)') 
+1
source

Instead of using raw prev() add a CSS selector to it to narrow your search

 $("pre").prevUntil('p').attr("class"); // OR $("pre").prevUntil('.paragraph').attr("class"); 

If you intend to use CSS3 โ€œhackโ€ to force IE 6/7/8 to behave correctly, don't try to rely on the expected DOM structure when going through the DOM, try to be more specific.

EDIT

changed the function call prev() to prevUntil()

0
source

All Articles