Homeemacs › Custom inlined CSS in Org-mode HTML export

Custom inlined CSS in Org-mode HTML export

When you export an Org-mode document to HTML the default CSS style is:

  • inlined in the file, which is rather handy: a single file for you whole document.
  • not exactly pretty, but you can change this.

So I naturally look at the Org-mode documentation on customizing the CSS only to find that the simplest and recommended way of doing it is to add a special keywords at the top of your document:

#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="style1.css" />

Which means that I won’t have a single file anymore. Plus I have to put these each time I want a custom CSS. Not cool.

What I want is to change the default inlined style for every document I export to HTML. And also a nicer way to set a new style for a single document.

The documentation does mention the org-html-style-default and org-html-head-include-default-style variables, let’s have a look at org-mode/lisp/ox-html.el

Note: I’m using a recent version of Org-mode which has a new parse/export system. If you’re using a version ≥8 you should be fine.

The docstring of org-html-style-default reads:

The default style specification for exported HTML files. You can use `org-html-head’ and `org-html-head-extra’ to add to this style. If you don’t want to include this default style, customize `org-html-head-include-default-style’.

We just have to set org-html-head-include-default-style to nil and place our own style in org-html-head. I’ve added a function to the org-export-before-processing-hook to setup these variables before exporting.

Here’s what I put in my init file:

(defun my-org-inline-css-hook (exporter)
  "Insert custom inline css"
  (when (eq exporter 'html)
    (let* ((dir (ignore-errors (file-name-directory (buffer-file-name))))
           (path (concat dir "style.css"))
           (homestyle (or (null dir) (null (file-exists-p path))))
           (final (if homestyle "~/.emacs.d/org-style.css" path)))
      (setq org-html-head-include-default-style nil)
      (setq org-html-head (concat
                           "<style type=\"text/css\">\n"
                           "<!--/*--><![CDATA[/*><!--*/\n"
                           (with-temp-buffer
                             (insert-file-contents final)
                             (buffer-string))
                           "/*]]>*/-->\n"
                           "</style>\n")))))

(eval-after-load 'ox
  '(progn
     (add-hook 'org-export-before-processing-hook 'my-org-inline-css-hook)))

I’ve settled on inlining a default style in .emacs.d/org-style.css or the content of a file style.css if it exists in the same directory as my document.

In hindsight I think I should make the 2 variables buffer-local before setting them but it works well like this.

1 Comments.[ Leave a comment ]

  1. I faced the same problem. I wanted HTML files that did not need to load an external CSS file so they’d be more portable. I just add

    #+SETUPFILE: .publish-style

    in my org file. .publish-style contains my CSS, with each line prefixed with #+STYLE:. Ugly, but it works, and lets me use different CSS files for different org files, should I want to.

Leave a Comment

NOTE - You can use these HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>