3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Markdownでスライドを書いてCSSでスタイルを設定してVivliostyleで組んでプレゼンする

Last updated at Posted at 2025-04-10

研究会発表でのプレゼンを想定して、スライドをHTML…というかMarkdownとCSSで作る場合の嬉しいところをピックアップして、CSSの使い方を見てみます。

Markdown→HTML→CSSでプレゼンという処理系はいくつかあって、同じCSSの手法がそのまま使えるとは限りません。この記事ではVivliostyle12を想定します。

想定する状況は次のようなものです。まず、学会の研究会での発表ならば元になる論文/予稿があって、主張をテキストで表現できているところからスライド作りが始まると思います。また、ヘッダーやフッターに挿入する項目(「日付」、「研究会名」、など)や書式(「スライド番号/総スライド数」、など)が研究室などで指導されていたりもします。

この記事のサンプルは次の通りです:

Vivliostyleを使ってサンプルを試す方法は、記事の最後「サンプルを試す」で説明します。

テキストの回り込み

HTML+CSSでは図にfloatプロパティを設定して、テキストが図を回り込むのが普通で、特に工夫はいりません。プレゼン・アプリだと改行を手作業で入れたりテキスト・ボックス全体の幅を狭くしたりして調整するところです。

画像の左側にテキストが回り込んでいる例の図

「◯にA」の図はcircle.svgというSVGファイルで、次のMarkdownで挿入されています。

![](circle.svg){style="float-reference: page; float: block-start inline-end;"}

これは普段のWebページでは見られないfloatの設定です。float-reference: page;は配置の基準をpageと設定していて3float: block-start inline-end;は、横書きの場合は、page右上に寄せるように指定しています4

改行位置の調整

CSSでは自動的に折り返される改行の位置を、word-breakプロパティ5を使って調整できます。

既定値のword-break: normal;という設定では、普通の規則で改行します:

普通の規則で改行してテキストが図を回り込んでいる図

word-break: auto-phrase;という設定では、日本語として、より自然な位置で改行します:

日本語として自然な位置で改行してテキストが図を回り込んでいる図

auto-phraseの効果については好みが分かれるかもしれません。

なお、サンプルのスライド全体には、試しにword-break: auto-phrase;と設定しています。

文字数が均等になるような改行

先頭スライド/カバー・スライドのタイトルは文字も大きいので1行に収まらないことがあります。そんなときに、前記のように自然な位置で改行して、かつ、各行がほぼ同じ長さになるよう調整してもらうこともできます。

先頭スライドのタイトルが、次のようなMarkdownだとします。タイトルには改行が入っていません。

# Markdownでスライドを書いてVivliostyleで組んでプレゼン #

CSSの設定で、自動的に次のように改行させられます。

text-wrap-balance.png

CSSの設定は次のとおりです:

  • word-break: auto-phrase;で、ことばとして自然なところで改行します
  • text-wrap: balance;6で、行の文字数が均等になるように改行します

約物の前後の空白の詰め

"「"や"("といった約物が行頭・行末にきたり連続したりする場合の空白の詰めを,
text-spacing-trimプロパティ78で制御できます。

text-spacing-trim: normal;で、行頭の約物は詰めませんが、約物が連続するときに詰めます。これが既定値です。

text-spacing-trim-normal.png

text-spacing-trim: trim-both;と設定すると、行頭行末や連続する約物の空白を詰めます。

text-spacing-trim-trim-both.png

text-spacing-trim: space-all;と設定すると、約物の空白を詰めません。前の2つと比べてみてください。

text-spacing-trim-space-all.png

スライドはテキストが短く箇条書きも多いので、テキストのまとまりは行頭の揃えで見せるのがよいかもしれません。

サンプルのスライドは、全体にtext-spacing-trim: trim-both;と設定しています

ヘッダーとフッター

スライド本文から次のようなテキストを抜き出して、ヘッダーやフッターに表示できます:

  • 発表のタイトル(h1要素)やセクションの見出し(##見出し、つまりh2要素など)といった既定のタグの付いたテキスト
  • 日付、発表者、研究会名など既定のタグが付いていないテキスト

また、総スライド数を数えてくれて、その値を自動生成するテキストに含められます。

ヘッダー/フッターはCSSのマージン・ボックス

ヘッダーやフッターを表示するには、CSSのマージン・ボックスを利用します。マージン・ボックスは、@top-left@bottom-right-cornerなど、側面とコーナーの合計16個の場所が定義されています91011

スライド本文のテキストを抜き出して表示

スライド本文から所定のテキストを自動的に抜き出してヘッダーやフッターに表示できると、本文を修正したときの修正漏れを防げます。

これには、CSSの名前付き文字列(named string12)という仕組みを使います。

やり方は大まかに次の手順です:

  1. 抜き出したいテキストに印を付ける。
    「印が付く」=「セレクターで選べる」です
  2. その印を手がかりとしてテキストに名前を付ける
  3. その名前を使って、表示したい場所にテキストを生成する

次の順に説明します:

  1. 発表のタイトルやセクションの見出し
  2. 発表のタイトル、日付、発表者、研究会名など

発表のタイトルやセクションの見出し

発表タイトルにはh1、セクションの見出しにはh2といったHTML既定の印(タグ)を付けます。h2見出しを、(自動生成した)番号付きで各スライドの@top-rightマージンに表示するとしてみましょう。

それにはCSSのstring-setプロパティを使って、生成した番号に、例えばchapter-numberという名前を、テキストにchapterという名前を付けます。

h2 {
    string-set: chapter-number content(before), chapter content();
}

content(before)h2::before疑似要素の内容を示します。::before疑似要素に番号を生成してる想定です。content()content(text)という意味で、h2のテキストを示します。

そして、@top-rightマージンのcontentプロパティの値で、string関数の中でこれらの名前を使ってテキストを参照します。firstは、そのスライド(ページ)中の最初の見出しを使います; 見出しが2つあったら最初のものを使うということです。

@page {
    @top-right { content: string(chapter-number, first) " " string(chapter, first); }
}

これでスライドの右上に、番号付きで見出しが表示されます。このスライドは「6.3 発表の…」ですが、1つ上位の「6. ヘッダーとフッター」という見出しが表示されてます。

top-rightマージンに見出しが表示されている

日付、発表者、研究会名など - その1

「研究会名」といったHTML既定の印(タグ)はないので、印の工夫から始めます。

Vivliostyle用のMarkdownとして開発されている、VFM (Vivliostyle Flavored Markdown13)は、Markdownの見出しに応じてsection要素を生成して階層化してくれます14。これを利用します。

印を付ける

Markdown (VFM)で「研究会名」という見出しにconferenceクラスを設定します:

### 研究会名{.conference}

第3回 プレゼン研究発表会

すると、次のようなHTMLが生成されます:

<section class="level3" aria-labelledby="研究会名">
  <h3 class="conference" id="研究会名">研究会名</h3>
  <p>第3回 プレゼン研究発表会</p>
</section>

これで"第3回 プレゼン研究発表会"に印が付きました。つまり、:has(> .conference) > pというセレクターで取り出せます。「印が付く」=「セレクターで選べる」です。

名前を付ける

ここで次のようなCSSを適用すると、"第3回 プレゼン研究発表会"string-conferenceという名前が付きます。

h2.conference {
    display: none;
}
:has(> .conference) > p {
    string-set: string-conference content();
}

「研究会名」という見出しそのものはスライドに表示しないのでdisplay: none;としています。

フッターに生成する

次の設定で@bottom-centerマージンに研究会名を表示します。

@page {
    @bottom-center { content: string(string-conference); }
}

スライドの下中央に「第3回 プレゼン研究発表会」と表示されました。

bottom-centerマージンに研究発表会名が表示されている

日付、発表者、研究会名など - その2

「研究会名」を識別する印(タグ)を前提としないような、印の工夫から始めます。

印を付ける

VFMで次のように書いて、@bottom-centerマージンに表示したい項目にbottom-centerクラスを設定すると、次のようなHTMLが生成されます(aria-labelledby属性などを省略してます):

### 研究会名{.conference .bottom-center}

第3回 プレゼン研究発表会
<section>
  <h3 class="conference bottom-center">研究会名</h3>
  <p>第3回 プレゼン研究発表会</p>
</section>

"第3回 プレゼン研究発表会"に印が付きました。:has(> .bottom-center) > pというセレクターで取り出せます。

名前を付ける

ここで次のようなCSSを適用すると、"第3回 プレゼン研究発表会"string-bottom-centerという名前が付きます。

:has(> .bottom-center) > p:first-of-type {
    string-set: string-bottom-center content();
}

フッターに生成する

@bottom-centerマージンに表示します。

@page {
    @bottom-center { content: string(string-bottom-center); }
}

スライドの下中央に「第3回 プレゼン研究発表会」と表示されました。

bottom-centerマージンに研究発表会名が表示されている

日付、発表者、研究会名など - 検討

日付、発表者、研究会名などを本文から抜き出してヘッダー/フッターに表示する方法について、少し振り返ってみます。

印と見出し

印を付けるために見出し#####.conferenceクラスを設定して利用しました。

  • 印に見出しを利用すると、Markdownエディターのアウトライン表示に印が表示されます
  • このことを覚えておいて、後で説明するスライド区切りの設定などに必ず反映します

Markdownエディターでのアウトライン表示にこだわらなければ、その1方式のMarkdownで次のように書いて印を付けられます。

これは<span class="conference">プレゼン学会 第4回研究発表会</span>で発表したものです。

方式の比較

その1方式とその2方式、どちらがよいかは意見が分かれるところでしょう。

その1方式
  • Markdownを見ただけでは、フッター中央に何が表示されるか分かりません。何を表示するかはCSS側で決めます。
  • CSSには.conference(を直下に持つsectionの最初のp)をフッター中央に表示すると書いてあります。.conferenceはMarkdown(というかHTML)側が決めた印(クラス)ですが、CSS側はこれを前提にしています。
  • このCSSをたまたま見つけてスタイルを気に入った発表者が、発表者名をフッター中央に表示したいと思ったら、発表者名.conferenceクラスを設定するでしょう。
その2方式
  • CSSを見ただけでは、フッター中央に何が表示されるか分かりません。何を表示するかはMarkdown側で.bottom-centerクラスを指定して決めます。
  • これはMarkdown側にスタイル情報を含めることを意味します。

スライド番号 / 総スライド数

各スライドに番号(ページ番号)があると、Q&Aタイムで各スライドにランダムアクセスしやすいです。また、総スライド数が表示されていると、発表者本人だけでなく座長や聴いてる人たちも安心です。

スライド番号(ページ番号)や総スライド数(総ページ数)は、何もしなくても、それぞれpagepagesカウンターに設定されています。

そこで、CSSに次のように書くだけで、右下マージンに「スライド番号 / 総スライド数」が表示されます。

@page {
  @bottom-right {
      content: counter(page) " / " counter(pages);
  }
}

スライドの右下に「10 / 24」と表示されました。10番目のスライドで、総スライド数が24です。

bottom-rightマージンにスライド番号と総スライド数が表示されている

参考文献を脚注や文末脚注として表示

研究発表会のプレゼンでは、主な参考文献を脚注として各スライドの下部に表示(脚注)したり、最後のスライドにまとめて表示(文末脚注)したりすることがあります。

各スライドの下部に表示する例

サンプルのCSSでは、スライド下部に脚注として表示する場合は、span要素を使ってfnクラスを設定します。

…VFM (Vivliostyle Flavored Markdown)<span class="fn">[Vivliostyleに特化したMarkdown - VFMの使い方](https://gihyo.jp/article/2024/03/vivliostyle-02)</span>は、Markdownの見出しに応じてsection要素を生成して

「VFM (Vivliostyle Flavored Markdown)」の右肩に「*4」が付いて、そのスライド下部に本体が脚注として表示されました。

footnote.png

最後のスライドにまとめて表示する例

最後のスライドにまとめて表示する場合は、Markdownの記法はQiitaと同じです。

…ちなみに、CSS (Cascading Style Sheets)でも脚注を実現できます[^CSS]。

[^CSS]: CSS Generated Content for Paged Media Module 2. Footnotes [https://www.w3.org/TR/css-gcpm-3/#footnotes](https://www.w3.org/TR/css-gcpm-3/#footnotes)

注の本体は最後のスライドにまとめて表示されます。

endnote.png

スライドに詰め込む

(was:文字サイズの調整)

「1行だけスライドから溢れてしまったけど、テキストを修正する余裕がない」ことってありますよね。

見出しより下の部分<div style="font-size: 90%;">…</div>で囲んで文字サイズを調整します。

下のMarkdownが次のようだとすると:

## 見出し

このスライドの文字を小さくしたい。

次のように見出しより下の部分を囲みます:

## 見出し

<div style="font-size: 60%;">

このスライドの文字を小さくしたい。
</div>

その他の方法

他の方法で調整できるかもしれません。前の例のfont-size: 70%;部分には、次のようなパターンが考えら得ます。ただし、読みにくくなって不評を買うかもしれません。

  1. font-size: 90%;などで文字のサイズを少し小さくしてみます
  2. line-height: 1;などで行の幅を指定します。1などの数字にフォントサイズを掛けたものなります。1.51.8になってることが多いので、少し狭くしてみます
  3. word-break: break-all;で禁則なども無視して改行できるようにします。word-break: auto-phrase;は行数が増えがちです
  4. margin-inline-start: -2em;margin-inline-end: -2em;などで文字が進む方向の余白(マージン)の大きさを負にすると、行頭(-start)や行末(-end)で使える幅が広がって長い行が収まります
  5. margin-block-start: -1em;margin-block-end: -1em;などで行が進む方向の余白の大きさを負にすると、収まる行数が増えます…が、前後の行の文字と重なるかもしれません
  6. letter-spacing: -1px;などで字間のスペースに負の値を指定します
  7. position: relative; left: -1em; top: -1em;などとすると、サイズではなく位置(position)を上下左右にズラせます。この例だと左(left)に1文字分、上(top)に1文字分ズレ(relative)ます

スライドとしての基本的なスタイル設定とプレゼン操作

「A4の論文の印刷」ではなく「プレゼンのスライド」であるために、以下のようなお膳立てをします。

用紙サイズをA5横くらいに設定

A5横を基本に4:3や16:9になるように調整すると、見出しなどの既定の文字サイズがほどよい大きさになるでしょう9

@page {
    size: A5 landscape; /* 210mm 148mm */
    /* size: 216mm 162mm; 4:3 */
    /* size: 256mm 144mm; 16:9 */
}

#####でスライドを区切る

break-beforeプロパティ15を使って、##(HTMLのh2)に加えて###(HTMLのh3)くらいまでを既定のスライド区切りにしておきます。

  • VFMの場合、それらを直下に持つsection要素を1枚のスライドに対応させます
  • ヘッダー/フッターに表示するため導入した.conferenceクラスなど、便利な印を設定したh2h3をスライド区切りから除外します

任意でスライドを区切るためにの.break-before-pageクラスと、スライド区切りを止める.break-before-autoといったクラスも用意しておくと便利です。

.break-before-page,
section:has(> h2),
section:has(> h3:not(.conference, .bottom-center)) {
    break-before: page;
}
.break-before-auto,
section:has(> h2.break-before-auto, > h3.break-before-auto) {
    break-before: auto;
}

アウトライン番号

見出しの前に「1.」、「1.1」などと番号を振って、アウトライン(section構造)を示すと、プレゼンのときに今どこの話をしてるのか、聞き手が理解する助けになります。プレゼン・アプリには見られない機能です。

プレゼンはVivliostyleやPDFで

Vivliostyle Viewerではズーム(拡大/縮小)したり文字サイズを変更したりハイライトしたりできます

  • ズームではスライド全体が拡大・縮小します
  • 文字サイズの変更では、そのサイズで再レイアウトされ、スライド数が増えたり減ったりすることがあります
  • ちなみに画像は、文字サイズに基づいてblock-size: 2em;などと指定していると、文字とあわせて一緒にサイズが変わります。block-size: 320px;などの指定では、サイズは変わりません

highlight.png

もちろん、PDFで保存してPDFでプレゼンすることもできます。

レイアウトのテンプレート

最後に少しだけ…

CSSで、本文のテキストを2次元に配置したりできます。

次のようなMarkdownのテキストを:

### ポイント1

- こういった配置は他の誰かがデザインしたものを使えるとよいですね。
- この話は別の機会に

### ポイント2

- CSSの競合/相互作用を制御する**お約束**が必要でしょう。
- みんなが`!important`を使う世界もどうかと思いますし。

### ポイント3

- 色は匂へど散りぬるを
- 我が世誰ぞ常ならむ
- 有為の奥山今日越えて
- 浅き夢見し酔ひもせず。

### ポイント4

- 色は匂へど散りぬるを
- 我が世誰ぞ常ならむ
- 有為の奥山今日越えて
- 浅き夢見し酔ひもせず。

次のスライドの、「9.1 表示」の下のように表示できます:

grid.png

こういった配置は色や背景も含めていろんなパターンが考えられます。しかし、ゼミのレビューや発表当日が迫るなか、そんなCSSをゼロから工夫するのは苦しいです。

そこで、いろんなパターンがテンプレートなどとしてあらかじめ用意されてるとよいですね。それは複数の人が作ったCSSを組み合わせて使う世界なので、何らかのお約束が必要でしょう。この例のCSSは、このスライドのための個別CSSに設定してあって、テーマCSSで設定された見出し###の番号生成や改スライドを無効にするなどの工夫が必要でした。

サンプルを試す

Vivliostyleでサンプルを試す方法です

Vivliostyleのインストール方法はこちらの記事にあります:

実際に使ってみよう - Vivliostyleでなにができるの?

サンプルのMarkdown、図、CSSをダウンロードして、次のファイル構造にしてください(図はなくても、とりあえずエラーにはなりません):

|--author.css
|--figure
|  |--arrow-down.svg
|  |--arrow-right.svg
|  |--circle.svg
|  |--figure.svg
|  |--highlight.png
|--slide.md
|--theme.css

ここで次のコマンドを実行するとスライドをプレビューできます:

$ vivliostyle preview slide.md -T theme.css

ウィンドウを閉じるとプレビューが修了します。

PDFを出力するには次のようにします:

$ vivliostyle build slide.md -o slide.pdf -T theme.css

-Tまたは--themeオプションはスライドのCSSファイルを指定します。-oまたは--outputオプションは出力のファイルです。

author.cssもCSSファイルですが、これを使うことはslide.mdファイルの中の次の記述で指定しています:

---
link:
  - rel: 'stylesheet'
    href: 'author.css'
---

theme.cssはみんなのスライドで使えるように用意したCSSで、Vivliostyleではテーマ(theme)と呼びます。Vivliostyle Theme16というと、このようなテーマCSSやテーマCSSを運用する仕組みを指します。

author.cssはこのサンプルのスライド用に用意したCSSです。矢印や2次元配置は、ここで定義しています。

  1. Vivliostyle https://vivliostyle.org/

  2. Vivliostyleが拓くCSS組版の可能性 記事一覧 https://gihyo.jp/list/group/Vivliostyle%E3%81%8C%E6%8B%93%E3%81%8FCSS%E7%B5%84%E7%89%88%E3%81%AE%E5%8F%AF%E8%83%BD%E6%80%A7

  3. 3.1. The float-reference property - CSS Page Floats https://drafts.csswg.org/css-page-floats/#float-reference-property

  4. 3.2. The float property - CSS Page Floats https://drafts.csswg.org/css-page-floats/#float-property

  5. word-break https://developer.mozilla.org/ja/docs/Web/CSS/word-break

  6. text-wrap https://developer.mozilla.org/ja/docs/Web/CSS/text-wrap

  7. text-spacing-trim https://developer.mozilla.org/ja/docs/Web/CSS/text-spacing-trim

  8. CSS - text-spacing-trim - とほほのWWW入門 https://www.tohoho-web.com/css/prop/text-spacing-trim.htm

  9. @page https://developer.mozilla.org/ja/docs/Web/CSS/@page 2

  10. CSS Paged Media Module Level 3 - 5. Page-Margin Boxes https://www.w3.org/TR/css-page-3/#margin-boxes

  11. CSS - @page - とほほのWWW入門 https://www.tohoho-web.com/css/rule/page.htm

  12. 1.1. Named strings - CSS Generated Content for Paged Media Module https://www.w3.org/TR/css-gcpm-3/#named-strings

  13. Vivliostyleに特化したMarkdown - VFMの使い方

  14. セクション分け - Sectionization

  15. break-before https://developer.mozilla.org/ja/docs/Web/CSS/break-before

  16. CSSフレームワークVivliostyle Themeで簡単にページデザインを編集する

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?