stylusについて

# stylusとは？
StylusはSassとLessのいいとこどりと言われているCSSメタ言語の一つ。
SASS記法、SCSS記法のどちらでも記入することができるので、`.sass`か`.scss`を記載することができればstylusも入りやすいと思う。
node.jsのexpressやjadeと同じ人が開発している。
stylusの拡張子は`.styl`か`.stylus`
[stylus公式サイト](http://stylus-lang.com/)

---

# SASS記法とは

```sass
div
  margin: 0
  p
    font-size: 16px
```
Sassがもともと採用していた記法。
拡張子は`.sass`
記述が非常に簡素化されているため、コーディングがコンパクト、簡潔に書くことができる。
rubyに慣れていると描きやすいかも・・・！

---

# SCSS記法とは

```scss
div {
  margin: 0;
  p {
    font-size: 16px;
  }
}
```
SASSがCSSとの互換性が乏しかったために作られた記法。
拡張子は`.scss`
CSSの書き方がそのまま使える。
SCSSの方が書き方がCSSに近いので、CSSに慣れているとこっちの方がいいかも・・・!

---

# stylusをとりあえず使う
## stylusのインストール
```shell
$ npm install stylus -g
```
## stylusのインストールされているのか確認
```shell
$ stylus -V
```

## stylusのフォルダの場所
`-g`を使ってインストールした場合、
- windows
C:\Users\ユーザ名\AppData\Roaming\npm\node_modules\stylus
- Mac
/usr/local/lib/node_modules/stylus

にインストールされる。

## stylusファイルの作成
test.stylという名前で作成

```css:test.styl
fonts = helvetica, arial, sans-serif

body
  padding 50px
  font 14px/1.4 fonts
```
## stylusからcssに変換
test.stylのフォルダ上で

```shell
stylus test.styl
```

を実行。同ディレクトリに`test.css`という名前で作成され、

```css:test.css
body {
  padding: 50px;
  font: 14px/1.4 helvetica, arial, sans-serif;
}
```

という中身で出力される。

## コンパイルについて
###  同じディレクトリに同じファイル名でコンパイル

```shell
$ stylus test.styl
```

### 出力先を指定してコンパイル

```shell
$ stylus test.styl --out path/to/directory
$ stylus test.styl -o path/to/directory
```

### ファイルを監視して変更があればコンパイル

```shell
$ stylus -w test.styl
$ stylus --watch test.styl
```

---

# stylusの書き方について
## 基本的な書き方
普通のcssの記載のやり方も可能。
「:（コロン）」、「;（セミコロン）」、「,（カンマ）」、「{ }（波括弧）」を省略することもできる。
- stylus

```stylus:stylus
.hoge
  width 100px //記号の省略が可能

.hoge2 {
  width: 100px; //従来通りの描き方でもOK
}
```
- css

```css:css
.hoge {
  width: 100px;
}
.hoge2 {
  width: 100px;
}
```

## コメントアウト

- stylus

```stylus
// インラインコメント（コンパイル時になくなる）
/*
   通常のコメント（コンパイル時に残る）
*/
```

- css

```css:css
/*
   通常のコメント（コンパイル時に残る）
*/
```

## 複数クラス指定

- stylus

```stylus
//カンマ（,）区切り
textarea, input
  border 1px solid #eee
// 又は改行
textarea
input
  border 1px solid #eee
```

- css

```css:css
textarea,
input {
  border: 1px solid #eee;
}
```

---

# stylusで行うことができること1
基本的には`scss`などでできることと同じ。
## 入れ子
インデントで入れ子にできる。
- stylus

```css:stylus
body
  color #f00
  p
    color #000
```
- css

```css:css
body {
  color: #f00;
}
body p {
  color: #000;
}
```

## 親要素参照
`&`で親のスタイルやセレクタを参照できる
- stylus

``` stylus
// 擬似クラス
a
input
  color #a7a7a7
  text-decoration underline
  &:hover
    color #000
    tect-decoration none

// カラーなどのパターン
.footer
  background-color #fff
  &.typeA
    background-color #000
  &.typeB
    background-color #333
```
- css

```css:css
a,
input {
  color: #a7a7a7;
  text-decoration: underline;
}
a:hover,
input:hover {
  color: #000;
  tect-decoration: none;
}

.footer {
  background-color: #fff;
}
.footer.typeA {
  background-color: #000;
}
.footer.typeB {
  background-color: #333;
}
```

## 変数
あらかじめ名前を決めて`=`でつないで使うことができる
`.scss`とは違うので、注意。
（`.scss`の場合だと、`$font-size: 14px;`のように記載。）
- stylus

```css:stylus
font-size = 14px
red = #dc143c

body
  font font-size Arial, sans-serif
  border 2px solid red
```
- css

```css:css
body {
  font: 14px Arial, sans-serif;
  border: 2px solid #dc143c;
}
```

## 継承
他のセレクタに指定したスタイルを、好きなセレクタへ適用させることもできる
使い方として、使いたいセレクタのクラスを`@extend`で指定して使う。
- stylus

```stylus
.btn
  color #000
  background-color #fff
  border:solid 1px #666
  width 80px

// 呼び出し
.btn-A
  @extend .btn
  width 200px
.btn-B
  @extend .btn
  width 150px
```
- css

```css:css
.btn,
.btn-A,
.btn-B {
  color: #000;
  background-color: #fff;
  border: solid 1px #666;
  width: 80px;
}
.btn-A {
  width: 200px;
}
.btn-B {
  width: 150px;
}
```
また、`.（ドット）`ではなく`$`を使うことでコンパイル時に出力されない
単体で使わない場合には、`$`の方がよい。
- stylus

```stylus
$btn
  color #000
  background-color #fff
  border:solid 1px #666
  width 80px

// 呼び出し
.btn-A
  @extend $btn
  width 200px
.btn-B
  @extend $btn
  width 150px
```
- css

```css:css
.btn-A,
.btn-B {
  color: #000;
  background-color: #fff;
  border: solid 1px #666;
  width: 80px;
}
.btn-A {
  width: 200px;
}
.btn-B {
  width: 150px;
}
```

## mixin（ミックスイン）
定義したスタイルを呼び出すという点では継承と同じだが、セレクタのグループ化はされない。
引数を使うこともできるので、定義したスタイルの値の一部を変更を行うこともできる。
- stylus

```stylus
// スタイル定義
btn(font-color = #000)
  color font-color
  font-size 14px
  font-weight bold

// スタイル呼び出し
.btn-A
  btn()
  width 200px
.btn-B
  btn(#f0f)
  width 150px
.btn-C
  btn #ff0
  width 100px

```

- css

```css:css
.btn-A {
  color: #000;
  font-size: 14px;
  font-weight: bold;
  width: 200px;
}
.btn-B {
  color: #f0f;
  font-size: 14px;
  font-weight: bold;
  width: 150px;
}
.btn-C {
  color: #ff0;
  font-size: 14px;
  font-weight: bold;
  width: 100px;
}
```

また、ミックスインの機能を使ってベンダープレフィックスを定義することもできる

- stylus

```stylus
vendor(prop, args)
	-webkit-{prop} args
	-moz-{prop} args
	{prop} args
	
.hoge
    vendor 'box-shadow' 1px 0  0 #CCC
```

- css

```css:css
.hoge {
  -webkit-box-shadow: 1px;
  -moz-box-shadow: 1px;
  box-shadow: 1px;
}
```

### 囲み型のmixin

- stylus

```stylus
hover()
  &:hover, &:active
    {block}

.test
  +hover()
    text-decoration underline
```
- css

```css:css
.test:hover,
.test:active {
  text-decoration: underline;
}
```

## パーシャル
Cssのコンパイルが必要ないファイルは、ファイル名の前に「_（アンダースコア）」を付与させることで、コンパイル後にCSSファイルが生成されない。
`@import`でファイルを指定すれば読み込むことができる。
この際、「_（アンダースコア）」と拡張子は省略できる。
- stylus

```stylus
@import component/btn
@import component/alert
@import component/nav
```

`*`を使って一気にインポートを行うこともできる

- stylus

```stylus
@import component/*
```
このように記載することで`.styl`ファイルを追加するたびに読み込まなくても良いので、ちょっと楽。
※IR9以前の場合だと
- 1つのCSSファイル、又は1つのstyleタグ内のセレクタは4095個目までしか適応されない
- CSSファイル、またはstyleタグは31個目までしか適応されない
という制限もある。

## 演算
計算や文字列の操作を行うこともできる

### 計算と真偽値

- stylus

```css:stylus
body
  foo01 5px + 10
  foo02 2 ** 8
  foo03 5px * 2
  foo04 !!''
  foo05 hoge and fuga and pugya
  foo06 hoge or fuga or pugya
  foo07 1..5
  foo08 1...5
  foo09 'hoge' is a 'string'
  foo10 (1 2 3) == (1 2 3)
  foo11 (1 2 3) == (1 2)
  foo12 ((one 1) (two 2)) == ((one 1) (two 2)) 
  foo13 ((one 1) (two 2)) == ((one 1) (two)) 
  foo14 ((one 1) (two 2))[0]
  foo15 3 in (1 2 3 4)
```

- css

```css:css
body {
  foo01: 15px;
  foo02: 256;
  foo03: 10px;
  foo04: false;
  foo05: pugya;
  foo06: hoge;
  foo07: 1 2 3 4 5;
  foo08: 1 2 3 4;
  foo09: true;
  foo10: true;
  foo11: false;
  foo12: true;
  foo13: false;
  foo14: one 1;
  foo15: true;
}
```

### 値や文字列の操作

- stylus

```css:stylus
body
  foo01 foo + bar
  foo02 'foo ' + bar
  foo03 'foo ' + 'bar'
  foo04 'foo ' + 5px
  foo05 2s - 500ms
  foo06 5000ms == 5s
  foo07 50deg
```

- css

```css:css
body {
  foo01: foobar;
  foo02: 'foo bar';
  foo03: foobar;
  foo04: 'foo 5px';
  foo05: 1.5s;
  foo06: true;
  foo07: 50deg;
}
```

### 色の操作

- stylus

```css:stylus
body
  foo01 white - 50%
  foo02 black + 50%
  foo03 #eee - #f00
  foo04 #eee - rgba(black,.5)
  foo05 #cc0000 + 30deg
```

- css

```css:css
body {
  foo01: #808080;
  foo02: #808080;
  foo03: #0ee;
  foo04: rgba(238,238,238,0.5);
  foo05: #c60;
}
```

### 文字列置換

- stylus

```css:stylus
body
  foo '%s / %s' % (5px 10px)
```

- css

```css:css
body {
  foo: 5px / 10px;
}
```

## 条件分岐と繰り返し
forループやif文などを用いた条件分岐をプログラミング言語に近い感じで行うことができる。
1行目が 配列の定義。`,（カンマ）`区切ることもできる。また、 変数の展開は`{}`で行える。
### if/else文

- stylus

```stylus
liquid = true
.hoge
  if liquid
    width 100%
  else
    width 960px
```

- css

```css:css
.hoge {
  width: 100%;
}
```

### for/in文

- stylus

```stylus
array = 1 2 3 4
for num in array
  .mg-{num * 5}
    margin num * 5px
```

- css

```css:css
.mg-5 {
  margin: 5px;
}
.mg-10 {
  margin: 10px;
}
.mg-15 {
  margin: 15px;
}
.mg-20 {
  margin: 20px;
}
```

---

# stylusで行うことができること2
- ハッシュをCSSのプロパティ名と値に展開できる

```stylus:stylus
foo = {
  width: 100px,
  height: 200px,
  background: #f0f
  '&:hover': {
    background: #ff0
  }
}
foo2 = {
  bar: {
    width: 100px,
    height: 100px,
    background: #00f,
    opacity: 0.5
  }
}
sample2 = foo2.bar

.sample1
  {foo}
.sample2
  {sample2}
```

```css:css
.sample1 {
  width: 100px;
  height: 200px;
}
.sample1:hover {
  background: #ff0;
}
.sample2 {
  width: 100px;
  height: 100px;
  background: #00f;
  opacity: 0.5;
}
```

<p class="codepen" data-height="265" data-theme-id="0" data-default-tab="css,result" data-user="miwashutaro0611" data-slug-hash="QYWRqJ" style="height: 400px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid black; margin: 1em 0; padding: 1em;" data-pen-title="QYWRqJ">
  <span>See the Pen <a href="https://codepen.io/miwashutaro0611/pen/QYWRqJ/">
  QYWRqJ</a> by miwa_shuntaro (<a href="https://codepen.io/miwashutaro0611">@miwashutaro0611</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://production-assets.codepen.io/assets/embed/ei.js"></script>

- JSONを読み込んで色々できる
- JavaScriptの関数を呼べる

参考 : http://memowomome.hatenablog.com/entry/2016/07/28/080000

---

# sassとstylusの違いについて
参考 : [SassからStylusに乗り換えてみたので違いや躓いたところなど – モンキーレンチ](https://2inc.org/blog/2016/08/17/5330/)

---

# Stylusの良い点について(自己判断)
## `@mixin`とか`@include`を記入しなくても良い
Sassだとmixinやincludeの部分で`@`を書かなければならないが、それを使わなくてもよい

- scss

```scss:scss
@mixin font($size: 14px) {
  font-family: sans-serif;
  font-weight: normal;
  font-size: $size;
}
.hoge {
	@include font(16px);
}
```

- stylus

```css:stylus
font(size = 14px)
  font-family sans-serif
  font-weight normal
  font-size size

.hoge
	font 16px
```

## CSSを直接読み込める
StylusはSass記法（セミコロンや括弧を省略する書き方）とscss記法（普通のCSSみたいな書き方）の両方が使えるので、外部のcssを直接読み込んだり、`@import`ができる

## プログラミングっぽく書ける？
使ったことはないんで、どっかで使いたい。。。

- stylus

```stylus
$style($conf = {}) {
  $conf_default = {
    paddingLeft: 20px,
    fontSize: 14px,
    lineHeight: 24px,
  };
  $paddingLeft   = $conf.paddingLeft || $conf_default.paddingLeft;
  $fontSize      = $conf.fontSize || $conf_default.fontSize;
  $lineHeight    = $conf.lineHeight || $conf_default.lineHeight;

  padding-left: $paddingLeft;
  font-size: $fontSize;
  line-height: $lineHeight;
}

.hoge {
  $style($conf = {
    paddingLeft: 10px
  })
}
```

- css

```css:css
.hoge {
  padding-left: 10px;
  font-size: 14px;
  line-height: 24px;
}
```