【SCSS / SASS】オレオレ爆速Mixins

SASSをしばらく使ってみて、どんなプロダクトでも使うとコーディングが早くなる汎用的なMixinとクラスを発見したので共有したいと思います。

他にも「これも結構使えるテンプレだぞ！」ってやつがあったらコメントで教えていただきたいです。



## リセットCSS

早速Mixinじゃないですが、僕はあんまり巷に出回るリセットCSSが好きじゃなくて、自分が最低限必要だと思って毎回使ってるリセットCSSなのでご紹介しておきます。

一番下の`background-color`はコメントアウトを外すと要素が見やすくなります。

```scss
* {
  position: relative;
  margin: 0;
  padding: 0;
  font-feature-settings: 'palt';
  box-sizing: border-box;
  list-style-type: none;
  text-decoration: none;
  scroll-behavior: smooth;
  // background-color: rgba(255,0,0,0.05);
}
```



## ボタンにリンクを配置するとき

とてもよく使います。ボタンをリンクにするためのMixinです。

`div`や`span`で作ったボタンをそのまま`a`タグで囲うと、ボタンの中の文字だけがリンクになるので、ボタンの内側を全てリンクにする場合は`a`タグを`position: absolute`して、ボタンの内側に配置するのが一般的だと思います。

それを一々書かなくても良くしたMixinと、それを指定したクラスになります。

```scss
@mixin covered-link {
  position: absolute;
  z-index: 10;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

a.covered-link {
  @include a-link;
}
```

以下のように書くだけで使えます。（Pugを使ってます）

```pug
.button
	span ボタン
	a.covered-link(href='#')
```



## 背景画像を設定するとき

これもとてもよく使います。

`background-image`を設定するときの多くは中央寄せにしますし、繰り返ししないので、それをまとめたmixinです。要素に収まるように画像を配置するとき用の**bg-contain**と、要素いっぱいに配置するとき用の**bg-cover**があります。

```scss
@mixin bg-contain {
  background-repeat: no-repeat;
  background-position: center;
  background-size: contain;
}

@mixin bg-cover {
  background-repeat: no-repeat;
  background-position: center;
  background-size: cover;
}
```

以下のように使います。

```scss
.image {
	@include bg-cover;
  width: 100px;
  height: 100px;
}
```



## メディアクエリ

とてもよく使います。

メディアクエリを書きやすく、ブレイクポイントを変更しやすくしたものです。[こちらのサイト](https://www.tam-tam.co.jp/tipsnote/html_css/post10708.html)を参考にしました。

```scss
$breakpoint-width-up: (
  'sm': '480px',
  'md': '896px',
  'lg': '1024px',
) !default;

$breakpoint-width-down: (
  'sm': '479px',
  'md': '895px',
  'lg': '1023px',
) !default;

@mixin media-width-up($breakpoint: md) {
  @if str-index($breakpoint, px) {
    @media screen and (min-width: #{$breakpoint}) {
      @content;
    }
  }
  @else {
    @media screen and (min-width: #{map-get($breakpoint-width-up, $breakpoint)}) {
      @content;
    }
  }
}

@mixin media-width-down($breakpoint: md) {
  @if str-index($breakpoint, px) {
    @media screen and (max-width: #{$breakpoint}) {
      @content;
    }
  }
  @else {
    @media screen and (max-width: #{map-get($breakpoint-width-down, $breakpoint)}) {
      @content;
    }
  }
}

@mixin media-height-up($breakpoint) {
  @media screen and (min-height: #{$breakpoint}) {
    @content;
  }
}

@mixin media-height-down($breakpoint) {
  @media screen and (max-height: #{$breakpoint}) {
    @content;
  }
}
```

以下のように使います。横の長さはsm/md/lgでもpxでも指定できますが、縦の長さはpxでしか指定できないようにしています。

```scss
p {
  // 画面の幅がsm以下の場合に適用
  @include media-width-down(sm) {
    color: yellow;
  }
  // 画面の幅が600px以上の場合に適用
  @include media-width-up(600px) {
    color: white;
  }
  // 画面の縦の長さが1000px以下の場合に適用
  @include media-height-down(300px) {
    color: red;
  }
}
```





## 〇〇px以下で出現/消える要素

割とよく使うし、頼りになります。このMixinは上のメディアクエリに依存するので、使用するときは一緒に`@import`してください。

メディアクエリでどうにかなるときがほとんどですが、PC版とスマホ版で違う文字のデザインが要求されたりします。そのときに「うっ」とならずに、強引に解決してしまう方法です。あまり変な使い方をするとSEOやアクセシビリティ的にも良くないとは思いますが、開発は爆速で進みます。

```scss
@mixin visible-settings($size, $mode) {
  &.#{$size} {
    @if $mode == 'hidden' {
      @include media-width-up($size) {
        &.inline {
          display: inline;
        }
        &.inline-block {
          display: inline-block;
        }
        &.block {
          display: block;
        }
      }
      display: none;
    }
    @else {
      @include media-width-down($size) {
        &.inline {
          display: inline;
        }
        &.inline-block {
          display: inline-block;
        }
        &.block {
          display: block;
        }
      }
      display: none;
    }
  }
}

.when-less-than {
  &.hidden {
    @include visible-settings(md, 'hidden');
    @include visible-settings(sm, 'hidden');
  }
  &.appear {
    @include visible-settings(md, 'appear');
    @include visible-settings(sm, 'appear');
  }
}
```

以下のように使います。

```scss
span.appear.when-less-than.sm.inline // スマホ版で表示
span.hidden.when-less-than.sm.inline-block // PC/タブレット版で表示
```

注意点として、このクラスを指定した要素には`display`を上書きしないでください。



## フォントが混ざらないようにするとき

まあまあ使います。

フォントを指定するときは英語専用のフォントを優先的に指定して、日本語のときはその他のフォントを指定することがほとんどですが、日本語の中に英語が混じることになります。それが困るときに、このMixinを使用して、日本語のみのフォントを指定します。

```scss
@mixin font-family($lang) {
  @if $lang == ja {
    font-family: 'Noto Sans JP', sans-serif;
  } @else {
    font-family: 'Apple LiGothic Medium', 'Roboto', 'Noto Sans JP', sans-serif;
  }
}
```

以下のように使います。

```scss
p.only-japanese {
  @include font-family(ja);
  font-size: 14px;
}
```



## activeで出現するやつ

たまに使います。

JavaScriptでクラスをいじって、`.active`が付いている間だけ出現するやつです。

```scss
@mixin on-active-appear {
  opacity: 0;
  pointer-events: none;
  transition: opacity .5s;
  &.active {
    opacity: 1;
    pointer-events: auto;
  }
}
```

以下のように使います。

```scss
.login-button {
  @include on-active-appear
}
```

```pug
.login-button //- 見えない
.login-button.active //- 見える
```



## 隠しテキストを置くとき

SEOへの配慮も含めて、隠しテキストを置くときはよくあります。背景画像を使ったときの代替テキストや、`section`始めの区切りとしておくことがあります。apple.comで同様のテクニックが使われていたので、やっておくといいことがあると思います。`display:none`はしないのがポイントだと思われます。

```scss
@mixin visibility-hidden {
  position: absolute;
  overflow: hidden;
  width: 1px;
  height: 1px;
}

.visibility-hidden {
  @include visibility-hidden
}
```

以下のように使います。

```pug
.h2
	span.dog-image //- 犬の画像
	span.visibility-hidden Dog //- Dogというテキストを置いておく。
```