SlideShare a Scribd company logo
秋のJavaScript 祭in mixi
React で CSS カプセル化の可能性を考える
Yutaro Miyazaki (@vwxyutarooo)
ニート
フリーランス(Web制作)
会社員(フロントエンド)
React で CSS カプセル化の可能性を考える
React で CSS カプセル化の可能性を考える
React で CSS カプセル化の可能性を考える
React で CSS カプセル化の可能性を考える
React
Redux
Riot
Angular
CSS カプセル化
全てがグローバルスコープ
有効範囲を制限する
ScopedCSS
BEM・SMACSS・OOCSS
ネームスペースで解決してきた
フロントエンド意外お断り
そんなCSSもWebComponentsライクな
JSフレームワークの台頭により変化の兆しが
ShadowDOM(ShadowBoundary)
<div>
<style>
.title { color: #444; }
</style>
<h3 class="title">Item name</h3>
</div>
ScopedCSS
<div>
<style scoped>
.title { color: #444; }
</style>
<h3 class="title">Item name</h3>
</div>
encapsulation:ViewEncapsulation.Emulated
encapsulation:ViewEncapsulation.Native
Emulated
@Component({
selector: 'my-app',
encapsulation: ViewEncapsulation.Emulated,
styles: [`
.test { padding: 10px; }
`],
template: `
<div class="test">Test</div>
`
})
<body>
<my-app _nghost-cmy-1="">
<div _ngcontent-cmy-1="" class="test">Test</div>
</my-app>
</body>
.test[_ngcontent-cmy-1] {
padding: 10px;
}
Native
=ShadowDOM
<body>
<my-app>
▾ #shadow-root
<style>
.test { padding: 10px; }
</style>
<div class="test">
<div>Test</div>
</div>
</my-app>
</body>
<my-tag>
<h3>{ opts.title }</h3>
<style scoped>
:scope { display: block; border: 2px }
h3 { color: blue }
</style>
</my-tag>
↓
<style>
my-tag { display: block; border: 2px }
my-tag h3 { color: blue }
</style>
CustomElement風に擬似カプセル化
vue‑loader
<style scoped>
.example {
color: red;
}
</style>
<template>
<div class="example">hi</div>
</template>
↓
<style>
.example[_v-f3f3eg9] {
color: red;
}
</style>
<template>
<div class="example" _v-f3f3eg9>hi</div>
</template>
ReactでCSSカプセル化の可能性
前提認識
ネイティブなShadowDOMによるカプセル化は一旦忘れる
前提認識
全てのクラス・スタイルをカプセル化する必要はない
前提認識
グローバルのままがいい
Layout要素
Utility
カプセル化したい
Module要素
コンポーネントで完結するもの
可能性その1
CSSinJS
CSS in JS
const styles = {
root: {
color: color || avatar.color,
backgroundColor: backgroundColor || avatar.backgroundColor,
display: 'inline-flex',
alignItems: 'center',
justifyContent: 'center',
fontSize: size / 2,
borderRadius: '50%',
height: size,
width: size
}
};
return(
<div style={ styles.root }></div>
);
採用している React Component
MaterialUI
ReactToolbox
reactjs/react‑modal
ない
ない
ない
ない
ない
ない
ない
ない
ない
ない
キモい
嫌だ
ない
ごめん
言いすぎた
CSS in JS の問題
擬似クラス(:hover,:before,:after)
メディアクエリ
CSSアニメーション
シンタックス
CSS in JS 系リポジトリ
cssinjs/jss
cssinjs/react‑jss
FormidableLabs/radium
martinandert/react‑inline
smyte/jsxstyle
var Radium = require('radium');
var React = require('react');
var color = require('color');
@Radium
class Button extends React.Component {
render() {
return (
<button style={[ styles.base, styles[this.props.kind] ]}></button>
);
}
}
var styles = {
base: {
color: '#fff',
':hover': {
background: color('#0074d9').lighten(0.2).hexString()
}
},
...
};
アップサイド
シンタックス意外の問題は解決された
Styleの一部はPropで渡せる
考える必要なし
ダウンサイド
CSSじゃない→ 導入がハード
ロックインし過ぎ
カスケーディングしないだけ
(因みに) こうなった
@charset 'utf-8';
@import 'core/config';
.datepicker,
.timepicker {
font-size: 12px !important;
display: block !important;
overflow: hidden;
width: 100px !important;
height: auto !important;
border-width: 0 !important;
> div {
&:first-child {
line-height: inherit !important;
width: auto !important;
height: auto !important;
}
}
input {
line-height: 2 !important;
height: 36px !important;
padding: 0 10px !important;
text-align: center;
color: $colorFont !important;
border: 1px solid #ccc !important;
background-color: #fff !important;
}
可能性その2
CSSModule
特徴
CSSをCSSとして書ける
CSSクラスに一意のハッシュを自動で付与
/* volume-slide.scss */
.slider {
position: relative;
height: 100%;
&__track {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
width: 100%;
margin: auto 0;
background-color: rgba(255,255,255, .2);
}
&__handle {
position: absolute;
top: 0;
bottom: 0;
left: 0;
margin: auto;
cursor: pointer;
border-radius: 50px;
background-color: #fff;
&:before {
position: absolute;
top: 0;
bottom: 0;
// volume-slider.react.js
import styles from './volume-slider.scss';
render:
<slider className={ styles.slider }>
<div className={ styles.slider__track + ' ' + styles.black }></div>
<div className={ classnames(styles.slider__handle, styles.black) }></div
</slider>
出力:
<slider class="volume-slider__slider___2qmBE">
<div class="volume-slider__slider__track___1Okwk volume-slider__black___3-0A8"
<div class="volume-slider__slider__handle___X_x8Q volume-slider__black___3-0A8"
</slider>
ファイル名__クラス名__5桁のハッシュ
アップサイド
ファイル分割さえしていれば移行はスムーズ
SMACSSのModuleだけを置き換え
css‑moduleやめるときも特に何もしなくていい
ダウンサイド
WebpackとかBrowserifyの設定が必要
配布側では使えない
Webpack
{
test: /.css$/,
loaders: [
'style',
'css?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]
'postcss-loader',
]
}
Browserify
modularify
postcss‑modules
可能性その2.5
ReactCSSModule
React CSS Modules
CSSModulesだとnotenough
CSS Modules は
キャメルケースのクラス名に制限
styleオブジェクトの利用
グローバル,ローカルスコープのクラスの分別
未定義のCSSクラス参照時(エラー出ない)
React CSS Modules は
クラス名はスネークケースもいけるよ
classNameにstyleオブジェクト付けなくていいよ
グローバル,ローカルスコープのクラスが一目瞭然だよ
定義してないクラスにエラー吐くよ
// volume-slider.react.js
import CSSModules from 'react-css-modules';
import styles from './volume-slider.scss';
render:
<div styleName="slider">
<div styleName="slider__track"></div>
<div styleName="slider__handle">
</div>
</div>
export default CSSModules(VolumeSlider, styles);
出力:
<div class="volume-slider__slider___2qmBE">
<div class="volume-slider__slider__track___1Okwk volume-slider__black___3-0A8"
<div class="volume-slider__slider__handle___X_x8Q"></div>
</div>
グローバルなクラス=className
render:
<div className="global-css-class" styleName="slider">
<div styleName="slider__track"></div>
<div styleName="slider__handle">
</div>
</div>
ES7Decoratorがおすすめ
@CSSModules(styles, { allowMultiple: true })
export default class VolumeSlider extends React.Component {}
アップサイド
いいかも
ES7のDecorator使えば綺麗
ダウンサイド
依存関係が1個増える
可能性その3
CustomElement風
React で CSS カプセル化の可能性を考える
結論
Reactには無い
ただし
コンポーネントを配布する側では使いたい
import Select from 'react-select';
// Be sure to include styles at some point, probably during your bootstrapping
import 'react-select/dist/react-select.css';
react‑select・react‑spinner・react‑slider
Reactでやろうとする場合、loaderから
=現状だとscss側で対応
ダウンサイド
外部からの影響は受ける
グローバルがクリーンである必要
多少ユニークなクラス名が必要
HTMLUnknownElement...?
まとめ: React で CSS カプセル化は...
実用レベルであり
配布する時はCustomElement風
末端での利用ならばreact-css-module

More Related Content

PDF
Nuxt なしで Vue App 作る時に乗り越えるべき5つの壁
PDF
プロダクトに 1 から Vue.js を導入した話
PDF
Creators'night#12今井
PDF
「html5 boilerplate」から考える、これからのマークアップ
PDF
Creators'night#13 tech#2今井
PPTX
HTML5 on ASP.NET
ODP
osc-nagoya
PPTX
Vue.js 2.0を試してみた
Nuxt なしで Vue App 作る時に乗り越えるべき5つの壁
プロダクトに 1 から Vue.js を導入した話
Creators'night#12今井
「html5 boilerplate」から考える、これからのマークアップ
Creators'night#13 tech#2今井
HTML5 on ASP.NET
osc-nagoya
Vue.js 2.0を試してみた

What's hot (19)

PDF
SVG MANIAX Ver.2 - Mars vanilla
PDF
introduction to Marionette.js (jscafe14)
PDF
スマホにおけるWebGL入門
PDF
HTML5 と SVG で考える、これからの画像アクセシビリティ
PDF
何が変わった JavaFX 2.0
PPTX
チュートリアルではじめるVue.js
PDF
大規模なJavaScript開発の話
PDF
Vue Router + Vuex
PDF
Featuring Project Silk & Liike: 楽しい "モダン" Web 開発のちょっとディープなお話
PPTX
モテる JavaScript
PDF
基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~
PDF
実践Backbone.Marionette 現場の悩みと解決まで
PDF
Vue.js入門
PDF
はじめてのVue.js
PDF
node+socket.io+enchant.jsでチャットゲーを作る
PDF
情報編集(Web) HTML5 実践1 Canvas + Javascriptで図形を描く
PDF
Vue.js 基礎 + Vue CLI の使い方
PDF
Start React with Browserify
PDF
HTML5のCanvas入門 - Img画像を編集してみよう -
SVG MANIAX Ver.2 - Mars vanilla
introduction to Marionette.js (jscafe14)
スマホにおけるWebGL入門
HTML5 と SVG で考える、これからの画像アクセシビリティ
何が変わった JavaFX 2.0
チュートリアルではじめるVue.js
大規模なJavaScript開発の話
Vue Router + Vuex
Featuring Project Silk & Liike: 楽しい "モダン" Web 開発のちょっとディープなお話
モテる JavaScript
基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~
実践Backbone.Marionette 現場の悩みと解決まで
Vue.js入門
はじめてのVue.js
node+socket.io+enchant.jsでチャットゲーを作る
情報編集(Web) HTML5 実践1 Canvas + Javascriptで図形を描く
Vue.js 基礎 + Vue CLI の使い方
Start React with Browserify
HTML5のCanvas入門 - Img画像を編集してみよう -
Ad

Similar to React で CSS カプセル化の可能性を考える (20)

ZIP
実践Sass 前編
PDF
CSS Design and Programming
PDF
今更ながらCSS3を試してみた
PDF
ネストを覚えた人のためのSassの便利な使い方
PDF
Css
PDF
リファクタリングHTML/CSS ~レガシー世界を超えて~ #scripty03
PPT
CSS勉強会
PDF
マークアップ講座 02 CSS
PDF
なんでCSSすぐ死んでしまうん
PDF
メディア芸術基礎 Ⅰ 第4回:CSS入門 情報の形を視覚化する
PDF
CSS3 Design Recipe
PPTX
今からでも遅くない! React事始め
PDF
Sass(SCSS)について
PPTX
まだDOM操作で消耗してるの?
PDF
Movable Typeセミナー 2010年4月5日 アイデアマンズ
PDF
CSS は、もっと楽になる – LESS を活用してコーディング作業をシンプルに
PDF
gulp + sass で目指せ倍速コーディング(東区フロントエンド勉強会 2015年 第1回) 本編
PDF
壊れやすいCSS
PDF
大阪Node学園八時限目 「コーディングのためのless - 基礎編 -」
PDF
React.js + Flux入門 #scripty02
実践Sass 前編
CSS Design and Programming
今更ながらCSS3を試してみた
ネストを覚えた人のためのSassの便利な使い方
Css
リファクタリングHTML/CSS ~レガシー世界を超えて~ #scripty03
CSS勉強会
マークアップ講座 02 CSS
なんでCSSすぐ死んでしまうん
メディア芸術基礎 Ⅰ 第4回:CSS入門 情報の形を視覚化する
CSS3 Design Recipe
今からでも遅くない! React事始め
Sass(SCSS)について
まだDOM操作で消耗してるの?
Movable Typeセミナー 2010年4月5日 アイデアマンズ
CSS は、もっと楽になる – LESS を活用してコーディング作業をシンプルに
gulp + sass で目指せ倍速コーディング(東区フロントエンド勉強会 2015年 第1回) 本編
壊れやすいCSS
大阪Node学園八時限目 「コーディングのためのless - 基礎編 -」
React.js + Flux入門 #scripty02
Ad

React で CSS カプセル化の可能性を考える