Подтвердить что ты не робот

Использование Sass Variables с CSS3 Media Queries

Я пытаюсь объединить использование переменной 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;, она возвращает ошибку для переменной undefined. Любые идеи, что мне не хватает?

4b9b3361

Ответ 1

Это просто невозможно. Поскольку триггер @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
          ...

На самом деле это не СУХОЕ, но лучшее, что вы можете сделать.

Если изменения совпадают каждый раз, когда вы также можете подготовить mixin, содержащий все изменяющиеся значения, так что вам не нужно будет его повторять. Кроме того, вы можете попытаться объединить mixin с определенными изменениями. Как:

@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

Ответ 2

Как и Филипп Зедлер, вы можете сделать это с помощью 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);
}

Ответ 3

Изменить: Пожалуйста, не используйте это решение. Ответ ronen намного лучше.

Как решение 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";
}

Вы определяете все чувствительные элементы в файле, включенные с помощью переменных, определенных в запросе на медиа. Итак, все, что вам нужно повторить, - это оператор импорта.

Ответ 4

У меня была та же проблема.

Переменная $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;
    }
}

Ответ 5

Это невозможно с SASS, но возможно с переменными CSS (или пользовательскими свойствами CSS). Единственный недостаток - поддержка браузера - но на самом деле есть плагин PostCSS - postcss-css-variable - который "упрощает" использование CSS-переменных (что также дает вам поддержку для старых браузеров).

Следующий пример прекрасно работает с SASS (и с postcss-css-variable вы также получаете поддержку для старых браузеров).

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

Это приведет к следующему CSS. Повторяющиеся медиазапросы увеличивают размер файла, но я обнаружил, что увеличение обычно незначительно, когда веб-сервер применяет 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;
  }
}

Ответ 6

С @ronen отличным ответом и картой, есть некоторая реальная сила:

@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 нацеленных на .myDiv с кучей разных значений.


Карта документов: https://sass-lang.com/documentation/functions/map

Пример использования карты: https://www.sitepoint.com/using-sass-maps/