I am attempting to use the built-in theme 'sphinxdoc' for my reStructuredText documentation that's being built with Sphinx for deployment on readthedocs.io. This works as I was hoping except for the behavior of the table of contents, which stays at the top when I scroll down, losing visibility. I would like the table of contents to stay visible on the side of the page, as it does for the Sphinx documentation. How can this be done? Is this a layout issue, addressed with CSS, etc.?
2 Answers
As noted in the built-in themes:
Note
The Sphinx documentation now uses an adjusted version of the sphinxdoc theme.
...which in turn has the comment:
// intelligent scrolling of the sidebar content
I couldn't find whether the modified theme sphinx13
could be installed, but you could just grab the code and override the sphinxdoc
theme with it.

- 13,693
- 1
- 44
- 57
I know this is old but I wanted to do this too.
So just for future reference for anyone trying to do this you do not need to install the spinx13 theme as mentioned in a previous answer.
- You need to add the following to a
layout.html
in thetemplate
directory
{# put the sidebar before the body #}
{% block sidebar1 %}{{ sidebar() }}{% endblock %}
{% block sidebar2 %}{% endblock %}
{% block extrahead %}
<link href='https://fonts.googleapis.com/css?family=Open+Sans:300,400,700'
rel='stylesheet' type='text/css' />
{{ super() }}
{#- if not embedded #}
<style type="text/css">
table.right { float: left; margin-left: 20px; }
table.right td { border: 1px solid #ccc; }
{% if pagename == 'index' %}
.related { display: none; }
{% endif %}
</style>
<script>
// intelligent scrolling of the sidebar content
$(window).scroll(function() {
var sb = $('.sphinxsidebarwrapper');
var win = $(window);
var sbh = sb.height();
var offset = $('.sphinxsidebar').position()['top'];
var wintop = win.scrollTop();
var winbot = wintop + win.innerHeight();
var curtop = sb.position()['top'];
var curbot = curtop + sbh;
// does sidebar fit in window?
if (sbh < win.innerHeight()) {
// yes: easy case -- always keep at the top
sb.css('top', $u.min([$u.max([0, wintop - offset - 10]),
$(document).height() - sbh - 200]));
} else {
// no: only scroll if top/bottom edge of sidebar is at
// top/bottom edge of window
if (curtop > wintop && curbot > winbot) {
sb.css('top', $u.max([wintop - offset - 10, 0]));
} else if (curtop < wintop && curbot < winbot) {
sb.css('top', $u.min([winbot - sbh - offset - 20,
$(document).height() - sbh - 200]));
}
}
});
</script>
{#- endif #}
{% endblock %}
- add a custom css file
mycustom.css
to_static
(can be named anything.css as long as it is added to theconf.py
file -- see step 3)
div.sphinxsidebarwrapper {
position: relative;
top: 0px;
padding: 0;
}
div.sphinxsidebar {
margin: 0;
padding: 0 15px 0 15px;
width: 210px;
float: left;
font-size: 1em;
text-align: left;
}
div.sphinxsidebar .logo {
font-size: 1.8em;
color: #0A507A;
font-weight: 300;
text-align: center;
}
div.sphinxsidebar .logo img {
vertical-align: middle;
}
div.sphinxsidebar .download a img {
vertical-align: middle;
}
- edit the
conf.py
file:
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
# add custom css
def setup(app):
app.add_stylesheet('mycustom.css') # give a filename you created.
That was enough to get it to work with me.
Note I was using html_theme = 'bizstyle'
- I haven't tested this with other themes.
Note you may have to adjust the css
file and layout.html
to suit your needs.
For more on the layout.html and templating see here.
All this code was taken and modified from here

- 31
- 1
-
[@NeilCook](https://stackoverflow.com/users/7858439/neil-cook) I got the scrolling part to work (showing the sidebar always) except for one problem: the sidebar is shown flush in the right 'frame' only on the top page index.html. On any other page, the sidebar overlaps the content window/frame with 80% of sidebar width inside the content window, and the right frame has the remaining 20%. I tried playing with layout.html and css file to no avail. Any help is appreciated. – NameRakes Oct 14 '21 at 11:18
-
After some searching figured out that `.related{ display: inline-block }` style setting in `layout.html` for all pages does the trick. [MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/display) was a great resource in my search. – NameRakes Oct 14 '21 at 23:27