自分の書いたCSSと戦うためのまとめ(OOCSS)

www.slideshare.net
あわわ・・・確かに・・・何ですぐ死んでしまうん・・・

今自分が半年くらい前に書いたCSS(死にそう)と格闘しているんだけど、どういう方針で直すのか、
そもそもどういう方針で書いていくのが正しいのかわからなくなったので調べてみた。

現状分析

現状のCSS・・・
  • bootstrapの上に重ねがけしている(bootstrapの指定方法にぶつける書き方が多い)
  • その一方で独自クラスみたいなものが存在する (ルール特になし、辛い)
  • 入れ子のクラスが存在する

 こういうの、入れ子と言っていいのかわかないけどこういうの

.class1 .class2 {
 color:red;
}
  • 限定的なクラスが多くて 使いまわせない
  • その上クラス名から内容を推察しづらい
どうしたいか
  • 使いまわせるようにしたい
  • クラスの重ね順だけ意識すればいいようにしたい(優先度が異なる書き方をできるだけしない)
  • 内容が推察できるクラス名に統一したい

恥ずかしいけど逆に言うと何も考えずにとにかく動け!でCSSを書いていました。
一番苦しんでるのは結局それを直す自分なのでここで綺麗にしておきたい!

まず使っているBootstrapはどんな設計なのか?

Bootstrap は OOCSS という設計に基いているらしい。
getbootstrap.com

OOCSSとは

app.codegrid.net
とてもわかりやすいです、ありがとうございます。
引用しつつ要点だけまとめると・・

要点

・OOCSSとは、Object Oriented CSSの略。(「Object Oriented」は、「オブジェクト指向」)
・Nicole Sullivanという人が提唱。
・一つ一つのパーツをCSSオブジェクトと呼ぶ。(オブジェクトはレゴのパーツようなもの)
CSSオブジェクトを組み合わせてページを作成する。
・構造とスキンを分離する

CSSオブジェクト

以下は自分が理解するための具体的な例
(といいつつ上記サイトの写経改変です。)
こういうサイトを作る。
f:id:flypia:20170220002527j:plain
青文字のような構成にするとき各h2のcssを考えると

#main h2 {
  ・・・
}
#main .contact .header h2 {
 ・・・
}
#sidebar h2 {
 ・・・
}

この書き方めっちゃしてるんですけどOOCSS的にはダメなのです。
記事で既に書かれているところと重複するけれど、なぜダメなのかというと
・文脈に合わせて書いているので、文脈自体が変化した場合ccsが死ぬ
・文脈がわかっていないとなんのこっちゃ
・#mainの中に別のスタイルを当てたいh2が出現した場合、cssを上書きすることになる(無駄)
・上書きできないこともある(詳細度の問題)
こういう書き方を選択する場合って、#mainの中に同じスタイルを当てたいh2が複数ある場合が多いと思う。上の問題を解消しようとすると結局コピペが多くなってまた無駄ということなんですよね。。

レゴのように考える

じゃあどうするかという問題ですが、Nicole Sullivanは「Webページを、レゴの集まりで考えよ」と言います。

ページを構成するパーツを、レゴのパーツのように分け、それをページにどんどん積んでいくと考えなさい。Webページは、レゴの集まりなのです。そして、ひとつひとつのパーツは、そのパーツで完結するようにCSSを書きなさい。そうすれば、さきほど例に挙げたような破綻は起こりません、とOOCSSは言うのです。
知っておきたいHTMLテンプレート設計法 - OOCSSの基本 | CodeGrid

レゴやったことない!!
f:id:flypia:20170220010744j:plain
一つ一つのパーツに対して命名するらしい。
このパーツを組み合わせてページを作る。
のは、わかるんだけど、パーツの切り分けが正直一番悩むところなんだよなと思うんです。
パーツについてはデザインありきなのかなとも思うので、そういう意味だとデザイナーさんと話してみてもいいのかもしれない。

ストラクチャ(構造)とスキン

構造とスキンを分離する、ということ。
ここからいつも拝見してるTAMさんのブログを参照します。
www.tam-tam.co.jp
理解のため写経改変。
【陥りやすい問題】
・インラインのようなcss

.mr-10 {
  margin-right:10;
}

これは見たことある。別のやつ作る時に外部の方にお願いした時についてきたのがこれだった。10px単位とかでクラス化してあった。(初めて人が作ったCSSを見たのも思えばそれだった)それを改変したんだけど全然使いませんでした。
・セマンティックな例
セマンティック
セマンティックWebとは|Semantic Web − 意味 / 定義 : IT用語辞典

.subTtl01  {
 width: 100px;
 margin: 0 auto;
 padding: 5px;
 font-size: 14px;
 color: #cc0000; 
}

.subTtl02 {
 width: 100px;
 margin: 0 auto;
 padding: 5px;
 font-size: 14px;
 color: #ffffff; 
}

どっちかというとこういう感じのcssを書いてきた気がします。
では子孫セレクタを使わずに「構造とスキン」を分離する書き方をするとこいつはどうなるのか?

.ttlArea  {
 width: 100px;
 margin: 0 auto;
 padding: 5px;
}

.txt14 {
 font-size: 14px;
}

.subTtl01  {
 color: #cc0000; 
}

.subTtl02  {
 color: #ffffff; 
}

これなら色違いとかのタイトルが増えてもうまくいきそう。
bootstrapの.btnとかまさにそういう感じですね。

思ったより長くなったので続きはまた今度

Unityチャレンジその1

Unityいいなとかゲーム作りて〜などと言いつつ今まで本だけ買って満足していたのでマジでやるぞ。
まずはこれだー!
github.com

公式の玉転し。
できたー!
Unity WebGL Player | Roll-a-Ball-myprac
・緑のピンを全部とるゲームです。
・キーボード→で玉を移動できます。
・ピンクの壁にぶつかるとはじめからやり直しになってしまうぞ!

日曜日の午後から初めて公開まで5時間?くらいだろうか・・・前にちょっと触った時は何が何だかわからなかったんだけど集中してやったら何となくわかってきた感じがする。
そういうわけではまった?ところを書きます。

ゲームが完成するまで

参考にしたリファレンスは上記の通り。
環境はMac、Unityバージョンは最新(5.5.1)
ここ
Unity - Update
からダウンロードしたのは良かったんだけど、よく確認せずにダウンロード、インストールしたせいで、後述する公開段階になってつまづいた。

作成中につまづいたりしたことは・・・

・パネルオブジェクトの動かし方(操作方法)
 positionで座標変更するのはわかるんだけど私はドラッグで移動させたかった。そしてドラッグ移動は割と癖があるような気がします(個人差がきっとめちゃくちゃあります)
 ちゃんと移動させたいオブジェクトの座標ど真ん中あたりをクリックしないとダメっぽい。
 最終的には座標で調整するんだけど、動きを掴むまでは「なんで!動かない!なんで!」ってなった。。。
・オブジェクトへの色のつけ方(操作方法)
 今となればちょっと恥ずかしいけどAlbedoの横のスポイトみたいなやつではなく四角いところをクリックしよう。
 わかってる今となってはなんでわからなかったのかよくわからないけど多分手順書をよく読まなかったからだと思う。
・キーボードの入力は何に対応しているのか(操作方法?)
 入力機能の追加でキー入力がボールの動きに対応するようになったのはいい。で、再生して「何が」対応するようになったのかわからなかった。これも恥ずかしいんだけどキーボード上下左右キーです、、、なんか勘違いして1とか4とか押してた。
・Itemは画面上に8つしかないのに9こItemがある(操作ミス?)
 これはゲームのクリアを追加する、の場面で。Itemオブジェクトだけではなくてそれらを単にまとめているだけのItemフォルダにもItemタグを追加していたため。タグが付いているオブジェクトの数を数えるんだから当然なんだけど、ユーザーの操作で消えるItemは8つにしていたために「もう一人いる・・・???」状態だった。

公開するまで

これがめちゃくちゃ時間かかりました。
順を追う。

①WebPlayerで公開する

→ダメだった。
まずBuildするのにWebPlayerがない。
f:id:flypia:20170205221346p:plain
一番上にあるはずなんだよなあ〜
注意点としてはWebPlayerを別途ダウンロードしないと遊べない、Chromeなど一部ブラウザでプレイできないなど。。。
Unityで作ったゲームをWebPlayerで公開する - Qiita
参考にさせていただきました。
なんでないんだろうなあ、調べてもわからなかったんだけどUnityのバージョン依存かなんかでないんだと思っておくことにしました、、

WebGLで書き出し

→キャプチャを撮ってなかったんだけど、Build SettingsにWebGL項目はあるのにインストールしろ見たいなボタンが出ていて、ボタンを押してもダウンロードできないという。
ここではじめ適当にUnityをダウンロードしてしまったことが響いてくるんですが、後からダウンロードして事なきを得ました(よかった)
【Unity】Android SDKやJDKを設定する項目が見つからない時の対処法 - テラシュールブログ
めちゃくちゃ参考にしましたありがとうございました。。。
要ははじめにインストールしてなかったので、ないものはできないよっていう話。
手順としては、Unityをインストールした時のインストーラーを起動して、
・すでにあるもののチェックを外した状態で、
・必要なものにチェックを入れて
インストールするだけです。それはそうなんだけど、そんな事やった事なかったからドキドキした。
f:id:flypia:20170205223502p:plain
こんな感じでインストールしなおしてください。
すると、WebGLBuildができるようになるぞ!やった〜

③どこで公開するか?

[unityroom編]
→引き続き調べるとこんなサイトが!
ゲーム投稿サイト unityroom - Unityのゲームをアップロードして公開しよう
楽しげ〜〜とビビっときてここで公開する方法を探す。
手順としてはTwitterアカウントを作って、連携することでアカウントを作成、右上の新しいゲームを登録するからアップロードするだけ。なんて簡単なんだ、、、
ほ〜〜んとめっちゃ簡単なのに結論としてはできなかった。
WebGLでBuildしたものの中のReleaseフォルダ内を全部アップロードするだけなんだけど、足らないんですよね、、、
f:id:flypia:20170205222438p:plain
この中の.jsgzファイルがね、、二個あるんだよね、、二個アップロードしたいんだけどさ、、
f:id:flypia:20170205222256p:plain
足らない。。。
足らないなりにアップロードしてみたけどエラー出て動かないし、どうもUnity5.4以下じゃないと動かないらしくて断念(確定情報ではないです)

[githubpageで公開編]

githubでwebページを公開する方法がわからなかったために時間がかかってしまった。
参考にさせていただきました(本当にありがとうございました)
UnityのWebGLで書きだしたゲームをGitHubを使って公開する - Qiita
GitHubを使って3分でHPを公開する。 - Qiita

前提条件として、
githubでWebページを公開するためには、
 ・username.github.io.gitリポジトリを作成する  
詳しくはGitHub Pages - Websites for you and your projects, hosted directly from your GitHub repository. Just edit, push, and your changes are live.
 ・その上で公開したいレポジトリから[gh-pages]というブランチを切って、必要ファイルを入れる、もしくは
 公開したいレポジトリのmasterブランチにdocsディレクトリを作る。

これらが必要。
なんだけど、はじめのレポジトリ作ってなくてマスターにプッシュしまくってた。
index.htmlリンクをクリックしてもソースが出てくるだけになるので気をつけよう。

[その他]

そんなわけでいらないレポジトリをたくさん作ったら消しておきましょう。。
消したいレポジトリを選択して、歯車マークの付いてるSettingをクリック。
遷移先の最下部にDelete this repositoryがあるんでそこから消しちゃおう〜

感想

ちょいちょい戸惑ったけど、とっても楽しかった!
ボールに対して物理演算機能を追加して、落下を確認した時は「すっげ〜〜〜〜〜〜!!」
ってなりました。すご。
5時間足らずでボール転がしが作れてしまうなんてなんで今までやらなかったんだろう。。
でもまとまった時間で一気にやるのが自分にとってはいいのかなとも思う。
土日で基本的なゲームを作って、平日に機能追加してくのが良さげなのかな。
そんなわけでチュートリアル玉転がしを改造していくぞ〜!
フィールドをまずは広くしよう。続!

phpで多次元配列をソートする

例えば、 ある学年の1組、2組、3組の生徒がテストをしたとして、 生徒に対して一意のidと、生徒の組、点数 を多次元配列で表した時に、 ①学年の組ごとに昇順に並べ ②かつ点数順に並べたい みたいな時にどーするのっていう話。

// 多次元配列
// idは一意、groupはクラス、scoreが点数
$tajigen_data = array(
      '田中' => array(
          'id' => '001', 
          'group' => '2', 
          'score' => '60',
      ),
      '山田' => array(
          'id' => '002', 
          'group' => '2', 
          'score' => '85',
      ),
      '鈴木' => array(
          'id' => '003', 
          'group' => '2', 
          'score' => '55',
      ),
      '佐藤' => array(
          'id' => '004', 
          'group' => '2', 
          'score' => '72',
      ),
          '田島' => array(
          'id' => '005', 
          'group' => '1', 
          'score' => '63',
      ),
      '山村' => array(
          'id' => '006', 
          'group' => '1', 
          'score' => '88',
      ),
      '鈴元' => array(
          'id' => '007', 
          'group' => '1', 
          'score' => '49',
      ),
      '安藤' => array(
          'id' => '008', 
          'group' => '1', 
          'score' => '75',
      ),
      '山元' => array(
          'id' => '009', 
          'group' => '3', 
          'score' => '58',
      ),
      '鈴山' => array(
          'id' => '010', 
          'group' => '3', 
          'score' => '99',
      ),
      '安元' => array(
          'id' => '011', 
          'group' => '3', 
          'score' => '65',
      )
    );

こういう感じのやつ。 array_multisortっていうのが使えそうだな〜とQiitaを見ててあたりをつけたけど、

qiita.com

つまり

// 多次元配列のあるkeyの値でソートする
//例えばgroupでソートすると
array_multisort(array_column($tajigen_data, 'group'), SORT_ASC, $tajigen_data);
var_dump($tajigen_data);

みたいな感じ。 それだと昇順にはできても、組の括りを保ったまま、スコア降順にできるのか????って思ったんだけど こうするとできる。

foreach ($tajigen_data as $key => $row) {
    $group[$key] => $row['group'];
    $score[$key] => $row['score'];
}
array_multisort($group , SORT_ASC, $score, SORT_DESC, $tajigen_data);
var_dump($tajigen_data);

array_multisortの引数に二つのソート条件を入れる。そんで、優先順位(引数の順番)をグループ優先にすると。 は???って感じなんだけど、要は ・引数の順番で優先順位がある ・array_multisortは引数複数指定できる ってわけで。

だけどもそもそもなんでforeachしなきゃだめなんだ?とかいう疑問が降って湧いてくるし、ていうか $keyとか$rowとかどっから出てきたんだよという気持ちで理解に苦しむので、 ちゃんと理解できるように読み解くことにした(結果phpの事なんもわかってなかったので、復習を兼ねて、次の記事でおさらいするぞ!)

今週。。

今週先輩がインフルになってしまってめちゃくちゃ破茶滅茶やること多くて、なんやかんや言いつつ先輩に甘えていたことが腹立たしく、その気持ちを忘れないようにこうして残しておこうと思う。
いやでも体調管理というか、先輩頼むから体調悪いときは帰って家に、、、、、お願いだから、、、、飲み会に出るな、、、

・体調悪いときは早めに休む(結果その方が影響なかったりする)
・休んでも大丈夫な体制を意識(属人化しない)

これを毎日唱えよう

比較演算子の順番について

以上、以下を表す比較演算子で気を付けること

mozilaのリファレンス(https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Comparison_Operators

if (cnt === 0) {
        $(target).text("あああ");
} else if (cnt =< 21) {
        if (hoge === "A") {
            $(target).text(cnt + "いいい");
        } else {
            $(target).text(cnt + "ううう");
        }
    } else {
        $(target).text(cnt + "えええ");
    }
}

どこかが間違ってる。

if (cnt === 0) {
        $(target).text("あああ");
} else if (cnt <= 21) {
        if (hoge === "A") {
            $(target).text(cnt + "いいい");
        } else {
            $(target).text(cnt + "ううう");
        }
    } else {
        $(target).text(cnt + "えええ");
    }
}

以下は<=で表す。 <、=の順番が変わると動かない。 値をみる処理の順番として、"より小さい"または"等しい"(以下) (<=)とみるので、先に"等しい"を持ってくると"より小さい"という部分が拾えないのではないかと推測した。 演算子の優先順位 - JavaScript | MDN

めかぶについて調べた

MeCab(めかぶ)について

MeCabとは

MeCab京都大学情報学研究科−日本電信電話株式会社コミュニケーション科学基礎研究所 共同研究ユニットプロジェクトを通じて開発されたオープンソース 形態素解析エンジンです。
http://taku910.github.io/mecab/) より引用
クックパッド開発者ブログによるめかぶの仕組み解説(http://techlife.cookpad.com/entry/2016/05/11/170000
納豆めかぶで修造語録の頻出ワードを解析 (http://vsanna.sakura.ne.jp/wp/2015/02/natto_mecab/) なんか楽しそう。

形態素解析とは

ざっくり…日本語の文章を、形態素(言語で意味を持つ最小単位)に分割する技術。
何に使うか…かな漢字変換検索エンジン予測変換等。
何でできるか…MecabChaSen、JUMAN、KAKASI等。

インストール手順

環境:Windows10
http://taku910.github.io/mecab/) を見ながら進める。

①ダウンロード

上記サイトのまんなかあたり[ダウンロード]のBinary package for MS-Windows、[mecab-0.996.exe:ダウンロード]をクリック。
文字コードutf-8。辞書を作ると言われるので作ってもらう。10秒くらいで完了する。
これで完了。

とりあえず使ってみる

が、文字コードutf-8にしたので公式サイトのとりあえず解析は使えない。

% mecab
すもももももももものうち
すもももももももものうち        險伜捷,荳闊ャ,*,*,*,*,*
EOS

(Shift-JISでインストールすると使える。)

utf8で使ってみる

http://handsrecs2nd.seesaa.net/article/140090025.html) を参考に動作確認を行う。

①ファイルの作成

ファイル名:in.txt
文字コードUTF-8
ファイルの中身:吾輩は猫である。名前はまだない。
場所:デスクトップとかやりやすいところ

※同じく出力用のout.txtも作っておく(設定は同じ)。

コマンドプロンプトで以下を入力
"C:\Program Files (x86)\MeCab\bin\mecab.exe"  C:\Users\XXX\Desktop\in.txt -o  C:\Users\XXX\Desktop\out.txt

環境変数いじるのがめんどくさいのでフルパスで全部書いた。

③結果

(out.txtの中に作られている)

吾輩   名詞,代名詞,一般,*,*,*,吾輩,ワガハイ,ワガハイ
は 助詞,係助詞,*,*,*,*,は,ハ,ワ
猫 名詞,一般,*,*,*,*,猫,ネコ,ネコ
で 助動詞,*,*,*,特殊・ダ,連用形,だ,デ,デ
ある  助動詞,*,*,*,五段・ラ行アル,基本形,ある,アル,アル
。 記号,句点,*,*,*,*,。,。,。
名前  名詞,一般,*,*,*,*,名前,ナマエ,ナマエ
は 助詞,係助詞,*,*,*,*,は,ハ,ワ
まだ  副詞,助詞類接続,*,*,*,*,まだ,マダ,マダ
ない  形容詞,自立,*,*,形容詞・アウオ段,基本形,ない,ナイ,ナイ
。 記号,句点,*,*,*,*,。,。,。
EOS

すごい。

そのた(ついで)

自分の日報の頻出ワード検索をする。(今度)

めかぶの由来は開発されたかたがめかぶ好きだかららしいです。

gulpを触ってみよう【旧】

gulpとは

スクランナー。あれやってこれやってというタスクを登録し、一気にやってもらうやつ。フロントエンド用。似たようなものにGruntがある。
ちなみもう脱gulpな動きもある
http://qiita.com/chuck0523/items/dafdbd19c12efd40e2de
らしいのだけど、とりあえずやってみようというところで、gulpを導入する。

gulpの導入

Node.jsのインストール

windowsを想定。 公式サイト(https://nodejs.org/en/ )から最新版のNodeをいれる。 インストールができたらターミナルで以下コマンドを入力しバージョンが表示されるか確認。

>node -v
v0.12.6

gulpのグローバルインストール

PCのどこでも使えるようにグローバルでインストール。ターミナル開いてすぐのとこで以下コマンドを入れる。

>npm install --global gulp-cli
>gulp -v

※もし過去にgulpを入れたことが有ったら、衝突を防ぐため(npm rm –global gulp)と入力して一旦gulpを削除すること。

gulp使用フォルダの作成

gulpを実際に使用したいフォルダを作成する。(作成したフォルダにhtmlやcssをいれることになる。既にあるフォルダにいれるのなら、そのプロジェクトのルートディレクトリに入れるといいと思う。)以下このフォルダのことをプロジェクトフォルダとする。

package.jsonの作成

プラグインの定義とかを記入するpackage.jsonを作成する。 ターミナルでgulpを使用したいプロジェクトフォルダへ移動し、以下コマンドを記入。

>npm init

※なんか沢山設定値を聞かれるけど全部空欄でもいいらしいので-yオプションを付けて質問回避してもいいのでは。 コマンド入力後にプロジェクトフォルダを開くとpackage.jsonができているはず。

gulpのローカルインストール

プロジェクトフォルダへ移動し、以下コマンドを入力。

>npm install --save-dev gulp

インストール後、プロジェクトフォルダ直下にgulpfile.jsというjsファイルを作成し、以下を記述。

//plug-in
var gulp = require('gulp');

プラグインのインストール

通常、プラグインのインストールとアンインストールは以下コマンドで行う。

// プラグインのインストール
npm install プラグイン名 --save-dev
 
// プラグインのアンインストール
npm uninstall プラグイン名 --save-dev

複数プラグインをまとめて一括とかもできる(調べたらわかる)
今回は
cssを圧縮するプラグイン (ミニファイ) をインストールする。(随時更新)

gulp-minify-cssのインストール

以下コマンドを入力。

npm install gulp-minify-css --save-dev

以下をgulpfile.jsに追記。

//CSS圧縮
gulp.task('minify-css', function() { //minify-cssがタスク名
  gulp.src("css/*.css") //対象ファイル(*はすべてという意味)
    .pipe(minifycss())
    .pipe(gulp.dest('dist/css/'));
});

ちなみに現在のプロジェクトフォルダはこんな感じ

ディレクトリ構成例(■はディレクトリ)
■mysite----
 index.html
 package.json
   gulpfile.js
   ■node_modules 
 ■css----
  mystyle.css
 ■js----
  myscript.js

使ってみる

gulpに登録したタスクを実行してみる。タスコの実行は、「gulp タスク名」でできる。 以下をターミナルで入力。

gulp minify-css

実行が終わると、プロジェクトフォルダにdistフォルダができていて、その中に圧縮されたファイルがある。やったー。

追記:既にかなり古い内容となってしまっていたため、書き直し中。