環境
- React 17.0.1
- react-scripts 4.0.0
やりかたいろいろ
モダンなのは、Styled Components
かCSS Modules
か。
CSS Modules
は、スコープが読み込んだファイルに限定される上に、CSSシンタックスハイライトが使える。
やりかた | CSS in JS | 外部ファイル | CSSの全機能使えるか | CSSシンタックスハイライト | おすすめ度 |
---|---|---|---|---|---|
CSS Modules | No | Yes | Yes | Yes | ◯ |
Styled Components | Yes | No | Yes | Yes | ◯ |
インライン・スタイル | Yes | No | No | No | △ |
Radium | Yes | No | Yes | No | △ |
外部CSSファイル (※CSSのネームスペースがグローバルになる) |
No | Yes | Yes | Yes | ☓ |
CSS in JS ライブラリとして、emotion がメジャーっぽい。
https://qiita.com/__sakito__/items/d240840eef7123f62acf
create-react-app でプロジェクトを作った場合のデフォルトは、CSS Modules。
CSS Modules
- CSSファイルを
[name].module.css
(e.g.App.module.css
)という名前にする(中身は通常のCSS)。 -
className
でスタイルを適用する。 -
react-scripts@2.0.0
からは、デフォルトで使えます。
src/App.module.css
.App {
text-align: center;
background-color: black;
color: white;
}
@media(min-width: 500px) {
.App {
width: 450px;
}
}
src/App.js
import styles from './App.module.css';
...
return(
// classNameでstyleを適用する
<div className={styles.App}>
...
</div>
// 別の例
<div className={styles['form-control']}>
// 動的に style を適用する
<div className={`${styles['form-control']} ${!isValid && styles.invalid}`}>
);
Styled Components
npm install --save styled-components
// or
yarn add styled-components
-
styled
をimportする -
styled.<html-element>
でスタイルを定義する
src/App.js
import styled from 'styled-components'
const StyledDiv = styled.div` // `styled.{html-element}`という形式でスタイルを定義する
text-align: center;
background-color: black;
color: white;
&:hover { // & は .div を示す
background-color: white;
color: black;
}
@media(min-width: 500px) {
width: 450px;
}
`;
...
return(
<StyledDiv> // 定義したJSXを使う
...
</StyleDiv>
);
動的に値を変える場合
src/App.js
const StyledDiv = styled.div`
text-align: center;
background-color: ${props => props.alt ? 'black' : 'red'};
`;
...
return(
<StyledDiv alt={this.state.clicked}> // booleanを返すstateを指定する
...
</StyleDiv>
);
メリット
- インラインスタイルが使える(= スコープをそのファイルに限定できる)。
デメリット
CSSのシンタックスハイライトが使えない
インライン・スタイル
src/App.js
render() {
const style = {
textAlign: 'center', // キャメルケースを使う
backgroundColor: 'black',
color: 'white'
};
...
return(
<div style={style}>
...
</div>
);
メリット
- インラインスタイルが使える(= スコープをそのファイルに限定できる)。
- スタイル(の一部)を JavaScript/TypeScript でプログラマブルに変更できる。
- 但し、CSS のクラスをプログラマブルに適応することは可能なため、他の方法と比較して大きなメリットではない。
デメリット
- 擬似クラス(e.g.
hover
)、疑似エレメント、メディアクエリー、keyframe animation が使えない。 - スタイルをコンポーネント間で簡単に共有できない。
Radium
npm install --save radium
// or
yarn add radium
pseudo selectorを使う場合
-
Radium
をimportする -
Radium()
で囲う
src/App.js
import Radium from 'radium'; // Radiumをimportする
render() {
const style = {
textAlign: 'center',
backgroundColor: 'black',
color: 'white',
':hover': { // psuedo selectorが使えるようになる
backgroundColor: 'white',
color: 'black'
}
};
// コード内で上書きする場合
style[':hover'] = {
backgroundColor: 'blue',
color: 'red'
};
...
return(
<div style={style}>
...
</div>
);
...
export default Radium(App); // Radium()で囲う
media queriesを使う場合
- 前述の「pseudo selectorを使う場合」の内容に加えて、、、
-
StyleRoot
をimportする - アプリケーション全体を
StyleRoot
で囲う
src/App.js
import Radium, { StyleRoot } from 'radium'; // StyleRootをimportする
render() {
const style = {
textAlign: 'center',
backgroundColor: 'black',
color: 'white',
'@media(min-width: 500px)': { // media queriesが使えるようになる
width: '450px'
}
};
...
return(
<StyleRoot> // StyleRootで囲う
<div style={style}>
...
</div>
</StyleRoot>
);
...
export default Radium(App);
メリット
- インラインスタイルが使える(= スコープをそのファイルに限定できる)。
- 通常の CSS が使える。
デメリット
- CSSのシンタックスハイライトが使えない
外部CSSファイル
src/App.css
.App {
text-align: center;
background-color: black;
color: white;
}
@media(min-width: 500px) {
.App {
width: 450px;
}
}
src/App.js
import './App.css';
...
return(
<div className="App">
...
</div>
);
メリット
- CSSがそのまま使える。
デメリット
- グローバルに定義されるので、メンテナンス性が低い。