スクリプトが無効の場合のスタイル

たとえばホームページのビジュアル要素など、いったん非表示にしておいてスクリプトでふわっとフェードインさせたい、みたいなことはよくある。そのとき非表示にする操作も JavaScript にやらせると一瞬見えてしまうことがあるので CSS で非表示化したいが、それだとスクリプトが無効の場合に何も表示されなくなってしまう… というような、スクリプトによる操作を前提にしたスタイルのフォールバックをどうするかという問題。

ここのところよく使っていたのは、JavaScript で html 要素の class 属性を操作し、それをもとに CSS を書くという手。Modernizr でも使われてるあれ。

(function () {
    var root = document.documentElement;
    root.className = root.className.replace(/\bno[-_]?js\b/ig, '') + ' js';
})();

こんなようなコードを head 内で読み込んでおけば、スクリプトが有効の場合には html 要素の no-js (または no_jsnoJS) クラスが削除されて js クラスが付与されるので、これをもとに CSS のルールセットを分岐させればいい。

.foo { ... }
.js .foo { display: none; }

またはこう:

.foo { display: none; ... }
.no-js .foo { display: block; }

ちなみに Sass 3.2 の placeholder (%) セレクタを使うとこう書けて便利:

.js %js-hidden { display: none; }
.foo { @extend %js-hidden; ... }

このスクリプトは body の最後に置いたのでは遅いので、head に置くほうがいい。なお HTML 4.01 や XHTML 1.0 では html 要素は class 属性を持てない (動くけど)。

そしてもうひとつの手として最近思いついたのが、head 内で noscript 要素 を使って別のスタイルシートを読み込む方法。

<head>
    ...
    <link rel="stylesheet" href="/css/style.css">
    <noscript>
        <link rel="stylesheet" href="/css/noscript.css">
    </noscript>
    ...
</head>

デフォルトのスタイルシートではスクリプト有効の前提で書いて、無効の場合のスタイルを別ファイルに書けばいい。ひとつの要素に対して複数のファイルを編集しなきゃいけないけど、スニペットに依存しない点は良いと思う。

なお HTML 4.01 や XHTML 1.0 では head 内に noscript を置けないし、noscript 内に link を置けない。HTML5 Rocks!