第5章 現場で使える実践Sassテクニック

5-3 スマホ・マルチデバイス、ブラウザ対応で使えるテクニック

スマホサイトでよく見る、リストの矢印をミックスインで管理する

@mixin linkIcon($color: #333){
    &::before {
        content: "";
        position: absolute;
        top: 50%;
        right: 15px;
        width: 10px;
        height: 10px;
        margin-top: -7px;
        border-top: 3px solid $color;
        border-right: 3px solid $color;
        transform: rotate(45deg);
    }
}
ul.linkList {
    margin: 20px;
      li {
          list-style: none;
          margin: 0 0 1px;
      a {
          position: relative;
          display: block;
          padding: 15px {
              right: 27px;
          }
          background: #eee;
          color: #333;
          text-decoration: none;
          @include linkIcon();
      }
    }
}
ul.linkList {
  margin: 20px;
}
ul.linkList li {
  list-style: none;
  margin: 0 0 1px;
}
ul.linkList li a {
  position: relative;
  display: block;
  padding: 15px;
  padding-right: 27px;
  background: #eee;
  color: #333;
  text-decoration: none;
}
ul.linkList li a:before {
  content: "";
  position: absolute;
  top: 50%;
  right: 15px;
  width: 10px;
  height: 10px;
  margin-top: -7px;
  border-top: 3px solid rgba(0, 0, 139, 0.8);
  border-right: 3px solid rgba(0, 0, 139, 0.8);
  transform: rotate(45deg);
}

埋め込み動画のアスペクト比計算にpercentage() を使って楽をする

<div class="movie">
    <iframe width="640" height="360" src="https://…(略)…" frameborder="0" allowfullscreen></iframe>
</div>
@media all and (max-width: 768px) {
  .movie {
    position: relative;
    padding-top: 56.25%;
  }
  .movie > iframe {
    position: absolute;
    top: 0;
    left: 0;
    width: 100% !important;
    height: 100% !important;
  }
}
// Responsive Movie
@mixin rwd-iframe($width: 16, $height: 9) {
    position: relative;
    padding-top: percentage($height / $width);
    >iframe {
        position: absolute;
        top: 0;
        left: 0;
        width: 100% !important;
        height: 100% !important;
    }
}
@media all and (max-width: 768px) {
    .movie {
        @include rwd-iframe(640, 360);
    }
}

メディアクエリ用のミックスインを作成して楽々レスポンシブ対応

@media only screen and (max-width : 767px) { ... }
@media only screen and (max-width : 320px) { ... }
$breakpoints: (
    xs: "only screen and (max-width: 320px)",
    s: "only screen and (max-width: 575px)",
    m: "only screen and (max-width: 767px)",
    l: "only screen and (max-width: 991px)",
    xl: "only screen and (max-width: 1199px)",
);
@mixin media($breakpoint) {
    @media #{map-get($breakpoints, $breakpoint)} {
        @content;
    }
}
body {
    background-color: white;
    @include media(l) {
        background-color: blue;
    }
    @include media(m) {
        background-color: green;
    }
    @include media(xs) {
        background-color: red;
    }
}
body {
  background-color: white;
}
@media only screen and (maxwidth: 991px) {
  body {
    background-color: blue;
  }
}
@media only screen and (maxwidth: 767px) {
  body {
      background-color: green;
  }
}
@media only screen and (maxwidth: 320px) {
  body {
    background-color: red;
  }
}

マップのキーの有無を map-has-key()で判定してわかりやすいエラー表示にする

@mixin media($breakpoint) {
    @if map-has-key($breakpoints, $breakpoint) {
        @media #{map-get($breakpoints, $breakpoint)} {
            @content;
        }
    }
    @else {
        @error "$breakpoints に #{$breakpoint} ってキーは無いよ!";
    }
}

CSSハックをミックスインにして便利に使う

/* IE11用のハック */
@media all and (-ms-high-contrast: none) {
  *::-ms-backdrop, .box {
    background: blue;
  }
}
// IE11ハック
@mixin hack-ie11 {
    @at-root {
        @media all and (-ms-high-contrast: none) {
            *::-ms-backdrop, & {
                @content;
            }
        }
    }
}
.box {
    @include hack-ie11 {
        background: blue;
    }
}
@media all and (-ms-high-contrast: none) {
  *::-ms-backdrop, .box {
    background: blue;
  }
}
.box {
    .list {
        .item {
            background: red;
            @include hack-ie11 {
                background: blue;
            }
        }
    }
}
.box .list .item {
  background: red;
}
@media all and (-ms-high-contrast: none) {
  *::-ms-backdrop, .box .list .item {
    background: blue;
  }
}

Retina ディスプレイなど、高解像度端末の対応を楽にする

@mixin bg_size($w, $h: auto) {
    @if $h == auto {
        background-size: round($w / 2) + px $h;
    }
    @else {
        background-size: round($w / 2) + px round($h / 2) + px;
    }
}
.item {
    background: #fff url(/img/bg.png) no-repeat center;
    @media screen and (-webkit-min-device-pixel-ratio: 1.5), (min-resolution: 2dppx) {
        @include bg_size(690, 400);
    }
}