sphinx-better-theme: usable documentation

sphinx-better-theme is a theme for Sphinx that looks nice, is easy to style with CSS, works well on small screens and mobile devices, and organizes the page better. See Why? for details.

You can get the source and open issues on Github.

Installation

Get it from PyPI:

> pip install sphinx-better-theme

Or download the zip file and run the usual command:

> python setup.py install

Once the package is installed, make these changes to conf.py to direct Sphinx to use the theme:

from better import better_theme_path
html_theme_path = [better_theme_path]
html_theme = 'better'

Read the Docs Configuration

Using sphinx-better-theme with Read the Docs is easy. You just need to tell it to install the package.

First, create a requirements.txt file just for your docs. It should look like this:

sphinx-better-theme==0.1.4
# other dependencies for your docs if any

I suggest putting it in your docs folder, e.g. at docs/requirements.txt.

Then, go to your Read the Docs admin panel. Make sure the Use virtualenv checkbox is enabled, and set the Requirements file field to the path to your requirements.txt file.

Read the Docs should now build and display your theme correctly, assuming your conf.py contains the changes described above.

User guide

For installation instructions, see Installation.

If you get stuck, you can look for information in Sphinx’s documentation for using a theme, but in theory all the relevant information is collected right here. Open a Github issue if something’s missing.

This document assumes you’ve already set up Sphinx and have some docs written.

sphinx-better-theme is meant to be customized primarily via CSS. There are a few options that you can set in conf.py, but they are either functionality-related or appear in more than one annoying-to-type selector.

CSS-based customization is currently limited by the inflexibility of the markup. That situation should improve over time as sphinx-better-theme sheds more and more of its inheritance from the basic theme.

Feel free to read the conf.py for this site to get ideas for your own site. Make sure you also read Suggested Sphinx options.

Theme options

Unless you’re creating your own theme that inherits from sphinx-better-theme, you’re probably setting theme options in conf.py. Here are all the defaults:

html_theme_options = {
  # show sidebar on the right instead of on the left
  'rightsidebar': False,

  # inline CSS to insert into the page if you're too lazy to make a
  # separate file
  'inlinecss': '',

  # CSS files to include after all other CSS files
  # (refer to by relative path from conf.py directory, or link to a
  # remote file)
  'cssfiles': ['_static/my_style.css'],  # default is empty list

  # show a big text header with the value of html_title
  'showheader': True,

  # show the breadcrumbs and index|next|previous links at the top of
  # the page
  'showrelbartop': True,
  # same for bottom of the page
  'showrelbarbottom': True,

  # show the self-serving link in the footer
  'linktotheme': True,

  # width of the sidebar. page width is determined by a CSS rule.
  # I prefer to define things in rem because it scales with the
  # global font size rather than pixels or the local font size.
  'sidebarwidth': '15rem',

  # color of all body text
  'textcolor': '#000000',

  # color of all headings (<h1> tags); defaults to the value of
  # textcolor, which is why it's defined here at all.
  'headtextcolor': '',

  # color of text in the footer, including links; defaults to the
  # value of textcolor
  'footertextcolor': '',

  # Google Analytics info
  'ga_ua': '',
  'ga_domain': '',
}

Adding static files

(This is all vanilla Sphinx, but you’ll need it for the next section.)

  1. Configure a static directory:

    html_static_path = ['_static']
    
  2. Put a file in it (e.g. docs/_static/cat.png).

  3. Use it.

Using CSS files

  1. Add your CSS file as a static file as above (like docs/_static/style.css).
  2. Add the file name to the html_theme_options['cssfiles'] list in conf.py (like html_theme_options['cssfiles'] = ['_static/style.css'])

You should read better’s CSS files or poke around with your browser’s element inspector to get an idea of what selectors you should override. better_basic.css_t is my fork of the basic theme’s CSS, and better.css_t is the stylistic overrides.

Using Javascript files

  1. Add your Javascript file as a static file as above.
  2. Add the file name (relative to the static directory) to the html_theme_options['scriptfiles'] list.

Suggested Sphinx options

Set html_short_title to "Home" so the first breadcrumb says “Home” instead of your long project title:

html_short_title = "Home"

Change your sidebars. Since the nav bars have useful “next” and “previous” links in this theme, you can remove the “Next Topic” and “Previous Topic” sidebar components. Here’s what that looks like:

html_sidebars = {
    '**': ['localtoc.html', 'sourcelink.html', 'searchbox.html'],
}

Here are two more custom sidebar components that the mrjob docs use to improve usability:

  • On the index page, don’t include any table of contents in the sidebar. Instead, link to commonly used pages.
  • Link to the mailing list, or whatever the preferred support channel is for your project.

mrjob’s config looks like this to support those components:

html_sidebars = {
    '**': ['localtoc.html', 'sidebarhelp.html', 'sourcelink.html',
           'searchbox.html'],
    'index': ['indexsidebar.html', 'sidebarhelp.html', 'sourcelink.html',
              'searchbox.html'],
}

Those HTML files live in docs/_templates/. See Sphinx’s templating guide for more information about how to write them.

Demos

Sphinx style demo

See sphinx-better-theme: usable documentation for the table of contents. Reproducing it here would make Sphinx mad.

Feel free to open Github issues about the specifics of the styles on this page.

Paragraph-level markup

note, warning

Note

This is a note. It can have monospaced text.

Warning

This is a note. monospaced text.

versionadded, deprecated

New in version 0.1: Some stuff added in a version.

Deprecated since version 0.1: Some stuff deprecated in a version.

seealso

See also

mrjob
Another awesome open source project
Buildy
A cool online game
rubric

A paragraph heading that is not used to create a TOC node

centered

LICENSE AGREEMENT

hlist
  • A list of
  • short items
  • that should be
  • displayed
  • horizontally

Misc

glossary
glossary
A directive that contains a definition list with terms and definitions. The definitions will then be referencable with the term role.
term
A string defined in the glossary.

Here we reference the glossary term.

productionlist
try_stmt  ::=  try1_stmt | try2_stmt
try1_stmt ::=  "try" ":" suite
               ("except" [expression ["," target]] ":" suite)+
               ["else" ":" suite]
               ["finally" ":" suite]
try2_stmt ::=  "try" ":" suite
               "finally" ":" suite

Showing code examples

Double colon

Here is some unhighlighted code:

old pond...
a frog leaps in
water’s sound
code-block

Line numbers with the second line emphasized:

1
2
if True:
    print "This is some Python"

No line numbers:

if True:
    print "This is some Python"
Tables
This is a table
1 2 3 4
5 6 7 8

Inline markup

References

A link to the above heading

A link to the index document

Download this demo (demo.rst)

ENV_VAR

token

--option <option>

Description of option.

--option, --option-without-ref

term (see Glossary for an example with a link)

Other semantic markup

abbr (hover)

command is an OS-level command.

dfn is the defining instance of a term in the text.

/a/file/path/variable/more

GUI control label

Control-x Control-f (keystroke sequence)

Content-Type (mail header)

MAKE_VAR

manpage(1)

Menu ‣ Selection

mime/type

Usenet newsgroup (wat?)

Name of an executable program (not just :command: for some reason?)

unquoted?regular*[expression]

A piece of literal text with variables

PEP 8

RFC 1072

Substitutions

Release 0.1.5, version 0.1.5, today Sep 08, 2018

Python

py_module

py_func(arg, a_long_argument=with_a_default, foo=bar, baz=qux, more=more, args=args, for=for, wrapping=wrapping)

A Python function definition.

py_func(), py_func_no_ref()

class PyClass(arg)
py_method(arg)

PyClass, PyClassNoRef, PyClass.py_method(), py_method_no_ref()

reStructuredText style demo

This is a simple demo of a subset of reStructuredText features.

Inline markup

The quick brown fox jumps over the lazy dog. Title reference.

Lorem ipsum [Ref] dolor sit amet.

[Ref]Book or article reference, URL or whatever.

Lorem ipsum [1] dolor sit amet … [2]

Footnotes

[1]Text of the first footnote.
[2]Text of the second footnote.

Lists and quote-like blocks

  • Bulleted list
  • with two items
  1. Numbered list
  2. with
  3. three items
  • Nested

    1. List
    • Hooray
    • Hooray
    • Hooray
    • Hooray
    1. List
    • Hooray
    • Hooray
    • Hooray
    • Hooray
  • Nested

    1. List
term (up to a line of text)

Definition of the term, which must be indented

and can even consist of multiple paragraphs

next term
Description.
Paragraph heading

(The above ToC triggers anchors around all page headings beyond what Sphinx does.)

Topic

A topic is like a block quote with a title, or a self-contained section with no subsections. Use the “topic” directive to indicate a self-contained idea that is separate from the flow of the document. Topics may occur anywhere a section or transition may occur. Body elements and topics may not contain nested topics.

parsed-literal is a literal-looking block with parsed text
Epigraph

No matter where you go, there you are.

—Buckaroo Banzai

Compound paragraph

This is a compound paragraph. The ‘rm’ command is very dangerous. If you are logged in as root and enter

cd /
rm -rf *

you will erase the entire contents of your file system.

Raw HTML
This is some raw HTML.

Admonition blocks

Attention

attention block block block block block block block block block block block

Caution

caution block

Danger

danger block

Error

error block

Hint

hint block

Important

important block

Note

note block

Tip

tip block

Warning

warning block

custom admonition

with content

Why?

  • It looks nice.
  • It’s easy to style with CSS (no _theme/ directory required).
  • The navigation is laid out better.
  • It works well on small screens and mobile devices.

If you find sphinx-better-theme lacking in any of these areas, please open a Github issue.

It looks nice

By default, the only colors are the background color, the body text color, and the link color. Content is separated by layout and whitespace, not background color changes.

The font defaults are a little more modern. There is less variation in font styles. Content is wrapped to about 100 characters by default.

Some docs may look better with more liberal use of color. This theme supports that visual style via CSS rules.

It’s easy to style with CSS

Unlike every other Sphinx theme I’m aware of, sphinx-better-theme lets you customize it with CSS without needing a _theme/ directory, or anything beyond a CSS file. And you don’t even need that; you can declare inline CSS in your Sphinx config file.

html_theme_options = {
  'inlinecss': 'color: green;',
  'cssfiles': ['_static/my_style.css'],
}

One of this project’s major goals is to make visual customization easier so that projects can brand their docs better.

The navigation is laid out better

The project title is displayed in a header instead of a tiny breadcrumb link.

The links to the next and previous pages in the navigation bars at the top and bottom use the actual names of the pages instead of the opaque “next” and “previous”. This feature was lifted from the Guzzle project’s docs.

It works well on small screens and mobile devices

The built-in themes do not work well on small screens. A few other third party themes get this right, but it’s not widespread.

Deficiencies

The markup isn’t easy enough to fully customize with CSS. One of the long-term goals of this project is to make the markup more semantic.

The placement of the logo image isn’t good.

Your idea here

Compatibility

sphinx-better-theme is compatible with Sphinx 0.6.4+ and Jinja 2.3.1+. Older versions may work but have not been tested.

Projects using sphinx-better-theme

  • mrjob has tens of thousands of words of guides and API docs.
  • Pillow is the modern fork of the Python Imaging Library and recently got a new set of docs.
  • zhang-shasha is a single page of simple Python library documentation.
  • pivotal_tools is a single page of command line tool documentation.
  • Rsyslog is a rocket-fast system for log processing. It offers high-performance, great security features and a modular design.

History/Roadmap

v0.1: Basic CSS-customizable style that looks nice in its default state

v0.11: Add easy Google Analytics support

v0.12: Improve base styles, responsive layout, document usage with Read the Docs

v0.13: Further style improvements, relbar shows only full titles of next/previous links

v0.1.4: Semantic versioning, mobile bug fixes, sidebar slimming, style improvements

v0.1.5: Remove a few useless options, allow remote CSS files, fix Google Analytics integration

v0.2: (planned) Rewrite markup to be semantic and customizable

v1.0: (planned) Extreme documentation polish and rounding out of edge cases

Other themes to check out

kr-sphinx-themes has two nice, clean themes used for many popular (and good-looking) projects.

sphinx-readable-theme is a theme optimized for readability of apidoc-generated docs.

sphinxtheme-readability is another attempt at a clean theme.

Cloud is a feature-rich theme with a responsive layout.

A few different themes are available for download at sphinx-themes.

Read the Docs uses a custom theme as the default for all docs hosted there.

The Guzzle project uses a heavily customized theme that’s also used by aws-cli.

The Julia language also uses an interesting custom theme.