CSSの変態向き - ID, classを顔文字でコーディングする方法

HTMLのIDとclassに顔文字記述しても、CSSではスタイルが適用されません。
ただCSSをごにょごにょするだけで、ID, classを顔文字、日本語でもコーディングすることができます。

誰が得をするのか全くわからないけど、紹介します。

HTMLのID, classを顔文字にする

HTMLのID, classを顔文字、または日本語で書きます。
下準備はこれでおk。

<!DOCTYPE html>
<html lang="ja">
<head>
   <meta charset="UTF-8" />
   <title>Document</title>
</head>
<body ID="(( ◉౪≡౪◉ ))≡౪◉ ))">
   <div class="(」・ω・)」うー!">
     <h1 ID="(/・ω・)/にゃー!">にゃー!</h1>
   </div>
</body>
</html>

CSSでごにょごにょ

CSSのID, classは、ある程度の文字を扱うことができますが、特定の記号や日本語はスタイルが適用されません。

.(」・ω・)」うー! { /* これじゃダメ */
  color: #f00;
}

仕様では以下のようになっています。

CSSでは、(要素名、クラス、およびセレクタ内のIDを含む)識別子は、文字[a-zA-Z0-9]およびISO 10646でU+00A0以上の文字、またハイフン(-)およびアンダースコア(_)のみを含むことができる。識別子は、数字、2つのハイフン、ハイフンの直後の数字で開始できない。また、識別子は、エスケープされた文字および数字コードとして任意のISO 10646文字を含めることができる(次項を参照)。
たとえば、識別子"B&W?"は"B\&W\?"または"B\26 W\3F"として記述してよい。

4.1.3 文字と活字ケース
Syntax and basic data types - CSS 2.1 spec (ja)

認められている範囲外の文字を使用する場合は、同じ引用先から具体的に方法が書かれています。

第三に、バックスラッシュエスケープは、著者が容易に文書内に挿入できない文字の参照を可能にする。この場合、バックスラッシュの後に最大で6桁の16進数(0..9A..F)を続ける。この数字は0でないISO 10646([ISO10646])文字を表さなければならない。(スタイルシートがUnicodeのコードポイントでのゼロの文字を含む場合に何が起こるか、CSS 2.1では未定義である。)範囲内の文字[0-9a-fA-F]は16進数が後に続く場合、数値の末尾は明確にする必要がある。これには二つの方法がある:

  1. スペース(または他の空白文字)を伴う: "\26 B"("&B")。この場合、ユーザエージェントは、"CR/LF"のペア(U+000D/U+000A)を単独の空白文字として処理すべきである。
  2. 厳密に6桁の16進数を与える: "\000026B"("&B")

実際には、これら二つの方法を組み合わせてもよい。16進エスケープの後では、1つの空白文字だけが無視される。この手段は、エスケープシーケンスの後に"本物"の空白文字を二重にしなければならないことに注意する。

上記の内容の通り、先ほどの顔文字をISO10646の文字コードを表す16進数に変換、一文字ごとにエスケープを行います。

/* class="(」・ω・)」うー!" */
.\0028 \300D \30FB \03C9 \30FB \0029 \300D \3046 \30FC \FF01  {
  color: #f00;
}

この方法で、下準備したHTMLのID, classをすべて書き出します。

/* ID="(( ◉౪≡౪◉ ))≡౪◉ ))" */
#\FF08 \0028 \0020 \25C9 \0C6A \2261 \0C6A \25C9 \0020 \0029 \FF09 \2261 \0C6A \25C9 \0020 \0029 \FF09  {
  color: #fff;
}

/* class="(」・ω・)」うー!" */
.\0028 \300D \30FB \03C9 \30FB \0029 \300D \3046 \30FC \FF01  {
  color: #ff0;
}

/* ID="(/・ω・)/にゃー!" */
#\0028 \FF0F \30FB \03C9 \30FB \0029 \FF0F \306B \3083 \30FC \FF01  {
  color: #f00;
}

もう何がなんだかわからない。
上記のように、コメントアウトを各セレクタごとに付けることでなんとかコーディングを行うことができます。
ただコメントアウトを手違いで消したりすると、後から修正を行う時に阿鼻叫喚です。

ID, classをわかりやすく管理する

Sass, Stylus, RooleなどCSSメタ言語の変数を使って管理する、ということも考えましたが、それはそれで面倒くさいです。
ここはあえてPHPを使用します。

準備したHTMLにlink要素を追加し、style.phpを読み込むようにします。

<link rel="stylesheet" href="style.php">

このままではstyle.phpは、PHPとしてブラウザが認識します。 style.phpがCSSであると認識するようにheaderを書き換え、さらにセレクタを16進数する変換するfunctionも書いておきます。
これで準備ができました。あとは普通に書くだけです。

<?php 
  header('Content-Type: text/css; charset=utf-8');
  
  function selector($str) {
    preg_match_all('/(.)/u', $str, $matches);
    foreach($matches[1] as $k => $v){
      $result = '\\' . strtoupper(bin2hex(mb_convert_encoding($v, 'UCS-2', 'UTF-8'))). ' ';
      echo $result;
    }
   }
?>
@charset "UTF-8";
#<?php selector("(( ◉౪≡౪◉ ))≡౪◉ ))") ?> {
  margin: 0;
  padding: 2em;
  background: #111;
  font-family: Arial. sans-serif;
  color: #fff
}

.<?php selector("(」・ω・)」うー!") ?> {
  background: #444;
}

#<?php selector("(/・ω・)/にゃー!") ?> {
  text-align: center;
  font-weight: normal;
}

ID, classを顔文字でやったサンプル

これでHTMLのID, classを顔文字や日本語にしろ、という指示がきても安心ですね。(ただしIE7以下をのぞく)

まとめ

「最近落ち着いた内容が多い」と言われることも多いので、今回はCSSのトリッキーな方法について焦点を当てました。
CSS Programmingなど、変態的 挑戦的な試みもちょっと飽きてきたなーと思い始めたら、やってみると面白いかもしれません。

最後に、この方法は色々混乱を招きやすいので、普通にコーディングしましょう。