Antenna House CSS Formatter はHTMLあるいはXMLとCSSからPDFを生成できます。
ところで、CSSを直接書くのは結構大変です。
スタイル設定を書いていると、数百行程度はすぐに超えてしまうかもしれません。
そうして膨れ上がったスタイル設定はメインテナンス性の観点からもあまり望ましくはありませんね。
そこで他の記述形式からCSSを生成する方法が普及してきました。
CSSを生成する言語あるいは処理系を指してメタCSSという呼称が用いられることもあります。メタCSSとしてはLESSやSCSSがあります。
本記事ではSCSSを記法として採用し、処理系としてsassを使用しました。SASSとSCSSの違いなどについては割愛します。SCSSは記法として素のCSS記法も可能なため、既に記述されているCSSからの移行が比較的容易いというメリットもあります。
今回はサンプルとして、弊社で公開している『CSSページ組版入門』のサンプルファイルを利用しました。
Antenna House CSS FormatterのバージョンはV7.2改訂1版を想定しています。
処理の流れとしては次のようになります。
1. SCSSファイルの記述
2. SCSSをCSSにコンパイル
3. HTML、XML+CSSをAH CSS Formatterで組版
sassの導入
sassは現在Dart言語で開発されていますが、インストールはDart環境よりもWeb系でより普及しているnpmやyarn経由の方が簡単かもしれません。
$ yarn add sass
今回SCSSに変更していくbooklet-page-ja.cssをリネームし、booklet-page-ja.scssとします。SCSSに変更後、sassによって改めてbooklet-page-ja.cssを生成します。
$ yarn run sass booklet-page-ja.scss booklet-page-ja.css
ネスト記法
booklet-page-ja.css(変換前)
...
/* 目次 */
.TOC > ul {
font-size: 15.5q;
font-family: source-serif-pro, source-han-serif, serif;
}
.TOC li.TocLevel1 {
font-size: 15.5q;
}
.TOC li.TocLevel2 {
font-size: 14q;
}
.TOC li.TocLevel3 {
font-size: 12.5q;
}
CSSでは基本的にセレクタは個別に書いていく必要がありますが、SCSSではセレクタの親子関係を入れ子で記述できます。また、「>
」や同じ要素で別のクラス指定のものも入れ子にし、Parent Selector 「&
」を使うことで目的の出力が得られます。
@page
はトップレベルのセレクタのため、「& :left
」のような利用方法はエラーとなります。
booklet-page-ja.scss
...
/* 目次 */
.TOC {
& > ul {
font-size: 15.5q;
font-family: source-serif-pro, source-han-serif, serif;
}
li {
&.TocLevel1 {
font-size: 15.5q;
}
&.TocLevel2 {
font-size: 14q;
}
&.TocLevel3 {
font-size: 12.5q;
}
}
...
フォーマットした上での行数は増えることもありますが、同じ要素やクラスを親とするスタイル指定がすっきりまとまりました。
SCSSでの「&」は「&-top」のようにも使えるのですが、CSSのNesting Module(Draft)では処理が変わってしまうため、使用を控えています。
@mixin
SCSSでは@mixin <name> (<arg>) { ...}
で指定した内容を@include <name>(<arg>)
で取り出して使用できます。
フッタのページ番号とヘッダのテキストでfont-familyとfont-sizeが揃っていたため、@mixinを使用してみましょう。
booklet-page-ja.css
... {
@top-left { /* 柱(ページヘッダ)*/
font-size: 11.5q;
font-family: source-serif-pro, source-han-serif, serif;
}
@top-right { content: none }
@bottom-left { /* ノンブル(ページ番号)*/
font-size: 11.5q;
font-family: source-serif-pro, source-han-serif, serif;
content: element(Title);
}
...
}
booklet-page-ja.scss
@mixin running-font {
font-size: 11.5pt;
font-family: source-serif-pro, source-han-serif, serif;
}
...
... {
@top-left { /* 柱(ページヘッダ)*/
@include running-font();
}
@top-right { content: none }
@bottom-left { /* ノンブル(ページ番号)*/
@include running-font();
content: element(Title);
}
}
今回は使用していませんが、SCSSではCSSに変換時に置換される変数が使用できます。CSSにも変数機能がありますが、組版に使う処理系がCSSの変数に対応していないときなどはこちらが有用です。
AH CSS Formatter V7.2はCSS変数に対応しています。
AH Formatter V7.2 | CSS仕様の実装状況
@mixin
などと併用するときは粒度の管理が大切です。
ファイルをまとめる
素のCSSでは分割したファイルは都度HTMLのlink要素で読み込んでいたかもしれません。CSSの@import
機能もありました。
「分割して細かくしていくうちに数十ファイルのCSSでどこに何が書かれているか分からなくなり、そのまますべて読み込むことにした」という話も耳にします。Webサイト読み込みにおけるパフォーマンス以外に、メインテナンス性にもかかわる話です。
SCSSでは複数の入力SCSSファイルから、1つまたは複数のCSSファイルを出力することもできます。
「SCSSファイルと同数のCSSファイルをチェックすることになり作業が倍に」といった事態にしないため、
出力するCSSファイルはまとめることにします。
複数の入力ファイルから出力を得る場合、sassへ指定する引数の書き方が少し変わります。
次のSCSSファイルのあるディレクトリをscss、出力するCSSファイルを含むディレクトリをcssとします。
$ yarn run sass scss:css
scssディレクトリ内部のSCSSファイルがCSSへと変換されます。scss/a.scss、scss/b.scssファイルが存在する場合はcss/a.css、css/b.cssファイルが生成されます。
さてこのとき、ファイル名の先頭を「_」とすることで、そのファイルは出力するCSSファイルから除かれます。この除外されてしまうファイルの意義はどこにあるかというと、出力対象の別ファイルから内部的に読み込ませるためにあります。
出力するCSSファイルから除外するファイルを_color.scssとします。
booklet-page-ja.scss
@use "_color"
...
@use
で読み込まれた_color.scssの内容は変換出力されたbooklet-page-ja.cssに反映されます。このとき名前空間などの概念が登場しますが、詳細はSCSS(SASS)のWebサイトなどをご覧ください。
ざっくりとした紹介となりましたが、メタCSSによってCSS組版の設定記述の見通しを良くする方法について説明しました。WebサイトでのSCSS-CSS利用との差異はほとんどありませんが、Webサイトよりも細かに異なるレイアウト指定を行うであろうCSSページ組版で、メタCSSによって得られる恩恵はより大きくなるのではないでしょうか。
参考資料