クモのようにコツコツと

フロントエンドエンジニア イイダリョウの技術ブログ。略称「クモコツ」

CSS変数でドット絵マリオをルイージにしたった!

CSSドット絵マリオ」の続きです。前回は1点ずつチマチマと打っていきましたが、たった一人ではいささか寂しいですね。そうだ、ルイージを呼ぼう。「CSS変数」を使えば一瞬でこのマリオがルイージに変わるはず。たぶん変わると思う。変わるんじゃないかな?まちょと覚悟はしておけ。では、どうぞ。

※目次:

※参考:前回の記事はこちら
CSSだけでドット絵マリオを描けるのか - クモのようにコツコツと

サイズを変えてみよう

前回作ったマリオはこちらです。

いきなりですが、すみません。このマリオ、実はドット絵といいながら正確には1ドット(1px)ずつ打っているわけではありません。
マスの大きさはimgタグのサイズで決めており、1マスあたり20px四方です。

img {
  background: #eee;
  width: 20px;
  height: 20px;
}

このサイズを例えば半分の10pxに打ち変えると…

img {
  background: #eee;
  width:  10px;
  height: 10px;
}

マリオのサイズが半分になります!

さらに、本来のドット絵の1ドットにあたる1pxにすると…

img {
  background: #eee;
  width:  1px;
  height: 1px;
}

うわわ!ちっさw
私が子供の時に遊んでいたファミコンスーパーマリオは今から見ると全然スーパーじゃない大きさなんですな。

See the Pen dot_e_06 by イイダリョウ (@i_ryo) on CodePen.

今回はキャラを二人に増やすので10pxくらいがちょうどいいかな。

マリオをルイージ色にしたい場合…

さて、サイズはimgの一箇所を変えればいい書き方をしたので変更が楽です。では次に色を変更したい場合はどうでしょう。マリオとルイージの色の違いはこんなです。

  • 体:マリオ(うすだいだい)→ルイージ(うすだいだい)
  • 服:マリオ(赤)→ルイージ(白)
  • 他:マリオ(鈍い緑)→ルイージ(明るい緑)

なんと前回、マリオが青じゃなくて赤いオーバーオールだったのが意外だったんだけど、今回もルイージが緑じゃなくて白いオーバーオールです!
おそらくこれも後ろの空の色との差を出すためと思われます。当時の限られた色数の中での工夫だったのでしょう。

マリオの色を表すCSSはこれです。 登場する色数は全部で3つ。

/*基本色 
体: #facd89;
服: #ff0000;
他: #638c0b;
*/

これをドットに打っていくとこうなる。

/*1行目*/
.dot_e li:nth-child(1) img:nth-child(1) {background: none;}
.dot_e li:nth-child(1) img:nth-child(2) {background: none;}
.dot_e li:nth-child(1) img:nth-child(3) {background: none;}
.dot_e li:nth-child(1) img:nth-child(4) {background: none;}
.dot_e li:nth-child(1) img:nth-child(5) {background: none;}
.dot_e li:nth-child(1) img:nth-child(6) {background: none;}
.dot_e li:nth-child(1) img:nth-child(7) {background: none;}
.dot_e li:nth-child(1) img:nth-child(8) {background: none;}
.dot_e li:nth-child(1) img:nth-child(9) {background: none;}
.dot_e li:nth-child(1) img:nth-child(10) {background: none;}
.dot_e li:nth-child(1) img:nth-child(11) {background: none;}
.dot_e li:nth-child(1) img:nth-child(12) {background: none;}
.dot_e li:nth-child(1) img:nth-child(13) {background: none;}
.dot_e li:nth-child(1) img:nth-child(14) {background: #facd89;}
.dot_e li:nth-child(1) img:nth-child(15) {background: #facd89;}
.dot_e li:nth-child(1) img:nth-child(16) {background: #facd89;}

/*以下、2行目〜16行目まで続く*/

どうですか、圧巻でしょう?w ちょっとこれ全部の色を打ち替えてらんないですよね。そこで「CSS変数」ですよ!

変数とは

変数はプログラミング言語では一般的な概念です。

JSの変数

例えばJSの変数は、お馴染みvar = hogeみたいなやつですよね。*1

※参考:【JSの基本-前編】書ける前に読む!HTML、CSS、JSの書式-4 - クモのようにコツコツと

//JS変数定義
var 変数名 = 値;

例えば人名を変数nameに入れると…

//変数定義
var name = "イイダリョウ";

alert( "わたしの名前は" + name + "ですとろい。");
//結果 わたしの名前はイイダリョウですとろい。

alert( "奴の名前は" + name + "に違ぇねぇ。");
//結果 奴の名前はイイダリョウに違ぇねぇ。

このように、何回も使うオブジェクトを変数で定義すると何度でも使いまわせて、あとからの変更も一箇所で済むので楽なわけです。

altCSSの変数

また、変数は「altCSS」でも一般的な概念です。

※参考:【LESS, SCSS, Sass, Stylus, PostCSS】 AltCSS 事始め - クモのようにコツコツと

例えば(上記の記事では触れられなかったが)SCSSの変数は、変数名の頭に$をつけます。こんな書き方です。

/*SCSS変数定義*/
$変数名: 値;

$といえばjQueryでおなじみの記号ですよね。

※参考:【卒jQueryへの道】生JSとライブラリとフレームワークの理解 - クモのようにコツコツと

PHPの変数ともよく似ていますね!

※参考:PHPの基本を理解するためにJSと比較する - クモのようにコツコツと

先ほどのマリオの3色を変数で定義するとこうなります。

/*基本色 */
/*体*/
$hada: #facd89;
/*服*/
$fuku: #ff0000;
/*他*/
$hoka: #638c0b;

/*1行目の14列目*/
.dot_e li:nth-child(1) img:nth-child(14) {background: $hada;}

変数を使えば基本色の3箇所の変更で全部が変わってくれるわけです!!

しかしながら、altCSSはそのままではブラウザに反映されず、コンパイルする必要があります。例えばSCSSの場合はRubyコンパイルします。

ところがななんと、CSSのデフォルト機能としてついにCSS変数が現れたのです!!これは目出度い。

CSS変数とは

CSS変数の書式はこんなです。

/*CSS変数定義*/
:root {
    --変数名: 値;
}

/*変数呼び出し*/
セレクタ: var(--変数名)

:rootというのは擬似クラスです。

※参考:擬似クラスとは
【CSSの基本】書ける前に読む!HTML、CSS、JSの書式-3 - クモのようにコツコツと

:rootはDOMツリーのルート(根っこ、最上位)であるhtmlタグを意味します。ここに変数を定義すると文書全体に適用されるグローバル変数になるわけです。

変数名の前にはハイフンを2つ--付けます。 定義した変数を呼び出すときはvar()というCSS関数を使います。

※参考:CSS関数とは
【CSSの基本】書ける前に読む!HTML、CSS、JSの書式-3 - クモのようにコツコツと

このvarはJSの変数と同じでバリアブル(variable)という意味です。カッコ()の中に引数として呼び出したい変数名を書きます。

おや?これって先ほどのaltCSSにあった「PostCSS」のプラグイン「cssnext」の変数と全く同じ書式ですよね!そう、cssnextはW3Cに採用予定の書式を一足先に体験させてくれるプラグインだったのです。

そして今やCSS変数はほとんどのブラウザで対応済みです!(ただし、IE11を除く。。)

※参考:Can I use... Support tables for HTML5, CSS3, etc

先ほどのマリオ三色をCSS変数で定義するとこうなります。

/*基本色 */
root: {
    /*体*/
    --hada: #facd89;
    /*服*/ 
    --fuku: #ff0000;
    /*他*/
    --hoka: #638c0b;
}

/*1行目の14列目*/
.dot_e li:nth-child(1) img:nth-child(14) {background: var(--hada);}

SCSSの$--になった感じですね。

CSS変数をマリオに適用

さて、マリオをルイージにするためにはまずマリオ自身もCSS変数に適用する必要があります。この段階では産みの苦しみとしてテキストエディタの「検索・置換」でいくつかの手順を踏まねばなりませぬ。

class名の変更

まず、class名。今後の展開を考えず、無計画に.dot_eなんて抽象的な名前を付けていました。こいつを.marioに変えましょう。

<ul class="mario">
   <!--(ドット絵いっぱい)-->
</ul>

まあHTMLはいい。変更はulのclass名一箇所だ。 問題はCSSです。CSS変数は「値」にしか適用できず、「セレクタ」や「プロパティ」の重複は検索・置換するしかしゃーない。

.mario {
  font-size: 0;
  margin: 0;
  padding: 0;
}

/*1行目*/
.mario li:nth-child(1) img:nth-child(1) {background: none;}
.mario li:nth-child(1) img:nth-child(2) {background: none;}
.mario li:nth-child(1) img:nth-child(3) {background: none;}
.mario li:nth-child(1) img:nth-child(4) {background: none;}
.mario li:nth-child(1) img:nth-child(5) {background: none;}
.mario li:nth-child(1) img:nth-child(6) {background: none;}
.mario li:nth-child(1) img:nth-child(7) {background: none;}
.mario li:nth-child(1) img:nth-child(8) {background: none;}
.mario li:nth-child(1) img:nth-child(9) {background: none;}
.mario li:nth-child(1) img:nth-child(10) {background: none;}
.mario li:nth-child(1) img:nth-child(11) {background: none;}
.mario li:nth-child(1) img:nth-child(12) {background: none;}
.mario li:nth-child(1) img:nth-child(13) {background: none;}
.mario li:nth-child(1) img:nth-child(14) {background: #facd89;}
.mario li:nth-child(1) img:nth-child(15) {background: #facd89;}
.mario li:nth-child(1) img:nth-child(16) {background: #facd89;}

/*以下、2行目〜16行目まで続く*/

こんなんでました。

お、よかった。ちゃんと色が当たってる。

CSS変数を定義

ではいよいよ、マリオのCSS変数を定義しましょう。

:root {
  /*体*/
--Hada: #facd89;
/*服*/ 
--Fuku: #ff0000;
/*他*/
--Hoka: #638c0b;
}

マリオの色を変数に置き換えます。

/*1行目*/
.mario li:nth-child(1) img:nth-child(1) {background: none;}
.mario li:nth-child(1) img:nth-child(2) {background: none;}
.mario li:nth-child(1) img:nth-child(3) {background: none;}
.mario li:nth-child(1) img:nth-child(4) {background: none;}
.mario li:nth-child(1) img:nth-child(5) {background: none;}
.mario li:nth-child(1) img:nth-child(6) {background: none;}
.mario li:nth-child(1) img:nth-child(7) {background: none;}
.mario li:nth-child(1) img:nth-child(8) {background: none;}
.mario li:nth-child(1) img:nth-child(9) {background: none;}
.mario li:nth-child(1) img:nth-child(10) {background: none;}
.mario li:nth-child(1) img:nth-child(11) {background: none;}
.mario li:nth-child(1) img:nth-child(12) {background: none;}
.mario li:nth-child(1) img:nth-child(13) {background: none;}
.mario li:nth-child(1) img:nth-child(14) {background: var(--Hada);}
.mario li:nth-child(1) img:nth-child(15) {background: var(--Hada);}
.mario li:nth-child(1) img:nth-child(16) {background: var(--Hada);}

/*以下、2行目〜16行目まで続く*/

こんなんでましたけどっ!

やた!CSS変数ちゃんと読み込まれましたね。

ルイージ召喚

さて、時は来た!ルイージを召喚しましょうぞ!

マリオ複製

まず、HTMLのマリオを複製して、class名をルイージ.luigi(こんな綴りなのね)にします。

<ul class="Mario">
   <!--(ドット絵いっぱい)-->
</ul>

<ul class="luigi">
   <!--(ドット絵いっぱい)-->
</ul>

次はCSS。マリオの設定をルイージにも加えたいのでセレクタ, .luigiを追加。 あと、マリオとルイージを横に並べたいのでdisplay: inline-blockに変更。

.mario,
.luigi {
  font-size: 0;
  margin: 0;
  padding: 0;
  display: inline-block;
}

この時点では.luigiには色は当たらないため、マリオの横に白い四角が現れたに過ぎない…

マリオのCSSを複製し、セレクタ.luigiにすると…

/*1行目*/
.luigi li:nth-child(1) img:nth-child(1) {background: none;}
.luigi li:nth-child(1) img:nth-child(2) {background: none;}
.luigi li:nth-child(1) img:nth-child(3) {background: none;}
.luigi li:nth-child(1) img:nth-child(4) {background: none;}
.luigi li:nth-child(1) img:nth-child(5) {background: none;}
.luigi li:nth-child(1) img:nth-child(6) {background: none;}
.luigi li:nth-child(1) img:nth-child(7) {background: none;}
.luigi li:nth-child(1) img:nth-child(8) {background: none;}
.luigi li:nth-child(1) img:nth-child(9) {background: none;}
.luigi li:nth-child(1) img:nth-child(10) {background: none;}
.luigi li:nth-child(1) img:nth-child(11) {background: none;}
.luigi li:nth-child(1) img:nth-child(12) {background: none;}
.luigi li:nth-child(1) img:nth-child(13) {background: none;}
.luigi li:nth-child(1) img:nth-child(14) {background: var(--Hada);}
.luigi li:nth-child(1) img:nth-child(15) {background: var(--Hada);}
.luigi li:nth-child(1) img:nth-child(16) {background: var(--Hada);}

/*以下、2行目〜16行目まで続く*/

おお!マリオが二人になった〜〜〜〜!!!!!

ルイージ変色!

よっしゃ!このマリオツインズの片方の色を変えてルイージにしてやります。 2人に共通する色は「肌色」。「服」と「他」の変数定義はローカルなセレクタに移動しましょう。

:root {
  /*体*/
--Hada: #facd89;
}

.mario{
/*マリオ服*/ 
--Fuku: #ff0000;
/*マリオ他*/
--Hoka: #638c0b;  
}

.luigi{
/*ルイージ服*/ 
--Fuku: #ff0000;
/*ルイージ他*/
--Hoka: #638c0b;  
}

こうすると、ローカル変数になるため、同じ変数名でありながら、上書きされずにそれぞれ別の色が設定できると期待しています。

さあ、いよいよ、ルイージの色を変えまっせぇ〜〜〜!! ルイージの色はこうでしたね。

  • 体:マリオ(うすだいだい)→ルイージ(うすだいだい)
  • 服:マリオ(赤)→ルイージ(白)
  • 他:マリオ(鈍い緑)→ルイージ(明るい緑)

だいたいこんな感じの色かと思う。さあ、どうなることやら(ドキドキ)

.luigi{
/*ルイージ服*/ 
--Fuku: #fff;
/*ルイージ他*/
--Hoka: #14b814;  
}

おお!ルイージ召喚成功〜〜〜〜!!!!!

私の脳内に鳴る「トゥ〜ン」というジャンプ音も、ダブルのユニゾンになりました♪

まとめ

ということで、CSSにもついに変数がやってきた、ヤァヤァヤァ!という喜びを噛み締めるべく、マリオをルイージにしてみました。

CSS変数を使えば例えば何かサイトを作ったときに、姉妹サイトのキーカラーを変えるとか、一瞬でできるわけです。 記事一覧のサムネイル枠のサイズ変更とかも一瞬です。工夫次第でいろいろな使い道が思い浮かびます!(セレクタ名にも変数が使えるとさらに素敵なんですけどねぇ…)

さて、ドット絵シリーズの次は「立ちポーズ」を作ってみようと思います。それでは、また!!

*1:他にconst、letもあるでよ!