Skip to content
Introduction to html/css/js lint tools.
CSS JavaScript
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
css
js
.gitignore
README.md
gruntfile.js
index.html
package.json

README.md

brushup-sample

About

HTMLInspectorとCSSLintとJSHintと試すリポジトリ。

License

サンプルコードはライセンスありません。 その他Grunt、HTMLInspector、CSSLint、JSHint等はそれぞれに準じます。

0. やりかた

0.1 gitがない人は

ダウンロードしてインストールする。黒い画面でgitコマンドが使えるようになる。

0.2 nodeがない人は

ダウンロードしてインストールする。黒い画面でnodenpmコマンドが使えるようになる

0.3 grunt-cliのインストール

$ npm install -g grunt-cli

黒い画面で実行し、インストールする。gruntコマンドが使えるようになる。

0.4 リポジトリのクローン

リポジトリをクローンしてきて、そのリポジトリに移動する。

$ git clone git@github.com:1000ch/brushup-sample.git
$ cd ./brushup-sample

package.jsonに定義してある依存モジュールをnpmでインストールする。gruntとかgrunt-contrib-jshint等がダウンロードされる。

$ npm install

通常は以下のコマンドを実行して、html/css/jsが保存等される場合にそれぞれにチェックがかかるようになっている。

$ grunt [watch]

これはgrunt-contrib-watchモジュールを使って実現しており、設定はgruntfile.jsの12行目から25行目に書いてある。今回は各タスクを別途実行して、HTML/CSS/JSそれぞれを修正していく。

0.5 黒い画面お手上げな人

このリポジトリのファイルのcssファイルやjsファイルをCSSLintJSHintに貼り付けて実行してみてください。

1. HTMLInspector - grunt-html-inspector

grunt-html-inspectorモジュールを利用して、設定はgruntfile.jsの3行目から5行目に書いてある。

$ grunt html-inspector

1.1 Failed rule "validate-attributes".

The 'bgcolor' attribute is no longer valid on the <body> element and should not be used.

<body bgcolor='#fff'>

bodyタグにbgcolorが付与されているが、使われるべきではない。文書構造をHTMLで定義し、ページの装飾をCSSで行う。

body {
  background: #fff;
}

1.2 Failed rule "unused-classes".

The class 'hoge' is used in the HTML but not found in any stylesheet.

HTML中にhogeというクラスが使用されているが、CSS中にその定義が存在していない。JSでgetElementsByClassNameする場合等は別だが、CSSの参照コストがかかるので定義されていないクラスは指定しない。

1.3 Failed rule "unnecessary-elements".

Do not use <div> or <span> elements without any attributes.

CSSのスタイリングや属性値が持たない<div><span>は、必要ないはず。HTMLでのネストを深くすることで様々な参照コストを上げる可能性があるので、避けること。

1.4 Failed rule "validate-attributes".

The 'alt' attribute is required for elements.

必須とされている属性は付与すること。<img>については、 srcを空にしないwidthとheightを指定する ことも忘れずにやること。 <img>等のsrc=''<a><link>href=''を空文字で指定すると、無駄なHTTPリクエストが発生してしまうブラウザがある。 それによってパフォーマンスが低下するだけでなく、セッションの管理のためにトークン等を利用している場合はリクエストによってトークンが更新されてしまい動かなくなってしまう可能性もある。また、widthheightを指定することでHTMLの解析時に<img>の占める領域が決定するため、画像のダウンロード後に発生する再レイアウトを予防することが可能。

1.5 Failed rule "validate-elements".

The <font> element is obsolete and should not be used.

HTMLは文書構造の定義、CSSは装飾という分離をするため、<font>タグは非推奨になった。同様の理由で<center><basefont>等も非推奨である。

1.6 Failed rule "inline-event-handlers".

An 'onclick' attribute was found in the HTML. Use external scripts for event binding instead.

<button id='#js-button' onclick='alert(0)'>ボタン</button>

HTMLのインラインでイベントを定義するべきではない。管理が非常に難しく、予期しない不具合を起こす可能性がある。

<button id='#js-button'>ボタン</button>

HTMLにはJSから参照するIDやクラスをふっておき、

document.getElementById('js-button').addEventListener('click', function() {
  alert(0);
}, false);

JS中でこのようにクリックイベントを定義する。

1.7 Failed rule "script-placement".

<script> elements should appear right before the closing </body> tag for optimal performance.

<script>タグは同期的に解決されるため、<head>タグの中に配置されていたりすると<body>タグの解析が始まる前に実行されるため、その間ページが白い画面になってしまう可能性がある。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Sample Page</title>
    <link rel="stylesheet" href="css/import.css">
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
    <script src="js/app.js"></script>
  </head>
  <body>
    <div class="outline hoge">
      <header></header>
      ...
    </div>
  </body>
</html>

</body>タグのすぐ上部に配置することで、それを避ける事が可能である。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Sample Page</title>
    <link rel="stylesheet" href="css/import.css">
  </head>
  <body>
    <div class="outline hoge">
      <header></header>
      ...
    </div>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
    <script src="js/app.js"></script>
  </body>
</html>

<script>タグを<head>の中に配置してはいけないわけではない。 <body>の評価より先にされなければならない場合(例えば要素をJSでゴリゴリ作るとか)はそうするべき。

2. CSSLint - grunt-contrib-csslint

grunt-contrib-csslintモジュールを利用して、設定はgruntfile.jsの6行目から8行目に書いてある。

$ grunt csslint

2.1 [L8:C11] zero-units

Values of 0 shouldn't have units specified. You don't need to specify units when a value is 0.

値が0の場合はpxをつけようが%をつけようが0に変わりないので、除く。

.outline {
  margin: 0px auto;
  min-width: 320px;
  max-width: 960px;
}

数文字減った所でファイルサイズが大幅に減るわけではないが、気をつけておいて損はない。

.outline {
  margin: 0 auto;
  min-width: 320px;
  max-width: 960px;
}

2.2 [L42:C19] overqualified-elements

Element (a.active) is overqualified, just use .active without element name. Don't use classes or IDs with elements (a.foo or a#foo).

a.activeは不要に詳細度が増しているセレクタである。.activeにすることで他のタグにも適用することが可能になる。更に具体的には

ul.nav li.active a {}

div.header a.logo img {}

.main ul.features a.btn {}

このように記述していると、<img><div class='header'><a class='logo'>に入れなければスタイルが適用されないし、.btnも名前から察するに単独で使用可能なクラスであるべきだろう。

.nav .active a {}

.logo > img {}

.features-btn {}

こうすることで<ul><ol>に変えてもスタイルが反映されるし、.features-btnも様々なタグで使用可能になった。

2.3 [L46:C1] shorthand

The properties padding-top, padding-bottom, padding-left, padding-right can be replaced by padding. Use shorthand properties where possible.

ショートハンドで記述可能な場合は、ショートハンドで記述することで冗長な表現を避ける事が出来る。

.foo {
  margin-top: 10px;
  margin-right: 20px;
  margin-bottom: 10px;
  margin-left: 20px;
}

.bar {
  margin-top: 5px;
  margin-left: 15px;
  margin-bottom: 10px;
  margin-right: 15px;
}

これは以下のように記述可能である。

.foo {
  margin: 10px 20px;
}

.bar {
  margin: 5px 15px 10px;
}

ショートハンドで記述可能なプロパティはmarginpaddingの他にもlinear-gradientborderなどがあるが、可読性を保った範囲で行っていく。

2.4 [L1:C1] import

@import prevents parallel downloads, use instead. Don't use @import, use instead.

import.cssで以下の記述を行っているためである。

@import url("reset.css");
@import url("app.css");

@importは直接にCSSファイルを解決するため、並列ダウンロードが可能な<link>タグを複数書くことで描画開始までを速くすることが可能である。

<link rel='stylesheet' href='reset.css'>
<link rel='stylesheet' href='app.css'>

更に良いのは、予めreset.cssapp.cssを結合しておくことでHTTPリクエストの数を減らすことが可能である。

3. JShint - grunt-contrib-jshint

grunt-contrib-jshintモジュールを利用して、設定はgruntfile.jsの6行目から8行目に書いてある。

$ grunt jshint

3.1 [L2:C14] W061: eval can be harmful.

evalで評価された文字列のJavaScriptは、スコープがわかりにくい上にパフォーマンスが低いため使うべきではない。

setTimeout(eval("alert('アラート')"), 0);

ではなく

setTimeout(function() {
  alert('アラート');
}, 0);

同等の処理をこのように記述することが可能。

3.2 [L5:C30] W010: The object literal notation {} is preferrable.

3.3 [L5:C32] W033: Missing semicolon.

セミコロンが抜けているのと、オブジェクトの初期化にはリテラル({})を使ったほうが良い。

var sampleObject = new Object();

ではなく

var sampleObject = {};

と書いたほうが良い。初期化に関しては後述の、配列の初期化と同様の理由である。

3.4 [L6:C28] W009: The array literal notation [] is preferrable.

オブジェクトに続いて、配列の初期化もリテラルを使った方がよい。

var sampleArray = new Array();

ではなく

var sampleArray = [];

と書いたほうが良い。 短く簡潔に書けるということと、コンストラクタを使うケースは引数の取り方がわかりにいので、思わぬ不具合を招く場合がある。

3.5 [L9:C19] W041: Use '!==' to compare with 'null'.

厳密等価演算子(==ではなく===!=ではなく!==)を使用するべき。

if(sampleObject != null) {
}

ではなく

if(sampleObject !== null) {
}

と書いたほうが良い。 等価演算子は内部的に型を変換しているため、低速であり評価のされ方で誤解を招く場合がある。厳密等価演算子は型変換がない分高速である。

You can’t perform that action at this time.