zoukankan      html  css  js  c++  java
  • SASS优化响应式断点管理

    前端开发whqet,csdn,王海庆,whqet,前端开发专家

    原文:《Managing Responsive Breakpoints with Sass

    作者:Hugo Giraudel,来自法国,著名SASS大牛,在SassWay等多个站点撰文推广sass,是SassyJSON、SassyMatrix等多个开源项目的开发人员,大家能够到他的官方站点github上了解详情。

    翻译:前端开发whqet,以意译为主,不当之处请大家批评指正。

    ---------------------------------------------------------------------------------------------------------------------------------

    当你须要搞定响应式布局时,一堆堆的媒体查询、大量的属性、属性值往往能够把你搞颠,SASS(或者诸如此类的预处理器)被觉得是处理响应式断点的最佳利器。

    说到响应式断点处理,非常多种方式涌上心头,常常有人问哪种方式最优,正如前端开发领域的大多数问题一样,这个问题相同没有标准答案,我们须要详细问题详细分析。更确切的说,难度不在于提出一个系统,而是提出一个既足够灵活(适用大部分场合)又不非常复杂的系统。

    在今天的文章里,我将给大家介绍若干种响应式布局断点的解决方式,每一种都经过实践验证,一些方案可能优于其它方案,我会把决定的权利交给大家。

    1.使用变量(With variables)

    BootstrapFoundation採用这样的方式,首先定义变量,然后在媒体查询中使用变量。换句话说,你能够在配置文件或者其它地方定义变量以备使用。我们来看看Bootstrap怎么干的。
    // Defining values
    $screen-sm-min: 768px;
    $screen-xs-max: ($screen-sm-min - 1);
    $screen-md-min: 992px;
    $screen-sm-max: ($screen-md-min - 1);
    $screen-lg-min: 1200px;
    $screen-md-max: ($screen-lg-min - 1);
     
    // Usage
    @media (max- $screen-xs-max) { ... }
    @media (min- $screen-sm-min) { ... }
    @media (max- $screen-sm-max) { ... }
    @media (min- $screen-md-min) { ... }
    @media (max- $screen-md-max) { ... }
    @media (min- $screen-lg-min) { ... }
    Foudation更进一步,使用跨范围的媒体查询,避免使用过多的max-width和min-width。
    // Defining values
    $small-range:   (0em, 40em);       /* 0, 640px */
    $medium-range:  (40.063em, 64em);  /* 641px, 1024px */
    $large-range:   (64.063em, 90em);  /* 1025px, 1440px */
    $xlarge-range:  (90.063em, 120em); /* 1441px, 1920px */
    $xxlarge-range: (120.063em);       /* 1921px */
     
    // Defining media queries
    $screen:       "only screen" !default;
    $landscape:    "#{$screen} and (orientation: landscape)" !default;
    $portrait:     "#{$screen} and (orientation: portrait)" !default;
    $small-up:     $screen !default;
    $small-only:   "#{$screen} and (max- #{upper-bound($small-range)})" !default;
    $medium-up:    "#{$screen} and (min-#{lower-bound($medium-range)})" !default;
    $medium-only:  "#{$screen} and (min-#{lower-bound($medium-range)}) and (max-#{upper-bound($medium-range)})" !default;
    $large-up:     "#{$screen} and (min-#{lower-bound($large-range)})" !default;
    $large-only:   "#{$screen} and (min-#{lower-bound($large-range)}) and (max-#{upper-bound($large-range)})" !default;
    $xlarge-up:    "#{$screen} and (min-#{lower-bound($xlarge-range)})" !default;
    $xlarge-only:  "#{$screen} and (min-#{lower-bound($xlarge-range)}) and (max-#{upper-bound($xlarge-range)})" !default;
    $xxlarge-up:   "#{$screen} and (min-#{lower-bound($xxlarge-range)})" !default;
    $xxlarge-only: "#{$screen} and (min-#{lower-bound($xxlarge-range)}) and (max-#{upper-bound($xxlarge-range)})" !default;
     
    // Usage
    @media #{$small-up}     { ... }
    @media #{$small-only}   { ... }
    @media #{$medium-up}    { ... }
    @media #{$medium-only}  { ... }
    @media #{$large-up}     { ... }
    @media #{$large-only}   { ... }
    @media #{$xlarge-up}    { ... }
    @media #{$xlarge-only}  { ... }
    @media #{$xxlarge-up}   { ... }
    @media #{$xxlarge-only} { ... }
    两种方法各有一个不爽的地方,在Bootstrap里每次都要使用max-width,在Foundation里我们须要使用插值变量这样的又丑又烦的方式。显示我们须要想办法解决这些问题。

    2.使用独立Mixin(With a standalone mixin)

    media queries in Sass 3.2》是CSS-Tricks里最火的文章之中的一个,在这篇文章里Chris Coyier在借鉴a former idea by Mason Wendella former idea by Jeff Croft两文的基础上,怎样使用sass实现响应式布局的断点管理。
    命名断点是非常重要的,由于能够为抽象的数字赋予意义(你知道767px是什么意思吗,我不知道,直到我去使用小屏幕的时候才知道)。为什么BootstrapFoundation要使用变量呢,不也是为了给抽象的数字起个名字吗?
    所以我们定义个mixin,接收断点名作唯一的參数,返回媒体查询的内容。准备好了吗?走起。
    @mixin respond-to($breakpoint) {
      @if $breakpoint == "small" {
        @media (min- 767px) {
          @content;
        }
      }
     
      @else if $breakpoint == "medium" {
        @media (min- 992px) {
          @content;
        }
      }
     
      @else if $breakpoint == "large" {
        @media (min- 1200px) {
          @content;
        }
      }
    }
    然后,我们这样使用mixin。
    @include respond-to(small) { ... }
    @include respond-to(medium) { ... }
    @include respond-to(large) { ... }
    这种方法是极好的(甄嬛体,老外也看?),原因有二:抽象数据有意义,大量断点集中管理。假设你想把“992px”改成“970px”,你不须要爬过每个css文件,而仅仅需更新mixin,然后所有更新。
    可是也还有两个问题:
    a.断点不easy从mixin里拿出来,放到配置文件中去。
    b.冗余太多。

    3. 可配置的mixin(With a configurable mixin  )

    <为了解决上面的两个问题,我们须要从断点mixin中抽出一个列表,仅仅剩下mixin核心,然后这个列表就能够随便移动,或者扔到配置文件中。
    然后,使用sass 3.3+中的maps,我们能够方便的使用关联的属性和属性值。
    $breakpoints: (
      'small'  : 767px,
      'medium' : 992px,
      'large'  : 1200px
    );
    然后原来的mixin进行相应的改动
    @mixin respond-to($breakpoint) {
      // Retrieves the value from the key
      $value: map-get($breakpoints, $breakpoint);
     
      // If the key exists in the map
      @if $value != null {
        // Prints a media query based on the value
        @media (min- $value) {
          @content;
        }
      }
     
      // If the key doesn't exist in the map
      @else {
        @warn "Unfortunately, no value could be retrieved from `#{$breakpoint}`. "
            + "Please make sure it is defined in `$breakpoints` map.";
      }
    }
    我们在改动mixin的同一时候也进行了一些提高,不要小看这些提高,我们加上了错误处理,假设在maps中没有找到断点值,将会弹出一个错误提示,这将便于我们开发过程中的调试。
    我们让mixin变得更加精简,能非常好的处理错误,同一时候我们去掉了一个功能——推断属性是否是你想要的(min-width,max-width,min-height等),这在移动优先的网页中没问题,由于我们仅仅须要min-width。可是,假设须要查询其它属性,我们须要把这个功能加回来。为了达到这个目的,我想到了一个非常优雅的解决方式,同一时候并不添加复杂性。
    $breakpoints: (
      'small'  : ( min-  767px ),
      'medium' : ( min-  992px ),
      'large'  : ( min- 1200px )
    );
      
    @mixin respond-to($name) {
      // If the key exists in the map
      @if map-has-key($breakpoints, $name) {
        // Prints a media query based on the value
        @media #{inspect(map-get($breakpoints, $name))} {
          @content;
        }
      }
     
      // If the key doesn't exist in the map
      @else {
        @warn "Unfortunately, no value could be retrieved from `#{$breakpoint}`. "
            + "Please make sure it is defined in `$breakpoints` map.";
      }
    }
    在这里,我们主要做了三个事情
    a. 检查查询的断点在map中存在不存在
    b.假设存在,打印相应的媒体查询。
    c.假设不在,进行错误提示。
    简单吧,假设我们回想前面的两个缺陷,已经不再有WET(Write Everything Twice))问题,也不再有不灵活的媒体查询。可是另一个问题,不支持复杂的媒体查询。复杂指的是涉及多个组件的查询(e.g. screen and (min- 767px))。我们上面这些方案除了第一种变量之外都不能非常好的解决问题。

    4. 使用外部工具(With an external tool)

    最后一个相同重要的是,假设不想创建自己的mixin,你能够使用外部的工具处理响应式布局的断点,有非常多sass的扩展在这个方面做得非常好。
    SassMQ by Kaelig
    Breakpoint by Mason Wendell and Sam Richard
    Breakup by Ben Scott
     SassMQBreakpointBreakup
    MQ type*-widthanyany
    No Query fallbackyepyepyep
    API complexitysimplevery simplemedium
    Code complexityvery simplecomplexesimple
    ExtraDebug modeSingularity.gs
    基本上是这样,假设发现有没有涉及的,记得一定告诉我。

    SassMQ

    // Configuration
    $mq-responsive: true;
    $mq-static-breakpoint: desktop;
    $mq-breakpoints: (
      mobile:  320px,
      tablet:  740px,
      desktop: 980px,
      wide:    1300px
    );
     
    // Example
    selector {
      @include mq($from: mobile) {
        property: value;
      }
    }

    BreakPoints

    $high-tide: 500px;
    $ex-presidents: 600px 800px;
    $surfboard- max-width 1000px;
    $surfboard-height: (min-height 1000px) (orientation portrait);
     
    selector {
      @include breakpoint($high-tide) {
        property: value;
      }
    }

    Breakup

    $breakup-breakpoints: (
      'thin' '(max- 35.999em)',
      'wide' '(min- 36em)',
      'full' '(min- 61em)'
    );
     
    selector {
      @include breakup-block('thin') {
        property: value;
      }
    }

    总结

    我们在这篇文章里看到的这么些个方案,都有长有短,没有一个完美的方案。最后我觉得还是由你来决定怎么把握可用性和复杂性的平衡。
    一句话,在合适的场合使用合适的工具。
    ------------------------------------------------------------------------------------------------------------------------------
    That's it. 敬请留言,说说你的意见和建议。

    ----------------------------------------------------------

    前端开发whqet,关注web前端开发,分享相关资源,欢迎点赞,欢迎拍砖。
    ---------------------------------------------------------------------------------------------------------

  • 相关阅读:
    8.11 hdu 多校第五场补题
    8.10 trie树模板
    8.6 edu25 ,577#div2 CF补题(二分 ,dp 与 贪心
    8.4 POJ 3237 (树链剖分+线段树
    8.4 poj 2763 Housewife Wind (树链剖分边权处理
    8.4 树链剖分
    8.3 树链剖分
    2019 hdu 第四场补题 (2
    2019 hdu 第四场补题 (1 ,签到题
    51NOD 1137 矩阵乘法
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/3765410.html
Copyright © 2011-2022 走看看