2021/11/12
BEM×SASSってもう古いの??モダンCSSを試してみる(styled-components編)
最近のフロントエンジニア界隈では、React.jsやVue.jsなどのJavaScriptフレームワークによるコーディングが一般的になって久しいようですが、CSSを取り巻く事情も、変化してきています。
Learn to become a modern frontend developer ←2021年時点でこちらのフロントエンド開発のロードマップを見ると、数年前に一般的になっていたBEMやSASSが必然ではなくなり、モダンCSS(CSS in JS)の習得が推奨されていることがわかります。
そういえば、技術系の記事でこういうの最近見かける機会が増えてきたなというのは感じていましたが、このまま習得せずに進むのはまずいと思い、モダンCSSというものを試してみることにしました。
ちなみにここで紹介されていたモダンCSSには、styled-components、CSS Module、Styled JSX、そして最近人気が出つつあるらしいEmotionが含まれていました。
試してみた感想をレポートしてみたいと思います。
まずは、ReactのCSS in JSで一番使われているらしいstyled-componentsを試してみました。
↓試しに作ってみたもの
DEMO
CSS in JSを使う意味
CSS in JSを使う意味の主なものとしては、
メンテナンス性の向上と、パフォーマンスの向上があると思います。
JavaScriptフレームワークでは、コンポーネント単位でソースを管理することが一般的ですが、その場合、CSSを別管理でひとまとめにするよりも、コンポーネントとセットで管理したほうが、CSSの記述箇所が見つけやすく、メンテナンス性が高くなります。
また、CSS in JSを使うと、表示中の要素だけCSSを書き出し、不要なCSSを書き出さないという処理が可能になるので、パフォーマンス性が上がり、SEOの評価も上がります。
styled-componentsの使い方
インストール
1 2 3 | yarn add styled-components もしくは npm install -D styled-components |
JSX or TSXファイルへのインポート
1 | import styled from 'styled-components'; |
StyledComponentの作成とコンポーネントへの配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | const StyledItem = styled.li` width: 300px; margin: 0 20px 40px; @media (max-width: 768px) { width: 100%; } `; const StyledLink = styled.a` display: flex; align-items: center; justify-content: center; height: 50px; border: solid 1px white; border-radius: 4px; transition: .3s; cursor: pointer; &:hover, &:active { background: white; color: blue; } `; const ListItem: React.FC = () => ( <StyledItem> <StyledLink href="/about">About</StyledLink> </StyledItem> ); |
styled.HTMLタグ名CSSコード
の形式でスタイルのついたコンポーネントを作成できます。
既存のコンポーネントに後付でスタイルを当てたい場合は、
1 2 3 4 5 6 7 | const StyledPlaceholder = styled(Placeholder)` width: 300px; margin: 0 20px 40px; @media (max-width: 768px) { width: 100%; } `; |
のように、styled(コンポーネント名)CSSコード
の形式で記述できます。
ご覧のように、CSSコードの記述はSASSと同じネストによる記述が可能ですので、SASSに慣れた人にとっては馴染みやすいと思います。
コンポーネントの状態と連動させる
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | const MenuButton: React.FC = () => { const [menuState, setMenuState] = useState(false); const onClick = useCallback(() => { setMenuState(oldState => !oldState) }, [setMenuState]); return( <> <button type="button" onClick={onClick} aria-label="ナビゲーションの切り替え"> <StyledIcon isActive={menuState}><span></span><span></span><span></span></S.Icon> </button> </> ) } interface NaviMenuProps { isActive: boolean } const StyledIcon = styled.i<NaviMenuProps>` display: block; width: 24px; height: 24px; position: relative; & > span { display: block; width: 100%; height: 2px; background: blue; ${({isActive}) => isActive && css` background: white; ` } } `; |
CSSコード内の${}の中で出し分けの記述をすることにより、要素に渡した属性の状態からCSSの切り替えを行うことができます。JavaScriptの値と直接連動するので、意図しない動作などを避けられそうです。
BEM×SASSと比べた感想
BEMでは、単一のclass名をつけるために、どういう名前にするかよく迷いますが、styled-componentsでは、スコープがあり、コンポーネント内であればスタイルのために単一のclass名を付ける必要がないため、コーディングの本質のところに集中しやすそうだと感じました。
また、BEM×SASSでは、要素のCSSを探すために検証で行番号を調べてファイルの中を探すといった工程が発生しますが、styled-componentsではコンポーネントと同じファイル内にCSSの記述があるため、要素の検証を使わなくてもCSSの記述を見つけやすいという事も感じました。また、JSの制御とCSSの連動も、より直接的に記述できるため、どこで制御しているのかわからないという自体になることもほぼないのではないかと思いました。
styled-componentsのデメリット
CSSを設定する要素ごとにコンポーネントを作ることになるため、HTMLとしての可読性が低くなるという問題があります。また、CSSの流用がしづらいというデメリットもあります。
これらのデメリットは、styled-componentsからインスパイアされて登場したEmotionでは克服されていて、まだ利用率はstyled-componentsのほうが高めのようですが、同じ記述形式を採用するのであれば、Emotionを利用したほうが良いかもしれません。
また、styled-componentsでは、要素ごとに変数としてCSSを記述するため、これまでのCSSとは記述方法が大きく変わってきます。CSSをまとめて記述したり、既存のCSSを移植したりしたい場合は、CSSを別ファイルとして管理するCSS Moduleを採用したほうが良いかもしれません。
Author Profile
NINOMIYA
Webデザイナー兼コーダー出身のフロントエンド開発者です。 UXデザインやチーム開発の効率化など、勉強中です。
SHARE