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/define.css);
@import url(../@vivliostyle/theme-base/css/reset.css);
@import url(../@vivliostyle/theme-base/css/basic.css);

/* Add required feature modules */
@import url(../@vivliostyle/theme-base/css/toc.css);
@import url(../@vivliostyle/theme-base/css/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.

Preview for verification:

npm run example: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 example: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.