ฉันกำลังพัฒนาหน้าเว็บในสภาพแวดล้อมเว็บเบราว์เซอร์แบบผสม (Chrome / IE11) IE11 ไม่รองรับตัวแปร CSS มีโพลีฟิลล์หรือสคริปต์ที่อนุญาตให้ฉันใช้ตัวแปร CSS ใน IE11 หรือไม่
ฉันกำลังพัฒนาหน้าเว็บในสภาพแวดล้อมเว็บเบราว์เซอร์แบบผสม (Chrome / IE11) IE11 ไม่รองรับตัวแปร CSS มีโพลีฟิลล์หรือสคริปต์ที่อนุญาตให้ฉันใช้ตัวแปร CSS ใน IE11 หรือไม่
คำตอบ:
ใช่ตราบใดที่คุณกำลังประมวลผลคุณสมบัติแบบกำหนดเองระดับรูท (IE9 +)
จาก README:
คุณสมบัติ
- การแปลงคุณสมบัติที่กำหนดเองของ CSS เป็นค่าคงที่
- การอัปเดตค่ารันไทม์แบบสดทั้งในเบราว์เซอร์รุ่นใหม่และเบราว์เซอร์รุ่นเก่า
- แปลง
<link>
,<style>
และ@import
CSS- แปลง
url()
เส้นทางสัมพัทธ์เป็น URL ที่สมบูรณ์- รองรับ
var()
ฟังก์ชันที่ถูกล่ามโซ่และซ้อนกัน- รองรับ
var()
ค่าทางเลือกของฟังก์ชัน- รองรับส่วนประกอบของเว็บ / Shadow DOM CSS
- โหมดนาฬิกาอัปเดตอัตโนมัติ
<link>
และ<style>
การเปลี่ยนแปลง- มีโมดูล UMD และ ES6
- รวมนิยาม TypeScript
- น้ำหนักเบา (6k นาที + gzip) และปราศจากการพึ่งพา
ข้อ จำกัด
- การสนับสนุนคุณสมบัติแบบกำหนดเองถูก จำกัด ไว้ที่
:root
และ:host
การประกาศ- การใช้ var () ถูก จำกัด ไว้ที่ค่าคุณสมบัติ (ตามข้อกำหนด W3C )
นี่คือตัวอย่างบางส่วนของสิ่งที่ไลบรารีสามารถจัดการได้:
คุณสมบัติแบบกำหนดเองระดับรูท
: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>
, <style>
และ@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>
แปลงส่วนประกอบของเว็บ / Shadow DOM
<custom-element>
#shadow-root
<style>
.my-custom-element {
color: var(--test-color);
}
</style>
<div class="my-custom-element">Hello.</div>
</custom-element>
เพื่อความสมบูรณ์: ข้อกำหนด w3c
หวังว่านี่จะช่วยได้
(โปรโมทตัวเองไร้ยางอาย: ตรวจสอบ)
--primary: #aaa
ประกาศจะไม่ถูกประมวลผล คำอธิบายรายละเอียดที่ระบุไว้ในปัญหานี้: ขยายการสนับสนุนด้านนอกของราก
:root
ข้อ จำกัด ไม่ใช่ปัญหาสำหรับฉัน { exclude: '[href*=jquery-ui],...', preserveStatic: false }
สำหรับการเพิ่มประสิทธิภาพการทำงานต่อไปตรวจสอบตัวเลือกเช่น
polyfill นี้ช่วยให้รองรับ Custom Properties ได้เกือบสมบูรณ์ ( ไม่ใช่เฉพาะระดับรูท ) ใน IE11:
https://github.com/nuxodin/ie11CustomProperties
สคริปต์ใช้ประโยชน์จากข้อเท็จจริงที่ว่า IE มีการสนับสนุนคุณสมบัติที่กำหนดเองน้อยที่สุดซึ่งคุณสมบัติสามารถกำหนดและอ่านได้โดยคำนึงถึงน้ำตก
.myEl {-ie-test:'aaa'} // only one dash allowed! "-"
จากนั้นอ่านในจาวาสคริปต์:
getComputedStyle( querySelector('.myEl') )['-ie-test']
- จัดการเนื้อหา html ที่เพิ่มแบบไดนามิก
- จับแบบไดนามิกเพิ่ม
<style>
,<link>
-elements- การล่ามโซ่
--bar:var(--foo)
- รั้งท้าย
var(--color, blue)
- : focus,: target,: hover
- รวม js:
style.setProperty('--x','y')
style.getPropertyValue('--x')
getComputedStyle(el).getPropertyValue('--inherited')
- รูปแบบอินไลน์:
<div ie-style="--color:blue"...
- งานน้ำตก
- งานมรดก
- ต่ำกว่า 3k (min + gzip) และไม่มีการพึ่งพา
<script src="yourJsPath/ie11CustomProperties.js"></script>
ในส่วนหัวของไฟล์ HTML ของคุณและ IE11 จะทำงานร่วมกัน
+1 สำหรับลิงก์ข้อมูลโค้ดปากกาในส่วนความคิดเห็นของคำถามด้านบนโดย [I has kode] สิ่งหนึ่งที่ฉันพบคือข้อมูลโค้ดต้องได้รับการแก้ไขเล็กน้อยเพื่อให้มีการประกาศฟังก์ชันที่กำหนดในรูปแบบ JSON เพื่อให้ IE11 ไม่บ่น ด้านล่างนี้คือข้อมูลโค้ดปากการุ่นแก้ไขเล็กน้อย:
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();
ฉันลองใช้ 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();
ในการรองรับ Internet Explorer เพียงใช้สคริปต์ด้านล่างในแท็กหัว index.html และมันก็ทำงานได้อย่างมีเสน่ห์
<script>window.MSInputMethodContext && document.documentMode && document.write('<script src="https://cdn.jsdelivr.net/gh/nuxodin/ie11CustomProperties@4.1.0/ie11CustomProperties.min.js"><\x2fscript>');</script>