DD_belatedPNG
by Drew Diller0.0.1a released 2008.12.07
Current: 0.0.8a on 2009.06.30
release updates / changelog
Medicine for your IE6/PNG headache!
Please familiarize yourself with known issues.
You might also enjoy DD_roundies.
Jason Fragoso was kind enough to provide a Belorussian translation for this documentation.
2011/4/8: This is no longer an actively maintained project. I apologize, I must move on with current events.
This is a Javascript library that sandwiches PNG image support into IE6 without much fuss.
You can use PNGs as the SRC of an <IMG/> element or as a background-image property in CSS.
If you attempt the latter, you will find that, unlike with vanilla usage of AlphaImageLoader, background-position and background-repeat work as intended.
As a bonus, "fixed" elements will respond to a commonly used set of Javascript style assignments, as well as the A:hover pseudo-class.
Table of Contents
Long story short, this uses Microsoft's implementation of VML instead of Microsoft's AlphaImageLoader filter. I stumbled upon the notion that PNG images show up correctly in a VML fill element while working on DD_roundies. Thereafter, some Googling revealed that a few people had already known about this.
The intended implementation is pretty easy:
- Download a copy of the DD_belatedPNG Javascript file - please do not hotlink mine, I am on a shared host.
- Refer to it in your document (second line of the example code a few bullets down).
- In another script node, add function calls to
DD_belatedPNG.fix(). fix()requires one argument: a text string representing a CSS selector.-
Here is an example:
<!--[if IE 6]>
<script src="DD_belatedPNG.js"></script>
<script>
/* EXAMPLE */
DD_belatedPNG.fix('.png_bg');
/* string argument can be any CSS selector */
/* .png_bg example is unnecessary */
/* change it to what suits you! */
</script>
<![endif]--> - As of 0.0.3a, you can roll a bunch of CSS selectors into one argument, just like how you'd do a selector group in a CSS file:
fix('.example1, .example2, img');
Due to popular demand, here is some documentation for how to "fix" elements on a pick-and-choose basis.
- Refer to the DD_belatedPNG script as noted earlier.
- Call
DD_belatedPNG.fixPng( yourElement ), with the sole argument being an HTMLDomElement instead of a CSS selector.
(Based on the normal usage approach)
- Invoking
DD_belatedPNG.fix()adds a line of CSS to the document via DOM. - The selector of this CSS is provided by the first argument for
fix, which should be a string (such as#content div). - The declaration of this CSS is an MSIE-proprietary behavior - basically a Javascript expression bound to elements on the fly, without walking through a NodeList collection.
- The content of the behavior executes a function with each matched element as its sole argument.
- The first duty of this function is to reset its own
style.behaviorto no longer have a value; allowing behaviors to continue unchallenged is a recipe of for CPU-eating disaster. - The function then examines the element's dimensions, location, and styles using
offsetWidth,offsetHeight,offsetLeft,offsetTop, andcurrentStyle - Using the above information, a VML
<DD_belatedPNG:rect/>node is constructed and prepended (insertBefore) to the element. - The VML node is absolutely positioned to follow behind the element like a lost little puppy. It copies the matched element's
z-index. - To support various positioning and repeat background properties, some of the VML element gets a
style.cliprectangle.
- You cannot use 'body' as the CSS selector argument for the
fix()function. The VML is positioned using sibling DOM relationships! You cannot create a previousSibling of<body>, so trying to do so fails (badly). As an alternative, you can wrap the contents of the<body>element with a wrapper element, and apply the background style andfixfunction to that instead. It is not a question of getting it to work, it is a question of performance. <TR>and<TD>elements do not play nicely yet. Do not attempt.- This script does not address
background-position: fixed;functionality. - "Fixed"
<IMG/>elements must take onvisibility:hidden;, and thus become unclickable. I see no workaround other than using clear pixel GIF replacements, and that is code that I am not going to write. <INPUT type="image"/>nodes are not supported. The node with the original PNGSRCmust take onvisibility:hidden;- The "clickable elements" example boasted in this document may fail when combined with an alpha (opacity) filter. I don't know of a workaround yet.
- Testing for PNG image presence is done by Javascript string search. If you have a URL that doesn't end in .png, you're not in luck. I suppose I could add a 'force' option - let me know if you need it.
Found something wrong? Send me bugs!
This is intended solely for Internet Explorer 6. Use the script with conditional comments.
- Find bugs.
- ???
Profit!- Test for memory leaks.
- This item will always persist: find performance improvements.
DD_belatedPNG is free software under the MIT License.
The License shall remain addressable at this URL:
http://dillerdesign.com/experiment/DD_belatedPNG/#license
Copyright (c) 2008 Drew Diller
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
My thanks to Jonathan Snook for pointing out something else I had written was almost there for good PNG support.
↓0.0.8a.js (Uncompressed, ~12Kb)
↓0.0.8a-min.js (Compressed, ~7Kb)
Any donations are sincerely appreciated, and help reduce the occurrence of glares from my wife when I am staying up past her bedtime writing software.
-
0.0.8a / 2009.06.30 (source.js / packed.js)
- "DD_belatedPNG is undefined" error should occur less often now.
- Auto-cleansing of VML artifacts when printing (or performing a print-preview) - thanks to Rémi Prévost!
- Allowing CSS padding of
<IMG/>elements in strict rendering mode. - Stricter adherence to JSLint.
- Switched to YUI Compressor for packed copy of lib.
- No JS error messages in Firefox (et al), if you choose to not include the lib through conditional comments.
-
0.0.7a / 2009.01.01 (source.js / packed.js)
- New feature: alpha filter value copying (in other words: opacity support, allows fades to happen for instance).
- Bug fix: saying
fix('img');froze IE6 in less than a second. Basically the size-finder images weren't being protected from them being matched and "fixed" (and they would, in turn, ask for more elements to be appended to the document - INFINITE LOOP). - Notice: some under-the-hood function names changed because I got sick of typing long ones.
- Performance improvement: matched elements won't get "fixed" if a PNG src or background image isn't detected. This means you can be lazy.
- Performance improvement: according to Fiddler2, images get cached correctly -- most of the time. I believe there is still an issue to solve related to latency.
- Performance improvement: appending "size finder" images to the document in a more intelligent, less greedy, as-needed basis.
<IMG/>support kinda sucked, but no one reported it. Improved it anyway.
-
0.0.6a / 2008.12.14 (source.js / packed.js)
- Edges of fixed elements are no longer fuzzy (except for floated elements, and only sometimes, and it goes away on mouseover... weird) - the one pixel gap problem has been mostly solved. Few people noticed, but it bugged me, and was VERY hard to fix.
-
0.0.5a / 2008.12.12 (source.js / packed.js)
- Hopeful memory improvement: now setting DD_belatedPNG to null in an
onbeforeunloadlistener. - Hopeful memory improvement: various VML manipulation methods used to be copied onto each matched element. Figured out how to just have them in the DD_belatedPNG namespace and keep everything working properly. Should have done this initially.
- Hopeful memory improvement: now setting DD_belatedPNG to null in an
-
0.0.4a / 2008.12.11 (source.js / packed.js)
- James O'Brien suggested applying a large negative
topto the dummy "size finder" images, in case one of them is very large, to prevent them from rendering an unnaturally tall page. - Very small change: added
onfocusandonblurevent handlers for anchors.
- James O'Brien suggested applying a large negative
-
0.0.3a / 2008.12.10 (source.js / packed.js)
<IMG/>support! A clear pixel gif is not required, I simply copy the matched image's border styles and setvisibility:hidden;. You can also be lazy about img.width and img.height attributes.- Removed the top/left 1px fudging of the image-filled rectangle (it wasn't visible enough to warrant the added complexity).
- Rémi Prévost submitted a patch for when an element's border is not set.
- Fixed a bug in which elements that spanned the entire width of the page were causing an "Infinite Scrollbar."
- You can now roll multiple selectors into one call to
fix(the change in JS simply does a split, by comma), likeDD_belatedPNG.fix('.thing, .something_else');
-
0.0.2a / 2008.12.09 (source.js / packed.js)
- After observing some offset misalignment and layering issues, each matched element and its parent is now forced into receiving hasLayout.
- If a z-index is specified on the matched element, it is now copied to the VML.
-
0.0.1a / 2008.12.07 (source.js / packed.js)
- Initial release.
CSS Background Properties
Use these fields to change background properties.
The last field is a text field and will accept 'red' or '#F00' or '#FF0000'.
Javascript Animation
Clickable Elements
Since AlphaImageLoader is not used, this approach doesn't appear to suffer from any of that filter's known layering issues.
You can click elements to your heart's content!
Be wary, mixing in an opacity filter may UNDO this beneficial feature!
<IMG/> Support
No pixel GIFs!
A:hover Psuedo-Class Support
Run your mouse over these:
psuedo classThere is a blog post about this at dillerdesign.wordpress.com.
Otherwise, you can email me.