2017-09-26 58 views
6

我正在開發混合網頁瀏覽器環境(Chrome/IE11)中的網頁。 IE11不支持CSS變量,是否有一個可以讓我在IE11中使用CSS變量的polyfill或腳本?IE11 - CSS變量是否存在填充/腳本?

+0

什麼樣的css變量? – bhansa

+3

https://codepen.io/aaronbarker/pen/MeaRmL –

回答

6

對於[我有kode]上面的問題註釋部分中的代碼筆片段鏈接+1。我發現的一件事是,該代碼片段需要稍微修改,以使IE11的JSON格式定義的函數聲明不會發生抱怨。下面是代碼片段筆的略微修改的版本:

let cssVarPoly = { 
    init: function() { 
     // first lets see if the browser supports CSS variables 
     // No version of IE supports window.CSS.supports, so if that isn't supported in the first place we know CSS variables is not supported 
     // Edge supports supports, so check for actual variable support 
     if (window.CSS && window.CSS.supports && window.CSS.supports('(--foo: red)')) { 
      // this browser does support variables, abort 
      console.log('your browser supports CSS variables, aborting and letting the native support handle things.'); 
      return; 
     } else { 
      // edge barfs on console statements if the console is not open... lame! 
      console.log('no support for you! polyfill all (some of) the things!!'); 
      document.querySelector('body').classList.add('cssvars-polyfilled'); 
     } 

     cssVarPoly.ratifiedVars = {}; 
     cssVarPoly.varsByBlock = {}; 
     cssVarPoly.oldCSS = {}; 

     // start things off 
     cssVarPoly.findCSS(); 
     cssVarPoly.updateCSS(); 
    }, 

    // find all the css blocks, save off the content, and look for variables 
    findCSS: function() { 
     let styleBlocks = document.querySelectorAll('style:not(.inserted),link[type="text/css"]'); 

     // we need to track the order of the style/link elements when we save off the CSS, set a counter 
     let counter = 1; 

     // loop through all CSS blocks looking for CSS variables being set 
     [].forEach.call(styleBlocks, function (block) { 
      // console.log(block.nodeName); 
      let theCSS; 
      if (block.nodeName === 'STYLE') { 
       // console.log("style"); 
       theCSS = block.innerHTML; 
       cssVarPoly.findSetters(theCSS, counter); 
      } else if (block.nodeName === 'LINK') { 
       // console.log("link"); 
       cssVarPoly.getLink(block.getAttribute('href'), counter, function (counter, request) { 
        cssVarPoly.findSetters(request.responseText, counter); 
        cssVarPoly.oldCSS[counter] = request.responseText; 
        cssVarPoly.updateCSS(); 
       }); 
       theCSS = ''; 
      } 
      // save off the CSS to parse through again later. the value may be empty for links that are waiting for their ajax return, but this will maintain the order 
      cssVarPoly.oldCSS[counter] = theCSS; 
      counter++; 
     }); 
    }, 

    // find all the "--variable: value" matches in a provided block of CSS and add them to the master list 
    findSetters: function(theCSS, counter) { 
     // console.log(theCSS); 
     cssVarPoly.varsByBlock[counter] = theCSS.match(/(--.+:.+;)/g) || []; 
    }, 

    // run through all the CSS blocks to update the variables and then inject on the page 
    updateCSS: function() { 
     // first lets loop through all the variables to make sure later vars trump earlier vars 
     cssVarPoly.ratifySetters(cssVarPoly.varsByBlock); 

     // loop through the css blocks (styles and links) 
     for (let curCSSID in cssVarPoly.oldCSS) { 
      // console.log("curCSS:",oldCSS[curCSSID]); 
      let newCSS = cssVarPoly.replaceGetters(cssVarPoly.oldCSS[curCSSID], cssVarPoly.ratifiedVars); 
      // put it back into the page 
      // first check to see if this block exists already 
      if (document.querySelector('#inserted' + curCSSID)) { 
       // console.log("updating") 
       document.querySelector('#inserted' + curCSSID).innerHTML = newCSS; 
      } else { 
       // console.log("adding"); 
       var style = document.createElement('style'); 
       style.type = 'text/css'; 
       style.innerHTML = newCSS; 
       style.classList.add('inserted'); 
       style.id = 'inserted' + curCSSID; 
       document.getElementsByTagName('head')[0].appendChild(style); 
      } 
     }; 
    }, 

    // parse a provided block of CSS looking for a provided list of variables and replace the --var-name with the correct value 
    replaceGetters: function(curCSS, varList) { 
     // console.log(varList); 
     for (let theVar in varList) { 
      // console.log(theVar); 
      // match the variable with the actual variable name 
      let getterRegex = new RegExp('var\\(\\s*' + theVar + '\\s*\\)', 'g'); 
      // console.log(getterRegex); 
      // console.log(curCSS); 
      curCSS = curCSS.replace(getterRegex, varList[theVar]); 

      // now check for any getters that are left that have fallbacks 
      let getterRegex2 = new RegExp('var\\(\\s*.+\\s*,\\s*(.+)\\)', 'g'); 
      // console.log(getterRegex); 
      // console.log(curCSS); 
      let matches = curCSS.match(getterRegex2); 
      if (matches) { 
       // console.log("matches",matches); 
       matches.forEach(function (match) { 
        // console.log(match.match(/var\(.+,\s*(.+)\)/)) 
        // find the fallback within the getter 
        curCSS = curCSS.replace(match, match.match(/var\(.+,\s*(.+)\)/)[1]); 
       }); 

      } 

      // curCSS = curCSS.replace(getterRegex2,varList[theVar]); 
     }; 
     // console.log(curCSS); 
     return curCSS; 
    }, 

    // determine the css variable name value pair and track the latest 
    ratifySetters: function(varList) { 
     // console.log("varList:",varList); 
     // loop through each block in order, to maintain order specificity 
     for (let curBlock in varList) { 
      let curVars = varList[curBlock]; 
      // console.log("curVars:",curVars); 
      // loop through each var in the block 
      curVars.forEach(function (theVar) { 
       // console.log(theVar); 
       // split on the name value pair separator 
       let matches = theVar.split(/:\s*/); 
       // console.log(matches); 
       // put it in an object based on the varName. Each time we do this it will override a previous use and so will always have the last set be the winner 
       // 0 = the name, 1 = the value, strip off the ; if it is there 
       cssVarPoly.ratifiedVars[matches[0]] = matches[1].replace(/;/, ''); 
      }); 
     }; 
     // console.log(ratifiedVars); 
    }, 

    // get the CSS file (same domain for now) 
    getLink: function(url, counter, success) { 
     var request = new XMLHttpRequest(); 
     request.open('GET', url, true); 
     request.overrideMimeType('text/css;'); 
     request.onload = function() { 
      if (request.status >= 200 && request.status < 400) { 
       // Success! 
       // console.log(request.responseText); 
       if (typeof success === 'function') { 
        success(counter, request); 
       } 
      } else { 
       // We reached our target server, but it returned an error 
       console.warn('an error was returned from:', url); 
      } 
     }; 

     request.onerror = function() { 
      // There was a connection error of some sort 
      console.warn('we could not get anything from:', url); 
     }; 

     request.send(); 
    } 

}; 

cssVarPoly.init(); 
0

我一直在使用的VS,因爲它並不微小期間喜歡CSS3變量不同的選擇,是SASS(SCSS),它可以讓我創建大量的變量,並簡化爲CSS文件。

0

我試過這個版本的Polyfill,但是當CSS中的一行有多個變量(FI字體和顏色)時出現錯誤。我的一位同事幫助我。 見線94

let cssVarPoly = { 
    init: function() { 
     // first lets see if the browser supports CSS variables 
     // No version of IE supports window.CSS.supports, so if that isn't supported in the first place we know CSS variables is not supported 
     // Edge supports supports, so check for actual variable support 
     if (window.CSS && window.CSS.supports && window.CSS.supports('(--foo: red)')) { 
      // this browser does support variables, abort 
      // console.log('your browser supports CSS variables, aborting and letting the native support handle things.'); 
      return; 
     } else { 
      // edge barfs on console statements if the console is not open... lame! 
      // console.log('no support for you! polyfill all (some of) the things!!'); 
      document.querySelector('body').classList.add('cssvars-polyfilled'); 
     } 

     cssVarPoly.ratifiedVars = {}; 
     cssVarPoly.varsByBlock = {}; 
     cssVarPoly.oldCSS = {}; 

     // start things off 
     cssVarPoly.findCSS(); 
     cssVarPoly.updateCSS(); 
    }, 

    // find all the css blocks, save off the content, and look for variables 
    findCSS: function() { 
     let styleBlocks = document.querySelectorAll('style:not(.inserted),link[type="text/css"]'); 

     // we need to track the order of the style/link elements when we save off the CSS, set a counter 
     let counter = 1; 

     // loop through all CSS blocks looking for CSS variables being set 
     [].forEach.call(styleBlocks, function (block) { 
      // console.log(block.nodeName); 
      let theCSS; 
      if (block.nodeName === 'STYLE') { 
       // console.log("style"); 
       theCSS = block.innerHTML; 
       cssVarPoly.findSetters(theCSS, counter); 
      } else if (block.nodeName === 'LINK') { 
       // console.log("link"); 
       cssVarPoly.getLink(block.getAttribute('href'), counter, function (counter, request) { 
        cssVarPoly.findSetters(request.responseText, counter); 
        cssVarPoly.oldCSS[counter] = request.responseText; 
        cssVarPoly.updateCSS(); 
       }); 
       theCSS = ''; 
      } 
      // save off the CSS to parse through again later. the value may be empty for links that are waiting for their ajax return, but this will maintain the order 
      cssVarPoly.oldCSS[counter] = theCSS; 
      counter++; 
     }); 
    }, 

    // find all the "--variable: value" matches in a provided block of CSS and add them to the master list 
    findSetters: function(theCSS, counter) { 
     // console.log(theCSS); 
     cssVarPoly.varsByBlock[counter] = theCSS.match(/(--.+:.+;)/g) || []; 
    }, 

    // run through all the CSS blocks to update the variables and then inject on the page 
    updateCSS: function() { 
     // first lets loop through all the variables to make sure later vars trump earlier vars 
     cssVarPoly.ratifySetters(cssVarPoly.varsByBlock); 

     // loop through the css blocks (styles and links) 
     for (let curCSSID in cssVarPoly.oldCSS) { 
      // console.log("curCSS:",oldCSS[curCSSID]); 
      let newCSS = cssVarPoly.replaceGetters(cssVarPoly.oldCSS[curCSSID], cssVarPoly.ratifiedVars); 
      // put it back into the page 
      // first check to see if this block exists already 
      if (document.querySelector('#inserted' + curCSSID)) { 
       // console.log("updating") 
       document.querySelector('#inserted' + curCSSID).innerHTML = newCSS; 
      } else { 
       // console.log("adding"); 
       var style = document.createElement('style'); 
       style.type = 'text/css'; 
       style.innerHTML = newCSS; 
       style.classList.add('inserted'); 
       style.id = 'inserted' + curCSSID; 
       document.getElementsByTagName('head')[0].appendChild(style); 
      } 
     }; 
    }, 

    // parse a provided block of CSS looking for a provided list of variables and replace the --var-name with the correct value 
    replaceGetters: function(curCSS, varList) { 
     // console.log(varList); 
     for (let theVar in varList) { 
      // console.log(theVar); 
      // match the variable with the actual variable name 
      // console.log (theVar); 
      var res = theVar.match(/--[a-zA-Z0-9-]+/g); 
      // console.log (res[0]); 
      theVar = res[0]; 
      let getterRegex = new RegExp('var\\(\\s*' + theVar + '\\s*\\)', 'g'); 
      // console.log(getterRegex); 
      // console.log(curCSS); 
      curCSS = curCSS.replace(getterRegex, varList[theVar]); 

      // now check for any getters that are left that have fallbacks 
      let getterRegex2 = new RegExp('var\\(\\s*.+\\s*,\\s*(.+)\\)', 'g'); 
      // console.log(getterRegex); 
      // console.log(curCSS); 
      let matches = curCSS.match(getterRegex2); 
      if (matches) { 
       // console.log("matches",matches); 
       matches.forEach(function (match) { 
        // console.log(match.match(/var\(.+,\s*(.+)\)/)) 
        // find the fallback within the getter 
        curCSS = curCSS.replace(match, match.match(/var\(.+,\s*(.+)\)/)[1]); 
       }); 
      } 

      // curCSS = curCSS.replace(getterRegex2,varList[theVar]); 
     }; 
     // console.log(curCSS); 
     return curCSS; 
    }, 

    // determine the css variable name value pair and track the latest 
    ratifySetters: function(varList) { 
     // console.log("varList:",varList); 
     // loop through each block in order, to maintain order specificity 
     for (let curBlock in varList) { 
      let curVars = varList[curBlock]; 
      // console.log("curVars:",curVars); 
      // loop through each var in the block 
      curVars.forEach(function (theVar) { 
       // console.log(theVar); 
       // split on the name value pair separator 
       let matches = theVar.split(/:\s*/); 
       // console.log(matches); 
       // put it in an object based on the varName. Each time we do this it will override a previous use and so will always have the last set be the winner 
       // 0 = the name, 1 = the value, strip off the ; if it is there 
       cssVarPoly.ratifiedVars[matches[0]] = matches[1].replace(/;/, ''); 
      }); 
     }; 
     // console.log(ratifiedVars); 
    }, 

    // get the CSS file (same domain for now) 
    getLink: function(url, counter, success) { 
     var request = new XMLHttpRequest(); 
     request.open('GET', url, true); 
     request.overrideMimeType('text/css;'); 
     request.onload = function() { 
      if (request.status >= 200 && request.status < 400) { 
       // Success! 
       // console.log(request.responseText); 
       if (typeof success === 'function') { 
        success(counter, request); 
       } 
      } else { 
       // We reached our target server, but it returned an error 
       console.warn('an error was returned from:', url); 
      } 
     }; 

     request.onerror = function() { 
      // There was a connection error of some sort 
      console.warn('we could not get anything from:', url); 
     }; 

     request.send(); 
    } 

}; 

cssVarPoly.init(); 
0

是的,只要你處理根級定製屬性(IE10 +)。

css-vars-ponyfill遠遠超出了在其他的答案中提到的codepen /填充工具可以處理。

自述:在傳統的瀏覽器CSS自定義屬性的靜態值

特點

  • 客戶端轉換
  • 在現代和傳統修改運行時的值統一接口瀏覽器
  • 傳統瀏覽器中後續調用的持久性更改
  • 支持自定義屬性的回退值
  • 可用UMD和ES6模塊
  • 重量輕(小於5K分鐘+ gzip的)和遊離的依賴性-

限制

  • 自定義屬性的支持限於:根聲明
  • var()的使用僅限於屬性值(根據W3C specification

這裏是什麼樣的庫可以處理的幾個例子:

根級定製屬性

:root { 
    --a: red; 
} 

p { 
    color: var(--a); 
} 

自定義屬性引用自定義屬性

:root { 
    --a: var(--b); 
    --b: var(--c); 
    --c: red; 
} 

p { 
    color: var(--a); 
} 

與自定義屬性複數值

:root { 
    --a: 1em; 
    --b: 2; 
} 

p { 
    font-size: calc(var(--a) * var(--b)); 
} 

回退值

p { 
    font-size: var(--a, 1rem); 
    color: var(--b, var(--c, var(--d, red))); 
} 

<link>@import規則進程CSS:

<link rel="stylesheet" href="/absolute/path/to/style.css"> 
<link rel="stylesheet" href="../relative/path/to/style.css"> 

<style> 
    @import "/absolute/path/to/style.css"; 
    @import "../relative/path/to/style.css"; 
</style> 

希望這會有所幫助。

(無恥自我推銷:支票)