2011年2月18日

CSS で記述の入れ子を可能にする「LESS」と、サヨナラCSSハック


LESS « The Dynamic Stylesheet language
http://lesscss.org/

CSS を書いているとき、
  • コメントアウトに /* ~ */ じゃなくて // を使いたい
  • 入れ子で書いたのを解釈して欲しい
と思ったことがある人なら多分夢のようなライブラリだと思う。
使い方は簡単で、説明に書いている通り head タグ内に less.js を読み込むための定義と、LESS で記述したスタイルを読み込むための定義を追加するだけ。
<link rel="stylesheet/less" type="text/css" href="styles.less">
<script src="less.js" type="text/javascript"></script>
styles.less にいつも通りの CSS を書けば普通に解釈してくれるし、以下のような書き方も可能になる。
.box-shadow-dark(@x: 0, @y: 0, @blur: 0) {
 box-shadow: @x @y @blur #888;
 -webkit-box-shadow: @x @y @blur #888;
 -moz-box-shadow: @x @y @blur #888;
}

ul {
  margin: 2em;

  //各ブラウザ向けの box-shadow を適用
  .box-shadow-dark(2px, 2px, 8px)

  //これは ul li として処理される
  li {
    list-style-type: circle;
  }
}
この他にも色や値の計算とか色々楽しそうな機能があるので、その辺は LESS のサイトの記述例を参考にしてください。 英語読まなくても例で動きが大体わかるぐらい簡潔な記述だと思います。
ちゃんとコンパイラもあるようなので動的に解釈されることに抵抗がある人も安心。

ただ、実際に LESS を使って書いてると意外と入れ子はクセモノだった。以下のような流れで気付いた。
  1. ul に margin 付けようかなー
    ul {
      margin: 2em;
    }
    
  2. ul の中の li に border 付けようかなー
    ul {
      margin: 2em;
      li {
        border: 1px solid #000;
      }
    }
    
  3. ul と p タグは同じ margin でいいなー
    ul, p {
      margin: 2em;
      li {
        border: 1px solid #000;
      }
    }
    
  4. あれ? ul li はいいけど p li なんていらなくね? 無駄じゃね?
面白いけど軽い気持ちで触るとグチャグチャになりそうなので注意して使ったほうがよさげ。

clearfix はどう書くか?
今までは clearfix を適用したい要素に対して HTML 側で class="clearfix" など付けたりしていたけど、LESS の機能を使うことで HTML 側に手を加えなくてもコンパクトに clearfix が適用できるようになりそうだ(元ネタに関してはSCSSの記事を参照)。
例えばこんな感じ。
.clearfix() {
  zoom: 1;
  &:after {
    content: url(data:image/gif;base64,R0lGODlhAQABAGAAACH5BAEKAP8ALAAAAAABAAEAAAgEAP8FBAA7);
    display: block;
    clear: both;
    height: 0;
  }
}

//使うときはこうする
ul {
  .clearfix;
  li {
    float: left;
  }
}
個人的に content に 1x1 画像使う奴が好きなのでこれにした。
(でも LESS が処理した結果 CSS が肥大化するような気もするのでテキストのほうがいいのかも)
HTML側は普通に書けばいいだけ。
<ul>
  <li>横並びのメニュー</li>
  <li>みたいな奴</li>
  <li>作ってる風</li>
</ul>
<ul>
  <li>これはまた左端から</li>
  <li>並ぶように</li>
  <li>できてる</li>
</ul>
簡単すぎて拍子抜けしちゃうけどちゃんと動く。
こうやってみると after のところの文法は SCSS 由来なのかな?

サヨナラ CSS ハック
LESS を少し試した限り、IE 向けの CSS ハック類は使えないものがチラホラあった。
けど別にどうでもいいよね。
ここでやってる方法を真似すればいい。以下の例は lang 属性の値を ja に修正済み。
<!DOCTYPE html> 
<!--[if lt IE 7 ]> <html lang="ja" class="ie6 ielt8"> <![endif]--> 
<!--[if IE 7 ]>    <html lang="ja" class="ie7 ielt8"> <![endif]--> 
<!--[if IE 8 ]>    <html lang="ja" class="ie8"> <![endif]--> 
<!--[if (gte IE 9)|!(IE)]><!--> <html lang="ja"> <!--<![endif]--> 
<head>
要するに IE6, IE7, IE8 の時は html タグにクラスが付くようになる。
CSS を書く際には .ie6 body { background-color: red; } とかやれば IE6 のみに適用できる。
これは Modernizr とも親和性が高い方法で、Modernizr も併用すると box-shadow とか border-radius が使えない環境などでスタイルを書き分けることもできる。
いい時代ですね。

2011/02/18 ---- 追記

Sass、そしてSassy CSS (SCSS)
http://hail2u.net/documents/sass-and-sassy-css.html
LESS と同じようなものがあるみたいだ。
link 要素に直接書ける LESS の方が敷居は低いけど機能面はどのぐらい違うんだろう……?
取りあえずその記事を参考に clearfix を書きなおす話を加えてみた。素晴らしい。
Clip to Evernote