Help us understand the problem. What is going on with this article?

SCSSの基本的な書き方

基本的な書き方

入れ子にする

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

index.html
<div>
  <p>パンケーキ食べたい</p>
</div>
style.scss
div {
  background: red;
  width: 400px;
  height: 400px;
  p {
    color: white;
    font-weight: bold;
    text-align: center;
  }
}

▼出力結果

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

「&」でくっつける

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

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

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 */

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

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;
  }
}

便利ポイント

変数

変数が使える。

/* 変数宣言の仕方*/
$変数名: ;
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;
  }
}

▼出力結果

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

条件分岐

条件分岐できる。

if文

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
}

▼出力結果

style.css
  div {
    width: 100%;
  }

elseとelse ifも使える

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;
  }
}

▼出力結果

style.css
div {
  background: red;
}

反復処理

for文

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

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

▼出力結果

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

while文

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

▼出力結果

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

each文

構文
@each $var in <list> 
/* $var -> 任意の変数 */
/* <list> -> カンマ区切りのリスト。リストの数だけ繰り返す
each.scss
@each $neko in mike, kuro, bus {
  .#{$neko}-icon {
    background-image: url('/images/#{$neko}.png');
  }
}

▼出力結果

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');
}

関数

関数が使える。

/* 関数宣言の仕方 */
@mixin 関数名(引数1, 引数2, ...) {
  関数の中身
}

/* 関数の呼び出し方 */
@include 関数名(引数1, 引数2, ...);

▼今回作った関数

メディアクエリ

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%;
  }
}

▼出力結果

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%;}
}

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

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);
}

▼出力結果

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

フォントの読み込み

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;
}

▼出力結果

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;
}
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away