SCSSの基本的な書き方

#基本的な書き方

###入れ子にする
{}の中に子要素のタグ（class、IDなど）を書くと勝手に親要素を認識してくれる。

```html:index.html
<div>
  <p>パンケーキ食べたい</p>
</div>
```

```scss:style.scss
div {
  background: red;
  width: 400px;
  height: 400px;
  p {
    color: white;
    font-weight: bold;
    text-align: center;
  }
}
```

▼出力結果

```css:style.css
div {background: red; width: 400px; height: 400px;}
div p {color: white; font-weight: bold; text-align: center;}
```

###「&」でくっつける
上の基本的な書き方だと親と子の形でしか書けないので、下の例のようにしたい場合は「&」で対応する。

▼こうやって吐き出させたい

```css:style.css
div {width: 300px; height: 200px; background: red;}
div:before {content: ''; display: block; width: 300px; height: 150px; background: blue;}
div.hoge {width: 150px; height: 29px; background: yellow;} /* classがhogeのdiv */
div .hoge {width: 120px; height: 53px; background: green;} /* divの中にいるclassがhoge */
```

▼&を使ってこうやって書く

```scss:style.scss
div {
  width: 300px;
  height: 200px;
  background: red;
  &:before {
    content: '';
    display: block;
    width: 300px;
    height: 150px;
    background: blue;
  }
  &.hoge { /* classがhogeのdiv　&がついてるからdivと.hogeがくっつく */
    width: 150px;
    height: 29px;
    background: yellow;
  }
  .hoge { /* divの中にいるclassがhoge　&がついていないのでdivと.hogeがくっつかない */
    width: 120px;
    height: 53px;
    background: green;
  }
}
```

#便利ポイント
##変数
変数が使える。

```scss
/* 変数宣言の仕方*/
$変数名: 値;
```

```scss:style.scss
$main_color: red; 
$sub_color: blue;
$font_size: 16px;

div {
  color: $main_color;
  font-size: 18px;
  p {
    border: 1px solid $main_color;
    color: $sub_color;
    font-size: $font-size;
  }
}
```

▼出力結果

```css:style.css
div {color: red; font-size: 18px;}
div p {border: 1px solid red; color: blue; font-size: 16px;}
```

##条件分岐
条件分岐できる。

####if文

```scss:style.scss
div {
  @if 1 + 1 == 2 { width: 100%; } // 1+1=2なのでtrue
  @if 1 > 2 {width: 50%;} // 1は2より小さいのでfalse
  @if null {width: 10%;} // nullはfalse
}
```

▼出力結果

```css:style.css
  div {
    width: 100%;
  }
```

####elseとelse ifも使える

```scss:style.scss
$color = red;
div {
  @if $color == blue {
    background: blue;
  } @else if $color == yellow {
    background: yellow;
  } @else if $color == red {
    background: red;
  } @else {
    background: white;
  }
}
```

▼出力結果

```css:style.css
div {
  background: red;
}
```


##反復処理
####for文

```scss:for.scss
@for $i from 1 through 3 {
  .hoge-#{$i} {width: 100px * $i;} // 文字列として$iを使う場合（注:1）は「$i」ではなく「#{$i}」にする
}
```

注1:20190530 「クラス名の文字列に使う場合」を「文字列として$iを使う場合」に修正しました。

▼出力結果

```css:for.css
.hoge-1 {width: 100px;}
.hoge-2 {width: 200px;}
.hoge-3 {width: 300px;}
```

####while文

```scss:while.scss
$i: 1;
@while $i < 4 {
  .hoge-#{$i} {width: 100px * $i;}
  $i: $i + 1;
}
```

▼出力結果

```css:while.css
.hoge-1 {width: 100px;}
.hoge-2 {width: 200px;}
.hoge-3 {width: 300px;}
```

####each文

```scss:構文
@each $var in <list> 
/* $var -> 任意の変数 */
/* <list> -> カンマ区切りのリスト。リストの数だけ繰り返す
```

```scss:each.scss
@each $neko in mike, kuro, bus {
  .#{$neko}-icon {
    background-image: url('/images/#{$neko}.png');
  }
}
```

▼出力結果

```css:each.css
.mike-icon {
  background-image: url('/images/mike.png');
}
.kuro-icon {
  background-image: url('/images/kuro.png');
}
.bus-icon {
  background-image: url('/images/bus.png');
}
```


##関数
関数が使える。

```scss
/* 関数宣言の仕方 */
@mixin 関数名(引数１, 引数２, ...) {
  関数の中身
}

/* 関数の呼び出し方 */
@include 関数名(引数１, 引数２, ...);
```

▼今回作った関数

####メディアクエリ
```scss:media_queries.scss
$breakpoint-tablet: 1024px; /* 変数宣言 */
$breakpoint-mobile: 640px; /* 変数宣言 */

/* $break-point以下の時に@contentを適用 */
@mixin max-screen($break-point) { 
  @media screen and (max-width: $break-point) {
    @content;
  }
}
/* $break-point以上の時に@contentを適用 */
@mixin min-screen($break-point) { 
  @media screen and (min-width: $break-point) {
    @content;
  }
}
/* $break-point-min以上、$break-point-max以下の時に@contentを適用 */
@mixin screen($break-point-min, $break-point-max) { 
  @media screen and (min-width: $break-point-min) and (max-width: $break-point-max) {
    @content;
  }
}

/* 使用例 */
div {
  @include max-screen($breakpoint-mobile) { /* 640px以下のとき */
    width: 100%;
  }
  @include min-screen($breakpoint-tablet) { /* 1024px以上のとき */
    width: 50%;
  }
  @include screen($breakpoint-mobile, $breakpoint-tablet) { /* 640px以上1024px以下のとき */
    width: 80%;
  }
}

```

▼出力結果

```css:media_queries.css
@media screen and (max-width: 640px) {
  div {width: 100%;}
}
@media screen and (min-width: 1024px) {
  div {width: 50%;}
}
@media screen and (min-width: 640px) and (max-width: 1024px) {
  div {width: 80%;}
}
```

####ベンダープレフィックスの付与

```scss:vender_prefix.scss
$set-prefix: '', '-moz-', '-webkit-'; /* つけたいやつを変数に入れる */

// プロパティに付与
@mixin ProprtySetPrefix($name, $value) {
  @each $prefix in $set-prefix {
    #{$prefix}#{$name}: $value;
  }
}
// 値に付与（flex、グラデーションに対応できていない...）
@mixin ValueSetPrefix($name, $value) {
  @each $prefix in $set-prefix {
    #{$name}: #{$prefix}$value;
  }
}

/* 使用例 */
div {
  @include ProprtySetPrefix(transition, .2s);
}

```

▼出力結果

```css:vender_prefix.css
div {
  transition: .2s;
  -moz-transition: .2s;
  -webkit-transition: .2s;
}
```

####フォントの読み込み

```scss:font.scss
@mixin font-face($name, $path, $weight: null, $style: null, $exts: otf ttf) {
  $src: null;
  $formats: (
    otf: "opentype",
    ttf: "truetype"
  );
  @each $ext in $exts {
    $format: map-get($formats, $ext);
    $src: append($src, url(quote($path)) format(quote($format)), comma);
  }
  @font-face {
    font-family: quote($name);
    font-style: $style;
    font-weight: $weight;
    src: $src;
  }
}

/* 使用例 */
@include font-face('Note Serif Japanese', '../../../../fonts/NotoSerifCJKjp-Regular.otf', 400, null, otf);

p {
  font-family: 'Noto Serif Japanese', sans-serif;
}
```

▼出力結果

```css:font.css
@font-face {
  font-family: 'Noto Serif Japanese';
  font-weight: 400;
  src: url(../fonts/NotoSerifCJKjp-Regular.otf) format("opentype");
}

p {
  font-family: 'Noto Serif Japanese', sans-serif;
}
```