Slide 1

Slide 1 text

ブロックテーマ時代における、テーマの CSS について考える Toro_Unit / 2025.09.13 @ Shinshu WordPress Meetup 1

Slide 2

Slide 2 text

$ whoami Toro_Unit / 占部 紘 Frontend & WordPress Engineer Github: @torounit Twitter: @Toro_Unit 2

Slide 3

Slide 3 text

Contributions WordPress / Gutenberg Team Shinshu WordPress Meetup WordCamp Tokyo 2023 Speaker WordCamp Kansai 2024 Organizer Team WordCamp Kansai 2025 Organizer Team 3

Slide 4

Slide 4 text

4

Slide 5

Slide 5 text

テーマ作ってますか? 5

Slide 6

Slide 6 text

スタイルの管理どうしてますか? 6

Slide 7

Slide 7 text

theme.json /styles/block-style-variation.json (Section Styles) 7

Slide 8

Slide 8 text

theme.json 昔よりかなりいろんなことができるようになった。 margin / padding / gap / border typography color / background border-radius / box-shadow etc... https://make.wordpress.org/core/2025/03/12/roster-of- design-tools-per-block-wordpress-6-8-edition/ 8

Slide 9

Slide 9 text

Section Styles ( WordPress 6.6+ ) ブロックのバリエーションを、 json で定義できるように。その定 義にも、 theme.json のようなス タイルのプロパティが使える。 子ブロックのスタイルも定義でき る。 https://make.wordpress.org/core/2024/ 06/24/section-styles/ 9

Slide 10

Slide 10 text

これでもう CSS 書かなくていいんじゃね? 10

Slide 11

Slide 11 text

・・・・・・・・・ 11

Slide 12

Slide 12 text

いやそんなことないですよね。 12

Slide 13

Slide 13 text

theme.json で出来ないこと メディアクエリ / コンテナクエリ 擬似クラス / 擬似要素 CSS アニメーション Subgrid / 複雑な CSS Grid レイアウト position / z-index etc... 13

Slide 14

Slide 14 text

簡単なモノであれば、theme.json で記述出来るが... { "css": "& .wp-block-button__link::after { content: '→'; }" } この時点でつらい。 しかもブロックごとのCSSには、パーサーの関係で メディアクエリ等など様々な機能が使えない。 & th, &td {} とかも使えない。 14

Slide 15

Slide 15 text

コアのブロックへのスタイルをCSSファイルで記述すれば解決! wp_enqueue_block_style( 'core/button', array( 'handle' => 'my-core-button-default', 'src' => get_parent_theme_file_uri( 'styles/blocks/core/button/default.css' ), 'path' => get_parent_theme_file_path( 'styles/blocks/core/button/default.css' ), ) ); wp_enqueue_block_style( 'core/button', array( 'handle' => 'my-core-button-variation', 'src' => get_parent_theme_file_uri( 'styles/blocks/core/button/variation.css' ), 'path' => get_parent_theme_file_path( 'styles/blocks/core/button/variation.css' ), ) ); 15

Slide 16

Slide 16 text

styles/blocks/core/button/variation.css .wp-block-button.is-style-my-core-button-variation { .wp-block-button__link::before { content: '→'; } } 16

Slide 17

Slide 17 text

ブロックバリエーションのスタイルも定義できたし、 もう問題無いですね! ブロックを組み合わせて、バリエーションを変えてページを 作るだけですね! 17

Slide 18

Slide 18 text

・・・・・・・・ 18

Slide 19

Slide 19 text

どうしてこうなった 19

Slide 20

Slide 20 text

スタイルが肥大化してしまう原因 20

Slide 21

Slide 21 text

複数のブロックの組み合わせで作るデザイン上のコンポーネントの存在。 21

Slide 22

Slide 22 text

デザインとしてのコンポーネントと、ブロックの粒度が一致しない。 CSS Grid 等の DOM の親子関係に依存するスタイルの存在。 これらのバリエーションを作るために、
= グループブロックが多用 される。 これらの要因が複合し、ブロックスタイルが量産される。 22

Slide 23

Slide 23 text

その結果 再利用性は低いスタイルが量産され、使い勝手が悪化。 グループブロックに限らず汎用性の高いブロックのスタイル増えがち。 23

Slide 24

Slide 24 text

「複数のブロックの組み合わせで作るデザイン上のコンポーネント」 24

Slide 25

Slide 25 text

これってブロックパターン、テンプレートパーツですよね。 25

Slide 26

Slide 26 text

パターン・テンプレートパーツと同じ粒度で CSS を書けばよいのでは? 26

Slide 27

Slide 27 text

追加 CSS を設定した状態でパターンとして 保存し、パターンごとのCSSを作成すれば良い? parts/ └── my-part.html patterns/ └── my-pattern.php styles/ ├── parts/ │ └── my-part.css └── patterns/ └── my-pattern.css 27

Slide 28

Slide 28 text

この方法の問題点 パーツ・パターンごとに CSSファイルが増えるが関連付けが手動(ファイ ル名、クラス名)なので、管理しづらい。 スターターテンプレートなど、パターンからパターンを呼ぶようなものも ある。 28

Slide 29

Slide 29 text

そんなことを悩んでいたときこんな話を思い出す。 Riot and Components「Riotとコンポーネント」by Tsutomu Kawamura https://speakerdeck.com/cognitom/riot-and-components 29

Slide 30

Slide 30 text

30

Slide 31

Slide 31 text

31

Slide 32

Slide 32 text

32

Slide 33

Slide 33 text

フロントエンドの世界では、コンポーネント単位でCSSを 管理するのが一般的になって早数年 Vue.js / Svelte / Riot.js ...etc CSS-in-JS Styled Components Emotion CSS Modules Gutenberg も React で記述されており、管理画面のコンポーネントにも このような技術が用いられている。 33

Slide 34

Slide 34 text

パターン・パーツ上で完全にCSS管理できないか? 34

Slide 35

Slide 35 text

35

Slide 36

Slide 36 text

36

Slide 37

Slide 37 text

Tailwind CSS 「ユーティリティファースト」が特長のCSSフレームワーク。 最近の流行というより、スタンダードな方法の一つとして定着してる。 Tailwind CSS で構成された UI キットなども多数。 Flowbite https://flowbite.com/ とか。 37

Slide 38

Slide 38 text

38

Slide 39

Slide 39 text

39

Slide 40

Slide 40 text

Q:「めちゃくちゃ大量のCSSクラスが準備されてるけどどうすんの?」 A:「使う分だけビルド時に生成されるので、最終的なCSSは 小さくなる」 40

Slide 41

Slide 41 text

Q:「それって WordPress の ブロックテーマでもできるの?」 41

Slide 42

Slide 42 text

postcss.config.js module.exports = { plugins: { '@tailwindcss/postcss': {}, }, }; 42

Slide 43

Slide 43 text

package.json { "private": true, "scripts": { "build": "wp-scripts build --webpack-copy-php", "dev": "wp-scripts start --webpack-copy-php" }, "devDependencies": { "@tailwindcss/postcss": "^4.1.11", "@wordpress/scripts": "^30.20.0", "tailwindcss": "^4.1.11" } } 43

Slide 44

Slide 44 text

src/index.js import './theme.css'; 44

Slide 45

Slide 45 text

src/theme.css Tailwind CSS の preflight を読み込むと WordPressのスタイルが壊れるので 除外。 https://tailwindcss.com/docs/preflight#disabling-preflight @layer theme, base, components, utilities; @import "tailwindcss/theme.css" layer(theme); @import "tailwindcss/utilities.css" layer(utilities); パターンやら、パーツやら、テンプレートやらを対象にする。 @source "../{parts,templates,patterns}/**/*.{php,html}"; 45

Slide 46

Slide 46 text

WordPress のブレークポイントに合わせる https://github.com/WordPress/gutenberg/tree/trunk/packages/viewport#usage @theme { --breakpoint-sm: 600px; --breakpoint-md: 782px; --breakpoint-lg: 960px; --breakpoint-xl: 1280px; } 46

Slide 47

Slide 47 text

画像ブロックの size-full が Tailwind CSS の size-full と衝突するので その対処。 .wp-block-image.size-full { /* width: auto; height: auto; */ @apply w-auto h-auto; } 47

Slide 48

Slide 48 text

おまけ blockごとのCSSを別のファイルに分割したときも それらの CSS で @apply つかって Tailwind CSS を使いたいとき。 .wp-block-button__link { @apply relative; &::after { @apply absolute top-1/2 right-3 -translate-y-1/2; content: '→'; } } 48

Slide 49

Slide 49 text

webpack.config.js で頑張れば出来る。ふだんこんな感じでやってる。 const defaultConfig = require("@wordpress/scripts/config/webpack.config"); const RemoveEmptyScriptsPlugin = require("webpack-remove-empty-scripts"); const path = require("path"); const glob = require("glob"); /* 各ブロックのCSSファイルをentryに追加するためのオブジェクトを作成*/ const blockStyleDir = "src/styles"; const blockEntries = glob .sync("blocks/**/*.css", { cwd: blockStyleDir }) .map((key) => [`styles/${key.replace(".css", "")}`, path.resolve(process.cwd(), blockStyleDir, key)]); const blockEntriesObj = Object.fromEntries(blockEntries); module.exports = { ...defaultConfig, entry: { ...defaultConfig.entry, "styles/theme/theme": path.resolve(process.cwd(), "src/styles/theme/theme.css"), ...blockEntriesObj, }, plugins: [ ...defaultConfig.plugins, new RemoveEmptyScriptsPlugin({ stage: RemoveEmptyScriptsPlugin.STAGE_AFTER_PROCESS_PLUGINS, }), ], watchOptions: { ignored: ["**/node_modules", "**/build/**"], }, }; 49

Slide 50

Slide 50 text

ワークフロー 1. npm run dev で wp-scripts start 2. ブラウザで確認しながら、パターンやパーツの編集 3. WordPress の機能で難しいものは追加クラスを書く。 4. create-block-theme の機能でテーマファイルを更新。 面倒なときは、直接ファイルを弄るときもよくある。 50

Slide 51

Slide 51 text

HTML として吐き出されないブロックについて コメントの中身も読んでくれるので、ダイナミックブロック(ナビゲーショ ンとか)でも機能する。 ただし、子要素に対しての変更時に、そのセレクタに __ (アンダース コア2つ)が入るとエスケープやらの問題で上手くいかない。 51

Slide 52

Slide 52 text

感想 全部 Tailwind CSS で書くと管理画面上での変更が効かなかったり等が発生 するので、WordPress 側で出来ることはそちらで。足りないところを Tailwind CSS で補う感じ。 まぁなんだかんだこんな感じで1年くらいやってみているけど、今のとこ ろ上手くいってる感じがする。この CSS どこで使ってるの?みたいな話 はだいぶ無くなった。 Tailwind CSS v4 になって、設定ファイルが不要になったのも楽で良い。 ブロックの追加CSSをいじると壊れるのはどーせ一緒なので気にしない。 壊れたらパターンをリセットすれば解決する。 52

Slide 53

Slide 53 text

余談 daisyUI のページで 言及されてた。wasm とか使って tailwindcss のビルドしてる。 採用しないけど、 いろいろ興味深い。 世界は広いなぁって思った。 https://github.com/wind-press/ 53

Slide 54

Slide 54 text

Thanks!!! 54