ヒツジ「俺……、Vivliostyleで技術同人誌を書くんだ……。」
~30分後~
ヒツジ「おいぃ!?秘伝のCSSが効かないんだが!?」
## 何があったの
Vivliostyle9.0以降、Markdownで指定したフロントマターCSSを読み込まなくなった。
```markdown
---
link:
- rel: "stylesheet"
href: "../../css/content-style.css"
---
## ここから本文
hogehoge
```
大まかな構成はこんな感じ。
```
.
├── README.md
├── vivliostyle.config.js
├── css
│ ├── base.css (ベースCSS)
│ ├── content-style.css (本文用CSS)
│ └── section-title.css (セクション用CSS)
└── docs
├──content
└── chapter1.md
└── section
└── sc-chapter1.md
```
`docs/content/`もしくは`docs/section/`に入っているMarkdownファイルで、`css`にあるCSSを参照したい。(セクション用/本文用CSSを分けている)
細かいフォルダー構成が知りたい場合、こっちを見てくれると助かる。
- [aidoyuzuna/vivliostyle-sandbox at experiment1](https://github.com/aidoyuzuna/vivliostyle-sandbox/tree/experiment1)
## 忙しい人のための結論
フロントマターで指定しないで`vivliostyle.config.js`で指定しろ。以上!
```js
module.exports = {
entry: [
{
path: 'docs/content/sc-chapter1.md',
theme: 'css/section-title.css',
},
{
path: 'docs/content/chapter1.md',
theme: 'css/content-style.css',
},
],
};
```
## 解説
### なんでこうなったの?
Vivliostyle 9.0になってからプレビュー・ビルド関係の処理が変わったっぽい。
#### Ver8.20.0以前
(html出力先設定しなければ)markdownと同じ階層にhtmlファイルが生成される。CSS・画像・Javascriptファイルなども「自分が作成したファイルを」参照している。
#### Ver9.0以降
プレビュー・ビルド時に、`.vivlostyle`フォルダーを作成。その中に「`vivliostyle.config.js`で指定したファイル」のコピーを生成・参照する仕様になったぽい。
「`vivliostyle.config.js`で指定したファイル」ってのが厄介で、「Markdownのフロントマターで呼び出しているファイルは」生成対象外(=404扱い)っぽいのよね。プレビュー中に`.vivliostyle`にCSSファイルを入れても反映されないし、再プレビュー・ビルドすると生成同期がかかるので、移行したCSSファイルが削除されてしまう。なんてこった!
### 対処法:フロントマターを諦め、vivliostyle.config.jsに書け
逆に言えば`vivliostyle.config.js`で指定してしまえば生成してくれるので、そっちに書き込むのがいいかもしれない。`theme`プロパティにあてたいCSSを書けばOK。
#### ファイル全体
```js
module.exports = {
theme: "content-style.css"
entry: [
"docs/section/sc-chapter1.md",
"docs/content/chapter1.md",
],
};
```
この方法だと`entry`に指定しているMarkdownファイルに`content-style.css`がかかる。複雑なCSSじゃなければ、1つのCSSにまとめて全体に適応してもいいかもしれない。
#### ファイルごとに別のCSSをあてたい
```js
module.exports = {
entry: [
{
path: 'docs/content/sc-chapter1.md',
theme: 'css/section-title.css',
},
{
path: 'docs/content/chapter1.md',
theme: 'css/content-style.css',
},
],
};
```
多分フロントマターに個別にCSSをあてていた人は、「ページor章ごとにCSSを変えたい!」とか思っている人だと思う。私もそれでセクションと本文でCSSを分けていた。
`vivliostyle.config.js`で個別に`theme`を適応できるので、それでやっていけばOK。
## 余談
### 余談1:CSSをimportしている場合
`section-title.css`と`content-style.css`では`base.css`をインポートしている。しかし、これも上記の理屈の「`vivliostyle.config.js`で指定していないファイル」扱いになるので生成されない。まあ、これも`vivliostyle.config.js`に書けばいいだけの話ではある。
具体的に言うと、「全体の`theme`に`base.css`をあて、個別にCSSをあてる」感じ。
```js
module.exports = {
theme: "css/base.css",
entry: [
{
path: 'docs/content/sc-chapter1.md',
theme: 'css/section-title.css',
},
{
path: 'docs/content/chapter1.md',
theme: 'css/content-style.css',
},
],
};
```
もしくは個別に複数CSSを指定するとか。
```js
module.exports = {
entry: [
{
path: 'docs/content/sc-chapter1.md',
theme: ['css/base.css','css/section-title.css'],
},
{
path: 'docs/content/sample.md',
theme: ['css/base.css','css/content-style.css'],
},
],
};
```
### 余談2:staticでフォルダー参照を行う
```js
module.exports = {
entry: [
"docs/section/sc-chapter1.md",
"docs/content/chapter1.md",
],
static: {
'/css': 'my-theme',
},
};
```
```markdown
---
link:
- rel: "stylesheet"
href: "/my-theme/content-style.css"
---
## ここから本文
hogehoge
```
`static`で表示したいフォルダーを記載し、Markdownの`href`で指定する方法もある。この方法だと、フロントマターに書いてあるJavascriptファイルなども読み込むことが可能らしい。(自分は試してない)
ただ、この方法だと下記の不都合も発生した。
- フォルダー参照がややこしくなり、デバッグしにくい
- (正しいURLになっても)プレビューで反映されない。ビルドでは反映される
友人のぷりんさんの執筆本環境では`static`参照がスムーズに行けたらしいが、私の構成・環境だとうまくいかなかったので、おススメはできないかも。
## 最後に
この場を持って、私のパニックに付き合ってくれた[すむーずぷりんちゃん🍮(@mat_der_D)さん / X](https://x.com/mat_der_D))にお礼を言おうと思う。ありがと~!
## 参考リンク
- [vivliostyle-cli/docs/config.md at main · vivliostyle/vivliostyle-cli](https://github.com/vivliostyle/vivliostyle-cli/blob/main/docs/config.md)
- [チュートリアル③原稿とテーマのカスタマイズ | Vivliostyle](https://vivliostyle.org/ja/tutorials/customize/)
- [feat: Vite plugin by spring-raining · Pull Request #550 · vivliostyle/vivliostyle-cli](https://github.com/vivliostyle/vivliostyle-cli/pull/550)