IE11 - CSS değişkenleri için bir çoklu dolgu / komut dosyası var mı?


93

Karma bir web tarayıcısı ortamında (Chrome / IE11) bir web sayfası geliştiriyorum. IE11, CSS değişkenlerini desteklemiyor, IE11'de CSS değişkenlerini kullanmama izin verecek bir çoklu dolgu veya komut dosyası var mı?


Ne tür css değişkenleri?
bhansa


@ R.StackUser Do aşağıdaki yanıtlardan birini doğru olarak işaretleyin. Şerefe.
AndrewL64

Bu Custom-Properties-Polyfill'e bir göz atın: github.com/nuxodin/ie11CustomProperties
Tobias Buschor

Yanıtlar:


114

Evet, kök düzeyinde özel özellikleri (IE9 +) işlediğiniz sürece.

BENİOKU'dan:

Özellikleri

  • CSS özel özelliklerinin statik değerlere istemci tarafı dönüşümü
  • Hem modern hem de eski tarayıcılarda çalışma zamanı değerlerinin canlı güncellemeleri
  • Dönüşümler <link>, <style>ve @importCSS
  • Göreli url()yolları mutlak URL'lere dönüştürür
  • Zincirlenmiş ve iç içe geçmiş var()işlevleri destekler
  • var()İşlev geri dönüş değerlerini destekler
  • Web bileşenlerini / gölge DOM CSS'yi destekler
  • İzleme modu otomatik güncellemeleri açık <link>ve <style>değişiklikler
  • UMD ve ES6 modülü mevcuttur
  • TypeScript tanımları dahil
  • Hafif (6.000 dk + gzip) ve bağımlılık içermez

Sınırlamalar

  • Özel mülkiyet desteği ile sınırlıdır :rootve :hostbeyanlar
  • Var () kullanımı özellik değerleriyle sınırlıdır ( W3C spesifikasyonu başına )

İşte kitaplığın başa çıkabileceklerine dair birkaç örnek:

Kök düzeyinde özel özellikler

:root {
    --a: red;
}

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

Zincirlenmiş özel özellikler

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

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

İç içe geçmiş özel özellikler

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

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

Yedek değerler

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

Dönüşümler <link>, <style>ve @importCSS

<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>

Web bileşenlerini / gölge DOM'u dönüştürür

<custom-element>
  #shadow-root
    <style>
      .my-custom-element {
        color: var(--test-color);
      }
    </style>
    <div class="my-custom-element">Hello.</div>
</custom-element>

Eksiksizlik adına: w3c özellikleri

Bu yardımcı olur umarım.

(Utanmaz kendini tanıtma: Çek)


6
Kabul edilen cevap bu olmalıdır. Codepen özelliklerden yoksun olmakla kalmaz, aynı zamanda küçültülmüş css, arka plan görüntüsü değişkenleri, css'deki yorumlar vb. Gibi şeyleri idare edemez. Biliyorum çünkü kapsamlı bir şekilde test ettim. Ponyfill'i @jhildenbiddle'dan kullanmanızı tavsiye ederim
Andres M

Mükemmel! Teşekkür ederim!
Tackgnol

1
@Davey - ponyfill kapsamlı özel özellikleri desteklemiyor, bu nedenle --primary: #aaabildirim işlenmeyecek. Bu konuda daha ayrıntılı bir açıklama sağlanmıştır: Desteğin kök dışında genişletilmesi .
jhildenbiddle

2
@Davey IE'de özel özelliklerin değerine erişebilirsiniz, ancak "-" ile başlayamazsınız.
Çoklu dolgumun

1
Bilginize, bunu alternatiften (ie11CustomProperties) çok daha hızlı buldum - :rootsınırlama benim için sorun değil. Daha fazla performans kazanımı için seçeneklere bakın, örn { exclude: '[href*=jquery-ui],...', preserveStatic: false }.
Dunc

63

Bu çoklu dolgu, IE11'de Özel Özellikler için ( yalnızca kök düzeyinde değil ) neredeyse tam destek sağlar :
https://github.com/nuxodin/ie11CustomProperties

Nasıl çalışır

Komut dosyası, IE'nin özelliklerin kademeli olarak tanımlanabileceği ve okunabileceği minimum özel özellik desteğine sahip olduğu gerçeğini kullanır.
.myEl {-ie-test:'aaa'} // only one dash allowed! "-"
daha sonra javascript'te okuyun:
getComputedStyle( querySelector('.myEl') )['-ie-test']

README'deki özellikler:

  • dinamik eklenmiş html içeriğini işler
  • kolları dinamik eklendi <style>, <link>-elemanları
  • zincirleme --bar:var(--foo)
  • geri çekil var(--color, blue)
  • : odak,: hedef,: üzerine gelme
  • js-entegrasyonu:
    • style.setProperty('--x','y')
    • style.getPropertyValue('--x')
    • getComputedStyle(el).getPropertyValue('--inherited')
  • Satır içi stiller: <div ie-style="--color:blue"...
  • kademeli işler
  • miras işleri
  • 3k'nin altında (dk + gzip) ve bağımlılık yok

Demo:

https://rawcdn.githack.com/nuxodin/ie11CustomProperties/b851ec2b6b8e336a78857b570d9c12a8526c9a91/test.html


1
Bu polyfill'in nasıl kullanıldığını anlamam biraz zaman aldı. README.md bu konuda çok net değil. Çözüm: <script src="yourJsPath/ie11CustomProperties.js"></script>HTML dosyanızın baş bölümüne eklemeniz yeterlidir ve IE11 aynı fikirde olacaktır.
Jpsy

1
Geri bildiriminiz için teşekkür ederiz. Şimdi bir kullanım bölümü var
Tobias Buschor

3
Benim için bu çok daha ince çözüm doğru yaklaşım. Yukarıdaki ponyfill, daha önce var olduğu için daha yüksek derecelendirilmiştir (First commit Nov 2017), ie11CustomProperties ise ilk olarak Temmuz 2019'da yapıldı. Kendinizi değerlendirin. "DAHA İYİ KALİTE" İÇİN DAHA YÜKSEK OY SAYISINI HATA YAPMAYIN.
digitaldonkey

9

Yukarıdaki soru yorumu bölümündeki kod kalem pasajı bağlantısı için +1 [I has kode] tarafından. Yine de bulduğum bir şey, IE11'in şikayet etmemesi için JSON biçiminde tanımlanmış işlev bildirimlerine sahip olmak için snippet'in biraz değiştirilmesi gerektiğidir. Kod kalem pasajının biraz değiştirilmiş versiyonu aşağıdadır:

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();

3

Polyfill'in bu sürümünü denedim, ancak CSS'deki bir satırda birden çok değişken (FI yazı tipi ve rengi) olduğunda hatalarla karşılaştım. Bir meslektaşım bana yardım etti. 94. satıra bakın.

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

Internet Explorer'ı desteklemek için, index.html head etiketinde aşağıdaki komut dosyasını kullanmanız yeterlidir ve harika bir şekilde çalışmaktadır.

<script>window.MSInputMethodContext && document.documentMode && document.write('<script src="https://cdn.jsdelivr.net/gh/nuxodin/ie11CustomProperties@4.1.0/ie11CustomProperties.min.js"><\x2fscript>');</script>
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.