Medya sorgularında çalışmayan CSS yerel değişkenleri


140

Medya sorgusunda CSS değişkenlerini kullanmaya çalışıyorum ve çalışmıyor.

:root {
  --mobile-breakpoint: 642px;
}

@media (max-width: var(--mobile-breakpoint)) {

}

Birkaç tarayıcıda denediniz mi? (Chrome ve Firefox gibi)
Cohars

1
Önişlemci olmadan
@SandrinaPereira

1
@SandrinaPereira Firefox ve Chrome'da yapabilirsiniz 👍
Cohars


4
Sadece Google üzerinden bu bulgu insanlar için netleştirmek için: Eğer yapabilirsiniz bir medya sorgusu kapsamında iç CSS özel özellikler kullanmak, sadece bir medya sorgu bildiriminde bunları kullanamaz.
David Deprost

Yanıtlar:


112

Gönderen spec ,

var()İşlev, bir eleman üzerinde herhangi bir özelliği bir değerin bir kısmının yerine kullanılabilir. var()Fonksiyon özellik adları, seçicileri veya özellik değerlerine dışında başka hiçbir işlem olarak kullanılamaz. (Bunu yapmak genellikle geçersiz sözdizimi veya anlamı değişkenle bağlantısı olmayan bir değer üretir.)

Yani hayır, bunu bir medya sorgusunda kullanamazsınız.

Ve bu mantıklı. Çünkü --mobile-breakpointörneğin öğeye, :rootyani <html>öğeye ayarlayabilir ve oradan diğer öğelere devralınabilir. Ancak bir medya sorgusu bir öğe değildir, kendisinden miras almaz <html>, bu nedenle çalışamaz.

CSS değişkenlerinin başarmaya çalıştığı şey bu değil. Bunun yerine bir CSS ön işlemcisi kullanabilirsiniz.


77
Yanıt, spesifikasyonun şu anda medya sorgularındaki CSS değişkenlerini işlemediği için doğrudur, ancak yanlış, CSS değişkenlerinin başarmaya çalıştığı şey bu değildir. Tekrarları ve sihirli sayıları azaltmak, tam olarak CSS değişkenlerinin oluşturulmasının nedenidir
mikemaccana

69

As Oriol cevap vardır , şu anda, CSS Değişkenler Seviye 1'ler var()medya sorguları kullanılamaz . Ancak, bu sorunu ele alacak son gelişmeler oldu. Birkaç yıl içinde, CSS Ortam Değişkenleri Modülü Seviye 1 standardize edilip uygulandığında, env()değişkenleri tüm modern tarayıcılarda medya sorgularında kullanabileceğiz .

Spesifikasyonu okuduysanız ve bir endişeniz varsa veya medya sorgusu kullanım durumu için desteğinizi dile getirmek istiyorsanız, bunu GitHub w3c / csswg-drafts # 1693'te veya "[ css-env-1] ” .


Orijinal cevap 2017-11-09 : Kısa bir süre önce, CSS Çalışma Grubu , CSS Değişkenleri Seviye 2'nin kullanıcı tanımlı ortam değişkenlerini kullanmasını destekleyeceğine env()karar verdi ve bunları medya sorgularında geçerli kılmaya çalışacaklar . Grup, bu sorunu, Apple'ın Eylül 2017'de iPhone X'in resmi duyurusundan kısa bir süre önce standart kullanıcı aracısı özelliklerini önermesinden sonra çözdü (ayrıca bkz. WebKit: Timothy Horton tarafından "iPhone X için Web Siteleri Tasarlama" ). Diğer tarayıcı temsilcileri daha sonra, televizyon ekranları ve taşma kenarları olan mürekkep baskısı gibi birçok cihazda genellikle yararlı olacaklarını kabul ettiler. ( env()eskiden çağrılırdıconstant(), ancak bu artık kullanımdan kaldırıldı. Peter-Paul Koch'un yazdığı bu makale gibi eski isme atıfta bulunan makaleler görmeye devam edebilirsiniz .) Birkaç hafta geçtikten sonra , Mozilla'dan Cameron McCormack bu ortam değişkenlerinin medya sorgularında kullanılabileceğini fark etti ve Tab Atkins, Jr. Daha sonra , kullanıcı tanımlı ortam değişkenlerinin medya sorgularında kullanılabilen genel, geçersiz kılınamayan kök değişkenler olarak özellikle yararlı olacağını fark etti. Şimdi, Apple'dan Dean "Dino" Jackson, Atkins'e 2. Seviye düzenleme aşamasında katılacak .

w3c/csswg-drafts1693 numaralı GitHub sayısında bu konudaki güncellemelere abone olabilirsiniz . (Özellikle ilgili tarihsel ayrıntılar için, CSSWG Toplantı Botunun kararlarında gömülü toplantı günlüklerini genişletin ve "medya sorguları" anlamına gelen "MQ" yu arayın.)

Gelecekte daha fazla gelişme olduğunda bu soruyu güncellemeyi planlıyorum. Gelecek heyecan verici.


Güncelleme 2018-02-08 : Safari Teknoloji Önizlemesi 49 , calc()medya sorgularını ayrıştırmak için destek ekledi ve bu da env()onları desteklemenin bir başlangıcı olabilir .


Güncelleme 2018-04-27 : Google'daki Chromium ekibi üzerinde çalışmaya karar verdi env(). Buna karşılık, Atkins env()ayrı, resmi olmayan bir taslak standardı belirlemeye başladı : CSS Ortam Değişkenleri Modülü Seviye 1 . (Bkz W3C / # 1693 csswg-hazırladı onun GitHub yorumunu ve onun comment içinde W3C / csswg-hazırladı # 1817 .) Açık bir kullanım durumunda gibi medya sorguları değişkenler dışarı taslak görüşmeleri:

Ortam değişkenleri, belirli bir öğeden çizilen herhangi bir şeyin değerine bağlı olmadığından, işlevin geçerli olmayacağı @mediakurallar gibi, yararlanılması gereken bariz bir öğenin olmadığı yerlerde kullanılabilirler var().

Spesifikasyonu okuduysanız ve bir endişeniz varsa veya medya sorgusu kullanım örneği için desteğinizi dile getirmek istiyorsanız, bunu GitHub w3c / csswg-drafts # 1693'te veya "[ön ekli herhangi bir CSS GitHub sorununda yapabilirsiniz css-env-1] ” .


Güncelleme 2019-07-06 : Özellikler üzerinde çalışma devam ediyor. 2627 numaralı GitHub sorunu ve 3578 numaralı GitHub sorunu , medya sorgularındaki özel çevresel değişkenlere ayrılmıştır.


31

Ancak, YAPABİLECEKLERİNİZ @media,: root ifadenizi sorgulamaktır!

:root {
     /* desktop vars */
}
@media screen and (max-width: 479px) {
    :root {
        /* mobile vars */
    }
}

Tamamen Chrome, Firefox ve Edge'de en azından bu gönderi itibariyle en son üretim sürümlerinde çalışır.


Vay canına teşekkürler! Bu kesinlikle doğru cevap olmalıdır.
SimplyComplexable

1
Bunu bildiğim iyi oldu. Bir sınırlama: Bu değere a olarak da erişmeniz gerekiyorsa var, bu nedenle başka yerlerde hesaplamalarda kullanılabilir css, bu yine de iki yere "sihirli değer" (burada 479px) koymayı gerektirir: medya sorgusu ve bir var bildirimi.
ToolmakerSteve

8

Görünüşe göre yerel CSS değişkenlerini bu şekilde kullanmak mümkün değil. Bu sınırlamalardan biridir .

Bunu kullanmanın akıllıca bir yolu, tüm stilinizi etkilemek için medya sorgusundaki değişkenlerinizi değiştirmektir. Bu makaleyi tavsiye ederim .

:root {
  --gutter: 4px;
}

section {
  margin: var(--gutter);
}

@media (min-width: 600px) {
  :root {
    --gutter: 16px;
  }
}

"Medya sorgusunda değişkenlerinizi değiştirin" in anlamını anlamıyorum, örnek gösterebilir misiniz?

1
Kastettiğim bu değil. Medya sorgusu değerini sordum.

4
Evet, az önce bağladığım makalede var. Bunun beklediğiniz gibi olmadığını biliyorum, ancak CSS değişkenleri medya sorgularını tanımlamak için kullanılamaz
Cohars

8

İstediğinizi elde etmenin bir yolu npm paketi kullanmaktır postcss-media-variables.

Eğer npm paketlerini kullanmakta sorun yoksa, o zaman burada da belge için bir göz atabilirsiniz.

Misal

/* input */
:root {
  --min-width: 1000px;
  --smallscreen: 480px;
}
@media (min-width: var(--min-width)) {}
@media (max-width: calc(var(--min-width) - 1px)) {}

@custom-media --small-device (max-width: var(--smallscreen));
@media (--small-device) {}

4
Teşekkürler, ama herhangi bir önişlemci kullanmamaya çalışıyordum.


1
@sebilasse: özel medya sorguları , css değişkenlerini medya sorguları için kesme noktaları olarak kullanamama sorununu
çözmüyor

1
postcss bir önişlemci değil

1

Diğer cevapları okuyabileceğiniz gibi, bunu yapmak hala mümkün değil .

Birisi özel çevresel değişkenlerden bahsetti ( env()yerine özel css değişkenlerine benzer var()) ve ilke doğru, ancak yine de 2 ana sorun var:

  • zayıf tarayıcı desteği
  • Şimdiye kadar onları tanımlamanın bir yolu yok (ama muhtemelen gelecekte olacak, çünkü bu şimdiye kadar sadece resmi olmayan bir taslak)

1

Kısa cevap

Medya sorgularının değerini değiştirmek ve bunu bir css değişkeninin değerine ayarlamak için JavaScript'i kullanabilirsiniz.

// get value of css variable
getComputedStyle(document.documentElement).getPropertyValue('--mobile-breakpoint'); // '642px'

// search for media rule
var mediaRule = document.styleSheets[i].cssRules[j];

// update media rule
mediaRule.media.mediaText = '..'


Uzun cevap

Sayfanıza ekleyebileceğiniz küçük bir senaryo yazdım. Bu değerine sahip her ortam kuralı değiştirir 1pxcss değişkenin değeri ile --replace-media-1px, değerle kuralları 2pxile --replace-media-2pxbenzeri ve. Bu medya sorguları için çalışır with, min-width, max-width, height, min-heightve max-heightbunlar kullanılarak bağlanır bile and.

JavaScript:

function* visitCssRule(cssRule) {
    // visit imported stylesheet
    if (cssRule.type == cssRule.IMPORT_RULE)
        yield* visitStyleSheet(cssRule.styleSheet);

    // yield media rule
    if (cssRule.type == cssRule.MEDIA_RULE)
        yield cssRule;
}

function* visitStyleSheet(styleSheet) {
    try {
        // visit every rule in the stylesheet
        var cssRules = styleSheet.cssRules;
        for (var i = 0, cssRule; cssRule = cssRules[i]; i++)
            yield* visitCssRule(cssRule);
    } catch (ignored) {}
}

function* findAllMediaRules() {
    // visit all stylesheets
    var styleSheets = document.styleSheets;
    for (var i = 0, styleSheet; styleSheet = styleSheets[i]; i++)
        yield* visitStyleSheet(styleSheet);
}

// collect all media rules
const mediaRules = Array.from(findAllMediaRules());

// read replacement values
var style = getComputedStyle(document.documentElement);
var replacements = [];
for (var k = 1, value; value = style.getPropertyValue('--replace-media-' + k + 'px'); k++)
    replacements.push(value);

// update media rules
for (var i = 0, mediaRule; mediaRule = mediaRules[i]; i++) {
    for (var k = 0; k < replacements.length; k++) {
        var regex = RegExp('\\((width|min-width|max-width|height|min-height|max-height): ' + (k+1) + 'px\\)', 'g');
        var replacement = '($1: ' + replacements[k] + ')';
        mediaRule.media.mediaText = mediaRule.media.mediaText.replace(regex, replacement);
    }
}

CSS:

:root {
  --mobile-breakpoint: 642px;

  --replace-media-1px: var(--mobile-breakpoint);
  --replace-media-2px: ...;
}

@media (max-width: 1px) { /* replaced by 642px */
  ...
}

@media (max-width: 2px) {
  ...
}
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.