UP | HOME

Created: Aug 20, Wed, 2025

Modified: Sep 02, Tue, 2025

My Org CSS
Documentation and Source Code

This is my custom stylesheet for Org-exported HTML pages. It is built on top of Gong's Org CSS.

The goal is to create clean HTML pages for both screen viewing and PDF printing. Gong's CSS provides a great starting point, and I have been using it for over five years. Over time, however, I have developed several opinions on how to "improve" it in my preferred way, which then motivates this project.

This document is written in Emacs Org mode, and invoking the command org-babel-tangle will extract all CSS snippets into a single file ./dou-new-org.css.

Table of Contents

General Considerations

I have always appreciated the elegance of serif fonts, especially their exquisite details at larger sizes. I also value the clean look and excellent readability of sans-serif fonts, particularly in smaller text. Considering these preferences, I use the following font settings:

  • Lora (a serif font) for titles and headlines.
  • Fira Sans (a sans-serif font) for the main text[1].
  • Fira Code (a monospace font) for code and code-like elements.

I also use a variety of colors to make the page look vivid and fresh:

  • Black #00000 for the title and subtitle.
  • Blue #527d9a for headlines, matching the color of hyperlinks.
  • Magenta #d33682 for inline code, consistent with the Solarized palette I use in Org mode.

In the next section, I will provide CSS snippets to achieve these effects, along with a few other specific tweaks.

CSS Snippets

Grouped by elements or topics.

Blockquote

Use italic style.

blockquote {
    font-style: italic;
}

Body

Set font; set body width to 950 px if possible.

body {
    font-family: Fira Sans, Noto Sans CJK SC, sans-serif;
}

@media screen and (min-width: 960px) {
    body {
        width: 950px;
    }
}

Code

Set color for inline code; remove the border and padding for inline code; Set font for all code-like elements[2].

:not(pre) > code {
    color: #d33682;
    border: initial;
    padding: initial;
}

code, kbd, pre, samp {
    font-family: Fira Code, Noto Sans Mono CJK SC, monospace;
}

Headlines

Set font; set color.

h1, h2, h3, h4, h5, h6 {
    font-family: Lora, Noto Serif, Noto Serif CJK SC, serif;
    color: #527d9a;
}

Home and up links

Align left.

#org-div-home-and-up {
    text-align: left;
}

Preamble and Postamble

Gray out.

.status {
    color: #888888;
}

Reference list

Increase the lineskip to match normal text[3].

.csl-entry {
    margin: 1em auto;
}

Section symbol

Add the section sign "ยง".

h2::before,
h3::before,
h4::before,
h5::before,
h6::before {
    content: "§ ";
    margin-right: 0.4em;
    font-size: 70%;
    vertical-align: top;
}

Summary

Set cursor.

summary {
    cursor: pointer;
}

Table of Contents

Set font to match headlines.

#table-of-contents {
    font-family: Lora, Noto Serif, Noto Serif CJK SC, serif;
}

Title and subtitle

Use small caps; align left; normal weight; smaller size for the subtitle; medium weight for the subtitle;

.title {
    font-variant-caps: small-caps;
    text-align: left;
    font-weight: 400;
}

.subtitle {
    font-size: 60%;
    font-weight: 500;
}

To-do keywords

Consistent with the appearance in my Org mode.

.todo {
    background-color: inherit;  /* disable default background-color */
}

.done {
    background-color: inherit;  /* disable default background-color */
}

.todo.TODO {
    color: #dc322f;  /* solarized red */
}

.todo.NEXT{
    color: #d33682;  /* solarized magenta */
}

.todo.FOLLOW{
    color: #268bd2;  /* solarized blue */
}

.todo.WAITING{
    color: #2aa198;  /* solarized cyan */
}

.todo.INACTIVE{
    color: #6c71c4;  /* solarized violet */
}

.done.CANCELLED{
    color: #859900;  /* solarized green */
}

.done.DONE{
    color: #859900;  /* solarized green */
}

TODO Appendix: Animate the Details Element

Add smooth transitions for collapsing and expanding of <details> and <summary> elements.

CANCELLED Appendix: Copy Button for Code Blocks

Add a button for copying the content of code blocks.

DONE Appendix: Display Language Name in Source Blocks

Extend Gong's CSS to support more lanauges.

.org-src-container>pre.src-conf:before {
    content: "Conf"
}

.org-src-container>pre.src-elisp:before {
    content: "Emacs Lisp"
}

.org-src-container>pre.src-toml:before {
    content: "TOML"
}

DONE Appendix: Hide the Table of Contents

Use JS to hide the default TOC in the title. In particular, wrap the whole TOC (if persent) within the title via a detail/summary pair.

// Hide TOC
document.addEventListener('DOMContentLoaded', function () {
  // Get the title and TOC elements
  const title = document.querySelector('h1.title');
  const toc = document.querySelector('#table-of-contents');
  const titleParent = title.parentNode

  // Only proceed if both elements are found
  if (title && toc) {
    // Create the needed elements
    const details = document.createElement('details');
    const summary = document.createElement('summary');

    // Move the title inside the summary (preserving events, properties etc.)
    summary.appendChild(title);

    // Assemble the structure
    details.appendChild(summary);
    details.appendChild(toc);

    // Insert details as the first child of the original parent of title.
    titleParent.insertBefore(details, titleParent.firstChild);

    // title and toc have now been moved into 'details', no need to remove originals
  }
});

Usage. Save the above snippet as ./hide-toc.js, and insert it in the exported HTML head via adding a line

#+HTML_HEAD_EXTRA: <script defer src="hide-toc.js"></script>

DONE Appendix: Related Emacs Settings

Below is my configuring snippet related to org exporting for this project.

(use-package org
  ;; org export general options
  :config
  (setq org-export-default-language "en")
  (setq org-export-with-section-numbers nil)
  (setq org-export-with-sub-superscripts '{})
  (setq org-export-with-toc 4)
)

(use-package org
  ;; org HTML export options
  :config
  (setq org-html-checkbox-type 'unicode)
  (setq org-html-doctype "html5")
  (setq org-html-footnote-format "<sup>[%s]</sup>")
  (setq org-html-head-include-default-style nil)
  (setq org-html-htmlize-output-type 'inline-css)
  (setq org-html-metadata-timestamp-format "%b %d, %a, %Y")
  (setq org-html-postamble "\
<p class=\"author\">Author: %a</p>
<p class=\"date\">Exported: %T</p>")
  (setq org-html-preamble "\
<p class=\"date\">Created: %d</p>
<p class=\"date\">Modified: %C</p>")
  (setq org-html-self-link-headlines t)
  (setq org-html5-fancy t)
)

Footnotes:

[1]

For specific pages (e.g., math-related posts), I may use Lora for the main text to enhance the professional feelings. This can be done by setting export options on a per-file basis by adding a line

#+HTML_HEAD_EXTRA: <style>body {font-family: Lora, Noto Serif, Noto Serif CJK SC, serif;}</style>
[2]

Set the export option org-html-htmlize-output-type to inline-css to ensure that Emacs exports code blocks with the same color scheme as the current buffer; see here for more explanations.

[3]

See my post for how to write citations in Org mode.

Author: Dou Meishi

Exported: Sep 02, Tue, 2025