CSS Modulesのベストプラクティスを探る #scripty06

1.2K Views

September 14, 16

スライド概要

2016/9/14の勉強会にて発表された資料です。

SCRIPTY#6 ~フロントエンド紳士・淑女のための勉強会~
http://scripty.connpass.com/event/38935/

profile-image

2023年10月からSpeaker Deckに移行しました。最新情報はこちらをご覧ください。 https://speakerdeck.com/lycorptech_jp

シェア

またはPlayer版

埋め込む »CMSなどでJSが使えない場合

(ダウンロード不可)

関連スライド

各ページのテキスト
1.

CSS Modules の ベストプラクティスを探る ヤフー株式会社 メディア・マーケティングソリューションズグループマーケティングソリューションズカンパニー プロモーション広告開発本部マーケッターPF開発部 UIエンジニアリング 柴田 和祈 / @shibe97

2.

柴田 和祈 @shibe97 デザイナー / フロントエンドエンジニア Yahoo! JAPANの 広告入稿管理ツールの フロントエンドを担当しています。 子育てに悪戦苦闘中。 Copyright (C) 2016 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止

3.

CSSの問題点 ・グローバルなスコープ ・BEM等の手法によるclass名の冗長さ Copyright (C) 2016 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止

4.

React: CSS in JS Christopher "vjeux" Chedeau I'm Christopher Chedeau, working at Facebook in the front-end infrastructure team and among other things helping build React

5.
[beta]
// Thumbnail.css.js
export default {
image : {
borderRadius : '3px'
}
}
// Thumbnail.js
import styles from './Thumbnail.css.js';
render() {
return (<img style={styles.image} />);
}
Copyright (C) 2016 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止
6.

CSS in JS ・JSのオブジェクトとしてstyleを用意し、 HTMLのインラインstyle属性に挿入する ・JSファイルとしてCSSを管理するため、 ローカルスコープとなる Copyright (C) 2016 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止

7.

CSS in JS のダメなところ Copyright (C) 2016 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止

8.

・classの重ねがけをするのにオブジェクトの マージが必要(これを好む人もいる?) ・セレクタの優先度もないので後からマージ したもの勝ち ・擬似要素や :hover などが使えない Copyright (C) 2016 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止

9.

そこで、CSS Modules Copyright (C) 2016 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止

10.
[beta]
// Thumbnail.css
.image {
border-radius : 3px;
}
// Thumbnail.js
import styles from './Thumbnail.css';
render() {
return (<img className= {styles.image} />);
}
Copyright (C) 2016 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止
11.

CSS Modules ・cssファイルをJSにimportする ・擬似要素や :hover を使うことができる ・プラグインで記法をカスタマイズできる Copyright (C) 2016 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止

12.

内部では何が起こっているのか Copyright (C) 2016 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止

13.

内部的な動き ・webpackのcss-loaderによって最終的に HTMLの<head>タグ内の<style>としてインライン挿入される ・セレクタ名がBase64変換されるため、他とセレクタと被りを 心配する必要がなくなる ・webpack.config.jsで以下のように形式を指定することもできる [ファイル名]__[クラス名]__[ランダム値] Copyright (C) 2016 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止

14.
[beta]
// Thumbnail.css
.image {
border-radius : 3px;
}
// Thumbnail.js
import styles from './Thumbnail.css';
render() {
return (<img className= {styles.image} />);
}
Copyright (C) 2016 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止
15.
[beta]
// HTMLの<head>タグ内
.Thumbnail__image__1z6i8 {
border-radius : 3px;
}
// HTMLの<body>タグ内の該当箇所
<img class="Thumbnail__image__1z6i8" />
Copyright (C) 2016 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止
16.

BEM記法は使える? Copyright (C) 2016 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止

17.

BEMとは ・Block (親)、 Element (子)、 Modifier (状態) を 組み合わせて行うCSSの設計思想 ・壊れにくいCSS設計として発案されたもの Copyright (C) 2016 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止

18.

BEMとは <div class="block"> <div class="block__element"></div> <div class="block__element block__element--modifier"></div> </div> <div class="block block--modifier"> <div class="block__element"></div> </div> Copyright (C) 2016 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止

19.

// Nav.scss .Nav { display: flex; &__item { width: 100px; &--rounded { border-radius: 3px; } } } // Nav.css .Nav { display: flex; } .Nav__item { width: 100px; } .Nav__item--rounded { border-radius: 3px; } Copyright (C) 2016 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止

20.

一方、CSS Modulesでは Copyright (C) 2016 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止

21.

ファイル名__クラス名__ランダム値 Copyright (C) 2016 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止

22.
[beta]
// Nav.css
.Nav {
display: flex;
&__item {
width: 100px;
&--rounded {
border-radius: 3px;
}
}
}
// <head>タグ内
.Nav__Nav__1GXYJ { display: flex; }
.Nav__Nav__item__2H3QS { width: 100px; }
.Nav__Nav__item--rounded__BwfvB { border-radius: 3px; }
Copyright (C) 2016 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止
23.

ファイル名とBlock名が被って 冗長なので… Copyright (C) 2016 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止

24.

クラス名__ランダム値 Copyright (C) 2016 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止

25.
[beta]
// Nav.css
.Nav {
display: flex;
&__item {
width: 100px;
&--rounded {
border-radius: 3px;
}
}
}
// <head>タグ内
.Nav__1GXYJ { display: flex; }
.Nav__item__2H3QS { width: 100px; }
.Nav__item__rounded__BwfvB { border-radius: 3px; }
Copyright (C) 2016 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止
26.

しかし… Copyright (C) 2016 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止

27.
[beta]
import styles from './styles/nav.css';
render() {
return (
<ul className={styles.Nav}>
<li className={styles.Nav__item}>hoge</li>
<li className={styles.Nav__item--rounded}>fuga</li>
</ul>
);
}
Syntax Error
Copyright (C) 2016 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止
28.

JSではハイフンを 変数名として使えない Copyright (C) 2016 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止

29.

ならばmodifierをアンスコに、 ランダム値をハイフンにしてみる Copyright (C) 2016 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止

30.
[beta]
import styles from './styles/nav.css';
render() {
return (
<ul className={styles.Nav}>
<li className={styles.Nav__item}>hoge</li>
<li className={styles.Nav__item__rounded}>fuga</li>
</ul>
);
}
Compiled successfully!
Copyright (C) 2016 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止
31.

さらに Copyright (C) 2016 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止

32.

import styles from 'nav.css' ↓ import nav from 'nav.css' Copyright (C) 2016 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止

33.
[beta]
import nav from './styles/nav.css';
render() {
return (
<ul className={nav.Nav}>
<li className={nav.Nav__item}>hoge</li>
<li className={nav.Nav__item__rounded}>fuga</li>
</ul>
);
}
Copyright (C) 2016 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止
34.

nav.Navが冗長 Copyright (C) 2016 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止

35.

Blockをなくす Copyright (C) 2016 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止

36.
[beta]
// Nav.css
.Nav {
display: flex;
&__item {
width: 100px;
&__rounded {
border-radius: 3px;
}
}
}
// <head>タグ内
.Nav--1GXYJ { display: flex; }
.Nav__item--2H3QS { width: 100px; }
.Nav__item__rounded--BwfvB { border-radius: 3px; }
Copyright (C) 2016 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止
37.
[beta]
// Nav.css
.wrapper {
display: flex;
}
.item {
width: 100px;
&__rounded {
border-radius: 3px;
}
}
// <head>タグ内
.wrapper--1GXYJ { display: flex; }
.item--2H3QS { width: 100px; }
.item__rounded--BwfvB { border-radius: 3px; }
Copyright (C) 2016 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止
38.
[beta]
import nav from './styles/nav.css';
render() {
return (
<ul className={nav.wrapper}>
<li className={nav.item}>hoge</li>
<li className={nav.item__rounded}>fuga</li>
</ul>
);
}
Copyright (C) 2016 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止
39.

だいぶスッキリ!! Copyright (C) 2016 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止

40.

ディレクトリ構成について Copyright (C) 2016 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止

41.

その1. コンポーネントの隣にCSSを置く Copyright (C) 2016 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止

42.

components App.js Modal Alert.js Submit.js Copyright (C) 2016 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止

43.

components App.js Modal Alert.js Alert.css Submit.js Submit.css Copyright (C) 2016 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止

44.

AlertModal タイトル テキストテキストテキストテキスト テキストテキスト SubmitModal タイトル テキストテキストテキストテキスト テキストテキスト 送信 キャンセル Copyright (C) 2016 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止

45.

それぞれCSSを用意してしまうと 冗長な部分が出てくる Copyright (C) 2016 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止

46.

共通部分を別CSSに切り出してみる Copyright (C) 2016 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止

47.

components App.js Modal Alert.js Alert.css Submit.js Submit.css Container.css Copyright (C) 2016 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止

48.

Alert.js / Submit.js 両方から 読み込むのもアリだけど… Copyright (C) 2016 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止

49.

components App.js Modal Alert.js Alert.css Submit.js Submit.css Container.js Container.css Copyright (C) 2016 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止

50.

CSSが共通化できるということは コンポーネントも共通化できるはず Copyright (C) 2016 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止

51.

なぜならどちらもViewだから Copyright (C) 2016 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止

52.

その2. コンポーネントと同じ階層構造の ディレクトリを作る Copyright (C) 2016 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止

53.

components App.js Modal Alert.js Submit.js styles App.css Modal Alert.css Submit.css Copyright (C) 2016 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止

54.

・JSからimportする際に相対パスをたどるのが大変 ・同階層のパターンと比べて、融通は利きやすい Copyright (C) 2016 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止

55.

好きな方をどうぞw Copyright (C) 2016 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止

56.

まとめ ・CSS ModulesでBEMの良さを活かすには、 [クラス名]--[ランダム値]形式で出力が良さそう ・CSSの記法はBEMのBを取ったEMっぽいやつが 良さそう ・ディレクトリ階層はどっちでも良さそう Copyright (C) 2016 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止

57.

Thanks :) @shibe97 Copyright (C) 2016 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止