1

我有一个基于 Twitter Bootstrap 响应式媒体查询的 Sass mixin 用于我的媒体查询:

@mixin respond-to($media) {
    @if $media == handhelds {
        /* Landscape phones and down */
        @media (max-width: 480px) { @content; }
    }
    @else if $media == small {
        /* Landscape phone to portrait tablet */
        @media (max-width: 767px) {@content; }
    }
    @else if $media == medium {
        /* Portrait tablet to landscape and desktop */
        @media (min-width: 768px) and (max-width: 979px) { @content; }
    }
    @else if $media == large {
        /* Large desktop */
        @media (min-width: 1200px) { @content; }
    }
    @else {
        @media only screen and (max-width: #{$media}px) { @content; }
    }
}

我在我的 SCSS 文件中这样称呼它们:

.link {
   color:blue;
   @include respond-to(medium) {
        color: red;
    }
}

但是,有时我想用相同的样式设置多个查询的样式。现在我正在这样做:

.link {
    color:blue; /* this is fine for handheld and small sizes*/

    /*now I want to change the styles that are cascading to medium and large*/
    @include respond-to(medium) {
        color: red;
    }
    @include respond-to(large) {
        color: red;
    }
}

但我在重复代码,所以我想知道是否有更简洁的方法来编写它,以便我可以针对多个查询。像这样的东西,所以我不需要重复我的代码(我知道这不起作用):

@include respond-to(medium, large) {
    color: red;
}

有关处理此问题的最佳方法的任何建议?

4

3 回答 3

4

像这样的 mixin 会让您处于一个不太灵活的位置,而不仅仅是因为您使用的是 px(请参阅: http: //blog.cloudfour.com/the-ems-have-it-proportional-media-queries-英尺/)。简单地说,你让你的 mixin 太具体了,对其他网站来说不是很可重用。

我目前正在使用 4 个 mixin 的集合来处理最常见的媒体查询:min-width、max-width、between 和 outside(我在下面采样了 min-width 和 between)

$output-media-width: true !default; // true = all, otherwise use a list of numeric values (eg. 320px 23em)

@mixin media-min-width($bp) {
    @if type-of($output-media-width) != list {
        @media (min-width: $bp) {
            @content;
        }
    } @else {
        $output-bp: find-comparable($bp, $output-media-width);
        @if not comparable($output-bp, $bp) {
            @debug "Output breakpoint: #{$output-bp}, Chosen minimum width: #{$bp}";
        } @else if $output-bp >= $bp {
            @content;
        }
    }
}

@mixin media-between($bp1, $bp2) {
    @if type-of($output-media-width) != list {
        @media (min-width: $bp1) and (max-width: make-less-than($bp2)) {
            @content;
        }
    } @else {
        $output-bp1: find-comparable($bp1, $output-media-width);
        $output-bp2: find-comparable($bp2, $output-media-width);
        @if not comparable($output-bp1, $bp1) or not comparable($output-bp2, $bp2) {
            @debug "Output breakpoints: #{$output-bp1} and #{$output-bp2}, Chosen breakpoints: #{$bp1} and #{$bp2}";
        } @else if $output-bp2  >= $bp1 and $output-bp2 < $bp2 {
            @content;
        }
    }
}

@function find-comparable($val, $list) {
    @each $item in $list {
        @if comparable($val, $item) {
            @return $item;
        }
    }
}

@function make-less-than($val) {
    @return if(unit($val) == em, $val - .001, $val - 1);
}

这个 mixin 套件让我可以生成一个响应式 CSS 文件或一组我想要的任何宽度的非响应式 CSS 文件(特别是对于那些不喜欢媒体查询的设备),只需在我的顶部有一个这样的变量文件:

$output-media-width: 800px 60em;

尺寸列表让我可以在 em 不合适的极少数情况下使用 px(例如用于处理图像)。

// Device widths
$device-x-narrow: 23em; // 320px
$device-narrow: 35em; // 480px
$device-medium: 60em; // 800px
$device-wide: 70em; // 1000px

article.event {
    @mixin tableify {
//      footer { display: table-row }
        footer section { display: table-cell }
        footer section + section { padding-left: 2em }
    }

    @include media-min-width($device-medium) { // 2-col layout still
        #main > & { // single event view
            @include tableify;
        }
    }

    // sometimes you need a non-standard breakpoint, too...
    @include media-min-width(27em) { // narrow devices
        section & {
            @include tableify;
        }
    }

    @include media-max-width(27em) {
        footer section.categories ul {
            display: block;
            padding-left: 0;
            li { display: inline }
            li + li { margin-left: 1em }
        }
    }
}
于 2012-11-03T23:47:34.453 回答
1

尽管@cimmanon 在我发布我正在使用 Twitter Bootstrap 之前回答了我的问题,但其中有一些非常有趣的想法,我想我将从现在开始将这些想法应用到使用 Twitter Bootstrap 的 Sass 项目中。这是我发现效果很好的方法:

/* Responsive dimensions */
$handheld-max: 479px;
$small-min: $handheld-max + 1;
$small-max: 767px;
$medium-min: $small-max + 1;
$medium-max: 979px;
$large-min: $medium-max + 1;
$large-max: 1199px;
$xlarge: 1200;

/*Responsive query mixins */
@mixin media-above($min) {
  @media (min-width: $min) { @content; }
}
@mixin media-below($max) {
  @media (max-width: $max) { @content; }
}
@mixin media-between($min, $max) {
  @media (min-width: $min) and (max-width: $max) { @content; }
}

然后像这样在我的代码中调用它(根据我在问题中的要求):

.link {
    color: blue;
    @mixin media-above($medium-min){
       color: red;
    }
}
于 2012-11-07T06:41:11.543 回答
0

Using bootstrap-sass variables, I defined such mixins in SASS syntax:

=media-width-below($max)
  @media (max-width: $max)
    @content

=media-width-between($min, $max)
  @media (min-width: $min), (max-width: $max)
    @content

=media-width-above($min)
  @media (min-width: $min)
    @content

=media-xs
  +media-width-above($screen-xs-min)
    @content

=media-sm
  +media-width-above($screen-sm-min)
    @content

=media-md
  +media-width-above($screen-md-min)
    @content

=media-lg
  +media-width-above($screen-lg-min)
    @content

Those mixins will be useable just like +make-sm-column or .col-md-5 classes. You can just use it like this:

body
  +media-xs
    background-color: yellow
  +media-sm
    background-color: blue
  +media-md
    background-color: red
  +media-lg
    background-color: green

When you will be making your browser smaller by changing it from large to xs, you'll see colors in this order: green, red, blue, yellow.

于 2014-01-22T23:07:22.827 回答