presentation-html-templating



presentation-html-templating

0 0


presentation-html-templating


On Github Takazudo / presentation-html-templating

HTMLテンプレートの設計

高津戸 壮 [@Takazudo]

自己紹介

言いたいこと

  • CSSをうまく書くのは難しい
  • そこにSassを使えばさらに難しくなる
  • 他の人はあなたの書いたCSSが理解できない
  • Sassが使われていたらもっと理解できない
  • CSSを書く上で難しい部分は設計
  • Sassはこれを解決してくれる道具ではない
  • Sassを使おうが使わまいがCSSを書く上で難しい部分は

どう設計するか

どう設計するか

ちゃんと考えて

Sassを活用する

  • OOCSS
  • BEM
  • SMACSS

OOCSS

OOCSSとは

  • Object Oriented CSS
  • Nicole Sullivan (Yahoo!)
  • オブジェクト指向っぽく考えて整理しよう
  • レゴみたいに組み合わせてページをつくろう

こういうのがダメ

#main h2 {
  ...
}
#main .contact .header h2 {
  ...
}
#sidebar h2 {
  ...
}
.somewhere .title h2 {
}

場所の名前に依存してスタイルを当てる

なぜダメか??

上書き合戦

コピー

詳細度

!important

ごちゃごちゃに & 容量増加

レゴみたいに考える

一つ一つの部品に名前をつける

/* heading module */

.heading {
  prop: val;
}

/* heading2 module */

.heading2 {
  prop: val;
}

/* heading3 module */

.heading3 {
  prop: val;
}
  .heading3 span {
    prop: val;
  }

レゴの部品: CSS Object

スキン

  • 共通項目を一つのモジュールに定義
  • バリエーションをスキンとして定義

プログラムでいう「継承」と近い概念

<span class="button">Button!!</span>
.button {
  font-size:1.5em;
  padding:.5em 2em .4em;
  border:3px solid #000;
  border-radius:10px;
}
<span class="button caution">Caution!!</span>
.caution {
  font-weight:bold;
  color:#fff;
  background:#FD3636;
  border-color:#BC2828;
}

マルチクラスで実装

<span class="button pdf">Download PDF!!</span>
.pdf {
  background:#ECE4AB;
  border-color:#D9D29E;
  padding-left:1.5em;
}
.pdf:before {
  content: '';
  display:inline-block;
  width:22px;
  height:22px;
  background:url(imgs/acrobat.png);
  vertical-align:-2px;
  margin:0 6px 0 0;
}
<span class="button play">Play sound!!</span>
.play {
  background:#C3E6EA;
  border-color:#AECDD0;
  padding-left:1.5em;
}
.play:before {
  content: '';
  display:inline-block;
  width:22px;
  height:22px;
  background:url(imgs/play.png);
  vertical-align:-2px;
  margin:0 6px 0 0;
}

OOCSSの教え

  • 行き当たりばったりだと破綻する
  • モジュール&スキン
  • ページはレゴの組み合わせみたいなものだ
  • スケールするサイトにはこのような設計思想が必要である

BEM

BEMとは

  • Yandex
  • 設計や実装の方法論のひとつ
  • クラス名の命名規則(厳格)
  • ツールを含めてBEMと言うこともある
  • Block
  • Element
  • Modifier

Block

ページを構成するパーツの単位

Element

Blockを構成するパーツの単位

Modifier

Block・Elementを変更する追加クラス

Block - Element - Modifier

BlockとElement

<section class="column"> ... </section>

<section class="column">
  <h1 class="column__head">About BEM</h1>
  <div class="column__body">
    <p class="column__p">The quick brown...</p>
    <p class="column__p">The quick brown...</p>
  </div>
</section>
.column {
  border:2px solid #000;
  border-radius:10px;
}
  .column__head {
    border-bottom:2px solid #000;
    padding:.8em 20px .7em;
    margin:0;
    font-size:1.4em;
  }
  .column__body {
    padding:1em 20px 0;
  }
    .column__p {
      margin:0;
      padding:0 0 1em;
    }

Modifier

<section class="column"> ... </section>
<section class="column column_state_disabled"> ... </section>
.column_state_disabled {
  opacity:.3;
}
<section class="column column_type_caution"> ... </section>
.column_type_caution {
  background:#EA3B3B;
}

Modifierの使いドコロ

  • JavaScript等で状態を変化させるとき
  • 一つのBlock(かElement)の変化したパターンを作りたいとき

クラス名ルール

  • BEM構造を表現するための区切り文字
  • 単語の区切りを表すための区切り文字

block__element

<section class="column">
  <h1 class="column__head">About BEM</h1>
  <div class="column__body">
    <p class="column__p">The quick brown...</p>
    <p class="column__p">The quick brown...</p>
  </div>
</section>

block_key_value

.column {
  opacity: 1;
}
.column_state_disabled {
  opacity: .3;
}

block__element_key_value

.graph__img {
  border: 2px solid #000;
}
.graph__img_type_important {
  border-color: red;
}

word-word-word...

.img-column {
  border:2px solid #000;
  border-radius:10px;
}
  .img-column__img-container {
    float:right;
    padding:0 0 1em 20px;
    width:134px;
  }

デメリット

  • ややこしい
  • クラス名長い

メリット

  • 設計思想/ルールの統一ができる
  • クラス名で構造を把握できる

BEMの教え

  • Block Element Modifierで考えるべし
  • 設計思想を統一すべし
  • 命名ルールを統一すべし

そうすればいろいろうまくいく

SMACSS

SMACSSとは

  • Scalable and Modular Architecture for CSS
  • スケールできてモジュールなCSS設計
  • Jonathan Snookがオススメする設計方法
  • カッチリした決まりというわけではない

SMACSSの考え方

CSSルールを次の5つに分けて考える

  • Base - ベースルール
  • Layout - レイアウトルール
  • Module - モジュールルール
  • State - 状態(ステート)ルール
  • Theme - テーマ

※テーマについては今回は省略

Base - ベースルール

サイトのデフォルトスタイルを定義する

  • Reset CSS / Normalize.css
  • +ベースとしたいスタイル

Eric Meyer Reset CSS

http://meyerweb.com/eric/tools/css/reset/

/* http://meyerweb.com/eric/tools/css/reset/ 
   v2.0 | 20110126
   License: none (public domain)
*/

html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed, 
figure, figcaption, footer, header, hgroup, 
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
    margin: 0;
    padding: 0;
    border: 0;
    font-size: 100%;
    font: inherit;
    vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure, 
footer, header, hgroup, menu, nav, section {
    display: block;
}
body {
    line-height: 1;
}
ol, ul {
    list-style: none;
}
blockquote, q {
    quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
    content: '';
    content: none;
}
table {
    border-collapse: collapse;
    border-spacing: 0;
}

Normalize.css

http://necolas.github.io/normalize.css/

/*! normalize.css v3.0.0 | MIT License | git.io/normalize */

/**
 * Remove default margin.
 */

body {
  margin: 0;
}

/* HTML5 display definitions
   ========================================================================== */

/**
 * Correct `block` display not defined in IE 8/9.
 */

article,
aside,
details,
figcaption,
figure,
footer,
header,
hgroup,
main,
nav,
section,
summary {
  display: block;
}

/**
 * 1. Correct `inline-block` display not defined in IE 8/9.
 * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.
 */

audio,
canvas,
progress,
video {
  display: inline-block; /* 1 */
  vertical-align: baseline; /* 2 */
}

/**
 * Prevent modern browsers from displaying `audio` without controls.
 * Remove excess height in iOS 5 devices.
 */

audio:not([controls]) {
  display: none;
  height: 0;
}

/**
 * Address `[hidden]` styling not present in IE 8/9.
 * Hide the `template` element in IE, Safari, and Firefox < 22.
 */

[hidden],
template {
  display: none;
}

/* Links
   ========================================================================== */

/**
 * Remove the gray background color from active links in IE 10.
 */

a {
  background: transparent;
}

/**
 * Improve readability when focused and also mouse hovered in all browsers.
 */

a:active,
a:hover {
  outline: 0;
}

...

+ベースとしたいスタイル

a { color: #00e; }
a:visited { color: #551a8b; }
a:hover { color: #06e; }
a:focus { outline: thin dotted; }

p {
  padding:0;
  margin:0 0 2em;
}

table {
  border-left: 1px solid #000;
  border-top: 1px solid #000;
}
th, td {
  border-right: 1px solid #000;
  border-bottom: 1px solid #000;
}

...

Layout - レイアウトルール

  • サイトレイアウトの枠組み
  • およびそれを調節するための仕組み
  • 段組
  • layout-XXXXX
  • l-XXXXX
<div id="all">
  <header id="header"> ... </header>
  <div id="body">
    <div id="sidebar"> ... </div>
    <main id="main"> ... </main>
  </div>
  <footer id="footer"> ... </footer>
</div>
<html class="l-flipped">
.l-flipped #sidebar {
  float: left;
  margin: 0 20px 0 0;
}
<html class="l-fixed">
.l-fixed #all {
  max-width:700px;
}
<div class="l-grid">
  <div class="l-grid-item"> ... </div>
  <div class="l-grid-item"> ... </div>
  <div class="l-grid-item"> ... </div>
</div>
.l-grid {
  ...
}
  .l-grid-item {
    ...
  }

Module - モジュールルール

  • レイアウトの中にモジュールを入れていく
  • OOCSS、BEMで解説したことと同じ
<section class="column">
  <h1 class="column-head">About SMACSS</h1>
  <div class="column-body">
    <p>The quick brown...</p>
    <p>The quick brown...</p>
  </div>
</section>
.column {
  border:2px solid #000;
  border-radius:10px;
}
  .column-head {
    border-bottom:2px solid #000;
    padding:.8em 20px .7em;
    margin:0;
    font-size:1.4em;
  }
  .column-body {
    padding:1em 20px 0;
  }
    .column-body > p {
      margin:0;
      padding:0 0 1em;
    }

サブクラス

<span class="button">Button!!</span>
<span class="button button-caution">Caution!!</span>
<span class="button button-pdf">Download PDF!!</span>
  • OOCSSの「スキン」は、SMACSSでは「サブクラス」
  • 実装方法もマルチクラス利用で同じ

State - 状態(ステート)ルール

  • BEMのModifierと同じ
<section class="column is-disabled"> ... </section>
.column.is-disabled {
  opacity:.3;
}

追加クラスで状態を表現

SMACCSの教え

  • Baseを作り
  • Layoutを作り
  • Moduleを積んでいけ
  • バリエーションはサブクラスで
  • 状態の変化はStateで

そう考えて設計するとうまくいくよ

http://smacss.com/

日本語版もあります

Sassをどう活かす?

@extend

<span class="button">Button!!</span>
.button {
  font-size:1.5em;
  padding:.5em 2em .4em;
  border:3px solid #000;
  border-radius:10px;
}

OOCSSでは……

<span class="button caution">Caution!!</span>
.caution {
  font-weight:bold;
  color:#fff;
  background:#FD3636;
  border-color:#BC2828;
}

スキン → マルチクラスで実装してた

BEMでは……

<span class="button button_type_caution">Caution!!</span>

Modifier → マルチクラス

SMACSSでは……

<span class="button button-caution">Caution!!</span>

サブクラス → マルチクラス

Sassなら……

<span class="button">Button!!</span>
<span class="button-caution">Caution!!</span>
.button {
  font-size:1.5em;
  padding:.5em 2em .4em;
  border:3px solid #000;
  border-radius:10px;
}

.button-caution {
  @extend .button;
  font-weight:bold;
  color:#fff;
  background:#FD3636;
  border-color:#BC2828;
}

@extendのスゴイ点

  • スキンのような概念を表現する方法がなかった
  • マルチクラスを利用するしかなかった
  • 見栄えの情報がHTMLに内包されていることに?
  • プリプロセッサの過程を経ることでその問題を解決

まとめ

  • 高速な開発が可能
  • プロジェクトの寿命を伸ばせる
  • チームによる実装を可能にできる
  • コードの再利用を可能にできる

by BEM

  • あーこの人の考えてること分かるわーと思われるCSSを書こう
  • 1ヶ月後の自分は既に他人である
  • モジュール一覧とかがあると、なお良い

宣伝

CodeGrid

  • ピクセルグリッドの技術情報配信サービス
  • フロントエンド周りの情報メイン
  • 月額840円
  • バックナンバーも全部読める

CSS関する過去配信シリーズ

  • SassとCSS設計
  • BEMによるフロントエンドの設計
  • SMACSSによるCSSの設計
  • RWDに効くCSSテクニック
  • 賢く使うStyleDocco導入ガイド
  • 生きたスタイルガイドのためのKSS
  • Compassで簡単、CSSスプライト作成

などなど

www.codegrid.net

以下ボツ

media
comment-lv1 comment-lv2 comment-lv3

<div class="media">
  <a href="#" class="img"><img src="..." alt=""></a>
  <div class="bd">
    <div class="txt">Hello...</div>
    <div class="info"><a href="#">@Takazudo</a> [2014/01/31]</div>
  </div>
</div>
<div class="media comment-lv1">
  ...
</div>
<div class="media comment-lv2">
  ...
</div>
<div class="media comment-lv3">
  ...
</div>

media

<div class="media">
  <a href="#" class="img"><img src="..." alt=""></a>
  <div class="bd">
    <div class="txt">Hello...</div>
    <div class="info"><a href="#">@Takazudo</a> [2014/01/31]</div>
  </div>
</div>
.media {
}
  .media > .img {
    float:left;
  }
    .media > .img img {
      border:4px solid #333;
    }
  .media > .bd {
    padding-left:10px;
    overflow:hidden;
    *zoom:1; /* ie */
  }
    .media > .bd > .txt{
    }
    .media > .bd > .info{
      font-size:.8em;
      padding:1em 0 0;
    }

comment-lv1

<div class="media comment-lv1">
  ...
</div>
.comment-lv1 {
  border-bottom:2px dashed #333;
  padding-bottom:1.5em;
  margin-bottom:1.5em;
}
  .comment-lv1 > .img img {
    width:80px;
    height:80px;
  }

comment-lv2

<div class="media comment-lv2">
  ...
</div>
.comment-lv2 {
  margin-top:1em;
  margin-bottom:0;
  padding-top:1em;
  padding-bottom:0;
  border-top:1px dashed #333;
}
  .comment-lv2 > .img img {
    width:50px;
    height:50px;
  }
  .comment-lv2 > .bd > .txt{
    font-size:.8em;
  }

comment-lv3

<div class="media comment-lv3">
  ...
</div>
.comment-lv3 {
  margin-top:1em;
  padding-top:1em;
  border-top:1px dashed #333;
}
  .comment-lv3 > .img img {
    width:50px;
    height:50px;
  }
  .comment-lv3 > .bd > .txt{
    font-size:.75em;
  }

BEM - Blockの入れ子

<section class="img-column">
  <h1 class="img-column__hd">About BEM</h1>
  <div class="img-column__bd">
    <div class="img-column__bd__img-container">
      ここにグラフが入る
    </div>
    <div class="img-column__bd__text">
      <p class="img-column__bd__text__p">The quick brown...</p>
      <p class="img-column__bd__text__p">The quick brown...</p>
    </div>
  </div>
</section>
<div class="graph">
  <div class="graph__hd">Sales chart</div>
  <div class="graph__bd">
    <img class="graph__bd__img" src="../common/imgs/graph.png" alt="">
  </div>
  <div class="graph__ft">The sales is so good...</div>
</div>
<section class="img-column">
  <h1 class="img-column__hd">About BEM</h1>
  <div class="img-column__bd">
    <div class="img-column__bd__img-container">
      <div class="graph">
        <div class="graph__hd">Sales chart</div>
        <div class="graph__bd">
          <img class="graph__bd__img" src="../common/imgs/graph.png" alt="">
        </div>
        <div class="graph__ft">The sales is so good...</div>
      </div>
    </div>
    <div class="img-column__bd__text">
      <p class="img-column__bd__text__p">The quick brown...</p>
      <p class="img-column__bd__text__p">The quick brown...</p>
    </div>
  </div>
</section>

Blockの入れ子

  • それぞれのBlockを別々につくる
  • 別のBlockを入れるElementを用意する
  • クラス名で全部スタイル当ててるので崩れたりしない

MindBEMding

  • CSS Wizardry - MindBEMding
  • mind-bending: ショッキングな、ドキッとさせる、圧倒的な、幻覚性の、精神に変調を起こさせる
  • もうちょっとだけ単純なやつ
  • 心はBEM
.block {}
.block__element {}
.block--modifier {}
.site-search {} /* Block */
.site-search__field {} /* Element */
.site-search--full {} /* Modifier */
.person {}
.person__hand {}
.person--female {}
.person--female__hand {}
.person__hand--left {}
.person {}
.hand {}
.female {}
.female-hand {}
.left-hand {}