sass
last update:
2021/02/26
Search :
: 0 results
dartsass
npm install sass --save-dev // install sass {sass folder}:{css folder} // compile sass {sass folder}:{css folder} --style=compressed // minify compile
ネスト(selector)
// scss div { padding: 0; a { width: 100px; span { color: #111; } > span { color: #222; } .class { color: #333; } &.class { color: #444; } &:hover { color: #555; } .class & { color: #666; } &_string { // sass version 3.3.7 color: #777; } span, strong { color: #888; } } } code_popup --- // css div { padding: 0; } div a { width: 100px; } div a span { color: #111; } div a > span { color: #222; } div a .class { color: #333; } div a.class { color: #444; } div a:hover { color: #555; } .class div a { color: #666; } div a_string { color: #777; } div a span, div a strong { color: #888; }
ネスト(property)
// scss div { border: { style: solid; left: { width: 1px; color: #111; } right: { width: 1px; color: #222; } } margin: 10px { top: 0; } } code_popup --- // css div { border-style: solid; border-left-width: 1px; border-left-color: #111; border-right-width: 1px; border-right-color: #222; margin: 10px; margin-top: 0; }
ネスト(media query)
// scss div { color: #aaa; @media all and (orientation:landscape) { color: #bbb; } } code_popup --- // css div { color: #aaa; } @media all and (orientation: landscape) { div { color: #bbb; } }
変数(データ型)
// scss $string_1: ".foo"; // .(ドット)など記号で始まる場合、引用符が必要 $string_2: color; $number_1: 1; $number_2: 1px; // cssで有効な単位は数値扱い $color_1: rgba(17,34,51,1.0); // アルファが1.0だと16進数6桁表記に変換される $color_2: #123; // 6桁表記に変換される $boolean: true; $null: null; $list: 0 0 no-repeat; // カンマ区切りも有効 $map: ( img_c: "/img/common/", img_s: "/img/sprite/", img_f: "/img/figure/" ); // グローバルスコープ = どこでも有効 // セレクタ内で宣言した変数はそのセレクタ内でのみ有効(ローカルスコープ) // グローバルとローカルで同じ変数名の場合はローカル優先 // listの値にlistやmapを入れたり、mapの値にlistやmapを入れることができる // mapのキーと値はeach文で変数2つとして使うことができる // 使えない変数名: 数字から始まる,@などの記号,--(ハイフン2個)から始まる #{$string_1} { line-height: $number_1; box-shadow: 0 $number_2 1px $color_1; #{$string_2}: $color_2; background-#{$string_2}: #000; @if $boolean == true { @if $null == null { background: url(#{map-get($map,img_c)}bg.png) $list; } } opacity: $null; // 値にnullが入るとプロパティ名も出力しない } // #{} = インターポレーション = 文字との連結やプロパティやセレクタのとき必要 code_popup --- // css .foo { line-height: 1; box-shadow: 0 1px 1px #112233; color: #112233; background-color: #000; background: url(/img/common/bg.png) 0 0 no-repeat; }
演算(数値)
// scss div { margin: 10px + 5; margin: 10px - 5; margin: 10px * 5; margin: (10px / 5); // 割算のスラッシュはフォント一括指定と区別するため括弧が必要 margin: 10px % 5; color: #111 + #aaa; color: #aaa + #aaa; // 範囲を超えたら自動調整 color: (#999 / 3); color: rgba(0, 50, 255, 0.5) + rgba(100, 50, 255, 0.5); // 255以上は自動調整,アルファは演算不可 $size: 20px; font: $size / 2; // 変数の時は割算でも括弧が要らない font: #{$size} / 2; // フォント一括指定にしたいときはインターポレーション } code_popup --- // css div { margin: 15px; margin: 5px; margin: 50px; margin: 2px; margin: 0px; color: #bbbbbb; color: white; color: #333333; color: rgba(100, 100, 255, 0.5); font: 10px; font: 20px / 2; }
演算(文字列)
// scss div:before { content : foo + bar; content : "foo" + bar; content : foo + "bar"; content : "foo" + "bar"; // 先頭の引用符の有無が反映される $root : "../"; $kind : "img/"; $file : "bg"; background: url("#{$root + $kind + $file}.png") 0 0 no-repeat; } code_popup --- // css div:before { content: foobar; content: "foobar"; content: foobar; content: "foobar"; background: url("../img/bg.png") 0 0 no-repeat; }
条件分岐(@if)
// scss $foo : 1; .bar { @if $foo { /* falseかnull以外の値が存在するとき */ color: #111; } @else { /* 値がfalseかnullのとき */ color: #222; } } // .bar { color: if($foo == 1, #111, #222); } も同義 .baz { @if $foo == 0 { /* 値が0のとき */ color: #333; } @else if $foo == 1 { /* 値が1のとき */ color: #444; } @else { /* 0か1以外の値が存在するとき */ color: #555; } } // .baz { color: if($foo == 0, #333, if($foo == 1, #444, #555)); } も同義 code_popup --- // css .bar { /* falseかnull以外の値が存在するとき */ color: #111; } .baz { /* 値が1のとき */ color: #444; } // 値が存在しない場合はコンパイルエラー // 他の演算子は !=, >, <, >=, <=, and, or, not
ループ(@for)
// scss @for $num from 1 through 3 { .icon_A_#{$num} { background: url(/img/icon_A_#{$num}.png) 0 (($num - 1)*100px) no-repeat; } } @for $num from 1 to 3 { .icon_B_#{$num} { background: url(/img/icon_B_#{$num}.png) 0 (($num - 1)*100px) no-repeat; } } code_popup --- // css .icon_A_1 { background: url(/img/icon_A_1.png) 0 0px no-repeat; } .icon_A_2 { background: url(/img/icon_A_2.png) 0 100px no-repeat; } .icon_A_3 { background: url(/img/icon_A_3.png) 0 200px no-repeat; } .icon_B_1 { background: url(/img/icon_B_1.png) 0 0px no-repeat; } .icon_B_2 { background: url(/img/icon_B_2.png) 0 100px no-repeat; }
ループ(@while)
// scss $num: 5; @while $num > 0 { .icon_#{$num} { background: url(/img/icon_#{$num}.png) 0 (($num - 1)*100px) no-repeat; } $num: $num - 1; } code_popup --- // css .icon_5 { background: url(/img/icon_5.png) 0 400px no-repeat; } .icon_4 { background: url(/img/icon_4.png) 0 300px no-repeat; } .icon_3 { background: url(/img/icon_3.png) 0 200px no-repeat; } .icon_2 { background: url(/img/icon_2.png) 0 100px no-repeat; } .icon_1 { background: url(/img/icon_1.png) 0 0px no-repeat; }
ループ(@each)
// scss // each文の中に値を適用 .foo { @each $prefix in -webkit- -moz- -ms- -o- null { #{$prefix}border-radius: 10px; } } // リストにしてからeach文に適用 $vendor: -webkit- -moz- -ms- -o- null; .bar { @each $prefix in $vendor { #{$prefix}border-radius: 20px; } } // マップにしてからeach文に適用 $vendor_prefix: ( webkit: -webkit-, mozilla: -moz-, ie: -ms-, opera: -o-, none: null ); .baz { @each $vendor, $prefix in $vendor_prefix { #{$prefix}border-radius: 30px; /* #{$vendor} */ } } code_popup --- // css .foo { -webkit-border-radius: 10px; -moz-border-radius: 10px; -ms-border-radius: 10px; -o-border-radius: 10px; border-radius: 10px; } .bar { -webkit-border-radius: 20px; -moz-border-radius: 20px; -ms-border-radius: 20px; -o-border-radius: 20px; border-radius: 20px; } .baz { -webkit-border-radius: 30px; /* webkit */ -moz-border-radius: 30px; /* mozilla */ -ms-border-radius: 30px; /* ie */ -o-border-radius: 30px; /* opera */ border-radius: 30px; /* none */ }
@use
// sass template {project} │ ├ css │ └ {project}.css └ sass ├ {project}.scss │ ├ _conf.scss │ └ parts ├ lib │ ├ _reset.scss │ └ _utility.scss ├ _base.scss ├ _layout.scss └ _module.scss // {project}.scss @use "conf"; @use "parts/lib/reset"; @use "parts/lib/utility"; @use "parts/base"; @use "parts/layout"; @use "parts/module"; // {project}.scss の中にlib,mod内のscssファイルの内容を読み込む // 名前がアンダーバーで始まるパーシャルファイルは、sassフォルダごとコンパイルしても個別に出力しない // @use文の値で、パーシャルファイルの最初のアンダーバーと拡張子は省略可能
!default
.foo { // A $body_font_size: 12px; $body_line_height: 1em; // B body { font-size: $body_font_size; // 12px line-height: $body_line_height; // 1em } } code_popup // Aが別ファイルのパーシャルなどからimportしたものの場合、上記のコードならBは問題無くcssに反映される // しかし、Aのパーシャル内で仮に変更があった下記のような場合、 .foo { // A' $body_font_size: 14px; // 値が更新されていた $text_line_height: 1.5em; // 変数名と値が更新されていた // B body { font-size: $body_font_size; // 14px line-height: $body_line_height; // コンパイルエラー } } code_popup // Bの $body_font_size には問題なくA'の値が適用されるが、$body_line_height は定義されていないのでエラーになる // そこで、下記のようにBで!defaultを指定しておくことにより、 .foo { // A' $body_font_size: 14px; // 値が更新されていた $text_line_height: 1.5em; // 変数名と値が更新されていた // B $body_font_size: 12px !default; $body_line_height: 1em !default; body { font-size: $body_font_size; // 14px line-height: $body_line_height; // 1em } } code_popup // A'の変数宣言はBにとって問題が無く、値が更新された $body_font_size には A'の値が適用され、A'の変数宣言に問題がある $body_line_height には !default の値が適用される
@mixin
// scss @mixin baz { margin: 0; padding: 10px; } .foo { @include baz; color: #000; } .bar { @include baz; color: #f00; } code_popup --- // css .foo { margin: 0; padding: 10px; color: #000; } .bar { margin: 0; padding: 10px; color: #f00; } // includeした場所にmixinの内容を読み込む // includeした場所よりmixinの表記場所が下にあるとコンパイルエラー // mixinの中でincludeすることも可 // mixinの中でincludeする場合は互いのmixinの表記順にルールは無い // 使えないmixin名: 数字から始まる,@などの記号,--(ハイフン2個)から始まる
@mixin(引数)
// scss @mixin baz($value: 10px) { // : 10px = 初期値 margin: 0; padding: $value; } .foo { @include baz; color: #000; } .bar{ @include baz(20px); color: #f00; } code_popup --- // css .foo { margin: 0; padding: 10px; // 引数を指定しなければ初期値が反映される color: #000; } .bar { margin: 0; padding: 20px; color: #f00; } // 初期値は未設定でも可 @mixin baz($value) { 〜 } // 初期値が未設定の時、includeで引数を設定しなければエラー // 引数の複数設定可 @mixin baz($value1: 10px, $value2: 20px, 〜 ) { 〜 }
@mixin(可変長引数)
@mixin foo1($value) { text-shadow: $value; } .bar1 { @include foo1(1px 1px 0 #555, -1px -1px 0 #eee); // 1つの引数に2つの値を渡しているのでエラー @include foo1((1px 1px 0 #555, -1px -1px 0 #eee)); // valid @include foo1(unquote("1px 1px 0 #555, -1px -1px 0 #eee")); // valid } @mixin foo2($value...) { // 引数の数を限定しない text-shadow: $value; } .bar2 { @include foo2(1px 1px 0 #555, -1px -1px 0 #eee); // valid } code_popup --- @mixin foo($t, $r, $b, $l) { padding-top: $t; padding-right: $r; padding-bottom: $b; padding-left: $l; } .bar { $value: 10px, 20px, 30px, 40px; @include foo($value); // $t に4つの値を渡し、$r,$b,$l に値が入らないのでエラー @include foo($value...); // valid } code_popup
@mixin(@content)
// scss @mixin media($value) { @if $value == pc { @media(min-width:769px){ @content; } } @if $value == tablet { @media(max-width:768px) and (min-width: 321px){ @content; } } @if $value == sp { @media(max-width:320px){ @content; } } } #header { background: #edf; color: #222; @include media(pc) { height: 100px; font-size: 18px; } @include media(tablet) { height: 60px; font-size: 16px; } @include media(sp) { height: 30px; font-size: 12px; } } code_popup --- // css #header { background: #edf; color: #222; } @media (min-width: 769px) { #header { height: 100px; font-size: 18px; } } @media (max-width: 768px) and (min-width: 321px) { #header { height: 60px; font-size: 16px; } } @media (max-width: 320px) { #header { height: 30px; font-size: 12px; } } // includeした場所にmixinの内容を読み込み、contentした場所にはincludeの{}の内容が入る // 上記はレスポンシブのmediaquery表記を簡素化するためmixinに纏めた例
@extend
// scss .baz { margin: 0; padding: 10px; } .foo { @extend .baz; color: #000; } .bar { @extend .baz; color: #f00; } code_popup --- // css .baz, .foo, .bar { margin: 0; padding: 10px; } .foo { color: #000; } .bar { color: #f00; } // extendした場所のセレクタ(.fooと.bar)が、指定したセレクタ(.baz)の後に追記される // mixinと違い、指定したセレクタの場所が上になければエラー、というルールは無い // 指定したセレクタが無い場合はエラーになるが、@extend .baz !optional; とすれば回避する // @mediaの中から、外にあるセレクタはextendできない
@extend(placeholder selector)
// scss %baz { margin: 0; padding: 10px; } .foo { @extend %baz; color: #000; } .bar { @extend %baz; color: #f00; } code_popup --- // css .foo, .bar { margin: 0; padding: 10px; } .foo { color: #000; } .bar { color: #f00; } // extendした場所のセレクタ(.fooと.bar)が、指定したセレクタ(%baz)に代わって表記される // mixinと違い、指定したセレクタの場所がextendした場所より上になければエラーというルールは無い // 指定したセレクタが無い場合はエラーになるが、@extend %baz !optional; とすれば回避する // @mediaの中から、外にあるプレースホルダセレクタはextendできない
@at-root
// sass .foo_1 { content: "1"; .foo_2a { content: "2a"; } @at-root .foo_2b { /* セレクタの前に付けることで親(.foo_1)の外に出す */ content: "2b"; } } .bar_1 { content: "1"; @at-root { /* 複数のセレクタを親(.bar_1)の外に出す */ .bar_2 { content: "2"; } .bar_3 { content: "3"; } } } @media all and (orientation:landscape) { .baz_1 { content: "1"; @at-root .baz_2a { /* @mediaの外に出ない */ content: "2a"; } @at-root (without: media) { .baz_2b { /* @mediaの外に出る */ content: "2b"; } } @at-root (without: media rule) { .baz_2c { /* @mediaの外に出て親(.baz_1)からも出る */ content: "2c"; } } @at-root (with: media) { .baz_2d { /* @mediaの外に同じ@mediaを作り、親(.baz_1)からは出る */ content: "2d"; } } } } code_popup --- // css .foo_1 { content: "1"; } .foo_1 .foo_2a { content: "2a"; } .foo_2b { /* セレクタの前に付けることで親(.foo_1)の外に出す */ content: "2b"; } .bar_1 { content: "1"; } /* 複数のセレクタを親(.bar_1)の外に出す */ .bar_2 { content: "2"; } .bar_3 { content: "3"; } @media all and (orientation: landscape) { .baz_1 { content: "1"; } .baz_2a { /* @mediaの外に出ない */ content: "2a"; } } .baz_1 .baz_2b { /* @mediaの外に出る */ content: "2b"; } .baz_2c { /* @mediaの外に出て親(.baz_1)からも出る */ content: "2c"; } @media all and (orientation: landscape) { .baz_2d { /* @mediaの外に同じ@mediaを作り、親(.baz_1)からは出る */ content: "2d"; } }
関数
// scss $path: ( img_c: "/img/common/", img_s: "/img/sprite/", img_f: "/img/figure/" ); div { background-image: url(#{map-get($path,img_c)}bg.png); } // map-get($map, $key) -> マップのキーから値を返す関数 // 関数一覧 -> http://sass-lang.com/documentation/Sass/Script/Functions.html code_popup --- // css div { background-image: url(/img/common/bg.png); }
@function
// scss @function function_name($value) { // 自作関数 @return $value * 100; } div { content: function_name(1px); } code_popup --- // css div { content: 100px; }
@debug
// scss @function double($value) { @debug $value; $value: $value * 2; @debug $value; @return $value; } .foo { content: double(10px); } code_popup --- // css .foo { content: 20px; } --- // console sass/filename.scss:2 DEBUG: 10px sass/filename.scss:4 DEBUG: 20px
@warn
// scss @function double($value) { @if type-of($value) == number { // type-of() -> 値のタイプを返す関数 @return $value * 2; } @else { @warn "引数には数値を入れてください"; @return null; } } .foo { content: double(null); } code_popup --- // css --- // console WARNING: 引数には数値を入れてください on line 5 of sass/filename.scss
///
code_popup
old(ruby-sass)
ruby -v // Rubyバージョン確認 gem -v // RubyGemsバージョン確認 sass -v // sassバージョン確認 sudo gem install sass // sassインストール sudo gem install sass -v [version] // バージョン指定インストール // sudo gem install sass -v 3.2.17 sudo gem install sass --pre // アルファ版インストール sudo gem install oily_png // スプライト画像生成の高速化 sudo gem update --system // RubyGemsアップデート sudo gem update sass // sassアップデート sudo gem uninstall sass // sassアンインストール sass -? // ヘルプ表示 http://sass-lang.com/documentation/file.SASS_REFERENCE.html // Reference http://sass-lang.com/documentation/file.SASS_CHANGELOG.html // Changelog --- // compile scssが以下のとき /* * comment A */ /*! * comment B */ // comment C body { margin: 0; padding: 0; div { display: block; } } code_popup sass [scss path]:[css path] sass [scss path]:[css path] -t nested /* * comment A */ /*! * comment B */ body { margin: 0; padding: 0; } body div { display: block; } sass [scss path]:[css path] -t expanded /* * comment A */ /*! * comment B */ body { margin: 0; padding: 0; } body div { display: block; } sass [scss path]:[css path] -t compact /* comment A */ /*! * comment B */ body { margin: 0; padding: 0; } body div { display: block; } sass [scss path]:[css path] -t compressed /*! * comment B */body{margin:0;padding:0}body div{display:block} --- 監視コンパイル sass -w [scss path]:[css path] sass -w [scss dir]:[css dir] // フォルダ指定 sass -w --line-comments [scss dir]:[css dir] // line comment付き sass -w --no-cache [scss dir]:[css dir] // キャッシュフォルダを作らない sass -w [scss dir]:[css dir] --load-path [other project dir] // 別プロジェクトからライブラリ等をimport --- cssからscssにコンパイル sass-convert --to scss [css path] [scss path] sass-convert --recursive --from css --to scss [dir] [dir]// フォルダごと
old(gulp-sass)
// npm command npm install gulp-sass --save-dev // install npm uninstall gulp-sass --save-dev // uninstall npm install gulp-sass@x.x.x --save-dev // specified version install npm info gulp-sass // check version // gulpfile.js var sass = require('gulp-sass'); gulp.task('sass', function(){ gulp.src('scssのパス') .pipe(sass()) .pipe(gulp.dest('出力するcssのパス')); }); gulp.task('default', ['sass']); code_popup
old (node-sass)
npm install node-sass --save-dev // install node-sass -o {css folder} {sass folder} // compile