エイチーム引越し侍Advent Calendar 14日目の記事です。
今回は、CSS設計手法について書こう~と思っていたのですが、
最近sass-lintのエラールールについて調べる機会があり、日本語訳の一覧がほしいなーと思ったので日本語訳についてまとめようと思います。
こちら
https://github.com/sasstools/sass-lint/tree/develop/docs/rules
を参考にしています。
各ルール内に入れている例は上記リンク先のルールにある例を引用しています。
ただ全部の例をもってきていないので分からない場合はリンク先で確認してください。
また、ルールは現時点ではすべて網羅できていませんが、また随時更新していこうかなと思ってます!
最初に書いておきますが、まじで長いです。
右側のスクロールバーをちらっと見るとわかるかと思いますが、まじでながいです。
エラーチェックの時のルール
ルールのルールって何、って話にはなってしまうんですが、エンジニアではない私が「?」ってなった点が
「0」と「1」の違いです。
この記事を読んでいる方の中にはそんなん分かってる!と思う方もたくさんいるとは思いますが一応説明を書きますね。
設定時に、
rules:
zero-unit: 1
このようなルールを書いた場合、「0」がエラーチェックしない、「1」がエラーチェックする、です。
つまり上は「zero-unit」のエラーをチェックするという記述です。
例えば、
margin-bottom: 0px;
と書かれていた場合、zero-unit(値の0に単位をつけない)を「1」にしていたらエラーをチェックするので、上は×になります。
「0」にしていた場合は、チェックをしないだけなので「0px」だろうが「0」だろうが通ってしまいます。
つまり単位をつけることをOKとするわけではなく、単純にチェックしないだけなんですね。
それでは内容について早速いきます。さくさくいきます。
Attribute Quotes
アトリビュート(属性セレクタ)のクォーテーションマークの有無
チェックする場合、デフォルトは「true」(クォーテーションマークを使用)
// true
span[lang="pt"] {
color: green;
}
// false
span[lang=pt] {
color: green;
}
BEM Depth
BEMで書くときに中に入れられるセレクタ数の指定
option
max-depth: 数字 (デフォルトは1)
最大1にしたとき下記は超えているのでエラーになります。
.block {
&__element {
&__subelement {
// 2つ
}
}
}
.block__element__subelement__subelement-two {
// 3つ
}
Border Zero
borderが0pxのときの記述チェック
option
convention: '0'/'none' (デフォルトは0)
「0」でかくか「none」でかくか
それぞれチェックが通る書き方はこちら
// 0の場合
.foo {
border: 0;
}
// noneの場合
.foo {
border: none;
}
Brace Style
セレクタの後ろにある「{}」のスタイルのチェック
option
- style: '1tbs', 'stroustrup', 'allman' (デフォルトは1tbs)
- allow-single-line: true/false (デフォルトはtrue)
style
'1tbs'または'stroustrup'のときOKで、'allman'のときNGな書き方
.foo {
content: 'foo';
}
'allman'のときOKで、それ以外のときNG
.foo
{
content: 'foo';
}
セレクタのあと、同じ行に「{」を書くか改行して書くかの違いですね。
では、'1tbs'と'stroustrup'の違いは?となるわけですが、
それぞれOK、NGの例はこちらになります。
'1tbs'のときOKで、それ以外のときNGな書き方
@if ($foo) {
$bar: 'bar';
} @else {
$bar: false;
}
'stroustrup'のときOKで、それ以外のときNGな書き方
@if ($foo) {
$bar: 'bar';
}
@else {
$bar: false;
}
ifを使ったときなど閉じ括弧のあと次に続く場合の改行の有無です。
allow-single-line
一行で書いてもOKか
下記はtrueの場合はOK、falseの場合はNGになります。
.foo { content: 'foo'; }
// styleの設定が'1tbs'の場合はOK、それ以外はNG
@if ($foo) { $bar: 'foo'; } @else { $bar: false; }
// styleの設定が'stroustrup'または'allman'の場合はOK、'1tbs'はNG
@if ($foo) { $bar: 'foo'; }
@else { $bar: false; }
class-name-format
クラス名のフォーマットがルールに沿ってるかチェックします
option
- allow-leading-underscore: true/false (デフォルトはtrue)
- convention: デフォルトはhyphenatedlowercase
- convention-explanation: conventionの項目でルールが設定できなかったときにカスタムする
- ignore: 無視するclass名を記述
allow-leading-underscore
アンダースコアの使用
convention
クラス名の付け方のルール
設定 | 内容 |
---|---|
hyphenatedlowercase | 小文字をハイフンでつなぐ |
camelcase | キャメルケース |
pascalcase | パスカルケース |
snakecase | スネークケース |
などなど
オプションは色々と細かく設定できるみたいです。
例えば
- allow-leading-underscore: true
- convention: hyphenatedlowercase
で設定した場合、
OKな書き方
.hyphenated-lowercase {
content: '';
&._with-leading-underscore {
content: '';
}
}
NGな書き方
.HYPHENATED-UPPERCASE {
content: '';
}
.camelCase {
content: '';
@extend .snake_case;
}
というような感じになります。
こちらに関しては参考元ページにて様々な例が掲載されているのでそちらをご確認ください。
https://github.com/sasstools/sass-lint/blob/develop/docs/rules/class-name-format.md
(バリエーションが多いので諦めましたすみません…)
clean-import-paths
importするときにファイル名や拡張子をつけるか
option
- leading-underscore: true/false (デフォルトはfalse)
- filename-extension: true/false (デフォルトはfalse)
leading-underscore
importするファイル名にアンダースコアをつけるか
// false
@import 'foo';
@import 'bar/foo';
// true
@import '_foo';
@import '_bar/foo';
filename-extension
importするファイルの拡張子をつけるか
// false
@import 'foo';
@import 'bar/foo';
// true
@import 'foo.scss';
@import 'bar/foo.scss';
declarations-before-nesting
親セレクタのスタイルをネストした子セレクタの前に書く
// これはOK
foo {
content: 'baz';
.bar {
content: 'qux';
}
}
// これはNG
.foo {
.bar {
content: 'qux';
}
content: 'baz';
}
empty-args
mixinを定義するときまたは呼び出すときに「()」をつけるかつけないか
option
include: true/false (デフォルトはfalse)
// falseのときOKでtrueのときはNG
@mixin bar {
padding: 10px;
}
.bar {
@include bar;
}
// trueのときOKでfalseのときはNG
@mixin foo() {
padding: 10px;
}
.foo {
@include foo();
}
empty-line-between-blocks
ネストした時に各セレクタの上の行を一行空けるか空けないか
##Options
- include: true/false (デフォルトはtrue)
- allow-single-line-rulesets: true/false (デフォルトはtrue)
include
// true
.foo {
content: 'foo';
.bar {
content: 'bar';
// Waldo
&--baz {
content: 'baz';
}
}
}
// false
.foo {
content: 'foo';
.bar {
content: 'bar';
// Waldo
&--baz {
content: 'baz';
}
}
}
allow-single-line-rulesets
一行で書いてOKかをチェックするので、こちらがtrueの場合は下記の書き方がOKになります。
.foo { content: 'foo'; }
extends-before-declarations
スタイルの記述の前にextendを書く
// OK
.foo {
@extend %bar;
content: 'baz';
}
// NG
.foo {
content: 'baz';
@extend %bar;
}
extends-before-mixins
mixinをよみこむ前にextendを書く
// OK
foo {
@extend %bar;
@include baz;
}
// NG
.foo {
@include baz;
@extend %bar;
}
final-newline
一番最後に一行いれる
option
include: true/false (デフォルトはtrue)
falseのとき
.foo {
content: 'bar';
} // 最後の行
trueのとき
.foo {
content: 'bar';
}
// 最後の行
↑一行あける
force-attribute-nesting
セレクタに属性セレクタを続けて記述する場合は入れ子にする
// NG
input[type='radio'] {
color: red;
}
// OK
input {
&[type='radio'] {
color: red;
}
}
force-element-nesting
セレクタの後ろに続く要素は入れ子にする
// NG
div p {
content: '';
}
// OK
div {
p {
content: '';
}
}
force-pseudo-nesting
疑似要素にスタイルを指定するときはネストさせる
// NG
p:nth-of-type(2) {
margin: 0;
}
.parent {
.child {
p::first-line {
color: #ff0000;
}
}
}
.parent {
.child {
.sub p::first-line {
color: #ff0000;
}
}
}
// OK
p {
&:nth-of-type(2) {
margin: 0;
}
}
.parent {
.child {
p {
&::first-line {
color: #ff0000;
}
}
}
}
.parent {
.child {
.sub p {
&::first-line {
color: #ff0000;
}
}
}
}
function-name-format
関数名のルールの設定
基本的に上ででてきたクラス名のルールと同じです。
ただ、オプションにignoreは無いので注意。
詳しい設定例はこちらにあります。(function-name-formatのルールが記載されたページ)
https://github.com/sasstools/sass-lint/blob/develop/docs/rules/function-name-format.md
hex-length
16進数で記述するときの長さを指定
option
style: short/long (デフォルトはshort)
// shortの場合これはOK、longの場合はNG
.baz {
color: #fff;
}
// longの場合はOK、shortの場合はNG
.baz {
color: #ffffff;
}
// こんなときは短縮できないのでstyleをどちらに設定していても通ります
.qux {
color: #123456;
}
hex-notation
16進数を記述するときに大文字か小文字かのチェック
option
style: lowercase(小文字)/uppercase(大文字) (デフォルトはlowercase)
// 小文字に設定した場合にOK
.baz {
color: #12a;
}
// 大文字に設定した場合にOK
.baz {
color: #12A;
}
id-name-format
ID名のルール設定
クラス名のルール設定と同じです。
詳しい設定例はこちらにあります。(id-name-formatのルールが記載されたページ)
https://github.com/sasstools/sass-lint/blob/develop/docs/rules/id-name-format.md
indentation
インデントの指定。タブとスペースを混ぜないようにチェック
option
size: 数字 または 'tab' (デフォルトはスペース2つ)
// 2スペースを指定したときこれはOK
.foo {
content: 'bar';
.baz {
content: 'qux';
// Waldo
&--waldo {
content: 'alpha';
}
}
}
// NG
.foo {
content: 'bar';
.baz {
content: 'qux';
// Waldo
&--waldo {
content: 'alpha';
}
}
}
leading-zero
値の数字の1の位が0のときの記述
option
include: true/false (デフォルトはfalse)
// falseのときはOK、trueのときはNG
.foo {
font-size: .5em;
}
// trueのときはOK、falseのときはNG
.foo {
font-size: 0.5em;
}
max-file-line-count
最大行数を指定する
option
length: 数字, (デフォルトは300)
// NG(左の数字は行数を例として記述)
1| .test {
2| color: red
3| }
=====
~ snip ~
=====
299| .bar {
300| color: blue;
301| }
max-line-length
行の最大文字数を指定する
option
length: 数字, (デフォルトは80)
// NG
.really--long--class-name--that-unfortunately--isnt--very--succint--and-looks-stupid {
color: red;
}
// ==============================================================================
//
// This comment is too long clearly, we should probably make sure we have a rule to
// determine when we breach this length
//
// ==============================================================================
mixin-name-format
mixinの名前のルール設定
クラス名のルール設定とほぼ同じです。
ignoreは無いので注意
詳しい設定例はこちらにあります。(mixin-name-formatのルールが記載されたページ)
https://github.com/sasstools/sass-lint/blob/develop/docs/rules/mixin-name-format.md
mixins-before-declarations
mixinはスタイルの指定より前に書く
option
exclude(除外設定)
exclude: ['breakpoint', 'mq']
と書くと、指定したmixinはチェックから除外されます
// OK
.foo {
@include bar;
content: 'baz';
@include breakpoint(500px) { // チェックから除外されたmixin
content: 'qux';
}
@include mq(500px) { // チェックから除外されたmixin
content: 'qux';
}
}
// NG
.foo {
content: 'baz';
@include baz;
}
nesting-depth
どれぐらいまでネストできるかを指定する
option
max-depth: 数字 (デフォルトは2)
// max-depthが2の場合
.foo {
.baz {
&:hover {
// ここまで
}
}
}
.block {
&__element {
&--modifier {
// ここまで
}
}
}
no-attribute-selectors
属性セレクタにスタイルを書かない
// NG
[lang=ja] {
content: 'bar';
}
[href^="#"] {
content: 'norf';
}
input[type="text"] {
border:1px solid #000;
}
no-color-hex
16進数で色を書かない
// NG
.baz {
color: #fff;
}
// OK
.baz {
color: white;
}
no-color-keywords
キーワードで色をかかない
// NG
.baz {
color: white;
}
// OK
.baz {
color: #fff;
}
no-combinators
コンビネータ(子孫、隣接セレクタなど)を使用しない
この書き方はすべてNG
foo > .bar {
content: 'foo';
}
.foo .bar {
content: 'qux';
}
.foo {
> .bar {
content: 'foo';
}
}
no-css-comments
コメントの書き方のチェック
/* */
のブロックコメントは禁止。
コメントを書く場合は「//」をつかう一行コメント、もしくはブロックコメントを使う場合は「/*! */」というように「!」を加える
OKなコメントたち
// This is a good comment
// =========
// This is a good comment
// =========
//////////////////
// This is a good comment
//////////////////
/*! This is a good bang comment */
/*!
* This is a good bang comment
**/
NGなコメントたち
/* This comment will appear in your compiled css */
/*
* Mulitline comments are bad
*/
no-debug
@debug の使用を許可しない
// NG
@debug 'foo';
no-disallowed-properties
指定した特定のプロパティを使用したときにエラーを出す
option
properties: 使用NGにするプロパティ名 (デフォルトは空)
例
z-indexを使用したときにエラーを出す
ymlファイルの記述
no-disallowed-properties:
- 1
-
'properties':
- 'z-index'
上の設定をした時、下記はエラーになる
.foo {
z-index: 10;
}
no-duplicate-properties
同じブロック内でのプロパティの重複を許可しない
option
exclude: 除外したいプロパティ (デフォルトは空)
このエラーをチェックするにした場合、
.foo {
margin: 0 0 15px;
margin: 0;
}
これはだめです。
例えば除外設定に
no-duplicate-properties:
- 1
-
exclude:
- display
こんな感じで「display」プロパティを指定したとします。(flex効かないときの対応とかとか)
その場合は
.display-block {
display: flex;
display: inline-block;
float: right;
}
この記述はOKです。
しかし
.display-block {
display: flex;
float: right;
display: inline-block;
}
このように間に別のプロパティが入ってきて、許可したプロパティが続いていない場合は重複とみなされてNGです。
no-empty-rulesets
空のルールセットを許可しない
// NG
.foo {
}
no-extends
extendの使用を許可しない
// NG
.foo {
@extend %bar;
@extend .bar;
@extend #bar;
}
no-ids
IDセレクタの使用を許可しない
// NG
#foo {
content: 'bar';
}
no-important
!important の使用を許可しない
.foo {
content: 'bar' !important;
}
no-invalid-hex
使えない(使用できない)16進数があるときはエラーをだす
エラーが出る場合
// 3文字または6文字でないとき
$invalid-long: #1234567;
$invalid-med: #1234;
$invalid-short: #12;
// 無効な文字
$invalid-character-map: (
invalid-characters-upper-letters: #GHIJKL,
invalid-characters-upper-letters-short: #GHI,
);
no-mergeable-selectors
重複セレクタは許可しない
option
whitelist: 重複を許可するセレクタ (デフォルトは空)
.foo {
content: 'bar';
}
// 重複
.foo {
color: red;
}
オプションに
whitelist: ['div p', 'div a']
こんな感じで追加した場合は
div p {
color: red;
}
// 重複だけどエラーでないよ
div p {
content: '';
}
div a {
color: blue;
}
// 重複だけどエラーでないよ
div a {
content: '';
}
no-misspelled-properties
存在しなかったり誤字をしていたりする不明なプロパティのチェック
option
extra-properties: 除外する綴りのプロパティ (デフォルトは空)
NG例
// スペルミス
.foo {
borders: 0;
}
// 存在しないプロパティ
.bar {
border-right-left: 0;
}
// スペルミス
.baz {
-webkit-transit1on: width 2s;
}
オプションに 「transit1ion」 を追加すると
// incorrect spelling now whitelisted
.baz {
-webkit-transit1on: width 2s;
}
// incorrect spelling now whitelisted
.quz {
transit1on: width 2s;
}
これらはOKになります。
no-qualifying-elements
タグに属性・クラス・IDセレクタをつけてスタイルを指定しない
option
- allow-element-with-attribute: true/false (デフォルトはfalse)
- allow-element-with-class: true/false (デフォルトはfalse)
- allow-element-with-id: true/false (デフォルトはfalse)
何も設定していないときはこれらはNG
div.foo {
content: 'foo';
}
ul#foo {
content: 'foo';
}
input[type='email'] {
content: 'foo';
}
allow-element-with-attribute
属性セレクタを許可するか
trueにしたとき下記はOK、falseにしたときはエラーになります。
input[type='email'] {
content: 'foo';
}
a[href] {
content: 'foo';
}
allow-element-with-class
クラスセレクタを許可するか
trueにしたとき下記はOK、falseにしたときはエラーになります。
div.foo {
content: 'foo';
}
allow-element-with-id
IDセレクタを許可するか
trueにしたとき下記はOK、falseにしたときはエラーになります。
ul#foo {
content: 'foo';
}
no-trailing-whitespace
末尾のスペースを許可しない
// NG(\sはスペースかタブだと思ってください)
.foo {\s
margin: 1.5rem;
}
.foo {
margin: .5rem;\s
}
.foo {
margin: .4rem;
}\s
no-trailing-zero
小数点以下の末尾の0は許可しない
// NG
.foo {
margin: 1.500rem;
}
.foo {
margin: 4.0rem;
}
no-transition-all
transitionプロパティ使用時に「all」の指定を許可しない
// NG
.foo {
transition: all 2s;
}
.bar {
transition-property: all 2s;
}
no-universal-selectors
ユニバーサルセレクタ「*」の使用を許可しない
// NG
* {
content: 'foo';
}
*:before,
*:after {
content: 'norf';
}
no-url-domains
URLを指定するときにドメインの記述を許可しない
// OK
.foo {
background-image: url('/img/bar.png');
}
// NG
.foo {
background-image: url('https://foo.com/img/bar.png');
}
no-url-protocols
URLを指定するときに、ドメインを含んだものと//から始まる絶対パスの指定を許可しない
option
allow-protocol-relative-urls: true/false (デフォルトはfalse)
※sass-lint 2.0では廃止予定らしいです。
falseの場合
// OK
.foo {
background-image: url('/img/bar.png');
}
.foo {
background-image: url('img/bar.png');
}
.foo {
background-image: url('bar.png');
}
// NG
.foo {
background-image: url('https://foo.com/img/bar.png');
}
.foo {
background-image: url('http://foo.com/img/bar.png');
}
.foo {
background-image: url('//foo.com/img/bar.png');
}
trueにした場合は
.foo {
background-image: url('//foo.com/img/bar.png');
}
これがOKになります(引き続き相対パスはOK、ドメイン含むものはNG)
no-warn.md
@warn の使用を許可しない
// NG
@warn 'foo';
space-after-bang
「!」のあとのスペースの有無をチェック
option
include: true/false (デフォルトはfalse)
// false(空けない)のときはOK、trueのときはNG
.foo {
content: 'bar' !important;
}
// true(空ける)のときはOK、falseのときはNG
.foo {
content: 'bar' ! important;
}
space-after-colon
コロン(:)のあとのスペースの有無をチェック
option
include: true/false (デフォルトはtrue)
// true(空ける)のときはOK、falseのときはNG
.foo {
content: 'bar';
}
// false(空けない)のときはOK、trueのときはNG
.foo {
content:'bar';
}
space-after-comma
カンマ(,)のあとのスペースの有無をチェック
option
include: true/false (デフォルトはtrue)
// true(空ける)のときはOK、falseのときはNG
.foo {
@include baz('foo', 'bar');
box-shadow: 1px 1px black, 1px 1px black;
}
// false(空けない)のときはOK、trueのときはNG
.foo {
@include baz('foo','bar');
box-shadow: 1px 1px black,1px 1px black;
}
space-around-operator
演算子(+, -, /, *, %, <, > ==, !=, <=, >=)の前後のスペースをチェック
option
include: true/false (デフォルトはtrue)
// true(空ける)のときはOK、falseのときはNG
foo {
margin: 5px + 15px;
}
$foo: 1 + 1;
$bar: 2 - 1;
@if $foo == $bar {
$baz: 1;
}
// false(空けない)のときはOK、trueのときはNG
.foo {
margin: 5px+15px;
}
$foo: 1+1;
$bar: 2-1;
@if $foo==$bar {
$baz: 1;
}
trueとfalseともに、複数のスペースが含むものはエラーになります。
例
.foo {
margin: 5px + 15px;
}
$foo: 1 +1;
$bar: 2- 1;
space-before-bang
「!」の前のスペースの有無をチェック
option
include: true/false (デフォルトはtrue)
// true(空ける)のときはOK、falseのときはNG
.foo {
content: 'bar' !important;
}
// false(空けない)のときはOK、trueのときはNG
.foo {
content: 'bar'!important;
}
space-before-brace
「{」の前のスペースの有無
option
include: true/false (デフォルトはtrue)
// true(空ける)のときはOK、falseのときはNG
.foo {
content: 'bar';
}
// false(空けない)のときはOK、trueのときはNG
.foo{
content: 'bar';
}
space-before-colon
コロン「:」の前のスペースの有無
option
include: true/false (デフォルトはfalse)
// false(空けない)のときはOK、trueのときはNG
.foo {
content: 'bar';
}
// true(空ける)のときはOK、falseのときはNG
.foo {
content :'bar';
}
space-between-parens
「()」内の最初と最後のスペースの有無
option
include: true/false (デフォルトはfalse)
// false(空けない)のときはOK、trueのときはNG
@function foo($bar) {
@return $bar;
}
// true(空ける)のときはOK、falseのときはNG
@function foo( $bar ) {
@return $bar;
}
@mixin bar($baz ) {
content: $baz;
}
.foo {
@include bar( 'Hello' );
content: foo( 'bar');
width: calc( 100% - 10px);
}
trailing-semicolon
ブロックの最後のスタイルにつくセミコロン「;」の有無
(Sassだと除外可)
option
include: true/false (デフォルトはtrue)
// true(つける)のときはOK、falseのときはNG
.foo {
content: 'bar';
content: 'baz';
.waldo {
content: 'where';
}
}
// false(つけない)のときはOK、trueのときはNG
.foo {
content: 'bar';
content: 'baz'
.waldo {
content: 'where'
}
}
url-quotes
URLはクォーテーションマークで囲む
// OK
.foo {
background-image: url('foo.png');
}
// NG
.bar {
background-image: url(foo.png);
}
variable-name-format
変数名のルールの設定
基本的に上ででてきたクラス名のルール設定と同じです。
ただ、オプションにignoreは無いので注意。
詳しい設定例はこちらにあります。(variable-name-formatのルールが記載されたページ)
https://github.com/sasstools/sass-lint/blob/develop/docs/rules/variable-name-format.md
zero-unit
値が「0」のときに単位をつけるか
option
include: true/false (デフォルトはfalse)
// falseのときOKでtrueのときはNG
.foo {
margin: 0;
}
.bar {
padding: 5px 0 0;
}
// trueのときOKでfalseのときはNG
.foo {
margin: 0px;
}
.bar {
padding: 5px 0px 0px;
}
さいごに
おわりです。長かったですね。正直こんなに長くなると思ってなかったです。
後半になるにつれて書き方が雑になってしまいました…。
冒頭でも書きましたが、全部は書けていないので随時更新する予定ではいます。
sass-lint使用初心者のため、違うよーっていう部分がありましたらご指摘いただけるとうれしいです。
おつかれさまでした!