CSS3 मीडिया क्वेरी के साथ सैस वेरिएबल्स का उपयोग करना


120

मैं @media प्रश्नों के साथ एक सास चर के उपयोग को संयोजित करने का प्रयास कर रहा हूं:

$base_width:1160px;

@media screen and (max-width: 1170px) {$base_width: 960px;}
@media screen and (min-width: 1171px) {$base_width: 1160px;}

$base_width फिर तरल पदार्थ का उत्पादन करने के लिए स्टाइलशीट चौड़ाई प्रतिशत-आधारित माप में विभिन्न बिंदुओं पर परिभाषित किया गया है।

जब मैं ऐसा करता हूं, तो चर को ठीक से पहचाना जाने लगता है लेकिन मीडिया क्वेरी के लिए स्थितियां नहीं होती हैं। उदाहरण के लिए, उपरोक्त कोड स्क्रीन चौड़ाई की परवाह किए बिना एक 1160px लेआउट का उत्पादन करता है। अगर मैं @media स्टेटमेंट्स को फ़्लिप-फ्लॉप करता हूँ तो:

@media screen and (min-width: 1171px) {$base_width: 1160px;}
@media screen and (max-width: 1170px) {$base_width: 960px;}

यह स्क्रीन की चौड़ाई की परवाह किए बिना एक 960px लेआउट का उत्पादन करता है। यह भी ध्यान दें कि यदि मैं इसकी पहली पंक्ति को हटाता हूं तो $base_width: 1160px;एक अपरिभाषित चर के लिए एक त्रुटि देता है। कोई भी विचार जो मुझे याद आ रहा है?


जवाबों:


96

यह बस संभव नहीं है। चूंकि ट्रिगर @media screen and (max-width: 1170px)क्लाइंट-साइड पर होता है।

अपने अपेक्षित परिणाम को प्राप्त करना केवल तभी संभव होगा जब SASS ने आपके स्टाइलशीट में सभी नियम और संपत्तियों को अपने $base_widthचर के साथ पकड़ा और उन्हें तदनुसार कॉपी / बदल दिया।

चूंकि यह स्वचालित रूप से काम नहीं करेगा आप इसे इस तरह से हाथ से कर सकते हैं:

@media screen and (max-width: 1170px)
      $base_width: 960px // you need to indent it to (re)set it just within this media-query
      // now you copy all the css rules/properties that contain or are relative to $base_width e.g.
      #wrapper
          width: $base_width
          ...

@media screen and (min-width: 1171px)
    $base_width: 1160px
      #wrapper
          width: $base_width
          ...

यह वास्तव में DRY नहीं है लेकिन सबसे अच्छा आप कर सकते हैं।

यदि परिवर्तन हर बार समान होते हैं, तो आप सभी बदलते मूल्यों वाले मिश्रण को भी तैयार कर सकते हैं, इसलिए आपको इसे दोहराने की आवश्यकता नहीं होगी। इसके अतिरिक्त आप मिश्रण को विशिष्ट परिवर्तनों के साथ संयोजित करने का प्रयास कर सकते हैं। पसंद:

@media screen and (min-width: 1171px)
    +base_width_changes(1160px)
    #width-1171-specific-element // additional specific changes, that aren't in the mixin
        display: block

और मिक्सिन इस तरह दिखेगा

=base_width_changes($base_width)
    #wrapper
        width: $base_width

6
क्या यह अभी भी मामला है कि SASS @मीडिया प्रश्नों के अंदर $ चर के साथ काम नहीं करेगा?
HappyTorso

1
@HappyTorso यह हमेशा मामला रहेगा, जब तक कि क्लाइंट-साइड सैस कंपाइलर (उदाहरण के लिए जावास्क्रिप्ट में) जैसी कोई चीज नहीं है, जो व्यूपोर्ट के आकार पर चलता है। सैस चर का निर्माण समय पर स्थिर मूल्यों के लिए किया जाता है; वे अब रनटाइम पर मौजूद नहीं हैं। मीडिया क्वेरी का मूल्यांकन रनटाइम पर किया जाता है, जब मीडिया क्वेरी में बदलाव का गुण रखता है।
इरिक्सोको

26
@ericsoco मैं नहीं देखता कि यह एक कारण है। SASS आसानी से () बस चर के सभी उपयोगों को ट्रैक कर सकता है और मीडिया के प्रश्नों को सम्मिलित कर सकता है जहां उनका उपयोग किया जाता है; $foo: 1rem; @media (min-width: 10rem) {$foo: 2rem} .class {font-size: $foo} .class2 {padding: $foo}परिणाम होगा.class {font-size: 1rem} .class2 {padding: 1rem} @media (min-width: 10rem) (.class {font-size: 2rem} .class2 {padding: 2rem}}
powerbuoy

1
yep sass एक प्रीप्रोसेसर है, "यह बस संभव नहीं है" के लिए कोई कारण नहीं है ... यह कर सकता है, यह अभी लागू नहीं हुआ है।
ini

54

फिलिप जेडलर के जवाब के समान, आप इसे एक मिश्रण के साथ कर सकते हैं। यदि आप चाहते हैं कि आप एक ही फाइल में सब कुछ है।

    @mixin styling($base-width) {
        // your SCSS here, e.g.
        #Contents {
            width: $base-width;
        }
    }

    @media screen and (max-width: 1170px) {
        @include styling($base-width: 960px);
    }
    @media screen and (min-width: 1171px) {
        @include styling($base-width: 1160px);
    }

1
जल्दी या बाद में आप इस समस्या का सामना करेंगे,
थियो

यह मेरे जवाब से बेहतर है!
फिलिप जेडलर

इस उपाय को +1 करें। इसे एक मानचित्र ( sass-lang.com/documentation/functions/map ) के साथ मिलाएं और आपको कुछ शक्ति मिली है - मैं यहां एक अलग समाधान बताऊंगा । संपादित करें: किया। stackoverflow.com/a/56894640/385273
बेन

9

संपादित करें: कृपया इस समाधान का उपयोग न करें। रोनेन द्वारा उत्तर बहुत बेहतर है।

DRY समाधान के रूप में, आप @importइस तरह से एक मीडिया क्वेरी के अंदर बयान का उपयोग कर सकते हैं ।

@media screen and (max-width: 1170px) {
    $base_width: 960px;
    @import "responsive_elements";
}
@media screen and (min-width: 1171px) {
    $base_width: 1160px;
    @import "responsive_elements";
}

आप मीडिया क्वेरी में परिभाषित चर का उपयोग करके शामिल फ़ाइल में सभी उत्तरदायी तत्वों को परिभाषित करते हैं। तो, आप सभी को दोहराने की जरूरत है आयात विवरण।


9

यह SASS के साथ संभव नहीं है, लेकिन यह सीएसएस चर (या सीएसएस कस्टम गुणों ) के साथ संभव है । एकमात्र दोष ब्राउज़र समर्थन है - लेकिन वास्तव में एक पोस्टसीएसएस प्लगइन है - पोस्टस्क-सीएसएस-चर - जो सीएसएस चर का उपयोग "सपाट करता है" (जो आपको पुराने ब्राउज़रों के लिए भी समर्थन देता है)।

निम्नलिखित उदाहरण SASS के साथ बहुत अच्छा काम करता है (और पोस्टस्कॉल्स-सीएसएस-चर के साथ आपको पुराने ब्राउज़रों के लिए भी समर्थन मिलता है)।

$mq-laptop: 1440px;
$mq-desktop: 1680px;

:root {
    --font-size-regular: 14px;
    --gutter: 1rem;
}

// The fact that we have to use a `max-width` media query here, so as to not
// overlap with the next media query, is a quirk of postcss-css-variables
@media (min-width: $mq-laptop) and (max-width: $mq-desktop - 1px) {
    :root {
        --font-size-regular: 16px;
        --gutter: 1.5rem;
    }
}

@media (min-width: $mq-desktop) {
    :root {
        --font-size-regular: 18px;
        --gutter: 1.75rem;
    }
}

.my-element {
    font-size: var(--font-size-regular);
    padding: 0 calc(var(--gutter) / 2);
}

यह निम्नलिखित सीएसएस में परिणाम होगा। दोहराए जाने वाले मीडिया क्वेरीज़ फ़ाइल आकार को बढ़ाएंगे, लेकिन मैंने पाया है कि वेब सर्वर के लागू होने के बाद वृद्धि आमतौर पर नगण्य होती है gzip(जो कि आमतौर पर स्वचालित रूप से होती है)।

.my-element {
  font-size: 14px;
  padding: 0 calc(1rem / 2);
}
@media (min-width: 1680px) {
  .my-element {
  padding: 0 calc(1.75rem / 2);
  }
}
@media (min-width: 1440px) and (max-width: 1679px) {
  .my-element {
  padding: 0 calc(1.5rem / 2);
  }
}
@media (min-width: 1680px) {
  .my-element {
  font-size: 18px;
  }
}
@media (min-width: 1440px) and (max-width: 1679px) {
  .my-element {
  font-size: 16px;
  }
}

8

@ रॉनन के शानदार जवाब और नक्शे के साथ, कुछ वास्तविक शक्ति उपलब्ध है:

    @mixin styling($map) {
        .myDiv {
            background: map-get($map, 'foo');
            font-size: map-get($map, 'bar');
        }
    }

    @media (min-height: 500px) {
        @include styling((
            foo: green,
            bar: 50px
        ));
    }

    @media (min-height: 1000px) {
        @include styling((
            foo: red,
            bar: 100px
        ));
    }

अब .myDivविभिन्न मूल्यों के एक समूह के साथ बहुत अधिक DRY मीडिया प्रश्नों को लक्षित करना संभव है ।


मानचित्र डॉक्स: https://sass-lang.com/documentation/functions/map

उदाहरण मानचित्र उपयोग: https://www.sitepoint.com/using-sass-maps/


इसे देखने के लिए मुझे एक सेकंड का समय लगा, लेकिन यह @ रोनन के जवाब के समान तकनीक है, बस एक बार में कई वेरिएबल्स को सपोर्ट करने के लिए मैप इनपुट का उपयोग किया जाता है। मैं किसी भी तरह से इसके मूल्य में छूट नहीं दे रहा हूं, लेकिन यह समझना तब तक कठिन था जब तक मैंने वह संबंध नहीं बना लिया
जॉन

5

मुझे भी यही समस्या थी।

$menu-widthचर पर 240px होना चाहिए मोबाइल दृश्य @media only screen and (max-width : 768px)पर और 340px डेस्कटॉप दृश्य।

इसलिए मैंने केवल दो चर बनाए हैं:

$menu-width: 340px;
$menu-mobile-width: 240px;

और यहाँ है कि मैं इसे कैसे इस्तेमाल किया है:

.menu {
    width: $menu-width;
    @media only screen and (max-width : 768px) {
      width: $menu-mobile-width;
    }
}

1

दो सिफारिशें

1 छोटे स्क्रीन के लिए होने के लिए अपने "डिफ़ॉल्ट" सीएसएस बयानों को लिखें और केवल बड़ी स्क्रीन के लिए मीडिया प्रश्नों का उपयोग करें। आमतौर पर max-widthमीडिया क्वेरी की कोई आवश्यकता नहीं होती है ।

उदाहरण (यह मानते हुए कि तत्व में वर्ग "कंटेनर" है)

@mixin min-width($width) {
  @media screen and (max-width: $width) {
    @content;
  }
}

.container {
  width: 960px;

  @include min-width(1170px) {
    width: 1160px;
  }
}

2 यदि आप कर सकते हैं , तो समस्या को हल करने के लिए सीएसएस चर का उपयोग करें ।

@mixin min-width($width) {
  @media screen and (max-width: $width) {
    @content;
  }
}

:root {
  --container-width: 960px;
  @include min-width(1170px) {
    --container-width: 1160px;
  }
}

.container {
  width: var(--container-width);
}

ध्यान दें:

चूँकि इसमें 1160px की चौड़ाई होगी, जब खिड़की की चौड़ाई 1170px होगी, तो 100% की चौड़ाई और 1160px की अधिकतम-चौड़ाई का उपयोग करना बेहतर हो सकता है, और मूल तत्व में 5px की क्षैतिज पैडिंग हो सकती है, जब तक कि बॉक्स-आकार की संपत्ति बॉर्डर-बॉक्स पर सेट की गई है। समस्या को हल करने के कई तरीके हैं। यदि माता-पिता फ्लेक्स या ग्रिड कंटेनर नहीं है, तो आप उपयोग कर सकते हैं .container { margin: auto }

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.