English | 日本語
Developing Themes

Developing Themes

Creating a Theme

Scaffolding with create-vivliostyle-theme

Use the create-vivliostyle-theme CLI to generate a theme project scaffold.

npm create vivliostyle-theme <theme-name>

You will be prompted to enter the following:

Field Description
description Theme description
author Author name
email Email address
license License (MIT, Apache-2.0, etc.)
category Theme category (novel / magazine / journal / report / misc)

After completion, a vivliostyle-theme-<theme-name> directory is created.

Generated File Structure

vivliostyle-theme-<name>/
├── .gitignore
├── package.json          # Package definition (includes vivliostyle.theme config)
├── README.md             # Theme description and usage
├── theme.css             # Main theme CSS
├── vivliostyle.config.js # Configuration for previewing
└── example/
    └── default.md        # Sample manuscript (VFM format)

File roles:

File Role
package.json Theme metadata. The vivliostyle.theme property defines the theme name, author, main CSS, and category
theme.css The main style definition. Pre-configured with theme-base @import and CSS variable customizations
vivliostyle.config.js Used with vivliostyle preview to check the theme. Entry points to example/default.md
example/default.md Sample Markdown demonstrating theme application. Supports VFM syntax

Customizing the Scaffold

Editing theme.css

The generated theme.css includes theme-base module imports and CSS variable customization examples.

/* Import all theme-base modules */
@import url(../@vivliostyle/theme-base/theme-all.css);

/* Add code highlighting (Prism) */
@import url(../@vivliostyle/theme-base/css/lib/prism/base.css);
@import url(../@vivliostyle/theme-base/css/lib/prism/theme-okaidia.css);

:root {
  /* Basic styles */
  --vs-font-family: 'Times New Roman', serif;
  --vs-font-size: 12px;
  --vs--heading-line-height: 1.3;
  --vs--h1-font-size: 2.5em;

  /* Footnotes */
  --vs-footnote--call-content: '[' counter(footnote) ']';

  /* Page layout */
  --vs-page--mbox-content-bottom-center: counter(page);
  --vs-page--mbox-content-top-left: env(doc-title);

  /* Table of contents */
  --vs-toc--marker-margin-inline: 8rem;
}

Add your own styles at the end of this file. For example, to set the page size:

@page {
  size: A5;
  margin: 20mm 15mm;
}

Using theme-base Modules

theme-base is divided into functional modules. If you don't need all modules, you can import only the ones you need instead of theme-all.css.

/* Basic modules only */
@import url(../@vivliostyle/theme-base/css/common/meta-properties.css);
@import url(../@vivliostyle/theme-base/css/common/reset.css);
@import url(../@vivliostyle/theme-base/css/common/basic.css);

/* Add required feature modules */
@import url(../@vivliostyle/theme-base/css/partial/toc.css);
@import url(../@vivliostyle/theme-base/css/partial/footnote.css);

Available modules:

Category Module CSS Variable Prefix
common meta-properties.css — Document-wide meta properties --vs-
common reset.css — CSS reset
common basic.css — Basic HTML tag styles --vs--
partial crossref.css — Cross-reference for figures, tables, citations --vs-crossref--
partial endnote.css — Endnotes --vs-endnote--
partial footnote.css — Footnotes --vs-footnote--
partial footnote-external-link.css — Footnotes for external links --vs-footnote--
partial page.css — Paged media --vs-page--
partial section.css — Heading counters and section references --vs-section--
partial toc.css — Table of contents --vs-toc--
partial utility-classes.css — Utility classes
lib prism/base.css — Code highlighting base --vs-prism--
lib prism/theme-prism.css — Prism default theme --vs-prism--
lib prism/theme-okaidia.css — Okaidia theme --vs-prism--

For details, see the theme-base README.

Overriding CSS Variables

You can customize themes by overriding CSS variables exposed by theme-base and individual themes in :root.

:root {
  /* Font settings */
  --vs-font-family: 'Noto Serif JP', serif;
  --vs-font-size: 10.5pt;

  /* Headings */
  --vs--h1-font-size: 2em;
  --vs--heading-line-height: 1.4;

  /* Cross-reference counter style */
  --vs-crossref--counter-style: upper-roman;

  /* Page header/footer */
  --vs-page--mbox-content-top-left: env(pub-title);
  --vs-page--mbox-content-top-right: env(doc-title);
  --vs-page--mbox-content-bottom-center: counter(page);
}

As a practical example, theme-techbook exposes theme-specific CSS variables (--vs-theme--*):

:root {
  --vs-theme--anchor-color-body: #3498db;
  --vs-theme--blockquote-color-bg: #ecf0f1;
  --vs-theme--inline-code-color-bg: #ecf0f1;
  --vs-theme--image-resolution-for-figure-image: 300dpi;
  --vs-theme--page-top-left-content: env(pub-title);
  --vs-theme--page-bottom-content: counter(page);
}

Editing the example/ Directory

Place sample Markdown files in example/ to demonstrate theme application.

  • At least one Markdown file is required
  • VFM (Vivliostyle Flavored Markdown) syntax is supported
  • It is recommended to cover the major styles your theme supports (headings, code blocks, footnotes, images, math equations, etc.)

Preview for verification:

npm run preview

Publishing a Theme

Pre-publish Validation

Run vivliostyle-theme-scripts validate before publishing to verify your package.

npm run validate

Validation checks:

Check Severity Description
Style locator Error One of vivliostyle.theme.style, style, or main must be set
Author info Warning vivliostyle.theme.author or author should be set

Preview Check

npm run preview

Based on the vivliostyle.config.js configuration, a preview with the theme applied to the sample manuscripts in example/ will be displayed.

Required package.json Fields

{
  "name": "vivliostyle-theme-<name>",
  "main": "theme.css",
  "keywords": ["vivliostyle", "vivliostyle-theme"],
  "vivliostyle": {
    "theme": {
      "name": "Theme Display Name",
      "author": "Author Name",
      "style": "theme.css",
      "category": "misc",
      "topics": []
    }
  }
}
Field Required Description
vivliostyle.theme.style Path to the main CSS file
vivliostyle.theme.author Theme author name
vivliostyle.theme.name Theme display name
vivliostyle.theme.category novel / magazine / journal / report / misc
vivliostyle.theme.topics Array of topics describing the theme's use cases
keywords Recommended to include "vivliostyle" and "vivliostyle-theme"

See the Spec of Vivliostyle Theme for the full specification.

Publishing to npm

npm publish

After publishing, your theme can be found at:

Proposing as an Official Theme

You can propose your theme as an official Vivliostyle theme. See Adoption of the Official Theme for details.