IT story

CSS3 미디어 쿼리에 Sass 변수 사용

hot-time 2020. 9. 3. 23:47
반응형

CSS3 미디어 쿼리에 Sass 변수 사용


다음과 같이 Sass 변수를 @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;하면 정의되지 않은 변수에 대한 오류가 반환됩니다. 내가 놓친 아이디어가 있습니까?


이것은 단순히 불가능합니다. 트리거 @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

그리고 Mixin은 다음과 같습니다.

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

Philipp Zedler의 답변과 유사하게 mixin으로 할 수 있습니다. 원하는 경우 단일 파일에 모든 것을 포함 할 수 있습니다.

@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);
}

편집 : 이 솔루션을 사용하지 마십시오. 로넨의 대답이 훨씬 낫습니다.

As a DRY solution, you can use the @import statement inside a media query, e.g. like this.

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

You define all responsive elements in the file included using the variables defined in the media query. So, all you need to repeat is the import statement.


I had the same problem.

The $menu-width variable should be 240px on the mobile view @media only screen and (max-width : 768px) and 340px on the desktop view.

So i have simply created two variables:

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

And here is how i have used it:

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

This isn't possible with SASS, but it is possible with CSS variables (or CSS custom properties). The only drawback is browser support – but there's actually a PostCSS plugin - postcss-css-variables - that "flattens" the use of CSS variables (which gives you support for older browsers, too).

The following example works great with SASS (and with postcss-css-variables you get support for older browsers too).

$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);
}

This would result in the following CSS. The repetitive media queries will increase the file size, but I have found that the increase is usually negligible once the web server applies gzip (which it will usually do automatically).

.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;
  }
}

With @ronen's great answer and a map, there's some real power available:

@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
    ));
}

It's now possible to have lots more DRY media queries targeting .myDiv with a bunch of different values.


Map docs: https://sass-lang.com/documentation/functions/map

Example map usage: https://www.sitepoint.com/using-sass-maps/

참고URL : https://stackoverflow.com/questions/9122195/using-sass-variables-with-css3-media-queries

반응형