【Sass】Sassでレスポンシブ!メディアクエリを便利に書こう。
気が付いたら8月突入してて茫然としたhakoishiです。
しかももう1/3過ぎてるとか冗談はおよし。
さて、今回はSassでメディアクエリを便利に管理できる書き方の一例をば。
まとめて書いて、コンパイルの際にブレイクポイント毎に分散させます。
最近、レスポンシブ対応でコーディングをする機会があったのですが、ブレイクポイント毎にそれぞれセレクタを書いていったら管理しきれなくなってしまいました。
まるで統一感のないソースに…!
そこで考えたのが、同じセレクタはまとめて記述し、その内部でメディアクエリごとの分岐も書く方法です。
更に、メディアクエリ毎にまとめて吐き出されるようにしました。
一度に視界に入る範囲であれば、統一感を保った記述もしやすいかと。
scssファイルの構成と記述内容
メディアクエリ分岐などの枠をstyles.scssに、スタイルは_media-query.scssに記述します。
styles.scss
//デバイス定義(全端末共通、スマフォ、タブレット、PC)
$type: all sp tab pc;
//ブレイクポイント毎にデバイスを指定したうえで、_media-query.scssを呼び出す。
/* 全端末共通
-------------------------------------------------- */
$type: all;
@import "media-query";
/* スマフォ
-------------------------------------------------- */
@media only screen and (max-width:767px) {
    $type: sp;
    @import "media-query"
}
/* タブレット
-------------------------------------------------- */
@media only screen and (min-width:768px) and (max-width:1023px) {
    $type: tab;
    @import "media-query"
}
/* PC
-------------------------------------------------- */
@media only screen and (min-width:1024px) {
    $type: pc;
    @import "media-query"
}
_media-query.scss
/* #wrapper */
#wrapper {
    @if $type == all { //全端末共通
        width: 100%;
    
    } @else if $type==sp or $type==tab or $type==pc { //この内部はメディアクエリーで分岐
    
        @if $type == sp or $type == tab { //スマホとタブレット
            .sub-nav {
                display: none;
            }
        }
    
        @if $type == sp { //スマホ
            color: #000000;
        } @else if $type == tab { //タブレット
            color: #CCCCCC;
            
        } @else if $type == pc { //PC
            color: #FFFFFF;
        }
    }
}
/* #container */
#container {
  @if $type == all {
    margin: 0 auto;
    
    .unit-pic {
      float: right;
    }
    
  } @else if $type==sp or $type==tab or $type==pc {
  
    @if $type == sp {
      width: 95%;
            
      .unit-pic {
        width: 100px;
                
        span {
          display: block;
          text-align: center;
        }
      }
            
    } @else if $type == tab {
      width: 90%;
            
      .unit-pic {
        width: 200px;
      }
            
    } @else if $type == pc {
       width: 980px;
            
      .unit-pic {
        width: 300px;
      }    
    } 
  }
}
生成されるcss
styles.css
ブレイクポイントごとにまとまって生成されます。
/* 全端末共通
-------------------------------------------------- */
/* #wrapper */
#wrapper {
  width: 100%;
}
/* #container */
#container {
  margin: 0 auto;
}
#container .unit-pic {
  float: right;
}
/* スマフォ
-------------------------------------------------- */
@media only screen and (max-width:767px) {
  /* #wrapper */
  #wrapper {
    color: #000000;
  }
  #wrapper .sub-nav {
    display: none;
  }
  /* #container */
  #container {
    width: 95%;
  }
  #container .unit-pic {
    width: 100px;
  }
  #container .unit-pic span {
    display: block;
    text-align: center;
  }
}
/* タブレット
-------------------------------------------------- */
@media only screen and (min-width:768px) and (max-width:1023px) {
  /* #wrapper */
  #wrapper {
    color: #CCCCCC;
  }
  #wrapper .sub-nav {
    display: none;
  }
  /* #container */
  #container {
    width: 90%;
  }
  #container .unit-pic {
    width: 200px;
  }
}
/* PC
-------------------------------------------------- */
@media only screen and (min-width:1024px) {
  /* #wrapper */
  #wrapper {
    color: #FFFFFF;
  }
  /* #container */
  #container {
    width: 980px;
  }
  #container .unit-pic {
    width: 300px;
  }
}
まとめ
全部ifで{}内に納めないといけないのが冗長ではありますが、意外と更新性は悪くないのではないかと。
もう一つ蛇足。
本当はブレイクポイントを変数で定義して、@eachでデバイスリストを回して、の方向にしたかったです。
Sassの新バージョンではメディアクエリが変数に格納できると聞いてやってみたのですが、コンパイル通らず断念。@ifと@mediaの相性も良くなかったのかも。
とはいえ、バージョン上がる度にちょっとずつできる事が増えているみたいなので、期待して待ちます。



