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

What's hot (19)

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

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

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

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