Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
オブジェクト指向CSSが叶えたかったことと、CSSのいま / The aims of Obje...
Search
ShinkuFencer
March 24, 2024
Technology
13
5.8k
オブジェクト指向CSSが叶えたかったことと、CSSのいま / The aims of Object-oriented CSS and the current state of CSS usage
Object-Oriented Conference 2024
https://ooc.dev/2024/
で喋ったスライドです。
ShinkuFencer
March 24, 2024
Tweet
Share
More Decks by ShinkuFencer
See All by ShinkuFencer
入門『状態』#kaigionrails / "state" for beginners with Rails
shinkufencer
3
2.4k
無用な認知負荷を減らしてお手入れしやすいコードを書こう / Reduce unnecessary cognitive load and write maintainable code
shinkufencer
0
5.9k
DDD関連のフレーズから入るざっくりDDD超入門 / Roughly DDD Learn,Starting with DDD-related Phrases
shinkufencer
1
630
書くときにひと呼吸おいて考えてから 書いてほしいRailsコードの書き方 / Rails programing code that I hope you will consider if you really need it
shinkufencer
0
2k
とりあえず抑えておきたい Railsでの「テストの内容」の考えかた #kaigionrails /Test code concepts to keep in mind for now with Rails
shinkufencer
4
1.7k
before_actionとのつらくならない付き合い方 #kaigionrails / how to using "before_action" with happy in Rails
shinkufencer
5
6.6k
テストコード未経験者が RailsでそれなりにRSpecがかけるようになるまでの話 /Inexperience Rails developer ,Use Rspec
shinkufencer
2
1.2k
設計の話をする前にすり合わせしたい言葉 / Reconcile our word before start designing architecture
shinkufencer
1
1.8k
セイチョウのための一歩 ブログ習慣化のあゆみ
shinkufencer
1
1.8k
Other Decks in Technology
See All in Technology
LINEヤフーのフロントエンド組織・体制の紹介【24年12月】
lycorp_recruit_jp
0
530
社外コミュニティで学び社内に活かす共に学ぶプロジェクトの実践/backlogworld2024
nishiuma
0
260
Oracle Cloudの生成AIサービスって実際どこまで使えるの? エンジニア目線で試してみた
minorun365
PRO
4
280
小学3年生夏休みの自由研究「夏休みに Copilot で遊んでみた」
taichinakamura
0
160
1等無人航空機操縦士一発試験 合格までの道のり ドローンミートアップ@大阪 2024/12/18
excdinc
0
160
ずっと昔に Star をつけたはずの思い出せない GitHub リポジトリを見つけたい!
rokuosan
0
150
継続的にアウトカムを生み出し ビジネスにつなげる、 戦略と運営に対するタイミーのQUEST(探求)
zigorou
0
560
MLOps の現場から
asei
6
640
ハイテク休憩
sat
PRO
2
150
KubeCon NA 2024 Recap / Running WebAssembly (Wasm) Workloads Side-by-Side with Container Workloads
z63d
1
250
[Ruby] Develop a Morse Code Learning Gem & Beep from Strings
oguressive
1
170
TSKaigi 2024 の登壇から広がったコミュニティ活動について
tsukuha
0
160
Featured
See All Featured
VelocityConf: Rendering Performance Case Studies
addyosmani
326
24k
GraphQLとの向き合い方2022年版
quramy
44
13k
Building Better People: How to give real-time feedback that sticks.
wjessup
365
19k
Site-Speed That Sticks
csswizardry
2
190
Building a Modern Day E-commerce SEO Strategy
aleyda
38
7k
Bash Introduction
62gerente
608
210k
Java REST API Framework Comparison - PWX 2021
mraible
28
8.3k
Rebuilding a faster, lazier Slack
samanthasiow
79
8.7k
Facilitating Awesome Meetings
lara
50
6.1k
The Pragmatic Product Professional
lauravandoore
32
6.3k
Side Projects
sachag
452
42k
Intergalactic Javascript Robots from Outer Space
tanoku
270
27k
Transcript
オブジェクト指向CSSが 叶えたかったことと、CSSのいま Object-Oriented Conference 2024 2024/03/24 #ooc_2024 #ooc_2024_d しんくう@shinkufencer
今回しゃべること 2 • オブジェクト指向CSS(Object Oriented CSS)が登場し た頃に抱えてたCSSの問題をスタートラインに OOCSSが見出したObjectとその取り扱いがどう変化し てきたのかをダイジェストで紹介します •
今後のObjectとCSSの関わり方についてどのようなこ とが考えられるのかの私の考えお話します
今回しゃべらないこと 3 • 具体的な設計手法の詳細について • CSS設計を運用していく上での具体的な問題事例 • スタイリングのテクニック • フロントエンド開発のテクニック
OOCSSの登場時の CSSの使い方と課題感 4
OOCSS登場時の時代背景 5 • Object Oriented CSS(OOCSS)が提唱されたのは2009 年頃 • 2009年頃のCSSを使ったスタイリングはHTMLの要素 (divとか)やIDに対して記述をしていくほうが多かった
様子で、まだclassに対して書くほうが少なかった時代
2009年頃のHTMLとCSS(再現) 6 <html> <head> <meta charset="UTF-8"> <style> /* 中略 */
#navigation { margin: 0; padding: 10px 50px; border: 1px dotted #ddd; } #navigation ul { padding: 0; } #navigation li { /* 略 */ } #navigation a { /* 略 */ } </style> </head> <body> <section> <div id="navigation"> <ul> <li><a href="">トップページ </a> </li> <li><a href="">おしらせ</a> </li> <li><a href="">更新履歴</a> </li> <li><a href="">問い合わせ </a> </li> </ul> </div> </section> <section> <div id="contents"> ここに本文がはいります </div> </section> </body> </html>
2009年頃のHTMLとCSS(再現) 7 <html> <head> <meta charset="UTF-8"> <style> /* 中略 */
#navigation { margin: 0; padding: 10px 50px; border: 1px dotted #ddd; } #navigation ul { padding: 0; } #navigation li { /* 略 */ } #navigation a { /* 略 */ } </style> </head> <body> <section> <div id="navigation"> <ul> <li><a href="">トップページ </a> </li> <li><a href="">おしらせ</a> </li> <li><a href="">更新履歴</a> </li> <li><a href="">問い合わせ </a> </li> </ul> </div> </section> <section> <div id="contents"> ここに本文がはいります </div> </section> </body> </html> IDセレクタを利用して スタイリングの割当を 行っていた
8 2009年12月23日発売 ゼルダの伝説大地の汽笛のホームページ ゼルダの伝説 大地の汽笛 : 登場人物 https://www.nintendo.co.jp/ds/bkij/chara/index.html より引用
2009年頃に抱えていた課題感 9 そのときのCSSは以下のような課題感を抱えていた • 再利用性の低さと記述量肥大化 • 適用範囲の理解が難解で壊れるUI
課題感 - 再利用性の低さと記述量肥大化 10 • CSSのコードが特定のid属性に書かれていることが多い • id属性は重複が許されないので、似たものを記述する時 も再度別物として書く必要があった 再利用可能なものも再記述され
記述量増加によるファイル肥大化
課題感 - 適用範囲の理解が難解で壊れるUI 11 • CSSはページごとで読み分けたりせず、1つのファイル で管理するので優先されるものの判断が難しい • id/要素/classセレクタを使うので、詳細度の兼ね合い で一見してどれが適用されるか判断が難しい
追加時など他の箇所への影響が予測しづらく 意図しないところが壊れることがある
どの詳細度が優先されるかわかりづらい例 12 <html> <header> <style> div p { /* 詳細度は(0,0,2)
*/ color: red; } div p#first { /* 詳細度は(1,0,2) そのため他3つよりもこれが優先 */ color: green; } p#first { /* 詳細度は(1,0,1) */ color: orange; } div p[name="example"] { /* 詳細度は(0,1,2) */ color: yellow; } </style> </header> <body> <div> <p name="example" id="first">sample text</p> </div> </body> </html>
どの詳細度が優先されるかわかりづらい例 13 <html> <header> <style> div p { /* 詳細度は(0,0,2)
*/ color: red; } div p#first { /* 詳細度は(1,0,2) そのため他3つよりもこれが優先 */ color: green; } p#first { /* 詳細度は(1,0,1) */ color: orange; } div p[name="example"] { /* 詳細度は(0,1,2) */ color: yellow; } </style> </header> <body> <div> <p name="example" id="first">sample text</p> </div> </body> </html> 例えばフォントサイズを変更したくても どれに足せばいいのかわからないし 新たに足したら違うものに反映されるかも という怖さがある
大きく2つの課題感がある2009年頃 14 • OOCSSはこの課題感をとらえつつ提唱された • 具体的にはどのような考え方なのか?
Object Oriented CSS とはどういう考え方なのか 15
OOCSSの考え方 16 • Object Oriented CSS(OOCSS)は2009年にNicole Sullivan 氏によって提唱された • Webページをレゴの集まりのように捉える考え方。
• そのレゴひとつひとつを他のオブジェクト指向の考え 方になぞらえて”Object”と呼ぶ。
OOCSSにおけるObjectとは? 17 では具体的に”Object”とは何なのか? 提唱者のNicole Sullivan 氏は以下のように書いている。 基本的にCSSの”Object”は繰り返される視覚的なパターン のことで、HTMLやCSS(場合によってはJavaScript)の 独立したスニペットとして抽象化が可能なものです。 このオブジェクトはサイト全体でも再利用できます。
“ ” Home · stubbornella/oocss Wiki https://github.com/stubbornella/oocss/wiki#whats-a-css-object より引用
OOCSSにおけるObjectとは? 18 FAQ · stubbornella/oocss Wiki https://github.com/stubbornella/oocss/wiki/FAQ より引用 ①HTML DOMの1つ以上の
ノード ②CSS宣言 ①に関するStyle ③Objectの表示に 必要な画像など ④Objectに必要な JavaScript OOCSS Object
OOCSSの原則と期待される効果 19 • ”Object”の概念に対して、CSSを使って表現していく のがOOCSSの思想 • では具体CSSの定義はどう考えていけばいいのか? • CSSを定義するにあたり、Nicole Sullivan
氏は次の2つ の原則に沿って考えることを説明した
OOCSSの2つの原則 20 原則① 構造とスキンの分離 原則② コンテナとコンテンツの分離
OOCSSの2つの原則 21 原則① 構造とスキンの分離 原則② コンテナとコンテンツの分離 Webページの中で、繰り返し使えるものと 派生して変わるものを分けて考える原則 Webページの中で特定の場所に依存しないように 作りのまとまりを考え、わける原則
OOCSS原則① 構造とスキンの分離 22 • 構成する内容(構造)と見た目などの部分を分離して 考える原則。 • ボタンを例にどこが構造でどこがスキンかを整理しま す 送信
キャンセル
OOCSS原則① 構造とスキンの分離 23 テキスト ボタンの”構造” テキスト + ボタンの構造は 「テキスト」「角丸四角」 の変わらない2つの組み合わ
せ + =
OOCSS原則① 構造とスキンの分離 24 送信 ボタンの”スキン” 「キャンセル」の場合だけ、背 景色をグレーにするので派 生変化する部分はスキン キャンセル
OOCSS原則① 構造とスキンの分離 25 • CSSとして考える際に、ボタンの構造部分のCSSと見た 目を表現するCSSを分けることで拡張が可能になる • 似たようなボタンをたくさん定義するのではなく、ボ タンの共通部分と派生部分を分けることができる •
この原則を通して分類することで、共通利用できる パーツが見つけることができ、意味のある名付け(セ マンティックな名付け)がされる
OOCSS原則② コンテナとコンテンツの分離 26 • 「コンテンツ」は先であげたようなボタンのような パーツ、「コンテナ」はそれらを組わせたもの。 • この2つを分離するというのは、コンテンツはコンテ ナの構造に依存しない作りにするということ。 •
モーダルウィンドウを例にとって説明します。
OOCSS原則② コンテナとコンテンツの分離 27 OK コンテナとコンテンツ ボタン、テキスト、ウィンドウ の複数のコンテンツを組み合 わせて「モーダル」を実現して いる。 この場合はモーダルがコンテ
ナと考える このモーダルは注意 を促すものです!!
OOCSS原則② コンテナとコンテンツの分離 28 コンテナとコンテンツ コンテンツは他の場所で使う ので余白などはパーツを組コ ンテナに持たせる。コンテン ツに場所に依存する設定をし ない このモーダルは注意
を促すものです!! OK
OOCSS原則② コンテナとコンテンツの分離 29 • 「モーダル」のようなものも、一つの塊としてCSSを組 んでいたところに組み合わせるという概念を取り入れ た • 個別のコンテンツごとに別けて、それをコンテナとい う箱に入れることを前提とすることで様々なところで
使い回す前提の作りが意識される • この原則を通して、場所に依存されない記述がされて いく
OOCSS原則を適用する過程で期待される効能 30 構造とスキンの分離の効能 コンテナとコンテンツの分離の効能 分離の過程で繰り返し利用可能な粒度を見つけ Objectに対して意味に基づいた名前をつく 分離の過程で場所に依存した部分を切り離し 独立して使い回し可能なObjectの粒度になる
OOCSSの原則を適用して粒度が決まる 31 2つの原則に照らし合わせてWebページを見ていくことで Objectを見いだせた!派生パターンもわかった! このObjectに対してCSSを使って名前をつけて行こう!
OOCSS登場後にどう変わっていったか 32 • OOCSSの原則に則って考えることで、Objectに沿った CSSを定義することができるようになった • ただこのあと、このObjectにおいてどう移り変わった かということに関してはあまり語られてはいない • そのため今回は「OOCSSのObjectとして捉えた場合ど
うか?」というのを着眼点において 大きく3つのトピックをご紹介していきます
OOCSSのObjectの移り変わり その① CSS classの命名規則 33
OOCSSから命名規則 34 • OOCSSが登場後、Objectに相当する粒度のものにCSS のclassで名前をつける手法が使われ始めた • ただ個々人が思い思い名前をつけるとOOCSSにおける 「構造」にあたるものか、「スキン」にあたるものか が判別し辛いなどの問題があった •
class名の命名規則でそれらの問題をカバーしようとい う試みがいくつかあり、その中で一番有名なのがBEM
命名規則 BEM(Block,Element,Modifier) 35 • BEMはYandex社が2009年頃に提唱した考え方 • BEMはWebページの構造を Block, Element, Modifier
の3種類に分けてCSS記述をする考え方
命名規則 BEM(Block,Element,Modifier) 36 「Key concepts / Methodology / BEM」より引用 https://en.bem.info/methodology/key-concepts/
作りとして意味のある 単位をblockと捉える
命名規則 BEM(Block,Element,Modifier) 37 「Key concepts / Methodology / BEM」より引用 https://en.bem.info/methodology/key-concepts/
Blockを 構成するパーツを Elementとして捉える パターン違いは Modifierで表現
命名規則 BEM 38 • Block,Element,ModifierをCSSのclassの命名で表現す る。 .menu_bottom Block Modifier .menu__tab_enabled
Block Element Modifier
BEMを利用する場合の例 39 <section class="content"> <h2 class="content__title"> 素敵なタイトル </h2> <div class="content__body">
素敵な本文素敵な本文 </div> <div class="content__body content__body_alert"> ここは注意を促す文章 </div> </section> .content { max-width: 1000px; padding: 10px 15px; margin-right: auto; margin-left: auto; background-color: #DDC; } .content__title { margin-bottom: 10px; font-size: 1.25rem; font-weight: bold; } .content__body { font-size: 1rem; color: #222; } .content__body_alert { color: #F00; }
命名規則によって解決されたこと 40 • OOCSSではファジーだったCSSのclass名の記述に関し て、明確なルールが設けられた • class名を見ればどのような意味をもったものかが判断 しやすくなった
命名規則によって解決されたこと 41 • BEM登場後に「命名規則で行うアプローチ」は多く登 場した ◦ SMACSS ◦ FLOCSS ◦
SUIT CSS • いずれもBEMとは違う切り口の概念ではあるが、実現 するための手法としてはCSSのclassの名称や組み合わ せで表現している
命名規則が発展した後に見えてきた課題 42 • 命名規則は命名をユニークにすることで衝突を回避し ているので、意味が区別を意識しつつ名前被りが発生 しないように名付けをしないといけない • 従来のプログラミング言語であればパッケージのよう な概念でグルーピングができるが、当時のCSSはそのよ うな機構がないため、名付けの難易度が高い
SaSSなどの仕組みが登場したが、記述時点のグルーピングができるだけなので 最終的な名前付けは重複をさけるために長い名称になってしまっている
命名規則が発展した後に見えてきた課題 43 • そんな課題感を迎えるなか、時を同じくして以下のも のが隆盛してくる
OOCSS Objectの移り変わりその② JavaScriptの UI Component 44
JavaScript(JS)フレームワークの登場とCSS 45 • 2013年頃からにReactやVue.jsのようなUI Component 指向のフレームワークが登場した • OOCSSで提唱されたObjectの構成要素を考えるとほぼ UI Componentそのもの
• これらのフレームワークの登場とともに、JSと組み合 わせることでCSSをUI Componentの内部に閉じ込める 仕組みも併せて登場した • 大きくはCSS ModulesとCSS in JSの2種類がある 内部に閉じ込めるという観点ではWeb ComponentsとShadow DOMの仕組みもあるのですが 今回は尺の都合上省略します
CSS Module 46 • ReactなどJSで構成されたUI Component内のみ適用さ れるようにCSSのclass名を自動生成する仕組み • もともとは “css-loader”
というライブラリの実装だっ たが、CSS Moduleとして仕様化され、他ライブラリの 実装がある
Reactでのcss-loader利用例 47 .error { background-color: red; } Button.module.css import React,
{ Component } from 'react'; import styles from './Button.module.css'; class Button extends Component { render() { // reference as a js object return <button className={styles.error}>Error Button</button>; } } export default Button Button.js
Reactでのcss-loader利用例 48 .error { background-color: red; } Button.module.css import React,
{ Component } from 'react'; import styles from './Button.module.css'; class Button extends Component { render() { // reference as a js object return <button className={styles.error}>Error Button</button>; } } export default Button Button.js JSのコンパイル時にclass名に対して UI Component名やランダムなsuffixをつけ 専用の記述にし衝突回避
CSS in JS 49 • CSSそのものの書き方をJSやTypeScript(TS)の記法で 行うような仕組みの総称。 • ベースとなる仕様があるわけではなく、各々の個別の 実装が存在している。
• 代表的なライブラリとしては “styled-components” や “emotion” などがある。
Reactでのstyled-components利用例 50 import React from 'react'; import ReactDOM from 'react-dom/client';
import './index.css'; import styled from "styled-components"; const Button = styled.button<{ daigi?: boolean; }>` background: ${props => props.daigi ? "#BF4F74" : "white"}; color: ${props => props.daigi ? "white" : "#BF4F74"}; font-size: 1em; margin: 1em; padding: 0.25em 1em; border: 2px solid #BF4F74; border-radius: 3px; `; const root = ReactDOM.createRoot( document.getElementById('root') as HTMLElement ); root.render( <React.StrictMode> <Button>Normal</Button> <Button daigi>Primary</Button> </React.StrictMode> ); index.tsx
Reactでのstyled-components利用例 51 import React from 'react'; import ReactDOM from 'react-dom/client';
import './index.css'; import styled from "styled-components"; const Button = styled.button<{ daigi?: boolean; }>` background: ${props => props.daigi ? "#BF4F74" : "white"}; color: ${props => props.daigi ? "white" : "#BF4F74"}; font-size: 1em; margin: 1em; padding: 0.25em 1em; border: 2px solid #BF4F74; border-radius: 3px; `; const root = ReactDOM.createRoot( document.getElementById('root') as HTMLElement ); root.render( <React.StrictMode> <Button>Normal</Button> <Button daigi>Primary</Button> </React.StrictMode> ); index.tsx 表示分岐ロジックを JS(TS)の世界観で記述ができる
CSS ModulesやCSS in JSがもたらしたもの 52 • JavaScriptの管轄する世界でCSSの記述をすると、特定 のパーツの範囲だけ適用されるCSSを記述することがで きる •
またCSS in JSではTypeScriptも利用可能なため、従来 の型付き言語にあるような恩恵(型安全)なども受け ることができる • JSのUI Componentの構成はOOCSSに近く、CSSの名 付けよりも直感的にObjectを認識できる
53 OOCSSのObjectの移り変わりその③ CSSの新仕様
新しいCSS仕様の登場 54 • CSS ModulesもCSS in JSもReactやVue.jsなどのJSの ライブラリを使うことが前提の仕組みなので、それら がないと利用できない •
2023年ごろ、影響範囲の絞り込みができるCSSの新仕 様が登場した • それらの新仕様を組み合わせることでCSSだけでもJSの UI Component相当の影響範囲の絞り込みをつくること ができるようになってきている
@layer 55 • 従来からある詳細度のルールとは別に階層を設けるこ とで適用させるものを調整できる仕組み • 階層構造で適用範囲を調整することができる • 近年追加されたCSSの仕様であるため、特別なプラグイ ンなどは利用せずに使うことができる
@layerは2022年頃には概ね最新のブラウザのいずれにも採用されており 最新のブラウザであれば動作する状態になっている
@layerを適用した例 56 <html> <header> <style> /* 一番最後設置された layerから優先して反映される ,そのため赤文字になる */
@layer default_layer, power_orange, super_red; @layer default_layer { /* 詳細度は(1,0,2) */ div p#first { color: green; } /* 詳細度は(0,1,2) */ div p[name="example"] { color: yellow;} } @layer super_red { /* 詳細度は(0,0,2) */ div p { color: red;} } @layer power_orange { /* 詳細度は(1,0,1) */ p#first {color: orange;} } </style> </header> <body> <div> <p name="example" id="first">sample text</p> </div> </body> </html>
@scope(Scoped Style) 57 • 従来のセレクタの記述方法同様にスタイリングの範囲 を指定できる仕組み • 例としてdata-*属性に対して適用させる例を紹介しま す @scopeは2023年10月ごろリリースされたChrome118あたりから実装がされ
Edge,Safari,Operaなど主要ブラウザには実装されているが 2024年3月時点ではFirefoxの最新バージョン(123)は未対応
@scopeの使用例 58 <style> @scope( [data-component='normal-card'] ) { .card { width:
288px; height: auto; box-shadow: 2px 2px 6px rgba(0, 0, 0, .4); } .text_box { width: 100%; height: auto; padding: 20px 18px; background: #ffffff; box-sizing: border-box; } .title_text { font-size: 24px; font-weight: bold; line-height: 125%; } .overview_text { font-size: 18px; line-height: 150%; } } @scope( [data-component='mini-card'] ) { .card { width: 144px; height: auto; box-shadow: 2px 2px 6px rgba(0, 0, 0, .4); } .text_box { width: 100%; height: auto; padding: 20px 18px; background: #ffffff; box-sizing: border-box; } .title_text { font-size: 20px; font-weight: bold;line-height: 125%; } .overview_text { font-size: 12px; line-height: 150%; } } </style> <body> <div data-component='normal-card'> <div class="card"> <div class="text_box"> <div class="title_text">タイトル</div> <div class="overview_text"> ここには文章がはいります文章が入ります </div> </div> </div> </div> <br> <div data-component='mini-card'> <div class="card"> <div class="text_box"> <div class="title_text">タイトル</div> <div class="overview_text"> ここには文章がはいります文章が入ります </div> </div> </div> </div> </body>
@scopeの使用例 59 <style> @scope( [data-component='normal-card'] ) { .card { width:
288px; height: auto; box-shadow: 2px 2px 6px rgba(0, 0, 0, .4); } .text_box { width: 100%; height: auto; padding: 20px 18px; background: #ffffff; box-sizing: border-box; } .title_text { font-size: 24px; font-weight: bold; line-height: 125%; } .overview_text { font-size: 18px; line-height: 150%; } } @scope( [data-component='mini-card'] ) { .card { width: 144px; height: auto; box-shadow: 2px 2px 6px rgba(0, 0, 0, .4); } .text_box { width: 100%; height: auto; padding: 20px 18px; background: #ffffff; box-sizing: border-box; } .title_text { font-size: 20px; font-weight: bold;line-height: 125%; } .overview_text { font-size: 12px; line-height: 150%; } } </style> <body> <div data-component='normal-card'> <div class="card"> <div class="text_box"> <div class="title_text">タイトル</div> <div class="overview_text"> ここには文章がはいります文章が入ります </div> </div> </div> </div> <br> <div data-component='mini-card'> <div class="card"> <div class="text_box"> <div class="title_text">タイトル</div> <div class="overview_text"> ここには文章がはいります文章が入ります </div> </div> </div> </div> </body> 特定の条件に該当するときだけ 適用されるCSSを指定することが できる
適用範囲を絞るCSSの新仕様たち 60 • @layerや@scopeなどを使えばJavaScriptを利用しな くても仕組みとしてCSSの適用範囲を調整することがで きる • そのため命名規則で頑張らなくても、HTMLとCSSだけ でもわかりやすいObjectが作れるようなりそうな未来 が見えてきた
当初の課題は 現時点でどうなったのか 61
選択肢が増える中で改めて課題感に戻る 62 • 様々な選択肢が増えた中で2009年頃の以下の課題はど うなったのか? • 再利用性の低さと記述量肥大化 • 適用範囲の理解が難解で壊れるUI
「再利用性の低さと記述量肥大化」は? 63 • IDや要素に依存しにくいclassセレクタでの設定が基本 になった • CSSの命名規則で制御する考え方はもちろん、JSのUI ComponentをObjectとして取り扱うことができるよう になったのでパーツとして再利用が簡便になった
「適用範囲の理解が難解で壊れるUI」は? 64 • 初期は命名規則でやる人力の運用ではあったが、JSや CSSそのものが発展したことで、機械的な仕組みの力を 借りる運用が可能になった • 2009年時点のCSSは適用範囲が絞れなかったが、近年 はCSSの適用範囲をObject単位に閉じ込める事が可能 なったので理解が簡便になった
問題解消後に考えるべきこと 65 • OOCSSの頃にあった課題感は概ね解消に向かいつつあ る • ではいまのCSS設計を考えるときにはどのようなことを 頭に入れておくと良いのか
CSSのいま 66
UI ComponentとCSSの立ち位置の変化 67 • OOCSS登場当時はCSSのclass名がObject名を表現する のが最適解だったため、Objectの意味のある名付けは CSSが担っていた • 近年Webページを構成する主体がJSフレームワークに 移り変わってきた
• 結果としてセマンティックな名付けをされる対象もCSS からJSのUI ComponentなどCSSではないところが主体 になることが増えた このスライドではJSのUI Componentの話を中心にしてきたが パーツをWebアプリケーションフレームワークの部分テンプレート(Railsのpartialなど)が 担うことも可能なので、JSを利用しない場合でも名付けをCSS外に移譲できる
Objectの名付けの担当の変化 68 いままではCSSのclass名がObjectの意味を表す部分を 担ってきた ①HTML DOMの1つ以上の ノード ②CSS宣言 ①に関するStyle ③Objectの表示に
必要な画像など ④Objectに必要な JavaScript OOCSS Object
Objectの名付けの担当の変化 69 JSのUI Componentが主体の場合はComponentに意味のあ る名付けがされるのでCSSがそこまでやらずともよい ①HTML DOMの1つ以上の ノード ②CSS宣言 ①に関するStyle
③Objectの表示に 必要な画像など ④Objectを 構築する JavaScript OOCSS Object とほぼ同義の UI Component
UI ComponentとCSSの立ち位置の変化 70 • 結果としてCSSのclass名の名付けがセマンティックで なくても良い状態になってきている • また、命名規則のときには「意味のあるclass名の名付 けが難しい」という課題もあった •
そこでCSSの構成をセマンティックなものではなく、別 の切り口で取り扱うような考え方が登場した • その1つがTailwind CSS
Tailwind CSSとユーティリティクラス 71 • Tailwindは文字サイズや余白など単一の機能を持つ ユーティリティクラスを組み合わせてスタイリングを 実現させるフレームワーク • CSSのclass名のアプローチが大きく異なり 従来からある意味をもたせる「セマンティック」な
名付けではなく、機能的な名前を持たせる 「ユーティリティ」な名付けとなっている
従来のセマンティックなCSSで作る例 72 <div class="chat-notification"> <div class="chat-notification-logo-wrapper"> <img class="chat-notification-logo" src="/img/logo.svg" alt="ChitChat
Logo"> </div> <div class="chat-notification-content"> <h4 class="chat-notification-title">ChitChat</h4> <p class="chat-notification-message">You have a new message!</p> </div> </div> Utility-First Fundamentals - Tailwind CSS https://tailwindcss.com/docs/utility-first よりサンプルコードを引用 <style> .chat-notification { display: flex; max-width: 24rem; margin: 0 auto; padding: 1.5rem; border-radius: 0.5rem; background-color: #fff; box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04); } .chat-notification-logo-wrapper { flex-shrink: 0; } .chat-notification-logo { height: 3rem; width: 3rem; } .chat-notification-content { margin-left: 1.5rem; padding-top: 0.25rem; } .chat-notification-title { color: #1a202c; font-size: 1.25rem; line-height: 1.25; } .chat-notification-message { color: #718096; font-size: 1rem; line-height: 1.5; } </style> 順当にObjectの”意味”に 基づいた名前を設定している
Tailwind CSSでの記述例 73 <div class="p-6 max-w-sm mx-auto bg-white rounded-xl shadow-lg
flex items-center space-x-4"> <div class="shrink-0"> <img class="h-12 w-12" src="/img/logo.svg" alt="ChitChat Logo"> </div> <div> <div class="text-xl font-medium text-black">ChitChat</div> <p class="text-slate-500">You have a new message!</p> </div> </div> Utility-First Fundamentals - Tailwind CSS https://tailwindcss.com/docs/utility-first よりサンプルコードを引用
Tailwind CSSでの記述例 74 <div class="p-6 max-w-sm mx-auto bg-white rounded-xl shadow-lg
flex items-center space-x-4"> <div class="shrink-0"> <img class="h-12 w-12" src="/img/logo.svg" alt="ChitChat Logo"> </div> <div> <div class="text-xl font-medium text-black">ChitChat</div> <p class="text-slate-500">You have a new message!</p> </div> </div> Utility-First Fundamentals - Tailwind CSS https://tailwindcss.com/docs/utility-first よりサンプルコードを引用 CSSのclassが “機能”単位で名付けされ それらを組み合わせて スタイリングを行う
ユーティリティファースト 75 • Tailwindはユーティリティファーストな構成にするこ とにより、「パーツの意味」ではなく「スタイリング の機能単位」にCSSの名前を利用している • Tailwindを利用するすべてのシステムが一貫して同じ 名称のclassを使うので、利用の気遣いが減る •
全体に適用させるための「テーマ」のようなスタイリ ングに関しても相性がいいため、ユーティリティ ファーストのアプローチの利点も多い
CSS設計とどう向き合うか 76
CSS設計との向き合い方 77 • CSSを利用する方法の選択肢が増えたので、構築するも のによって適切なものを選択するとよい • 簡易な拡張予定のないページやObjectの作りが簡素な ものであればBEMなどの命名規則を基軸にしてカバー することもできる •
Webアプリケーションの場合は捉えるべきObjectの運 用を鑑みて、利用するJSフレームワークやチーム構成 とセットでどのアプローチをとるか考えるとよさそう
まとめ 78 • OOCSSは当時のCSSが抱える問題をObjectというパーツをも とに解決しようとした • この考え方からObjectの捉え方として命名規則やJavaScript と連動した考え方などが生まれてきた • OOCSS登場時の課題は概ね解決され、Objectを表現する上で
CSSの使われ方も変化してきた • すべてに合致する単一の考え方はないが、いくらかはユース ケースによって使い分けられる状況ではある
79 Thanks! しんくう / shinkufencer @shinkufencer コード日進月歩 https://shinkufencer.hateblo.jp/ 普段はRuby
on Railsを使った Webアプリケーション開発をやっています
Appendix 参考書籍/参考サイト 80
81 【書籍】 • CSS設計完全ガイド ~詳細解説+実践的モジュール集 - 技術評論社 https://gihyo.jp/book/2020/978-4-297-11173-1 • Web制作者のためのCSS設計の教科書
モダンWeb開発に欠かせない「修正しやすいCSS」の設計手法 - インプ レスブックス https://book.impress.co.jp/books/1113101128 • Tailwind CSS実践入門 - 技術評論社 ★オススメ https://gihyo.jp/book/2024/978-4-297-13943-8 【WEBサイト】 • 恐竜に教える現代のCSS – Part 1 | POSTD https://postd.cc/actualize-networkmodern-css-explained-for-dinosaurs/ • 知っておきたいCSS設計法 | 第1回 OOCSSの基本 https://www.codegrid.net/articles/2014-css-template-1/ • stubbornella/oocss: Object Oriented CSS Framework https://github.com/stubbornella/oocss • BEM https://en.bem.info/ • Utility-first CSS(Tailwind CSS)が合理的であることの説明と、CSSによるUI開発小史 | blog.tai2.net https://blog.tai2.net/utility-first-css.html • CSS設計って最近こういう感じだと思うんですけどどうですか - Speaker Deck https://speakerdeck.com/takazudo/cssshe-ji-tutezui-jin-kouiugan-zidatosi-undesukedodoudesuka • Now and Next Generation of CSS Cascading Model | ドクセル https://www.docswell.com/s/araya/51JEY8-fec-okinawa-2023
82 【WEBサイト】 • CSS Modulesの歴史、現在、これから - Hatena Developer Blog https://developer.hatenastaff.com/entry/2022/09/01/093000
• ZOZOTOWN Webフロントエンドリプレイスにおける CSS in JS の技術選定で Emotion を選定した話 - ZOZO TECH BLOG https://techblog.zozo.com/entry/zozotown-css-in-js • うひょさん、よしこさんと改めて考えるReactコンポーネント設計 | Offers Magazine https://offers.jp/media/event-report/a_3060 • 次世代 CSS 仕様が与えるコンポーネント時代の Web への影響 | blog.jxck.io https://blog.jxck.io/entries/2023-01-07/new-css-capabilities-for-component.html • Cascade Layerは汚れ切ったCSSの救世主になれるのか? https://zenn.dev/kyoheyee/articles/6bbc6f1dc55d0b • CSSにそのうち導入されそうな@scopeとその関連概念 https://zenn.dev/uhyo/articles/css-cascading-6-scope