Vivliostyleが拓くCSS組版の可能性

DTPあるあるのCSS組版的解決法

株式会社ディジタルグロースアカデミア リブロワークス部デザイン室の峠坂あかりと松澤維恋です。

リブロワークスでは、すでにいくつかの商業出版物でVivliostyleによるCSS組版を採用しています。実際の業務の流れとしては、リブロワークス デザイン室にて紙面デザインとCSSの作成を行い、それを社内外の編集者や著者に提供するという分業体制を敷いています。そのため、なるべく双方ともに作業しやすいような環境づくりを目指しています。

2023年にWeb技術で「本」が作れるCSS組版 Vivliostyle入門をCSS組版の入門書として執筆しましたが、今回の記事では、入門書から少しステップアップした、これまでの制作経験から得られたノウハウをご紹介します。

円滑にCSS組版案件を進行するために

IT書の編集者、著者であっても、組版用のCSSを書ける人はそう多くはありません。初めてCSS組版の案件を進行する場合、⁠細かい仕様が多くてわかりづらい」⁠作業を分担したいのに説明が難しい」と感じる人は多いでしょう。リブロワークス デザイン室では、編集者・著者がCSSに触れることなく、Markdownだけ編集すればいいように、まずは円滑に作業をするための事前準備をしています。

Markdown記法と表示結果をまとめる

円滑に進めるためには、⁠こう書けば、こうなる!」をまとめておくことが重要です。まずは、スプレッドシートなどにMarkdownの記述方法、プレビュー(紙面に反映されるデザイン⁠⁠、説明などをまとめています。

Markdownの記述方法と表示結果の対応表の例

上記のようにスプレッドシートで見える化しておくことで、一目でMarkdownとデザインの対応を理解できます。また、複数人で作業する場合に、仕様書として利用することもできます。

CSSファイルを適切に分割する

使用するCSSファイルの数に制限はないため、あとからメンテナンスしやすいように、役割ごとに複数のCSSファイルを作って作業します。一例として、リブロワークスでCSSを作成する場合、次のような役割別にCSSを分割しています。

CSS 役割
main.css 基本的な要素(FreeFormatに定義済みのもの)
custom.css その本にしかない要素。ミニコラムや側注など
page_settings.css CSS変数を集めている。@pageで設定するものが中心
font.css フォントまとめ(使用フォントが多い場合のみ)
main-chapter1.css 章カラーなど、章ごとで異なる要素(章構成が多い場合のみ)

表のように掲載される要素や状況に応じてCSSを使い分けることで、触れるべきCSSを瞬時に判断することができ、円滑に作業をするための仕組みを作ることができるのです。

CSSファイルの同期

CSSを読み込むためには、Markdown側にFrontmatterを記載します。

---
link:
  - rel: 'stylesheet'
    href: 'css/main.css' <!-- 読み込みたいCSS -- >
  <!-- 複数のCSSを読み込む場合(ここから) -- >
  - rel: 'stylesheet'
    href: 'page_settings.css'
  <!-- 複数のCSSを読み込む場合(ここまで) -- >
lang: 'ja'
---

Frontmatterはルールが厳しく、前後には半角の-が必ず3つ、:の後には必ず半角スペースが1つ、rel:href:の行頭を揃えるなど、守らなければならないルール存在します。しかし、コピー&ペーストなどを駆使して仕様どおりに記載すれば問題が起きることはまずありません。⁠Markdownで原稿を書く前に、まずFrontmatterをコピペする!」を意識して、CSS組版を行うようにしましょう。

また、CSS同士を紐付けたい場合は、CSSファイルに@import " ";と記載することで、複数のCSSを読み込むことが可能です。例えば、main.csspage_settings.cssを紐付けたい場合、main.cssに以下のコードを記載します。

@import "page_settings.css";
---
link:
  - rel: 'stylesheet'
    href: 'css/main.css' <!-- page_settings.cssと紐付いたmain.css -- >
lang: 'ja'
---

CSS同士を紐づけることで、Frontmatter上にCSSファイルの指定をする必要がなくなり、Markdown側の記載をシンプルにすることができます。Markdownには、なるべく原稿のみを記載するようにしたいので、リブロワークスではCSS同士を紐付けておくことが多いです。

途中でデザインを変更したくなったら

CSS組版では、文字サイズや各パーツのサイズを先に決めておくことで、パーツ自体のデザインは後から丸ごと差し替えることが可能です。デザインが確定しないと作業できない従来の組版に比べ、デザインの差し替えが容易だったり、リアルタイムで反映できたりするのがCSS組版のメリットと言っても過言ではないので、デザインが未確定の案件での使用にも適していると言えます。

文字やパーツのサイズが合っていれば、後からデザインを変更できる

見出し付きの囲み記事を作る

ここからは、いよいよ実作業に関するノウハウの説明をしていきます。CSS組版をする上で、まず意識すべきポイントは、section要素です。標準的なMarkdownでは、見出しにするテキストの前に#######を付けると、h1~h6要素に変換されます。Vivliostyleではこれに加えて、VFM(Vivliostyle用にカスタマイズされたMarkdown構文)の独自機能で以下の仕様のHTMLが生成されます。

  • 見出し+その下の要素をsection要素で囲む
  • {.クラス名}を書いてclassを付与する
  • 対になる#を書くことでsection要素の範囲(終わり位置)を指定できる

最後に記載した範囲の指定方法については、開発者コミュニティに提案して、検討のうえ追加された仕様です。section要素の範囲を明確にすることで、構造をわかりやすくし、デザインの適用範囲なども明確になります。

では、上記のsection要素についての説明をふまえ、まずは見出し付きの囲み記事を作る方法から解説します。ここで紹介する見出し付きの囲み記事とは、見出し+その下の要素で構成された記事全体を罫線や背景色で囲んだデザインを指します。

##### タイトルタイトルタイトル{.column} 

コラムやメモなどの囲み記事本文コラムやメモなどの囲み記事本文コラムやメモなどの囲み記事本文コラムやメモなどの囲み記事本文コラムやメモなどの囲み記事本文コラムやメモなどの囲み記事本文コラムやメモなどの囲み記事本文コラムやメモなどの囲み記事本文コラムやメモなどの囲み記事本文

##### 
<section class="level5" aria-labelledby="タイトルタイトルタイトル">
  <h5 class="column" id="h5_1">タイトルタイトルタイトル</h5>
  <p>コラムやメモなどの囲み記事本文コラムやメモなどの囲み記事本文コラムやメモなどの囲み記事本文コラムやメモなどの囲み記事本文コラムやメモなどの囲み記事本文コラムやメモなどの囲み記事本文コラムやメモなどの囲み記事本文コラムやメモなどの囲み記事本文コラムやメモなどの囲み記事本文</p>
</section>
コラムやポイントなどの囲み記事

紹介例のように、見出し+その下の要素で構成された記事全体を指定するためには、section要素に対してborderやbackgroundを設定する必要があります。h1~h6の親として自動生成されたsection要素を選ぶには、has()を利用しましょう。has()では、その意味のとおり「〇〇要素を含んだ××要素」を指定することができます。例えば、columnクラスの要素を直下に含むsectionを指定する場合、以下のようにCSSを書きます。

section:has(> .column){ /* .columnを直下に含むsection */
  border: solid 0.2mm #8df; /* 囲み罫線の設定 */
  border-radius: 10px; /* 角丸設定 */
  padding-inline: 6mm; /* 囲み内左右マージン*/
  padding-block: 4mm; /* 囲み内上下マージン */
  margin-block-start: 6mm; /* 囲み上マージン */
  width: 114mm; /* 囲み幅 */
  background: #eef; /* 囲み背景色の設定 */
}

気をつけるべきポイント

書籍によっては、h4レベルの小見出しをh5レベルの囲みに入れたい場合もあるかと思います。しかし、section要素が振られたの囲みに同ランク以上の要素を入れると、sectionクラスの入れ子構造が壊れてしまう可能性が高くなります。構造が壊れてしまうと、デザイン上の囲み範囲や、連番counter()がうまく反映されないなどの問題が起きるので、入れ子構造を理解して、囲みの中に入れる要素は低いランクにするなどの調整をしてください。

section構造が壊れてしまう記述例
##### タイトルタイトルタイトル{.column}

コラムやメモなどの囲み記事本文コラムやメモなどの囲み記事本文コラムやメモなどの囲み記事本文コラムやメモなどの囲み記事本文。

##### コラム内見出し

コラムやメモなどの囲み記事本文コラムやメモなどの囲み記事本文コラムやメモなどの囲み記事本文コラムやメモなどの囲み記事本文。

#####
囲み要素が正しく表示されない

before⁠afterで飾りをつける

節見出しなどに飾りをつける場合に、頻繁に用いられるのが疑似要素の::before、疑似要素の::afterです。疑似要素を絶対配置position: aboslute;にすれば位置やサイズは自由に調整できるので、節見出しの背景画像や節番号、デザインとして使用する「POINT」などの文字や、行頭のアイコンなど、本文には直結しないデザイン要素の配置に役立ちます。要素の直前や上に置きたいものは::before。要素の直後や下に置きたいものは::afterを使用しましょう。

飾りとして文字を入れる
section:has(> .column)::before { /* .columnを直下に含むsectionの擬似要素 */
  content: "Column"; /* テキスト"Column" */
  background-color: #8df;
  color: #fff;
  line-height: 5mm;
  inline-size: 17mm; /* 擬似要素の横サイズ */
  block-size: 5mm; /* 擬似要素の縦サイズ */
  position: absolute; /* 絶対配置 */
  border-radius: 10px;
  text-align: center;
  margin-block-start: -6.5mm;
}
囲み枠に「Column」の文字を挿入
連番や背景画像の設定
/* 節番号 */
h2::before {
  content: counter(chapter-counter) "-" counter(section-counter); /* counter関数(章番号)-counter関数(節番号) */
  color: #585656;
  counter-increment: section-counter; /* counter関数の変数名(節番号) */
  font-size: 44Q;
  line-height: 14mm;
  text-align: center;
  color: #fff;
  padding-block-start: 27mm;
  padding-inline: 0% 96%;

  /* 背景画像 */
  background-image: url("img/section-header.png"); /* 背景画像 */
  background-size: var(--page-width); /* 背景画像サイズ */
  background-repeat: no-repeat; /* 背景画像の繰り返し */
  inline-size: var(--page-width); /* 擬似要素の横サイズ */
  block-size: 79mm; /* 擬似要素の縦サイズ */
  position: absolute; /* 絶対配置 */
  inset-inline-start: -21mm; /* 左右位置指定 */
  inset-block-start: -18mm; /* 上下位置指定 */
}
節見出しに節番号と背景画像を挿入

リード文を入れる

リード文とは、節タイトルの下に入れる導入文のことを指します。主に、内容に興味を持たせる文章や節全体の要約などが入りますが、シンプルなデザインなら本文の体裁をそのまま使うこともあるパーツです。⁠節タイトルの部品と一体化したデザインにしたい」⁠本文と区切りが欲しい」といったような、少し凝ったデザインにしたい場合は<div class="section-lead"></div>で囲み、位置調整を行いましょう。節見出しなど、他の要素と直結する要素なので、絶対配置position: absolute;での設定がおすすめです。

<div class="section-lead">

ここでは、Rubyのプログラムを作成して、実行するまでの流れを解説します。最初にエディターでプログラムを書いて、コマンドプロンプトを実行するだけで、すぐに結果を確認できます。

</div>
.section-lead {
  position: absolute; /* 絶対配置 */
  inset-inline-start: 12mm; /* 左右位置指定 */
  inset-block-start: 41mm; /* 上下位置指定 */
  inline-size: 36em; /* 横サイズ(文字数指定) */
  line-height: 20Q;
}
節見出しデザイン内にリード文を配置

ページに柱とノンブルを入れる

柱やノンブルなど、版面周囲の決められた場所におく要素には、ページマージンボックスを使用しましょう。ページマージンボックスは、下図のように版面の周囲16箇所で分けられているため、ノンブルや柱など、該当する範囲にそれぞれ設定することができます。@page内にそれぞれの指定を書くことで反映されます。

ページマージンボックスの位置と名称
ノンブルと柱の設定
@page :right {
  /* ノンブル */
  @bottom-right { /* ノンブルを挿入するエリア */
    content: counter(page); /* ノンブルの設定(ページのcounter関数) */
    text-align: end;
  }
  /* 柱 */
  @bottom-center { /* 柱を挿入するエリア */
    content: string(chapter-number, first) " " string(chapter-title, first); /* section内最初の章番号 section内最初の章タイトル */
  }
}

h1 {
  /* 柱のテキスト */
  string-set: chapter-title content(), chapter-number content(before); /* h1のテキストをchapter-titleに設定  h1のbefore要素(章番号)をchapter-numberに設定 */
}
ページ下部に柱とノンブルを挿入

ページの端にツメを付ける

ツメ(サイドインデックス)には、running-elemntを使用します。running-elemntは、ドキュメント内の要素をページマージンボックスに表示できるCSS組版独自の機能です。

本記事の例では、sideindexposition: running(sideindex);を設定し、ページマージンボックス側にcontent: element(sideindex);を設定しています。章ごとに位置が変動するようにしたいので、top1top2top3など位置に応じたクラスを設けたうえで、変動させたい値を記述しています。今回は章ごとに変動する例を記載していますが、節ごとにツメを動かすこともできるので、自由度ははるかに高いです。

ただし、ページマージンボックスのstring-set、stringのような自動で見出しのテキストを拾う機能がないので、テキストは自分で入力する必要があります。

<div class="sideindex top1>

コンピュータの重箱の隅

</div>
:root {
  --sideindex-size: 9mm; /* ツメのサイズ */
}

@page :right {
  @right-top {
    content: element(sideindex);
  }
}

.sideindex {
  position: running(sideindex);
  writing-mode: vertical-rl; /* 縦書き */
  font-size: 12q;
}

/* 章ごとにツメ位置を変える */
.top1 {
  margin-inline-start: calc(var(--sideindex-size) * 0);
}
.top2 {
  margin-inline-start: calc(var(--sideindex-size) * 1);
}
.top3 {
  margin-inline-start: calc(var(--sideindex-size) * 2);
}

.top1::before {
  content: "1";
}
.top2::before {
  content: "2";
}
.top3::before {
  content: "3";
}

.top1::before, .top2::before, .top3::before {
  margin-inline-start: 7mm;
  margin-block: 0mm 2mm;
  padding-inline-start: 2.5mm;
  inline-size: 14mm;
  block-size: 9mm;
  border-radius: 5mm 0 0 5mm;
  background-color: #6dba44;
  color: #fff;
  font-size: 20Q;
  line-height: 9mm;
  writing-mode: horizontal-tb;
}
ツメが挿入される

連番を付ける

節番号や図表番号を自動で連番にさせるためには、連番をリセットするためのcounter-reset、要素を入れるためのcontent、連番を増やすためのcounter-incrementなどを組み合わせて使用します。挿入する場所は::beforeで設定します。

:root {
  counter-reset: chapter-counter 0; /* chapter-counterの開始番号を0にリセット */
}
h1 {
  counter-reset: section-counter 0; /* section-counterの開始番号を0にリセット */
}
h2::before {
  content: counter(chapter-counter) "-" counter(section-counter); /* counter関数(章番号)-counter関数(節番号) */
  color: #fff;
  counter-increment: section-counter; /* counter関数の変数名(節番号) */
  font-size: 48Q;
  font-weight: 900;
  line-height: 14mm;
  text-align: center;
  padding-block-start: 27mm;
}
連番が挿入される

なお、Markdown内に手作業でdivを書き込んでいる場合、その入れ子構造がおかしいためにCSSカウンターがうまく増減しないことあります。CSSの記述に問題ないにもかかわらず、数字が増えない場合はそこを確認してみてください。

また、chapter-countersection-counterは、Frontmatterで初期値を指定できます。CSSを書き換えなくても、Frontmatter内の初期値を変更するだけで章番号や節番号の振り直しが可能なので、ページ数が多かったり、Markdownが章ごとにあったりする場合などに需要のあるノウハウです。

---
link:
  - rel: 'stylesheet'
    href: 'css/main.css'
lang: 'ja'
body:
  style: "counter-reset: chapter-counter 2" <!-- chapter-counterの初期値指定 -->
---

任意改ページを入れる

-を3つ書くことで水平線hr要素)を生成することができます。水平線の上は1行分空けるようにしましょう。書籍で水平線を引くことは少ないため、リブロワークスではbreak-after: page;と組み合わせ、任意改ページの指定として使用しています。


---
hr {
  break-after: page;
  visibility: hidden;
}

表紙ページを作る

名前付きページ(Named pages)を使用すると、任意のページだけ設定を変更することができます。ページのマージンの変更などもできるので、各扉ページや奥付けなど、本編と異なる設定をする必要のあるページで使用します。

# コンピュータの<br>重箱の隅

<div class="chapter-lead">
章のリード文。章のリード文。章のリード文。章のリード文。
章のリード文。章のリード文。章のリード文。章のリード文。
</div>

#
@page tobira {
  background-color: #88ddff;

  @bottom-right {
    content: none; /* 柱なし */
  }
  @bottom-center {
    content: none; /* ノンブルなし */
  }
}
section:has(h1) { /* h1を含むsection */
  page: tobira; /* ページの名前をtobiraに設定 */
}
本文とデザインの違う扉ページが作成される

画像を回り込ませる

画像を本文に回り込ませる場合はfloatを使用します。例えば、画像を本文の右側に回り込ませたい場合、画像の外側にdiv要素などを追加し、"figure right"などのクラスを与えておきます。その要素に対してfloat: inline-endを設定することで、右側に回り込むようになります。

<div class="figure right">

![](img/img2-logic.svg)

</div>
.figure.right {
  float: inline-end;
  margin-inline-start: 1em;
}
画像が本文の横に回り込む

禁則をコントロールする

禁則処理の設定にはline-breakを使用します。デフォルトでの設定はline-break: auto;となり、一般的な禁則処理が施されている設定です。セレクタはanywhereloosenormalstrictなどがあり、記載している順で禁則が強くなります。autonormalは大体同じような処理をします。コードのような禁則処理を無視して書きたいときにline-break: anywhere;を使用することで、文字の「送られすぎ」を防ぐことができます。

auto⁠既定の改行規則

line-break: auto;

loose⁠最も制限の少ない改行規則

line-break: loose;

anywhere⁠改行規則を無視

line-break: anywhere;

字間を調整する

字間を調整するにはletter-spacingを使用します。pなどに適用すれば一括で、テキストをspanに分けて個別に適用すれば1字ずつ調整できます。letter-spacingのデフォルトは0なので、0より値が大きいと字間が空き、0より値が小さい字間が詰まります。また、font-feature-settingsで字間を調整する方法もあります。これは字形に応じたプロポーショナル詰めを適応する設定となるため、OpenTypeフォントの使用が必要でフォント内の詰め情報がないと効果が発揮されません。OpenTypeフォントを使用したうえで、font-feature-settingstext-spacingと組み合わせると、プロポーショナル詰めかつ和欧文間の空きも調整された綺麗な文字詰めにすることができます。

字間調整なし
日本語組版に適した設定値:paltの例

プログラムのコードリストを載せる

コードリストはバッククォート3つでコードの上下を囲み、上部のクォートから半角空けて言語名を指定することで作成することができます。使用するフォントは等幅のソースコード用フォントが望ましいです。フォントまわりの設定として、white-space: pre-wrap;や、禁則処理の項目でも説明したline-break: anywhere;を忘れずに指定しておきましょう。

また、トリプルクォートのあとに「py」「js」などの言語指定を入れると、Prism.jsに基づいたシンタックスハイライトが自動で割り振られます。言語指定に使用する略字や、シンタックスハイライトの割り振りはPrism.js公式サイトから確認できるので、言語指定に悩んだら一旦公式サイトを覗いてみることも手です。

Pythonのコード例

```py
from pathlib import Path
from bs4 import BeautifulSoup

result = '## 目次{#toc role="doc-toc"}\n'
outpath = Path('tocoutput.md')
outpath.write_text(result, encoding='utf-8')
```
<pre class="language-py">
  <code class="language-py">
    <span class="token keyword">from</span> pathlib <span class="token keyword">import</span> Path
    <span class="token keyword">from</span> bs4 <span class="token keyword">import</span> BeautifulSoup
    
    result <span class="token operator">=</span> <span class="token string">'## 目次{#toc role="doc-toc"}\n'</span>
    outpath <span class="token operator">=</span> Path<span class="token punctuation">(</span><span class="token string">'tocoutput.md'</span><span class="token punctuation">)</span>
    outpath<span class="token punctuation">.</span>write_text<span class="token punctuation">(</span>result<span class="token punctuation">,</span> encoding<span class="token operator">=</span><span class="token string">'utf-8'</span><span class="token punctuation">)</span>
  </code>
</pre>
pre {
  white-space: pre-wrap; /* 空白や改行文字を保持しつつ、テキストを必要に応じて折り返す */
  line-break: anywhere; /* 改行規則を無視 */
  text-spacing: none; /* 字間調整なし */
  font-size: 12Q;
  line-height: 18Q;
  border: solid 0.5mm #585656;
  padding-block: 0.5mm;
  padding-inline: 1.5mm;
  margin-block: 6mm;
  margin-inline: 0;
  background-image: url("img/vs_pre_bg.png"); /* ソースコード背景 */
  background-size: var(--page-body-width) 9mm;
  background-repeat: repeat-y; /* y方向に繰り返し */
  background-position-y: 0.5mm;
  border-radius: 1mm;
}
/* コード内色分け */
.token.keyword {
  color: #f00;
}
.token.string {
  color: #00f;
}
シンタックスハイライトのタグ指定によるコードの色分け

数式を入れる

vivliostyleでは、MathJaxというライブラリを使用して、LaTeX形式の数式をレンダリングすることができます。Markdownでの数式の表示方法には、テキストの途中に数式を表示するインライン数式と、blockレベルで表示するディスプレイ数式の2種類があるので、用途に応じて使い分けましょう。インライン数式にしたい場合は、$で囲み、ディスプレイ数式にしたい場合は$$で、該当箇所を囲みます。

インライン数式は$y=\frac{1}{x^2}$こんな感じになります。

ディスプレイ数式は$$f(x)=\frac{1}{\sqrt{2\pi}}\exp\left(-\frac{x^2}{2}\right)$$となります。

$$
\begin{eqnarray}
\frac{2}{3} + \frac{1}{5} &=& \frac{10}{15} + \frac{3}{15} \\
&=& \frac{13}{15}
\end{eqnarray}
$$
インライン数式とディスプレイ数式

clip-pathで手軽に図形を作る

簡単な図形であればIllustratorやPowerPointのような他のアプリを使用せず、CSSだけで作成することもできます。行頭にちょっとしたアイコンを入れたい場合や、画像を切り抜きたい場合などで重宝する機能です。clip-pathに使用することができる値は、inset(長方形)circle(円形)など、単調な図形のほか、polygon(多角形)path(パス文字列での生成)のような図形まで、種類や設定がさまざまなので、気になる方はclip-pathで調べてみてください。

吹き出しを作る

吹き出しは、喋らせるキャラクターのイラスト、吹き出しの囲み、吹き出しのくちばしの3パーツを組み合わせて作っていきます。くちばしの作り方には何通りかありますが、今回は先述したclip-pathを使用して作成していきましょう。

<p class="kaiwa deshi naki">CSS組版ってなんか難しそうで苦手意識があるなぁ……。ハードルも高そう……</p>

<p class="kaiwa sense fum">慣れると意外と簡単だよ! InDesignなどを使用した組版よりも楽な点もあるし、少しずつポイントをおさえて実践していこう!</p>
:root {
  --kaiwa-facesize: 21mm; /* イラストのサイズ指定 */
}

.kaiwa + .kaiwa {
  margin-block-start: 6mm; /* 吹き出し同士の空き */
}

.kaiwa { /* 吹き出しの囲み */
  background-color: #BCE1DF; /* 背景色 */
  border-radius: 1mm; /* 半径1mmの角丸 */
  margin: 2mm var(--kaiwa-facesize); /* 上下マージン2mm 左右マージンはイラスト分 */
  padding: 2mm; /* パディング2mm */
  font-size: 12Q; /* 文字サイズ12Q */
  line-height: 18Q; /* 行送り18Q */
  text-indent: 0; /* インデント0 */
  position: relative; /* 絶対参照の基準にする */
  inline-size: calc(var(--page-body-width) - var(--kaiwa-facesize) * 2); /* 横幅は版面からイラストサイズを引く */
}

.deshi { /* .deshiに対して */
  justify-self: end; /* 右揃え */
}

.sense::after { /* .senseの擬似要素::afterに対して */
  content: ""; /* 空のコンテンツ */
  background-color: #BCE1DF; /* 背景色 */
  clip-path: polygon(50% 0%, 50% 100%, 0% 50%); /* 三角形 */
  position: absolute; /* 絶対配置にする */
  inset-inline-start: -3mm; /* 左位置-3mm */
  inset-block-start: 2mm; /* 上位置2mm */
  inline-size: 10mm; /* 幅10mm */
  block-size: 5mm; /* 高さ5mm */
}

.sense.fum::before { /* .sense.fumの擬似要素::beforeに対して */
  content: ""; /* 空のコンテンツ */
  position: absolute; /* 絶対配置にする */
  inset-inline-start: calc(var(--kaiwa-facesize) * -1 + 0.6mm); /* 左位置イラストサイズ分引いて0.6mm足す */
  inset-block-start: -4mm; /* 上位置-4mm */
  inline-size: var(--kaiwa-facesize); /* 幅イラストサイズ */
  block-size: 14mm; /* 高さ14mm */
  background: url("kaiwaimg/chara2-1.png"); /* イラスト指定 */
  background-repeat: no-repeat; /* リピートなし */
  background-size: var(--kaiwa-facesize); /* 幅イラストサイズ */
  background-position-x: 0%; /* 背景のX座標0 */
  background-position-y: -3mm; /* 背景のY座標-3mm */
}

.deshi::after { /* .deshiの擬似要素::afterに対して */
  content: ""; /* 空のコンテンツ */
  background-color: #BCE1DF; /* 背景色 */
  clip-path: polygon(50% 0%, 100% 50%, 50% 100%); /* 三角形 */
  position: absolute; /* 絶対配置にする */
  inset-inline-end: -3mm; /* 右位置-3mm */
  inset-block-start: 2mm; /* 上位置2mm */
  inline-size: 10mm; /* 幅10mm */
  block-size: 5mm; /* 高さ5mm */
}

.deshi.naki::before { /* .sense.nakiの擬似要素::beforeに対して */
  content: ""; /* 空のコンテンツ */
  position: absolute; /* 絶対配置にする */
  inset-inline-end: calc(var(--kaiwa-facesize) * -1 + 0.6mm); /* 右位置イラストサイズ分引いて0.6mm足す */
  inset-block-start: -4mm; /* 上位置-4mm */
  inline-size: var(--kaiwa-facesize); /* 幅イラストサイズ */
  block-size: 14mm; /* 高さ14mm */
  background: url("kaiwaimg/chara1-1.png"); /* イラスト指定 */
  background-repeat: no-repeat; /* リピートなし */
  background-size: var(--kaiwa-facesize); /* 幅イラストサイズ */
  background-position-x: 0%; /* 背景のX座標0 */
  background-position-y: -3mm; /* 背景のY座標-3mm */
}
会話文が作成できる

さいごに

今回の記事では、リブロワークスが実作業で使用しているポイントや小技を紹介していきました。もちろん、解説したもの以外にも、CSS組版を円滑に進めるためのポイントは多く存在します。むしろ、今解決できない問題も、アップデートが入るたびに解決されるようになっていくのがCSS組版の良いところです。⁠現状のできる・できないの範囲を理解すること」⁠アップデートや新機能に対して敏感になること」を意識して作業することで、どんどん効率的になっていくことがCSS組版の面白さです。CSS組版を通じて、今読んでくださっている読者の方々と、この達成感や面白さを分かち合うことができれば幸いです。

おすすめ記事

記事・ニュース一覧