SCSSを活用した16の効果的なCSSリファクタリング手法

# 概要

とあるシステムで膨大なスタイルシート（2万行）をリファクタリングした記録です。

# 環境

- CSS3
- SCSS
- sass-lint

# リファクタリングのメモ

### その1. W3CのCSSチェックツール

[W3CのCSSチェックツール](https://jigsaw.w3.org/css-validator/#validate_by_uri) を使って、指摘箇所を修正しました。


### その2. 構文チェック

構文チェックはsass-lintを使いました。
シンタックスに意識してコーディングすることができます。



### その3. インデント

基本的なことですが、インデントがメチャクチャだったため、インデントを修正しました。
インデントを正しくすると可読性向上し、メンテナンスも楽になります。

```scss:before
.content {
   width: 100px;
.title {
   font-size: 24px;
}
   .text {
    font-size: 16px;}
}
```

```scss:after
.content {
   width: 100px;
   .title {
      font-size: 24px;
   }
   .text {
      font-size: 16px;
   }
}
```

### その4. ネスト

ネストを使っていないので、正しくネストするように直しました。
ネストすることで、コード量が少なくなりました

```scss:before
div {
    font-size: 16px;
}
div:first-letter {
    font-size: 130%;
}
```

```scss:after
div {
    font-size: 16px;
    &:first-letter {
        font-size: 130%;
    }
}
```

### その5. 擬似要素

擬似要素は、:(コロン一つ)ではなく、::(コロン二つ)とのことだったので、修正しました。
[参考:擬似要素](https://developer.mozilla.org/ja/docs/Web/CSS/Pseudo-elements)

```scss:before
div {
    font-size: 16px;
    &:first-letter {
        font-size: 130%;
    }
}
```

```scss:after
div {
    font-size: 16px;
    &::first-letter {
        font-size: 130%;
    }
}
```



### その6. 階層が深いネスト

無駄にネストの階層が深いと、逆に可読性が下がります。
階層が深くなりすぎないように修正しました。

```scss:before
.contents {
    .main {
        .text {
            div {
                .title { font-size: 24px; }
                .kana { font-size: 12px; }
            }
        } 
    }
}
```

```scss:after
.contents .main .text div {
    .title { font-size: 24px; }
    .kana { font-size: 12px; }
}
```

### その7. border-radius

border-radiusは、50%以上にしても表示が変わりません。
少し気持ちが悪いので、50%に統一しました。


```scss:before
.circle {
    border-radius: 100%;
}
```

```scss:after
.circle {
    border-radius: 50%;
}
```


### その8. スペースのない!important

`!important`の直前にスペースがない気持ち悪い表記、これでもちゃんと動くようです。
ちゃんとスペースを空けるように修正しました。

```scss:before
.text {
    color: red!important;
}
```

```scss:after
.text {
    color: red !important;
}
```


### その9. セレクタの最後がカンマ

CSS3の書き方では、セレクタの最後が,(カンマ)だとシンタックスエラーになるのですが、SCSSをコンパイル時に削除してくれていたようです。不要なのでカンマを削除しました。

```scss:before
a, {
    color: red;
}
```

```scss:after
a {
    color: red;
}
```

### その10. セミコロン

要素に対し、一番最後の行に;（セミコロン）が無いのはCSS3的には間違った記述ではないらしいが、
今後、スタイルを追加していくときにエラーになる可能性があるため、セミコロンを付けました。

```scss:before
.content {
    font-size: 16px;
    margin: 5px
}
```
```scss:after
.content {
    font-size: 16px;
    margin: 5px;
}
```

### その11. 無駄なベンダープレフィックス

[そのベンダープレフィックス、いつまでつけてるの？](https://qiita.com/amamamaou/items/42197e443134478befaf)を参考にさせて頂きました。

[Can I use](https://caniuse.com/)で、CSS3/HTML5のブラウザごとのサポート情報を確認できます。

### その12. 同じプロパティが指定されている

スタイルシートが大きくなるとよく見かけるが、結構気が付かない。
以下の記述は、marginが2回指定されていて、後ろの5pxが有効となる。
不要な、`margin: 10px;`は削除しました。

```scss:before
.content {
    width: 100px;
    height: 100px;
    margin: 10px; // 1回目
    line-height: 1.2;
    color: red;
    font-size: 16px;
    margin: 5px; // 2回目
}
```

```scss:after
.content {
    width: 100px;
    height: 100px;
    line-height: 1.2;
    color: red;
    font-size: 16px;
    margin: 5px;
}
```

### その13. 自分に勝つための!important

その11の進化系で、5pxに気が付かずに、10pxに !important をつけてしまったものかと思われる。
`margin: 10px;`が有効になっているので、`margin: 5px;`は消し、!importantも外しました。


```scss:before
.content {
    width: 100px;
    height: 100px;
    margin: 10px !important; // 1回目
    line-height: 1.2;
    color: red;
    font-size: 16px;
    margin: 5px; // 2回目
}
```

```scss:after
.content {
    width: 100px;
    height: 100px;
    margin: 10px;
    line-height: 1.2;
    color: red;
    font-size: 16px;
}
```

### その14. z-index

z-indexがインフレしていて、どこの要素より上に出したいのか分からないので、メンテが出来なくなってしまいます。
コーディングルールが決めておくのが良いと思われますが、今後メンテしやすいように、分かる範囲でコメントをつけました。


```scss:before
.popup {
   z-index: 1000;
}
.tooltip {
   z-index: 1001;
}
.message {
   z-index: 9999;
}
```

```scss:after
.popup {
   z-index: 1000;
}
.tooltip {
   z-index: 1001;//.popupより上
}
.message {
   z-index: 9999;//.tooltipより上
}
```

### その15. 同じような内容のスタイルが2つ指定されている

`.abc`と`.xyz`の両方でmarginを指定しています。

基本的には下にある.xyzが有効になりますが、
margin-topはmarginより強い書き方なので以下の通りになります
> margin-top: 20px; ← .abcのmargin-top
> margin-left: 5px; ← .xyzのmargin
> margin-right: 5px; ← .xyzのmargin
> margin-bottom: 5px; ← .xyzのmargin

意味のあるclass名にして、一つにまとめました。

```html:html before
<div class="abc xyz">
    コンテンツ
</div>
```

```scss:scss before
.abc {
    margin-top: 20px;
}
.xyz {
    margin: 10px 5px 5px 5px;
}
```


```html:html after
<div class="content_margin">
    コンテンツ
</div>
```

```scss:scss after
.content_margin {
    margin: 20px 5px 5px 5px;
}
```

### その16. paddingみたいなborder

paddingみたいなborderの使い方をしている箇所がありました。
このborderは、枠線を引くことが目的ではなく文字と枠の位置を調整するために指定されています。
paddingを用いて意図した使い方に修正しました。


```scss:before
div {
    background-color: red;
    border: solid 3px red;
}
```

```scss:after
div {
    background-color: red;
    padding: 3px;
}
```

# まとめ

まだまだテクニックはあると思いますが、今回はこのくらいにしておきます。
教訓として、メンテすることも考えて書くことが必要だと感じました。

ここまで読んでいただきありがとうございました。