前端基础——兼容性
一、CSS兼容性问题
1、HTML5 标签的兼容
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"/> <title></title> <!--如果有很多HTML5的标签,那样就会创建出太多的自定义元素了,所以下面可以用一个JS库去兼容--> <script src="js/html5shiv.js"></script> <!--<script type="text/javascript"> // 用JS创建一个自定义元素,自定义元素为内联元素,需要在样式中转化为块元素 document.createElement("header"); document.createElement("section"); document.createElement("footer"); </script>--> <style type="text/css"> header{ width: 200px; height: 200px; display: block; /*设置行内块元素与JS获得IE6的兼容*/ background: #000000; } section{ width: 150px; height: 150px; display: block; /*设置行内块元素与JS获得IE6的兼容*/ background: #eee999; } footer{ width: 100px; height: 100px; display: block; /*设置行内块元素与JS获得IE6的兼容*/ background: #999999; } </style> </head> <body> <header>header</header> <section>section</section> <footer>footer</footer> </body> </html>
html5shiv.js 兼容库代码,如下:
/*! HTML5 Shiv v3.6.1 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed */ (function(window, document) { /*jshint evil:true */ /** Preset options */ var options = window.html5 || {}; /** Used to skip problem elements */ var reSkip = /^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i; /** Not all elements can be cloned in IE **/ var saveClones = /^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i; /** Detect whether the browser supports default html5 styles */ var supportsHtml5Styles; /** Name of the expando, to work with multiple documents or to re-shiv one document */ var expando = '_html5shiv'; /** The id for the the documents expando */ var expanID = 0; /** Cached data for each document */ var expandoData = {}; /** Detect whether the browser supports unknown elements */ var supportsUnknownElements; (function() { try { var a = document.createElement('a'); a.innerHTML = '<xyz></xyz>'; //if the hidden property is implemented we can assume, that the browser supports basic HTML5 Styles supportsHtml5Styles = ('hidden' in a); supportsUnknownElements = a.childNodes.length == 1 || (function() { // assign a false positive if unable to shiv (document.createElement)('a'); var frag = document.createDocumentFragment(); return ( typeof frag.cloneNode == 'undefined' || typeof frag.createDocumentFragment == 'undefined' || typeof frag.createElement == 'undefined' ); }()); } catch(e) { supportsHtml5Styles = true; supportsUnknownElements = true; } }()); /*--------------------------------------------------------------------------*/ /** * Creates a style sheet with the given CSS text and adds it to the document. * @private * @param {Document} ownerDocument The document. * @param {String} cssText The CSS text. * @returns {StyleSheet} The style element. */ function addStyleSheet(ownerDocument, cssText) { var p = ownerDocument.createElement('p'), parent = ownerDocument.getElementsByTagName('head')[0] || ownerDocument.documentElement; p.innerHTML = 'x<style>' + cssText + '</style>'; return parent.insertBefore(p.lastChild, parent.firstChild); } /** * Returns the value of `html5.elements` as an array. * @private * @returns {Array} An array of shived element node names. */ function getElements() { var elements = html5.elements; return typeof elements == 'string' ? elements.split(' ') : elements; } /** * Returns the data associated to the given document * @private * @param {Document} ownerDocument The document. * @returns {Object} An object of data. */ function getExpandoData(ownerDocument) { var data = expandoData[ownerDocument[expando]]; if (!data) { data = {}; expanID++; ownerDocument[expando] = expanID; expandoData[expanID] = data; } return data; } /** * returns a shived element for the given nodeName and document * @memberOf html5 * @param {String} nodeName name of the element * @param {Document} ownerDocument The context document. * @returns {Object} The shived element. */ function createElement(nodeName, ownerDocument, data){ if (!ownerDocument) { ownerDocument = document; } if(supportsUnknownElements){ return ownerDocument.createElement(nodeName); } if (!data) { data = getExpandoData(ownerDocument); } var node; if (data.cache[nodeName]) { node = data.cache[nodeName].cloneNode(); } else if (saveClones.test(nodeName)) { node = (data.cache[nodeName] = data.createElem(nodeName)).cloneNode(); } else { node = data.createElem(nodeName); } // Avoid adding some elements to fragments in IE < 9 because // * Attributes like `name` or `type` cannot be set/changed once an element // is inserted into a document/fragment // * Link elements with `src` attributes that are inaccessible, as with // a 403 response, will cause the tab/window to crash // * Script elements appended to fragments will execute when their `src` // or `text` property is set return node.canHaveChildren && !reSkip.test(nodeName) ? data.frag.appendChild(node) : node; } /** * returns a shived DocumentFragment for the given document * @memberOf html5 * @param {Document} ownerDocument The context document. * @returns {Object} The shived DocumentFragment. */ function createDocumentFragment(ownerDocument, data){ if (!ownerDocument) { ownerDocument = document; } if(supportsUnknownElements){ return ownerDocument.createDocumentFragment(); } data = data || getExpandoData(ownerDocument); var clone = data.frag.cloneNode(), i = 0, elems = getElements(), l = elems.length; for(;i<l;i++){ clone.createElement(elems[i]); } return clone; } /** * Shivs the `createElement` and `createDocumentFragment` methods of the document. * @private * @param {Document|DocumentFragment} ownerDocument The document. * @param {Object} data of the document. */ function shivMethods(ownerDocument, data) { if (!data.cache) { data.cache = {}; data.createElem = ownerDocument.createElement; data.createFrag = ownerDocument.createDocumentFragment; data.frag = data.createFrag(); } ownerDocument.createElement = function(nodeName) { //abort shiv if (!html5.shivMethods) { return data.createElem(nodeName); } return createElement(nodeName, ownerDocument, data); }; ownerDocument.createDocumentFragment = Function('h,f', 'return function(){' + 'var n=f.cloneNode(),c=n.createElement;' + 'h.shivMethods&&(' + // unroll the `createElement` calls getElements().join().replace(/\w+/g, function(nodeName) { data.createElem(nodeName); data.frag.createElement(nodeName); return 'c("' + nodeName + '")'; }) + ');return n}' )(html5, data.frag); } /*--------------------------------------------------------------------------*/ /** * Shivs the given document. * @memberOf html5 * @param {Document} ownerDocument The document to shiv. * @returns {Document} The shived document. */ function shivDocument(ownerDocument) { if (!ownerDocument) { ownerDocument = document; } var data = getExpandoData(ownerDocument); if (html5.shivCSS && !supportsHtml5Styles && !data.hasCSS) { data.hasCSS = !!addStyleSheet(ownerDocument, // corrects block display not defined in IE6/7/8/9 'article,aside,figcaption,figure,footer,header,hgroup,nav,section{display:block}' + // adds styling not present in IE6/7/8/9 'mark{background:#FF0;color:#000}' ); } if (!supportsUnknownElements) { shivMethods(ownerDocument, data); } return ownerDocument; } /*--------------------------------------------------------------------------*/ /** * The `html5` object is exposed so that more elements can be shived and * existing shiving can be detected on iframes. * @type Object * @example * * // options can be changed before the script is included * html5 = { 'elements': 'mark section', 'shivCSS': false, 'shivMethods': false }; */ var html5 = { /** * An array or space separated string of node names of the elements to shiv. * @memberOf html5 * @type Array|String */ 'elements': options.elements || 'abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video', /** * A flag to indicate that the HTML5 style sheet should be inserted. * @memberOf html5 * @type Boolean */ 'shivCSS': (options.shivCSS !== false), /** * Is equal to true if a browser supports creating unknown/HTML5 elements * @memberOf html5 * @type boolean */ 'supportsUnknownElements': supportsUnknownElements, /** * A flag to indicate that the document's `createElement` and `createDocumentFragment` * methods should be overwritten. * @memberOf html5 * @type Boolean */ 'shivMethods': (options.shivMethods !== false), /** * A string to describe the type of `html5` object ("default" or "default print"). * @memberOf html5 * @type String */ 'type': 'default', // shivs the document according to the specified `html5` object options 'shivDocument': shivDocument, //creates a shived element createElement: createElement, //creates a shived documentFragment createDocumentFragment: createDocumentFragment }; /*--------------------------------------------------------------------------*/ // expose html5 window.html5 = html5; // shiv the document shivDocument(document); }(this, document));
2、元素浮动之后,能设置宽度的话就给元素加宽度.如果需要宽度是内容撑开,就给它里边的块元素加上浮动
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<style type="text/css">
.box{
width: 400px;
border: 1px solid #0000FF;
}
.clearfix{
zoom: 1;
}
.clearfix:after{
content: ".";
height: 0;
display: block;
visibility: hidden;
clear: both;
}
.left{
background: #FF0000;
float: left;
}
.right{
background: #EFFE00;
float: right;
}
h2{
float: left;
margin: 0;
height: 30px; 让浮动过的父级块中的子级元素,再浮动
}
</style>
<!--
在IE6下左右子级中的块元素设置高度后会撑开父级,并且独立各占一行
解决方案:让浮动过的父级块中的子级元素,再浮动,加样式,float: left;
-->
</head>
<body>
<div class="box clearfix">
<div class="left"><h2>今日标题</h2></div>
<div class="right"><h2>更多>></h2></div>
</div>
</body>
</html>
3、第一块元素浮动,第二块元素加margin值等于第一块元素,在IE6下会有间隙问题
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <style> body{ margin: 0; } .box{ width: 500px; } .left{ width: 200px; height: 200px; background-color: red; float: left; } .right{ width: 200px; height: 200px; background-color: blue; /*margin-left: 200px;*/ /*这里要注意,不用这种布局*/ float: left; } </style> <!-- IE6下中间会出现空白缝隙 解决方案: 1、不建议一个元素浮动,另一个元素用margin-浮动方向:200px。这么写 2、直接用浮动,就不会出现这种问题解决 --> </head> <body> <div class="box"> <div class="left"></div> <div class="right"></div> </div> </body> </html>
4、IE6下子元素超出父级宽高,会把父级的宽高撑开
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <style> .box{ width: 100px; height: 100px; border: 10px solid #000; } .content{ width: 200px; height: 200px; background-color: red; } </style> <!-- 解决方案: 不要让子元素的宽高超过父级 --> </head> <body> <div class="box"> <div class="content"></div> </div> </body> </html>
5、p 包含块元素嵌套规则
p标签 h标签 不要包含块元素
6、margin兼容性问题
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <style> .box{ background-color: green; overflow: hidden; zoom:1; } .item{ height: 50px; background-color: red; margin-top: 50px; } .mt100{ margin-top: 100px; } </style> <!-- 1、margin-top传递 触发BFC、haslayout,样式加 overflow: hidden;标准浏览器中可以解决问题,IE6中加 zoom:1;可以解决 2、上下margin叠压 尽量使用同一方向的margin,比如都设置top或者bottom,让一个margin:100px; 不要让一个margin-bottom:50px;另一个margin-top:50px,这种叠加方式 --> </head> <body> <div class="box"> <div class="item"></div> <div class="item mt100"></div> </div> </body> </html>
7、display:inline-block
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <style> div{ width: 100px; height: 100px; background-color: red; display: inline-block; *display:inline; *zoom:1; } </style> <!-- IE6 并不支持 display: inline-block; 因为这个属性是CSS2.1出来的 解决方案是在样式中添加代码: *display:inline; *zoom:1; --> </head> <body> <div>div</div> <div>div</div> <div>div</div> </body> </html>
8、IE6 最小高度问题
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <style> div{ height: 1px; background-color: red; overflow: hidden; /*兼容IE6*/ } </style> <!-- IE6下最小高度19px,即便设置为1px,在IE6下也是19的高度 解决方案: overflow:hidden; --> </head> <body> <div></div> </body> </html>
9、IE6 双边距
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <style> body{ margin: 0; } .box{ width: 750px; border: 1px solid #000; overflow: hidden; } .item{ width: 200px; height: 200px; background-color: red; margin-left: 50px; float: left; /**display: inline;*/ } </style> <!-- 当元素浮动后再设置margin那么就会产生双倍边距 解决方案: 针对ie6、7添加 display:inline 只针对IE添加 前面加个*号 --> </head> <body> <div class="box"> <div class="item"></div> <div class="item"></div> <div class="item"></div> </div> </body> </html>
IE6下的双边距,将块元素挤到下一行。
10、li 里元素都浮动 li 在IE6 7 下方会产生4px间隙问题
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <style> .list{ margin: 0; padding: 0; list-style: none; width: 300px; } .list li{ height: 30px; border: 1px solid red; line-height: 30px; /**vertical-align: top;*/ } .list li a{ float: left; } .list li span{ float: right; } </style> <!-- 在IE6下 li 与 li 之间存在间隙 解决方案: 针对ie6,7添加vertical-align: top; --> </head> <body> <ul class="list"> <li> <a href="">左边</a> <span>右边</span> </li> <li> <a href="">左边</a> <span>右边</span> </li> <li> <a href="">左边</a> <span>右边</span> </li> <li> <a href="">左边</a> <span>右边</span> </li> </ul> </body> </html>
11、浮动元素之间注释,导致多复制一个文字问题
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <style> .wrap{ width: 400px; } .left{ float: left; } .right{ width: 398px; float: right; } </style> <!-- 两个浮动元素中间有注释或者内联元素并且和父级宽度相差不超过3px的时候会出现“小尾巴” 解决方案: 1、两个浮动元素中间避免出现内联元素或者注释 2、与父级宽度相差3px或以上 --> </head> <body> <div class="wrap"> <div class="left"></div> <span></span><!-- IE下文字溢出BUG --> <div class="right">↓这是多出来的一只猪</div> </div> </body> </html>
12、IE6 7 父级元素的overflow:hidden 是包不住子级的relative
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <style> .box{ width: 200px; height: 200px; background-color: red; border: 10px solid black; overflow: hidden; *position: relative; /* 针对ie6、7给父级元素添加相对定位 */ } .content{ width: 400px; height: 400px; background-color: blue; position: relative; } </style> <!-- 解决方案: 针对ie6、7给父级元素添加相对定位,让父级和子级处于一个相同的环境 --> </head> <body> <div class="box"> <div class="content"></div> </div> </body> </html>
13、IE6下绝对定位元素父级宽高是奇数,绝对定位元素的right和bottom值会有1px的偏差
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <style> .box{ width: 308px; height: 308px; background-color: red; position: absolute; } .content{ width: 100px; height: 100px; background-color: blue; position: absolute; right: 0; bottom: 0; /*left:0;*/ /*top: 0; 对上和左并没有影响 */ } </style> <!-- 解决方案: 避免父级宽高出现奇数 --> </head> <body> <div class="box"> <div class="content"></div> </div> </body> </html>
14、IE6下绝对定位元素和浮动元素并列,绝对定位元素消失
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <style> .box{ width: 200px; height: 200px; border: 1px solid black; position: relative; } .item{ width: 150px; height: 150px; background-color: red; float: left; margin-left: 50px; *display: inline; } .box span{ width: 50px; height: 50px; background-color: yellow; position: absolute; right: -10px; top: -10px; } </style> <!-- 解决方案: 浮动元素和绝对定位元素是同级的话定位元素就会消失。所以咱们只要让他们俩不处于同级就可以避免这个bug。 --> </head> <body> <div class="box"> <div class="item"></div> <p> <!--在这里原来的span标签是与<div class="item"></div>同级并列的, 但是为了去除IE6的不兼容,将span标签放入在p标签中了,这样二者就不是并列关系了,所以不兼容情况解决--> <span></span> </p> </div> </body> </html>
15、IE6 下input的空隙
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <style> .box{ width: 200px; border: 1px solid #000000; background-color: red; } .box input{ border: 0; margin: 0; width: 200px; height: 30px; background-color: #fff; *float: left; /*针对IE6 7增加个浮动*/ } </style> <!-- 解决方案: 给input元素添加float --> </head> <body> <div class="box"> <input type="text" /> </div> </body> </html>
16、IE6 下 输入类型表单控件背景问题
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title></title> <style type="text/css"> input{ /*当输入框存在背景图片的时候,随着输入背景图片也跟着移动,这个时候要使用fixed属性将背景图片固定*/ background: url("img/bg_icon.jpg") no-repeat fixed; } </style> </head> <body> <input type="text"> <!-- 解决办法:给背景添加 background-attachment: fixed; 属性 --> </body> </html>
二、CSS hack
hack 黑客? (原意:修改)
针对不同的浏览器写不同的CSS 样式的过程,就叫CSS hack!
\9 所有的IE10及之前
* IE7及ie7以下的ie浏览器认识
_IE6及ie6的ie浏览器认识 远离css hack,有益身心健康!
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <style> div{ width: 200px; height: 200px; background-color: red; background-color: blue\9; *background-color: green; _background-color: yellow; } </style> <!-- \9 (前面加 \9)IE10以及IE10以下版本的 * (前面加下星号)IE7以及IE7以下版本的 _(前面加下划线)IE6以及IE6以下版本的 --> </head> <body> <div></div> </body> </html>
三、PNG24 兼容性问题
IE6不支持png24 图片。
两种方法:
方法1:调用JS
解决方案: JS插件(问题:不能处理body之上png24) DD_belatedPNG.fix('xxx');
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <script src="js/DD_belatedPNG_0.0.8a.js"></script> <script> DD_belatedPNG.fix("img, div"); </script> <style> body{ background-color: red; } div{ width: 300px; height: 300px; background: url("img/png.png") no-repeat; } </style> </head> <body> <div></div> <img src="img/png.png" alt="" /> </body> </html>
/** * DD_belatedPNG: Adds IE6 support: PNG images for CSS background-image and HTML <IMG/>. * Author: Drew Diller * Email: drew.diller@gmail.com * URL: http://www.dillerdesign.com/experiment/DD_belatedPNG/ * Version: 0.0.8a * Licensed under the MIT License: http://dillerdesign.com/experiment/DD_belatedPNG/#license * * Example usage: * DD_belatedPNG.fix('.png_bg'); // argument is a CSS selector * DD_belatedPNG.fixPng( someNode ); // argument is an HTMLDomElement **/ /* PLEASE READ: Absolutely everything in this script is SILLY. I know this. IE's rendering of certain pixels doesn't make sense, so neither does this code! */ var DD_belatedPNG = { ns: 'DD_belatedPNG', imgSize: {}, delay: 10, nodesFixed: 0, createVmlNameSpace: function () { /* enable VML */ if (document.namespaces && !document.namespaces[this.ns]) { document.namespaces.add(this.ns, 'urn:schemas-microsoft-com:vml'); } }, createVmlStyleSheet: function () { /* style VML, enable behaviors */ /* Just in case lots of other developers have added lots of other stylesheets using document.createStyleSheet and hit the 31-limit mark, let's not use that method! further reading: http://msdn.microsoft.com/en-us/library/ms531194(VS.85).aspx */ var screenStyleSheet, printStyleSheet; screenStyleSheet = document.createElement('style'); screenStyleSheet.setAttribute('media', 'screen'); document.documentElement.firstChild.insertBefore(screenStyleSheet, document.documentElement.firstChild.firstChild); if (screenStyleSheet.styleSheet) { screenStyleSheet = screenStyleSheet.styleSheet; screenStyleSheet.addRule(this.ns + '\\:*', '{behavior:url(#default#VML)}'); screenStyleSheet.addRule(this.ns + '\\:shape', 'position:absolute;'); screenStyleSheet.addRule('img.' + this.ns + '_sizeFinder', 'behavior:none; border:none; position:absolute; z-index:-1; top:-10000px; visibility:hidden;'); /* large negative top value for avoiding vertical scrollbars for large images, suggested by James O'Brien, http://www.thanatopsic.org/hendrik/ */ this.screenStyleSheet = screenStyleSheet; /* Add a print-media stylesheet, for preventing VML artifacts from showing up in print (including preview). */ /* Thanks to R�mi Pr�vost for automating this! */ printStyleSheet = document.createElement('style'); printStyleSheet.setAttribute('media', 'print'); document.documentElement.firstChild.insertBefore(printStyleSheet, document.documentElement.firstChild.firstChild); printStyleSheet = printStyleSheet.styleSheet; printStyleSheet.addRule(this.ns + '\\:*', '{display: none !important;}'); printStyleSheet.addRule('img.' + this.ns + '_sizeFinder', '{display: none !important;}'); } }, readPropertyChange: function () { var el, display, v; el = event.srcElement; if (!el.vmlInitiated) { return; } if (event.propertyName.search('background') != -1 || event.propertyName.search('border') != -1) { DD_belatedPNG.applyVML(el); } if (event.propertyName == 'style.display') { display = (el.currentStyle.display == 'none') ? 'none' : 'block'; for (v in el.vml) { if (el.vml.hasOwnProperty(v)) { el.vml[v].shape.style.display = display; } } } if (event.propertyName.search('filter') != -1) { DD_belatedPNG.vmlOpacity(el); } }, vmlOpacity: function (el) { if (el.currentStyle.filter.search('lpha') != -1) { var trans = el.currentStyle.filter; trans = parseInt(trans.substring(trans.lastIndexOf('=')+1, trans.lastIndexOf(')')), 10)/100; el.vml.color.shape.style.filter = el.currentStyle.filter; /* complete guesswork */ el.vml.image.fill.opacity = trans; /* complete guesswork */ } }, handlePseudoHover: function (el) { setTimeout(function () { /* wouldn't work as intended without setTimeout */ DD_belatedPNG.applyVML(el); }, 1); }, /** * This is the method to use in a document. * @param {String} selector - REQUIRED - a CSS selector, such as '#doc .container' **/ fix: function (selector) { if (this.screenStyleSheet) { var selectors, i; selectors = selector.split(','); /* multiple selectors supported, no need for multiple calls to this anymore */ for (i=0; i<selectors.length; i++) { this.screenStyleSheet.addRule(selectors[i], 'behavior:expression(DD_belatedPNG.fixPng(this))'); /* seems to execute the function without adding it to the stylesheet - interesting... */ } } }, applyVML: function (el) { el.runtimeStyle.cssText = ''; this.vmlFill(el); this.vmlOffsets(el); this.vmlOpacity(el); if (el.isImg) { this.copyImageBorders(el); } }, attachHandlers: function (el) { var self, handlers, handler, moreForAs, a, h; self = this; handlers = {resize: 'vmlOffsets', move: 'vmlOffsets'}; if (el.nodeName == 'A') { moreForAs = {mouseleave: 'handlePseudoHover', mouseenter: 'handlePseudoHover', focus: 'handlePseudoHover', blur: 'handlePseudoHover'}; for (a in moreForAs) { if (moreForAs.hasOwnProperty(a)) { handlers[a] = moreForAs[a]; } } } for (h in handlers) { if (handlers.hasOwnProperty(h)) { handler = function () { self[handlers[h]](el); }; el.attachEvent('on' + h, handler); } } el.attachEvent('onpropertychange', this.readPropertyChange); }, giveLayout: function (el) { el.style.zoom = 1; if (el.currentStyle.position == 'static') { el.style.position = 'relative'; } }, copyImageBorders: function (el) { var styles, s; styles = {'borderStyle':true, 'borderWidth':true, 'borderColor':true}; for (s in styles) { if (styles.hasOwnProperty(s)) { el.vml.color.shape.style[s] = el.currentStyle[s]; } } }, vmlFill: function (el) { if (!el.currentStyle) { return; } else { var elStyle, noImg, lib, v, img, imgLoaded; elStyle = el.currentStyle; } for (v in el.vml) { if (el.vml.hasOwnProperty(v)) { el.vml[v].shape.style.zIndex = elStyle.zIndex; } } el.runtimeStyle.backgroundColor = ''; el.runtimeStyle.backgroundImage = ''; noImg = true; if (elStyle.backgroundImage != 'none' || el.isImg) { if (!el.isImg) { el.vmlBg = elStyle.backgroundImage; el.vmlBg = el.vmlBg.substr(5, el.vmlBg.lastIndexOf('")')-5); } else { el.vmlBg = el.src; } lib = this; if (!lib.imgSize[el.vmlBg]) { /* determine size of loaded image */ img = document.createElement('img'); lib.imgSize[el.vmlBg] = img; img.className = lib.ns + '_sizeFinder'; img.runtimeStyle.cssText = 'behavior:none; position:absolute; left:-10000px; top:-10000px; border:none; margin:0; padding:0;'; /* make sure to set behavior to none to prevent accidental matching of the helper elements! */ imgLoaded = function () { this.width = this.offsetWidth; /* weird cache-busting requirement! */ this.height = this.offsetHeight; lib.vmlOffsets(el); }; img.attachEvent('onload', imgLoaded); img.src = el.vmlBg; img.removeAttribute('width'); img.removeAttribute('height'); document.body.insertBefore(img, document.body.firstChild); } el.vml.image.fill.src = el.vmlBg; noImg = false; } el.vml.image.fill.on = !noImg; el.vml.image.fill.color = 'none'; el.vml.color.shape.style.backgroundColor = elStyle.backgroundColor; el.runtimeStyle.backgroundImage = 'none'; el.runtimeStyle.backgroundColor = 'transparent'; }, /* IE can't figure out what do when the offsetLeft and the clientLeft add up to 1, and the VML ends up getting fuzzy... so we have to push/enlarge things by 1 pixel and then clip off the excess */ vmlOffsets: function (el) { var thisStyle, size, fudge, makeVisible, bg, bgR, dC, altC, b, c, v; thisStyle = el.currentStyle; size = {'W':el.clientWidth+1, 'H':el.clientHeight+1, 'w':this.imgSize[el.vmlBg].width, 'h':this.imgSize[el.vmlBg].height, 'L':el.offsetLeft, 'T':el.offsetTop, 'bLW':el.clientLeft, 'bTW':el.clientTop}; fudge = (size.L + size.bLW == 1) ? 1 : 0; /* vml shape, left, top, width, height, origin */ makeVisible = function (vml, l, t, w, h, o) { vml.coordsize = w+','+h; vml.coordorigin = o+','+o; vml.path = 'm0,0l'+w+',0l'+w+','+h+'l0,'+h+' xe'; vml.style.width = w + 'px'; vml.style.height = h + 'px'; vml.style.left = l + 'px'; vml.style.top = t + 'px'; }; makeVisible(el.vml.color.shape, (size.L + (el.isImg ? 0 : size.bLW)), (size.T + (el.isImg ? 0 : size.bTW)), (size.W-1), (size.H-1), 0); makeVisible(el.vml.image.shape, (size.L + size.bLW), (size.T + size.bTW), (size.W), (size.H), 1 ); bg = {'X':0, 'Y':0}; if (el.isImg) { bg.X = parseInt(thisStyle.paddingLeft, 10) + 1; bg.Y = parseInt(thisStyle.paddingTop, 10) + 1; } else { for (b in bg) { if (bg.hasOwnProperty(b)) { this.figurePercentage(bg, size, b, thisStyle['backgroundPosition'+b]); } } } el.vml.image.fill.position = (bg.X/size.W) + ',' + (bg.Y/size.H); bgR = thisStyle.backgroundRepeat; dC = {'T':1, 'R':size.W+fudge, 'B':size.H, 'L':1+fudge}; /* these are defaults for repeat of any kind */ altC = { 'X': {'b1': 'L', 'b2': 'R', 'd': 'W'}, 'Y': {'b1': 'T', 'b2': 'B', 'd': 'H'} }; if (bgR != 'repeat' || el.isImg) { c = {'T':(bg.Y), 'R':(bg.X+size.w), 'B':(bg.Y+size.h), 'L':(bg.X)}; /* these are defaults for no-repeat - clips down to the image location */ if (bgR.search('repeat-') != -1) { /* now let's revert to dC for repeat-x or repeat-y */ v = bgR.split('repeat-')[1].toUpperCase(); c[altC[v].b1] = 1; c[altC[v].b2] = size[altC[v].d]; } if (c.B > size.H) { c.B = size.H; } el.vml.image.shape.style.clip = 'rect('+c.T+'px '+(c.R+fudge)+'px '+c.B+'px '+(c.L+fudge)+'px)'; } else { el.vml.image.shape.style.clip = 'rect('+dC.T+'px '+dC.R+'px '+dC.B+'px '+dC.L+'px)'; } }, figurePercentage: function (bg, size, axis, position) { var horizontal, fraction; fraction = true; horizontal = (axis == 'X'); switch(position) { case 'left': case 'top': bg[axis] = 0; break; case 'center': bg[axis] = 0.5; break; case 'right': case 'bottom': bg[axis] = 1; break; default: if (position.search('%') != -1) { bg[axis] = parseInt(position, 10) / 100; } else { fraction = false; } } bg[axis] = Math.ceil( fraction ? ( (size[horizontal?'W': 'H'] * bg[axis]) - (size[horizontal?'w': 'h'] * bg[axis]) ) : parseInt(position, 10) ); if (bg[axis] % 2 === 0) { bg[axis]++; } return bg[axis]; }, fixPng: function (el) { el.style.behavior = 'none'; var lib, els, nodeStr, v, e; if (el.nodeName == 'BODY' || el.nodeName == 'TD' || el.nodeName == 'TR') { /* elements not supported yet */ return; } el.isImg = false; if (el.nodeName == 'IMG') { if(el.src.toLowerCase().search(/\.png$/) != -1) { el.isImg = true; el.style.visibility = 'hidden'; } else { return; } } else if (el.currentStyle.backgroundImage.toLowerCase().search('.png') == -1) { return; } lib = DD_belatedPNG; el.vml = {color: {}, image: {}}; els = {shape: {}, fill: {}}; for (v in el.vml) { if (el.vml.hasOwnProperty(v)) { for (e in els) { if (els.hasOwnProperty(e)) { nodeStr = lib.ns + ':' + e; el.vml[v][e] = document.createElement(nodeStr); } } el.vml[v].shape.stroked = false; el.vml[v].shape.appendChild(el.vml[v].fill); el.parentNode.insertBefore(el.vml[v].shape, el); } } el.vml.image.shape.fillcolor = 'none'; /* Don't show blank white shapeangle when waiting for image to load. */ el.vml.image.fill.type = 'tile'; /* Makes image show up. */ el.vml.color.fill.on = false; /* Actually going to apply vml element's style.backgroundColor, so hide the whiteness. */ lib.attachHandlers(el); lib.giveLayout(el); lib.giveLayout(el.offsetParent); el.vmlInitiated = true; lib.applyVML(el); /* Render! */ } }; try { document.execCommand("BackgroundImageCache", false, true); /* TredoSoft Multiple IE doesn't like this, so try{} it */ } catch(r) {} DD_belatedPNG.createVmlNameSpace(); DD_belatedPNG.createVmlStyleSheet();
方法2:
原生滤镜 _background:none;_filter : progid:DXImageTransform.Microsoft.AlphaImageLoader(src="XX.png", sizingMethod="crop");
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <script src="js/DD_belatedPNG_0.0.8a.js"></script> <script> DD_belatedPNG.fix("body"); </script> <style> body{ width: 500px; height: 500px; background:red url("img/png.png") no-repeat; _background-image:none; _filter : progid:DXImageTransform.Microsoft.AlphaImageLoader(src="img/png.png", sizingMethod="crop"); } </style> </head> <body> </body> </html>
四、样式优先级、提升样式优先级
默认 < 类型 < class < id < style(行间) < !important
!important 提升样式优先级权重