sphinx-book-theme
sphinx-book-theme copied to clipboard
Tie the theme to good design principles
With my scholarly hat on, it would be nice to apply a bit of theory to the design. It feels mainly the theme is being designing based on "I like the look of that", which is not necessarily a bad thing, but it would be good to do some due diligence and documentation on how the theme applies to good design principles. Just googling "web page design principles" you get 1000s of results, and obviously there's no silver bullet, but some that start to crop up often are:
- Simplicity and Visual Hierarchy: too many elements on the page can be distracting, the eye should be drawn to the most important
- Consistency: in typographies and color pallete
- F Pattern: Utilising eye tracking software, studies have identified that people tend to view computer screens in a ‘F’ shaped pattern. Meaning that users tend to focus on the left side of the screen and will only take in a few elements on the right side.
- mobile first: its generally easier to design for the simpler mobile first, then add in features for desktop
- Responsiveness/Load times
I love this idea. Agreed - your assessment of "I like the look of that" is partially true though I've definitely drawn inspiration from some specific other themes and sites (most notably, git book and the tufte css guide)
A few others that I have used:
- Draw attention to the content. Find ways to "highlight" the center column of the page.
- Mimic other modern book-like structures. Don't do anything too wacky that users aren't used to. Instead take inspiration from some of the modern book themes out there. Some inspiration:
- Draw inspiration from publishing-specific design and elements
- in particular, the Tufte CSS page
- Following Tufte - think about "ink to information ratio". Don't use too many visual elements or colors if it isn't necessary. Use whitespace instead of visual spacers, don't add lots of shading and fancy boxes unless it really helps parse the content, etc.
Responsiveness/Load times
Throttling myself to "Good 2G" speeds in Firefox's development tools, disabling cache and loading https://sphinx-book-theme.readthedocs.io/en/latest/ today takes... 59s to load the page. :o
The main culprits for this are:
- https://unpkg.com/[email protected]/lib/index.js (~500 kB)
- https://unpkg.com/@jupyter-widgets/[email protected]/dist/embed-amd.js (~900 kB)
Even without throttling, I can see that my browser waits for a bit downloading from unpkg.com before showing me the page.
Here's the screenshot of the dev-tools (full screen, zoomed out to show all assets)

Cheers, well thebelab we now "control": https://github.com/executablebooks/thebe, so could look if there is anything that could be optimized there.
I think we should absolutely have a speed audit and optimize the low-hanging fruit. E.g. thebe
and the widget
JS are really only needed on certain pages, so I wonder if we could get away with only loading as-needed (or vendoring that JS if we think it could speed things up)
Yep definitely should only add to pages that need it; I've wanted to work out a standard way to do that for some other sphinx extensions.
I also note that require and jupyter-widgets are not loaded asynchronously:
<script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.4/require.min.js"></script>
<script src="https://unpkg.com/@jupyter-widgets/html-manager@^0.18.0/dist/embed-amd.js"></script>
<script async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
<script async="async" src="https://unpkg.com/thebelab@latest/lib/index.js"></script>
I don't know if they should, or if it would make any difference? (if you want a refresher on asynchronous loading see https://flaviocopes.com/javascript-async-defer/#async-and-defer)
One thing I still haven't figured out is how to make a JS / CSS bundle load only on some pages. To my knowledge the only way to do this (other than directly modifying a template file) is to use app.add_js_file
, but this adds it for each page of the website rather than only specific pages. Is that the experience you've had as well?
Using this theme with https://github.com/pradyunsg/sphinx-themes, gives the following loading times for the various pages. (image below)
This is actually decent, with the page at ~500KB and most of it coming from Bootstrap. I think there's still a strong case for better optimization, but looks like that is more of a sphinx-thebe issue in general, rather than something specific to this theme.
And, in case you're wondering why I brought up #148, here's the preview image generated for this theme (as of today) by the automation there:
make a JS / CSS bundle load only on some pages ... other than directly modifying a template file
Not sure if this is what you already meant by template files, but you may possibly be able to do this via metadata and theming: https://www.sphinx-doc.org/en/master/templating.html
For example in https://github.com/executablebooks/meta/commit/dc88790f3993d1a3d97391cb884a5d9454831192, I only add the tabulator JS/CSS to a certain page, based on its docname. But if you could add metatags to certain pages via an extension, then you could also look for these
here's the preview image generated for this theme (as of today) by the automation there:
Yeh I think another good principle is to "prefer HTML/CSS over JS", i.e. if you disable JS it shouldn't adversely affect the UI and/or disable "critical" UX features
One thing I still haven't figured out is how to make a JS / CSS bundle load only on some pages. To my knowledge the only way to do this (other than directly modifying a template file) is to use app.add_js_file, but this adds it for each page of the website rather than only specific pages. Is that the experience you've had as well?
Recently found that you can use add_js_file
on the builder, e.g. in an env-updated
event only when certain criteria is met (see e.g. https://github.com/sphinx-doc/sphinx/blob/ae9f0dd29998a9985aea90777e92e03cf1c9d591/sphinx/ext/mathjax.py#L84)
edit: actually it is still for all pages 🤦 but at least you can stop the js in some cases