SCSS:我只能@include 来响应成功的@media 吗?

SCSS: Can I only @include in response to a successful @media?

对于 SCSS 文件,我试图通过设置变量来响应 @media 查询来制作响应式布局。

我目前有两个@media 查询,我希望其中只有一个会继续调用@mixin,并为特定情况定义地图:移动或桌面。

我的代码是:

$page-header-height : 45px;   // some dummy defaults
$page-subheader-height: 45px;
$page-footer-height : 50px;

$mobile-varmap : (
    "page-header-height" : 50px,
    "page-subheader-height": 50px
);

$desktop-varmap : (
    "page-header-height" : 90px,
    "page-subheader-height": 120px
);

@mixin setvariables($map) {
    $page-header-height: map-get($map, "page-header-height") !global;
    $page-subheader-height: map-get($map, "page-subheader-height") !global;
    $page-footer-height: 50px;
}
$screen-size-mobile: 360px;
$screen-size-tablet: 600px;

@media screen and (min-width:$screen-size-mobile) {
    body {
        @include setvariables($mobile-varmap);
    }
}

@media screen and (min-width:$screen-size-tablet) {
    body {
        @include setvariables($desktop-varmap);
    }
}

div.page-wrapper {
    display: grid;
    grid-template-areas: 'page-header''page-subheader''page-content''page-footer';
    grid-template-columns: auto;
    grid-template-rows: $page-header-height $page-subheader-height 1fr $page-footer-height;
    max-height: calc(100vh - 55px); // TODO: use variables to calc these
    min-height: calc(100vh - 50px);
    overflow: none;
}

我曾预计这会导致根据匹配的@media 查询设置$page-header-height 等,但结果是代码中最后出现的@media 查询决定了值生产出来的。

我需要做什么才能使用与屏幕尺寸相对应的 varmap 调用 setvariables()

注意:我只是将 body 标签添加到 @media 查询以响应查看一些示例 - 我不确定它们是否正确使用或确实有必要。

您的代码很好,但据我了解,您希望通过 @include setvariables($desktop-varmap); 设置的变量动态响应设备宽度...这不会发生,因为带有媒体查询的两个块不会渲染任何东西,变量只是在编译时改变。

构建所需内容的一种可能方法是只有一个配置映射,然后可以像这样迭代

@mixin setvariables($map) {
    $page-header-height: map-get($map, "page-header-height") !global;
    $page-subheader-height: map-get($map, "page-subheader-height") !global;
    $page-footer-height: 50px !global;
}

$responsive-vars: (
    mobile: (
        min-width: 360px,
        page-header-height: 50px,
        page-subheader-height: 50px
    ),
    desktop: (
        min-width: 600px,
        page-header-height: 90px,
        page-subheader-height: 120px
    )
);

@each $alias, $map in $responsive-vars {
    @media screen and (min-width: map-get($map, 'min-width')) {
        @include setvariables($map);
        
        div.page-wrapper {
            display: grid;
            grid-template-areas: 'page-header''page-subheader''page-content''page-footer';
            grid-template-columns: auto;
            grid-template-rows: $page-header-height $page-subheader-height 1fr $page-footer-height;
            max-height: calc(100vh - 55px); // TODO: use variables to calc these
            min-height: calc(100vh - 50px);
            overflow: none;
        }
    }
}

然而,这不是最实用的方法,因为大多数情况下您只想调整一些值,而对所有设备都有其他声明。相反,我建议完全放弃 setvariables() 混合并直接访问地图,如:

// https://css-tricks.com/snippets/sass/deep-getset-maps/#deep-get
@function map-deep-get($map, $keys...) {
    @each $key in $keys {
        $map: map-get($map, $key);
    }
    @return $map;
}

$responsive-vars: (
    mobile: (
        min-width: 360px,
        page-header-height: 50px,
        page-subheader-height: 50px
    ),
    desktop: (
        min-width: 600px,
        page-header-height: 90px,
        page-subheader-height: 120px
    )
);

div.page-wrapper {
    display: grid;
    grid-template-areas: 'page-header''page-subheader''page-content''page-footer';
    grid-template-columns: auto;
    max-height: calc(100vh - 55px); // TODO: use variables to calc these
    min-height: calc(100vh - 50px);
    overflow: none;
    
    @media screen and (min-width: map-deep-get($responsive-vars, 'mobile', 'min-width')) {
        grid-template-rows: 
            map-deep-get($responsive-vars, 'mobile', 'page-header-height')
            map-deep-get($responsive-vars, 'mobile', 'page-subheader-height')
            1fr
            map-deep-get($responsive-vars, 'mobile', 'page-footer-height');
    }
    
    @media screen and (min-width: map-deep-get($responsive-vars, 'desktop', 'min-width')) {
        grid-template-rows: 
            map-deep-get($responsive-vars, 'desktop', 'page-header-height')
            map-deep-get($responsive-vars, 'desktop', 'page-subheader-height')
            1fr
            map-deep-get($responsive-vars, 'desktop', 'page-footer-height');
    }
}

乍一看这可能看起来像很多代码,但它呈现的要少得多css。