好きなだけかりんとうを食べる人生

フロントエンドとかデザインとかバックエンドとか浅く広く。社会人3年目のうぇぶでぃれくたーです。

【EC-CUBE3.x】ログイン後のリダイレクト周りを制御する

最近よくEC-CUBEを触るようになったのでメモ代わりに。
ほんとはRiotとRailsとSwift触りたいけど、これはこれで楽しい。

ケース

  • ログイン前にカートに商品を追加する
  • 追加した状態でログインする
  • ログイン後のリダイレクト先をカートに変更したい
  • (通常のログイン後のリダイレクト先はトップのままでいい)

実装手順

  • カートからログインページに遷移する際、クエリ文字列に rd=‘cart’ を指定する
  • クエリ文字列に rd=‘cart’ が含まれている場合、twig側で input[type=‘hidden’] を追加し、ログインと同時にPOSTする
  • ログイン成功後に DefaultAuthenticationSuccessHandler による処理を挟むようにする
  • DefaultAuthenticationSuccessHandleronAuthenticationSuccess メソッド内に条件分岐によるリダイレクト処理を挟む

流れとしてはこんな感じ。

ソースコード

カートからログインページに遷移する際、クエリ文字列に rd=‘cart’ を指定する

src/Eccube/Controller/ShoppingController.php

public function index(Application $app, Request $request) {
    // 略
    if (is_null($Customer)) {
        $params = array('rd' => 'cart');
        $url = $app['url_generator']->generate('shopping_login', $params); // クエリ文字列用の配列を渡せばOK
        return $app->redirect($url);

クエリ文字列に rd=‘cart’ が含まれている場合、twig側で input[type=‘hidden’] を追加し、ログインと同時にPOSTする

app/template/default/Shopping/login.twig

{% if rd == 'cart' %}
    <input type="hidden" name="rd" value="cart">
{% endif  %}

src/Eccube/Controller/ShoppingController.php

public function login(Application $app, Request $request) {
    // 略
    if ($request->query->get('rd') == 'cart') {
        $rd = 'cart';
    }

    return $app->render('Shopping/login.twig', array(
        'error' => $app['security.last_error']($request),
        'form' => $form->createView(),
        'rd' => $rd // twig内で参照できるように渡す
    ));
}

ログイン成功後に DefaultAuthenticationSuccessHandler による処理を挟むようにする + DefaultAuthenticationSuccessHandleronAuthenticationSuccess メソッド内に条件分岐によるリダイレクト処理を挟む

src/Eccube/Application.php

$this['security.authentication.success_handler.customer'] = $this->share(function ()  {
    $handler = new \Eccube\Security\DefaultAuthenticationSuccessHandler(
        $this,
        $this['security.http_utils'],
        $this['security.firewalls']['customer']['form']
    );
    $handler->setProviderKey('customer');

    return $handler;
});

↑を追記する

src/Eccube/Security/DefaultAuthenticationSuccessHandler.php

<?php

namespace Eccube\Security;

use Eccube\Application;
use Symfony\Component\Security\Http\Authentication\DefaultAuthenticationSuccessHandler as BaseDefaultAuthenticationSuccessHandler;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Http\HttpUtils;

class DefaultAuthenticationSuccessHandler extends BaseDefaultAuthenticationSuccessHandler
{
    /**
     * @var Application
     */
    private $app;

    public function __construct(Application $app, HttpUtils $httpUtils, array $options = array())
    {
        parent::__construct($httpUtils, $options);
        $this->app = $app;
    }

    public function onAuthenticationSuccess( Request $request, TokenInterface $token)
    {
        // rdがcartの場合、カートからのログインなのでカートにリダイレクトさせる
        if ($request->request->get('rd') == 'cart') {
          return $this->httpUtils->createRedirectResponse($request, '/cart');
        }
        return parent::onAuthenticationSuccess($request, $token);
    }
}

↑を新しく作る

参考

EC-CUBE3カスタマイズ - ユーザーがログイン成功/失敗したときにプログラムを実行する方法

おわりに

ちゃんとsymfonyとかsilexのドキュメント読むと色々よしなに対応してくれてるんだなーと実感した。

単純にログイン後のリダイレクト先を一律変更するだけなら、
/src/Eccube/Application.phpinitSecurity() 内で宣言している
$app[‘security.firewalls’] 辺りをいじればいけると思う。 (試してないので保証はしない)

手探り感ぱないのは否めないし、もっと良い書き方とかありそう。

setTimeout()メソッドのひみつ

こんばんは。 GJ部おもしろいんじゃあ^〜

setTimeout()とは?

setTimeout()はご存知の通り、引数に指定した関数を遅延して実行するメソッドです。

setTimeout(function() {
  console.log("ほげ");
}, 1000);

※今回はサンプルなのでclearTimeout()でタイマー処理を解除していませんが、場合によってはsetTimeout()メソッドが内部の関数を参照し続けることによってgcの対象にならないケースもあります(=クロージャ)。ちゃんとclearしようね。

そんなsetTimeoutですが、web上でサンプルコードを漁っていると時々このようなコードを見かけます。

setTimeout(function() {
  // 処理
}, 0);

setTimeout()の注意点

普通に考えればsetTimeoutが評価された瞬間に内部の処理が実行されますが、 例えば以下のようなケースだと、

var hoge = function() {
    setTimeout(function() {
      console.log("GJ部");
    }, 0);
}
hoge();
console.log("おもしろいんじゃあ^〜");
"おもしろいんじゃあ^〜"
"GJ部"

このように出力されます。 みんな大好きサイ本によると、

setTimeout() を使った便利なテクニックの1つに、0 秒後に関数が呼び出されるというものがある。 このような形式で setTimeout() を呼び出すと、イベントハンドラの実行が完了し、ドキュメントの更新状態が終了した時点で、 指定した関数が呼び出される。ドキュメントコンテンツを取得したり、変更したりするイベントハンドラはこのテクニックを使って ドキュメントが安定した状態になるまでコードの実行を遅らせる必要がある。

とあります。 つまり、関数を代入したhogeの評価が終わるまでsetTimeoutの内部関数は呼び出されないんですね。

まとめ

setTimeoutの第二引数に0msを指定する=関数を即時実行するというわけではないんですね。 つまり、setTimeout()を利用することによって、DOMを構築したりイベントを実行した後に処理を実行することができるということでしょうか。色々試してみようと思います。

追記

ちなみにsetTimeout()の第二引数に0msを指定しても厳密には0msで処理が実行されるわけではなく、ブラウザ毎に最小指定可能引数が決まっています(chromeやffは4msとかだった気がする)。 リサイズ関連のメソッドでもsetTimeoutを使った便利なパターンを見つけたので、今度記事にしようと思います。

2015年なにしようかね

あけましておめでとう ございました。

2014年はどんな年だったか

前半はあんまり覚えてません。 2014年後半はひたすらUI考えてデザイン組んでました。
自分がフロントエンドエンジニアだってことを忘れることがあったくらい(; ・`ω・´)

もちろんコード書いたりもしたんですが、
どっちかというと設計メインだったので、
細かい部分でこういうことができるようになった!とかそういう実感はないです。

良かった点

スキルアップ

ひたすらUIとCSSの設計ばっかりやってたので、

  • UX~UIまでの一貫した設計
  • (フロントエンドが)実装しやすいデザイン構築
  • 運用を考慮したCSS設計

この辺りに関しては大分理解が深まりました(もちろんまだまだですが)。

新しい出会い

去年からインターンに加えて、新しくバイトや個人での受託のお仕事を始めたのですが、
どのコミュニティもとても刺激的でした。

反省点

なんだかんだ色々やろうと思ったけど、結局できてない

バックエンドやネイティブやりたい!とは思っていたものの結局できず仕舞い…
フロントもAngularとかBackboneやりたいと思いつつ…でした。

体調管理がう◯こ

しょっちゅう体調を崩して色んな方にご迷惑をお掛けしました。

2015年どうしましょ

なんでもとりあえずやってみる

やりたいと思ったことはまずやってから考えてみます。
バックエンドもネイティブもデザインも。

(技術的に)実装可能な領域を増やす

フロント→フルスタック
正月からずっとSQL書いてるけど早速効果を実感。
やれることが増えるってたのしい!

記録を残す習慣づくり

技術ブログ・日記 →書く(アウトプットする)機会を増やすことでインプットを更に効率的に。

スケジュール・タスク管理の徹底

月初めと週初め。

体づくり

不定期で行っている水泳を習慣づけようかと。
それから食べ物にも気をつけます。はじめようお弁当生活。

本業(P)

  • 本家
    今月の給料入ったらBD一気買い。 10thは…うーんがんばろう。
  • デレ
    肇フロント揃ったのでモチベだだ下がり…
    クオリティ次第ですがマラソンほぼ決定です。
  • ミリ
    最近ミリのモチベが異常。
    まずはミリ2ndに参戦したいです(初ライブ)。
    はやくLTPとLTH全部揃えたいな〜〜。
    とりあえず12月末を底まで回したのでシリアル14枚で臨みます。

おしまい。

【SQL】バックエンドド素人によるMySQL及びSQLメモ

あけましておめでとうございます。

接続

mysql -u username -p dbname;

接続解除

exit

データベースの追加

CREATE DATABASE dbname;

データベースの確認

SHOW DATABASES;

データベースの削除

DROP DATABASE dbname;

ユーザーの設定

grant all on blog_app.* to dbuser@localhost identified by '設定したいパスワード';

データベースの選択

USE dbname;

テーブルを追加

CREATE TABLE tablename(
    fname type restrict option,
    fname type
);
CREATE TABLE hoge(
    id INT PRIMARY KEY NOT NULL AUTO_INCREMENT,
    name VARCHAR(255) DEFAULT 'noname',
    password VARCHAR(15) NOT NULL UNIQUE 
);

hogeテーブルを生成、 フィールド名はそれぞれ、

id: 数字、主キー、NULL不可、自動採番有効 name: 文字列(256バイト)、デフォルト値「noname」 password: 文字列(16バイト)、NULL不可、一意性制約

ということになる

テーブルの確認

SHOW TABLES;

テーブルの削除

DROP TABLE tablename;

フィールドの挿入

INSERT INTO tname SET fname=VALUE, fname2=VALUE2;
INSERT INTO dbname.tname (fname, fname2) VALUES(VALUE, VALUE2);

フィールド一覧を表示する

SELECT * FROM tname;

データを変更する

UPDATE tname fname=VALUE WHERE 条件文;

※WHEREを省略すると「テーブル内にある全てのデータ」が対象になる

データを削除する

DELETE FROM tname WHERE 条件文;

※テーブル内にある条件文に一致するレコードを削除する

特定のフィールドを検索する

SELECT fname, fname2 FROM tname WHERE 条件文;

テーブルの構造を変更する

ALTER TABLE tname ADD fname type option 条件文;
ALTER TABLE my_items ADD maker_id INT NOT NULL AFTER id;

※ALTERはパターンが非常に多い(主キー追加・AI設定など)ので都度SQL文をチェックする

降順に並べる

SELECT * FROM tname ORDER BY fname DESC;

テーブルの構成を調べる

desc tname

おわりに

descめっちゃつかう!べんり!!

【レポート】面白法人カヤックのフロントエンド「面白コーポレートサイト」の演出手法!Canvas、スクロール芸、ゲーミフィケーション、etc.

これに行ってきました。 カヤックのHTMLファイ部部長による講演です。

参考になった部分を挙げていきます。

面白法人がつくるコーポレートサイト

面白コーポレートとは

従来のポートレート

  • 大量のページ
  • 堅いイメージ

カヤックの作るコーポレート

面白コーポレートを制作する際に気をつけるポイント

こだわりを徹底する たとえばMutations STUDIOであればゲーム性

法人が持つ人格「法人格」を再定義 1つのコピーから掘り下げていく

コーポレートサイトは表現の可能性が広い 会社によってKPIは様々

ワード

Q(キュー)サイトに学ぶ、演出のためのHTML5

こちらは技術的なtipsです。

なめらかで味のある線

1:マウスの各座標の中点を算出 2:各座標をハンドルに、2次ベジェ曲線で結んでいく

DOMの上でもペンで書ける

1:ドラッグ中はsection内全面にcanvas要素が広がっている 2:mouseup時に、必要なサイズにcanvasをトリミング →ページが重くなるのを回避

円の中に動画を表示する

1:mousemoveでの座標群を配列に格納しておく 2:座標群を結んだパスで動画をclip() 3:描き終わって更新不要な線は削除

スクロールに連動して文字を描く

座標をまとめた配列を持っておき、スクロール値から計算して適切な数の点を結んで描画

手書きメッセージ

1:管理画面内に専用のツール(手書きメッセージ製造機)を作成 2:ドラッグで描くことで、座標を集めた配列を生成出来る 3:新しい社員が入社しても更新できる

☆やパックマンを描いた時の処理

☆を描くと背景が夜空になり、パックマンを描くとサイトを食べ尽くす 1:表側では使わない、星形の画像(認識用)を用意 2:簡易的に画像類似度を求めて検出

メモ

リアルタイムで描画していくコンテンツは目を惹きますね。キューのHPなどは特に。 この辺りはcanvasの独壇場なんじゃないかと思います。

コンテンツが何を求めているのか、メッセージ性を追求する点はどのサービスにおいても非常に大事だと考えさせられました。 堅実なイメージが求められるコンテンツなどでは利用する機会は少ないかもしれませんが、今後何かしらのサービスを作る際の引き出しとして覚えておきたいですね。

-スマホUI勉強会 iPhone6で変わるUI、変わらないUI-に行ってきました

更新

スピーカーさんのslideshareへのリンクを張らせていただきました。
まだアップされていない方も、アップされ次第追加する予定です。

dots.経由で参加してきました。

開催日

2014/10/20

会場

シナジーカフェ GMO Yours

余談なんですがこのシナジーカフェ、すんごい綺麗で広かったです…写真撮ればよかった。 社員の方も何人かカフェ内で打ち合わせされている様子が見受けられたのですが、なんかもう、仕事できるオーラがふわんふわん漂ってました…

所々メモの抜け漏れがあり、その辺りはスライドがweb上にアップされてから補完する予定です。

GMOインターネット 稲守貴久さん

テーマ:スマートフォンUIおさらい

スマートフォンの登場から現在に至るまで、どのようにデザイントレンドが変化していったのか、 という導入にふさわしいセッションでした。

  • スマートフォンのUIは踊り場に来ている
  • 設計と実装のギャップを埋める手法を考える
  • 今後モバイル向けサービス事業者はどう対応するか

まとめ

WebSig24/7 あくやんさん

テーマ:めんどくさがりなデザイナーのタッチデバイスUI攻略

スライドはこちら

デバイスの種類が増えたので、実際にどう手を動かして実務に落としこんでいくか、 といった点にフォーカスしたセッションでした。
具体性に富んでいて、明日からすぐに応用できそうな内容で非常に参考になりました。

タッチデバイスUI3つのポイント

画面内のスクリーン領域とコントロール部分を意識する

スクリーン領域:情報を表示する場所
コントロール部分:情報を操作する場所

  • コントロール部分:意識的に使う
  • スクリーン領域:無意識に訴えかける
  • レイアウトしたいパーツがどういう立ち位置にいるのかを考える
  • パーツごとの意識付け、サイズに左右され過ぎない

グリッドとマージンを統一させる

  • iOS: 8px,Android: 4px →この数字ってなんだったんでしょう…??
  • スペース間を統一することで世界観も統一させる

UIガイドラインはひと通り読んだら忘れる

  • 「誰にいつ、どんなときに使われるのかを考えていく」
  • ガイドラインを考えのベースに、ユーザーの考えを優先

フローチャート

  • あくやんさん考案のフローチャート
  • スライドアップ待ちです…写真撮ればよかった><
  • テンプレートをたくさん見て、モックをたくさん作ろうとおもいます!!

Yahoo UIデザイナー 宇野 雄さん

テーマ:Apple信者だったボクは気づくとiPhone嫌いになっていたんだが

スライドはこちら

テーマ通り、iPhone6 Plusを買ったけど後悔している宇野さんが、具体的にiPhone6 Plusのどの点が嫌いなのかについて発表されていました。
もちろん6 Plusの批判に留まらず、iOSAndroidデザインの比較から、デザイナーが今後どのようにデバイス対応していくべきかというお話も。
xCodeがpdf形式で画像を書き出せるということを知りませんでした…はずかしい…

iPhoneを嫌いになった5つの理由

  • 曲がる
  • 刻印が傾いている
  • デカい
  • じゃあどう対応するか?
  • アプリが対応していない
  • 持ちにくい

個人的には、

動作の起点を考える
例:Evernoteアプリ 大事な要素はハンバーガーボタンとかで隠しちゃダメ

日常生活で使ってみないとわからない
店頭や検証機はユーザー目線じゃない
どんなユーザーがどれだけ使っているのかを見極めて今後の対応を進める

ユーザーファーストのサービスを作るためには、まず自分が最高のユーザーになること

この部分が非常に感心させられました。

GREE UXデザインチームマネージャー 村越 悟さん

テーマ:いろいろな発表があったのでこれからのデザイン環境について考えてみた

「iOS8と新型iPhoneの発表があったけど、いまいちワクワクしない。」
そう感じた村越さんが、

  • キャッチコピーの変遷に見るApple
  • One Handed Modeを考える
  • これからのデザインで大切なこと

以上3つの観点から感じられたことをまとめて発表されたセッションでした。
キャッチコピーから掘り下げる視点は新鮮でしたが、確かに、

iPod

1000 songs in your pocket.

iPhone

Today, Apple is going to reinvent the phone.

iPhone6/6 Plus

bigger than bigger.

なんだろう…1番下のコレジャナイ感… 開発者として、ベンダーの意向は常に抑えるべきだと強く感じました。

ミクシィ(ノハナ) UXデザイナー 馬場 沙織さん

テーマ:次の5年のUIを考える

テーマの通り、既存のUIをどう構成していくかという内容ではありませんでした。
今後どのようにIoT(Internet of Things)が変化していくのか、そしてUI/UXデザイナーはその変化にどうやって適応していくか、といった点にフォーカスした発表でした。

デバイスの方向性

世界

  • スマホの出荷台数はPCの約3倍
  • タブレットも2015年内にPCを逆転すると予想される
  • ファブレットは2016年内の半分を占めると予測
  • Androidは84.7%

日本

技術革新の方向性

2020年のIoT(Internet of Things) 色んなデバイスがインターネットにつながる

GoogleAppleの方向性

2社とも、生活領域のプラットフォーマーを目指している

次の5年のUIの可能性

  • タイピングができない学生が増えた
  • PCで行っていたことをモバイルで行うことになる
    →タッチ・音声入力が中心
  • 文字だけではなく、音声やモーションなどのレスポンスが求められている?
  • IoTでつながった多種のデバイスと連携、データのやりとり
    →パーソナライズ、自動入出力
  • デザイン性が重視されている生活領域にテクノロジーが進出
    →デザインとテクノロジーが高度に統合
    →プラットフォームやデバイスを超えた統一された体験を可能にするためのルールとツールが必要

僕自身、変化し続ける目先のデバイス対応に精一杯になりがちなんですが、より広い視野を持って、先を見据えたコンテンツ制作に励むことが大切ですね。

まとめ

この後トークセッションや懇親会があったのですが所用のため泣く泣く離脱…(´;ω;`)ウッ
普段バイト先やインターン先でスマホのUI/UXについてお話したり聞いたり、という機会が中々無かったため、発表全てが新鮮に感じられました。
実はこういった勉強会に参加するのは初めてで、「学生だしデザイン全然ダメダメだし参加しても大丈夫なのかな…」と不安だらけだったのですが、逆に刺激受けまくりのやる気湧きまくり状態でした。
社会人になると会社内で技術的なコミュニティが完結してしまいそうなので、これからも積極的に参加していこうと思います。

とりあえず千里の道も…というわけで、まずは自分の好きなサイト・テンプレートを分析して模写するところからですね!
がんばろーーー!

理想的なCSSの設計について

ついこの間仕事でクソみたいなcss書いて修正時に死んだ経験を踏まえて、設計をしっかり勉強することに。

現行のCSSが持つ問題点

定義が全てグローバル扱い

スコープ?なにそれおいしいの?

<div class="alert-btn">
  <a href="#">送信する</a>
</div>
.alert-btn a {
  text-decoration: none;
}
a {
  text-decoration: underline; /* 詳細度の関係上、上書きされない */
  color: #fff; /* CSS見てから上書き余裕でした^^ */
}

HTMLへの依存度が高い

特に要素セレクタを使うと依存度が高くなり、破綻しやすくなる傾向にある。

<div class="sample">
  <h1>これはサンプル</h1>
</div>
.sample h1 {
  font-weight: bold;
}
h1 {
  font-size: 14px;
}

このケースにおいてhtmlの構造が以下のように修正された場合、

<div class="sample">
  <h2>はサンプル</h2>
</div>

.sample h1は適用されなくなるため、その都度cssを変更する必要が出てくる。 もし他のページで同じスタイルを適用していた場合は、その適用箇所にも変更の影響が出る。 サンプルの時点でかなりめんどくさいのに、これが規模の大きな案件だったらキツい。てか死ぬ。

修正した時の影響範囲が大きい

プロジェクトの規模にもよると思うけど、特に汎用的なクラスはヤバい。

エラー吐かない

これはプリプロセッサ使えば解決する(たぶん)。

これらの問題点を解決するために考案されたのが以下のOOCSSである。

OOCSS

Object Oriented CSS
略してOOCSS。オブジェクト指向CSS。 ↑で挙げたような問題点を解決し、保守性・再利用性・拡張性・予測のしやすさを高めるためのアプローチ。

すごい乱暴な言い方になるけど、ページ内に存在するパーツをパターン毎に組み上げて分割することで、ブロックを組み立てるようなニュアンスでコーディングする、といったイメージ。 ボタンなどの例がわかりやすいかもしれない。

<div class="btn primary">送信する</div>
.btn {
  /* ボタンとしての最低限の機能 */
}
.primary {
  /* スタイル */
}
.secondary {
  /* スタイル */
}

体感だけどオブジェクト指向言語→HTML,CSSの順で勉強してきた人に多い気がする。 コツは

  • 共通する根本的な機能を抜き出すこと
  • 場所に依存しない設計を心がけること

の2つ。

SMACSS

Scalable and Modular Architecture for CSS
略してSMACSS。 CSSの弱点である保守性やメンテナンス性を高めつつ、デザインを統一させることでユーザー体験を一貫させ、UXの向上を図る。
OOCSSを実現するスタイルガイドの一種。

具体的には、

  • Base
  • Layout
  • Module
  • State
  • Theme

の5つのカテゴリーにCSSを分割し、管理する。

Base

サイト全体におけるデフォルトスタイル。
ここでデザインの詳細部を実装することは避ける(デザインはModuleが担当する)。
normalize.cssを採用してるとこが多い気がする(体感)。
自分は今までcompassreset.css使ってたけどnormalize.cssに乗り換えようか検討中。
多分慣れの問題。

Layout

そのまんま。ページを構成するパーツのレイアウトはここに。
marginpositionなどはここに該当する。
具体的にはheaderとかfooterとかの配置はここに記述することになる。
headerもfooterもユニークな要素だからId使ってもいいけど、使うと詳細度の関係上大抵めんどくさくなるので個人的には非推奨。

.l-header {}
.l-footer {}

って感じでプレフィックス付けると管理しやすくなる。

Module

ページ内において再利用可能なパーツのこと。
ボタンだったりリストだったり、ページを構成するほとんどの要素がここに属する。
Layoutの項でheaderとfooterのレイアウト情報を記述したけど、ここではそれらのデザイン部分を記述する。
ここで大切なのは、再利用のしやすさ保守性の高さ

State

そのまんま、コンテンツの「状態」。
JavascriptでDOM操作する際に主に使用する。

.is-active {
  display: block;
}
.is-hidden {
  display: none;
}

こんな感じで書けばイメージしやすいと思う。

Theme

テーマ。
サービスによっては、ユーザーが色を自由に切り替えるものがあると思うけど、多分それ用(自分もよくわからない)。
Moduleの色をここに記述する人もいるみたいだけど、これは人によって大分扱いが違うみたい。
個人的には色はModule内でSassの変数を利用して一元管理したい。

OOCSSとの違い

最大の違いは、SMACSSにはクラス名の抽象度に対するアプローチ(命名規則)が備わっているということ。
OOCSSで挙げた例で、.primaryとか.secondaryっていうクラス名があったけど、これは抽象的過ぎてページ内で衝突する可能性が非常に高い。

だからSMACSSのModule内では、

<div class="btn btn-primary">送信する</div>

こんな形で記述する。

BEM

命名規則の設計方法のひとつ。

  • Block
  • Element
  • Modifier

の3つにコンポーネントを分解し、それぞれの役割に従って命名する。略してBEM。
(個人的に)CSSで1番難しいのが命名規則
BEMに従えば命名もすんなり終わるっちゃ終わるんだけど、やっぱりめんどくさい部分もある。
初見だとめっちゃ気持ち悪い。
.Block__Element--Modifierといった流れでクラスを命名するので、後述のマルチクラスと併用するとHTMLがとんでもないことになる。
また、BlockやElementによっては名前が2単語で構成されるケース(.page-titleとか)もあるけど、そういった場合は.page-title__heading--titleのようなかなり見通しの悪いクラス名になる恐れがある。

SMACSS+BEM導入時の疑問点

  • 階層が深くなった時の処理 →深くなる時点で設計が破綻している可能性がある ElementのElementをわざわざ書く必要はない? (参考:いまどきのCSS – OOCSSとかBEMとかSMACSSとか)

  • 無駄にコードが増えそう 例:1箇所でしか利用しないコードをモジュール化する

  • どのタイミングでネスト構造を利用すべきなのか →モジュール化、コンポーネント化がしっかりされていれば自然とネストはそれほど深くならない(はず)

  • HTML汚くなるよね… →これは多分cssの簡潔さとのトレードオフ

  • クラスだけだとJSのパフォーマンス落ちるべ →フックにId使えや

OOCSS,SMACSSの問題点

  • クラスがセマンティックでなくなる
    →クラス名が抽象的になり、コンテンツの中身と結びつきが弱くなる
  • クラス名が増える →HTMLが汚れる

シングルクラスとマルチクラス

シングルクラス

  • HTML:きれい
  • CSS:きれいじゃない
  • BEMとの相性:よい

マルチクラス

  • HTML:きれいじゃない
  • CSS:きれい
  • BEMとの相性:よくない Javascriptのフックとしても使いやすいので個人的にはこっちの方がすき

SMACSS + BEM = 最良解というわけではない

SMACSSとBEMを導入することで、オブジェクトごとにスタイルを管理できるようになるため、スタイルの衝突は減少する。 同時に保守性も向上する。

しかし、なんでもSMACSSやBEMでおk…というわけでもない。 例えばLPをコーディングする時にコーダーに求められるものは、

スピード>デザインの再現度>>>保守性

である。 こういうケースではスタイルガイドを導入することによって開発スピードが落ちる恐れがあり、メリットもそれほど受けられない。

SMACSSを厳格に守る必要はなくて、各自の開発スタイルに合わせて調整するのがベストっぽい?

個人的なcss設計時のルール(草案)

いいなーって思った部分を集めてみた。

  • マルチクラスを採用
  • JavaScript参照用のclassはいらない(マルチクラスを採用してるから)
  • 細かい微調整系
  • text-align: center;
  • margin-bottom: 5px;
    →これらはhelper.scssにぶちこんで利用する
  • モジュールには位置情報を記述しない(再利用性を高める)

一番大事なのは「どのガイドラインを使うか」ではなく、「ルールを決めて実装する」ということ。
「HTMLの構造に依存しない」っていう方針はAngularJSと通ずるものがあって、非常に勉強になった。
とはいえもっとコード組まないと見えてこないものもあるので、これからもこの辺りは意識して設計していきたい。

さいごに

この本めちゃめちゃ参考になりました。
Web制作者のためのCSS設計の教科書 モダンWeb開発に欠かせない「修正しやすいCSS」の設計手法