Использование 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. Любые идеи, что мне не хватает?
Ответы
Ответ 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/