How to Use SASS Logic Within a CSS 3 Media Query

How to use SASS logic within a CSS 3 media query

This was a bug in SASS. It's been fixed as of version 3.1.0:

http://sass-lang.com/docs/yardoc/file.SASS_CHANGELOG.html#310

Using Sass Variables with CSS3 Media Queries

This is simply not possible. Since the trigger @media screen and (max-width: 1170px) happens on the client-side.

Achieving your expected result would only be possible if SASS grabbed all rules and properties in your stylesheet containing your $base_width variable and copied/changed them accordingly.

Since it won't work automatically you could do it by hand like this:

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

This is not really DRY but the best you can do.

If the changes are the same every time you could also prepare a mixin containing all the changing values, so you wouldn't need to repeat it. Additionally you can try to combine the mixin with specific changes. Like:

@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

And the Mixin would look like this

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

Nested CSS3 media queries in SCSS/Sass

It makes sense to merge identical items (screen) but not the min-widths as they are different. I've found SASS actually has very little understanding of what CSS rules are valid by design, in order to future-proof itself.

I wouldn't be comfortable using a merge query that has multiple queries like that not only because of the issue you're having but because it's precious wasted bytes that still have to go over the wire.

I would use @include to define the @media queries as it's a little nicer than the string method you're using and do it like this, which I feel is just as readable as your solution without the problems:

// The mixins can be defined in some shared file
@mixin media-gte-sm {
@media screen and (min-width: 768px) {
@content;
}
}
@mixin media-gte-lg {
@media screen and (min-width: 1200px) {
@content;
}
}

.search-copyright-tab .copyright {
@include media-gte-sm {
font-size: 19px;
}
@include media-gte-lg {
font-size: 21px;
}
}

Using media-queries to set variable values using Sass

This is an unusual instance of a common mistake: you are mixing server-side and client-side logic.

The @media (min-width: 750px) { ... } block is a directive which is passed onto the web browser to evaluate at run time, and conditionally apply rules. As you resize the browser window or viewport, the browser will continuously re-check this condition, and decide whether to apply the CSS rules it contains.

The $var: deskConfig; assignment, on the other hand, is a directive to the SASS/SCSS compiler. This runs over the entire file, processes it, and returns the result, which will probably be saved to disk, and served to every browser which visits. The compiler cannot know what size window someone will browse the site in.

The only thing SASS can do with @media queries is decide where to echo them in the resulting CSS. For instance, you can nest things "inside out", like .foo { @media(min-width: 750px) { color: red; } }, and SASS will generate the correct CSS @media(min-width: 750px) { .foo { color: red; } }.

I guess it would theoretically be possible for the compiler to detect that the assignment was in an @media block, and generate two versions of every single rule which mentioned that variable, so that .foo { color: $var; } automatically became .foo { color: red; } @media(min-width: 750px) { .foo { color: red; } }. But that would be incredibly complicated, and frankly rather confusing.

How to target two media queries using SASS interpolation?

This won't give you CSS error but is slightly different from what you need:

@media #{$mobile}, #{$tablet} {
/* my styles for mobile and tablet displays */
}

From MDN docs:

Comma-separated lists behave like the logical operator or when used in
media queries. When using a comma-separated list of media queries, if
any of the media queries returns true, the styles or style sheets get
applied. Each media query in a comma-separated list is treated as an
individual query, and any operator applied to one media query does not
affect the others. This means the comma-separated media queries can
target different media features, types, and states.

The thing is that concat that you are making with string interpolation isn't
compiled to valid CSS. Read more about media query logic here.

compass (scss) variables & media queries

As an alternative, try using the power of em's:

$arrow-size: 1.875em; // 30px, use pxtoem.com for conversion

div.selector {
height: 0px; width: 0px;
position: absolute;
bottom: 0px; left: 50%;
border-bottom: $arrow-size solid white;
border-left: $arrow-size solid transparent;
border-right: $arrow-size solid transparent;
}

@media only screen and (max-width: 449px) {
div.selector { font-size: 50%; }
}

Since the em is relative to the font-size, all you gotta do is play with that value to change the size of the arrow across different responsive states.

How to use media query and selectors at the same time using scss?

@media (prefers-color-scheme: dark) {
body {
&[data-theme="dark"] {
.ChatScreen {
background-color: #000;
}
}
}
}

You can look at sass mixins and define your dark styling and then include that rule wherever you need.

Edit

@mixin dark-theme {
.ChatScreen {
background-color: #000;
}
}

@media (prefers-color-scheme: dark) {
@include dark-theme;
}

body {
&[data-theme="dark"] {
@include dark-theme;
}
}

Mixing an @supports with an @media query in CSS

There isn't a way to combine two different conditional at-rules into one with OR logic (AND logic, as you've stated, can be done by nesting, even though strictly speaking they're still two separate rules). Unless you have plumbing that can automatically duplicate your CSS across two separate conditional rules for you, you will have to do that manually.

If possible, consider approaching this from a progressive-enhancement point of view rather than a graceful-degradation one. That is, rather than applying fallback styles to browsers that either don't support grid or are displaying on smaller screens, apply grid styles to browsers that support grid and are displaying on larger screens — this is where the nesting of rules you mention then makes sense:

@supports (display: grid) {
/* Or screen and (min-width: 701px),
or not screen and (max-width: 700px),
depending on your needs and preferences */
@media screen and (min-width: 700px) {
/* Grid styles */
}
}

If you're not a fan of the extra indentation, you can reduce it somewhat, or just not indent at all ;)



Related Topics



Leave a reply



Submit