themes

Developing Themes

Creating a Theme

Scaffolding with vivliostyle theme create

Vivliostyle CLI generates a theme project scaffold. npm create vivliostyle-theme is an alias of the same command.

vivliostyle theme create <directory>
# or
npm create vivliostyle-theme <directory>

You will be prompted to enter the following. Each one can also be given as a command-line option.

Field Option Description
Package name --name npm package name of the theme (default: vivliostyle-theme-<directory>)
Description --description Theme description
Author --author Author name
Category --category Theme category (novel / magazine / journal / report / misc)

Generated File Structure

<directory>/
β”œβ”€β”€ .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/
    β”œβ”€β”€ 01_typography.md      # Sample manuscripts (VFM format)
    β”œβ”€β”€ 02_figures-and-tables.md
    β”œβ”€β”€ 03_code-and-math.md
    └── assets/

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 the manuscripts in example/
example/*.md Sample Markdown demonstrating theme application. Supports VFM syntax

Customizing the Scaffold

Editing theme.css

The generated theme.css imports the theme-base modules and customizes them through CSS variables, along these lines:

/* Import the basic modules of theme-base */
@import '@vivliostyle/theme-base';

/* Import feature modules */
@import '@vivliostyle/theme-base/appendix';
@import '@vivliostyle/theme-base/citation';
@import '@vivliostyle/theme-base/endnote';
@import '@vivliostyle/theme-base/equation';
@import '@vivliostyle/theme-base/figure';
@import '@vivliostyle/theme-base/footnote';
@import '@vivliostyle/theme-base/listing';
@import '@vivliostyle/theme-base/math';
@import '@vivliostyle/theme-base/page';
@import '@vivliostyle/theme-base/section';
@import '@vivliostyle/theme-base/sidenote';
@import '@vivliostyle/theme-base/table';
@import '@vivliostyle/theme-base/theorem';
@import '@vivliostyle/theme-base/toc';

/* Add code highlighting (Prism) */
@import '@vivliostyle/theme-base/prism';
@import '@vivliostyle/theme-base/prism/theme-okaidia';

: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-bottom-center-content: counter(page);
  --vs-page--mbox-top-left-content: env(doc-title);

  /* Table of contents */
  --vs-toc--ol-indent-size: 1.5rem;
}

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. The package entry contains only the basic modules, so keep just the feature module imports you need.

/* Basic modules only */
@import '@vivliostyle/theme-base';

/* Add required feature modules */
@import '@vivliostyle/theme-base/toc';
@import '@vivliostyle/theme-base/footnote';

Available modules (imported as @vivliostyle/theme-base/<subpath>):

Subpath Contents CSS Variable Prefix
(package entry) CSS reset, variable defaults, basic HTML tag styles --vs-, --vs--
figure Figure numbering and cross-references --vs-figure--
table Table numbering and cross-references --vs-table--
citation Citation numbering and cross-references --vs-citation--
listing Code listing numbering and cross-references --vs-listing--
equation Equation numbering and cross-references --vs-equation--
theorem Theorem numbering and cross-references --vs-theorem--
appendix Appendix lettering and cross-references --vs-appendix--
endnote Endnotes --vs-endnote--
footnote Footnotes --vs-footnote--
footnote/external-links Footnotes for external links --vs-footnote--
page Paged media --vs-page--
section Heading counters and section references --vs-section--
toc Table of contents --vs-toc--
math Math (MathML / MathJax) display --vs-math--
sidenote Numbered sidenotes --vs-sidenote--
prism Code highlighting base --vs-prism--
prism/theme-prism Prism default theme --vs-prism--
prism/theme-okaidia 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;

  /* Shared cross-reference counter style */
  --vs-counter-style: upper-roman;

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

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

:root {
  --vs-theme-techbook--inline-code-color-bg: #ecf0f1;
  --vs-theme-techbook--inline-code-color-body: #34495e;
  --vs-theme-techbook--footnote-color-bg-on-screen: #e6f6d7;
  --vs-theme-techbook--image-resolution-for-figure-image: 300dpi;
}

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 validate before publishing to verify your package. In the generated scaffold it is wired to npm run validate.

npm run validate

Validation checks:

Check Severity Description
Style locator Error One of vivliostyle.theme.style, style, or main must be set
Style file Error The style file must exist inside the package directory (a warning if it is not a .css)
Author info Warning vivliostyle.theme.author or author should be set
Keywords Warning keywords should include vivliostyle-theme
Category Warning vivliostyle.theme.category must be one of the categories above

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.