Skip to content

Commit

Permalink
ENH: CSS only sidebar toggling (#454)
Browse files Browse the repository at this point in the history
  • Loading branch information
choldgraf authored Jan 14, 2022
1 parent 22ce601 commit ecf0035
Show file tree
Hide file tree
Showing 14 changed files with 182 additions and 179 deletions.
7 changes: 6 additions & 1 deletion sphinx_book_theme/layout.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,12 @@

<!-- Docs TOC is "d-none d-xl-block col-xl-2" -->
{% block docs_sidebar %}
<div class="col-12 {{ sidebar_width_class }} bd-sidebar site-navigation show{% if is_single_page %} single-page{% endif %}" id="site-navigation">
<!-- Checkboxes to toggle the left sidebar -->
<input type="checkbox" class="sidebar-toggle" name="__navigation" id="__navigation">
<label class="overlay" for="__navigation">
<div class="visually-hidden">Hide navigation sidebar</div>
</label>
<div class="col-12 {{ sidebar_width_class }} bd-sidebar site-navigation {% if is_single_page %} single-page{% endif %}" id="site-navigation">
{% if not is_single_page %}
{% include "sidebar.html" %}
{%- endif %}
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion sphinx_book_theme/static/sphinx-book-theme.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion sphinx_book_theme/theme.conf
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
inherit = pydata_sphinx_theme
pygments_style = tango
sidebars = sidebar-logo.html, search-field.html, sbt-sidebar-nav.html, sbt-sidebar-footer.html
stylesheet = sphinx-book-theme.css?digest=c3fdc42140077d1ad13ad2f1588a4309
stylesheet = sphinx-book-theme.css?digest=9c0365a0d202f391166e07e3b3d7f3e5

[options]
single_page = False
Expand Down
18 changes: 8 additions & 10 deletions sphinx_book_theme/topbar.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,14 @@
<div class="topbar-contents row">
<div class="col-12 col-md-3 bd-topbar-whitespace site-navigation show"></div>
<div class="col pl-md-4 topbar-main">
{% if theme_single_page != True %}
<button id="navbar-toggler" class="navbar-toggler ml-0" type="button" data-toggle="collapse"
data-toggle="tooltip" data-placement="bottom" data-target=".site-navigation" aria-controls="navbar-menu"
aria-expanded="true" aria-label="{{ translate('Toggle navigation') }}" aria-controls="site-navigation"
title="{{ translate('Toggle navigation') }}" data-toggle="tooltip" data-placement="left">
<i class="fas fa-bars"></i>
<i class="fas fa-arrow-left"></i>
<i class="fas fa-arrow-up"></i>
</button>
{% endif %}
<div class="topbar-left">
{% if theme_single_page != True %}
<label class="nav-toggle-button" for="__navigation">
<div class="visually-hidden">{{ translate('Toggle navigation') }}</div>
<i class="fas fa-bars"></i>
</label>
{% endif %}
</div>
{% include "topbar/download.html" %}
{% include "topbar/repobuttons.html" %}
{% include "topbar/fullscreen.html" %}
Expand Down
9 changes: 0 additions & 9 deletions src/js/sphinx-book-theme.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,3 @@
// Navbar toggle button
var initTriggerNavBar = () => {
if ($(window).width() < 768) {
$("#navbar-toggler").trigger("click")
}
}


// NavBar scrolling
var scrollToActive = () => {
var navbar = document.getElementById('site-navigation')
Expand Down Expand Up @@ -115,6 +107,5 @@ var initThebeSBT = () => {
}

sbRunWhenDOMLoaded(initTooltips)
sbRunWhenDOMLoaded(initTriggerNavBar)
sbRunWhenDOMLoaded(scrollToActive)
sbRunWhenDOMLoaded(initTocHide)
97 changes: 78 additions & 19 deletions src/scss/_leftbar.scss
Original file line number Diff line number Diff line change
Expand Up @@ -12,29 +12,10 @@
transition: margin-left .2s ease 0s, opacity .2s ease 0s, visibility .2s ease 0s;
z-index: 2000 !important;

// Over-ride bootstrap collapsing styles for a smooth transition
&.collapse {
visibility: hidden;
margin-left: -$leftbar-width;
opacity: 0;
display: block;
&.show {
visibility: visible;
margin-left: 0;
opacity: 1;
}
}

@include scrollbar-style();
@media (max-width: $breakpoint-md) {
position: fixed;
margin-top: $topbar-height;
border-right: 1px solid rgba(0,0,0,.1);

// If we're only a single page, sidebar should hide at narrow widths.
&.single-page {
display: none;
}
}

// Sidebar link color
Expand Down Expand Up @@ -106,3 +87,81 @@ nav.bd-links {
max-width: 275px;
}
}

// Toggle the left sidebar
@mixin sidebar-hidden {
~ #site-navigation, ~ .bd-content .bd-topbar-whitespace {
visibility: hidden;
margin-left: -$leftbar-width;
opacity: 0;
}

~ #site-navigation {
display: block;
}

// This should only be applied to the topbar-whitespace if we're on wide screen
@media (min-width: $breakpoint-md) {
~ .bd-content .bd-topbar-whitespace {
display: block;
}
}
}

input#__navigation {
display: none;
position: absolute;

// On wide screens, checking will hide everything
@media (min-width: $breakpoint-md) {
&:checked {
@include sidebar-hidden;
}
}

// On narrow screens, *unchecking* will hide everything, so it's hidden by default
@media (max-width: $breakpoint-md) {
&:not(:checked) {
@include sidebar-hidden;
}
}
}

// The HTML is technically in the topbar, but we put SCSS rules here since it
// behaves the same way as the sidebar
// TODO: This should be refactored to have a more sensible structure
.bd-topbar-whitespace {
width: $leftbar-width;
flex: auto;
transition: flex 0.2s ease 0s;
@media (max-width: $breakpoint-md) {
// Whitespace isn't needed on narrow screens since sidebar is separate
display: none;
}

// Navbar and topbar sidebar padding should max at 300px
@media (min-width: $breakpoint-md) {
max-width: 275px;
}
}

// Label at the top of the page
label.overlay {
background-color: rgba(0,0,0,.54);
height: 0;
opacity: 0;
position: fixed;
top: 0;
transition: width 0ms,height 0ms,opacity .25s ease-out;
width: 0;
}

// On narrow screens, we use this overlay to close the left sidebar
@media (max-width: $breakpoint-md) {
input:checked + label.overlay {
z-index: 1040; // This puts it above the topbar, below the sidebar
height: 100%;
opacity: 1;
width: 100%;
}
}
99 changes: 17 additions & 82 deletions src/scss/_topbar.scss
Original file line number Diff line number Diff line change
Expand Up @@ -42,21 +42,24 @@
div.dropdown-buttons-trigger, a.edit-button, a.full-screen-button {
float: right;
}
}
}

.bd-topbar-whitespace {
width: $leftbar-width;
flex: auto;
transition: flex 0.2s ease 0s;
@media (max-width: 768px) {
border-bottom: 1px solid transparent;
&.show, &.collapsing, body.scrolled & {
border-color: rgba(0, 0, 0, 0.1);
position: absolute;
bottom: 0;
width: 100%;
display: block;
// Left section of topbar
.topbar-left {
display: flex;
align-items: center;

label {
cursor: pointer;
color: $non-content-grey;
margin-bottom: 0;
font-size: 1.4em;
}
}

label, button {
&:hover i {
color: black;
}
}
}
}
Expand Down Expand Up @@ -111,71 +114,3 @@ button.topbarbtn img {
padding-right: 6px;
margin-left: -5px;
}

#navbar-toggler {
position: relative;
margin-right: 1em;
margin-left: .5em;
color: $non-content-grey;

i {
transition: opacity .3s, transform .3s;
position: absolute;
top: 16%;
left: 0;
display: block;
font-size: 1.2em;
}

i.fa-bars {
opacity: 0;
transform: rotate(180deg) scale(.5);
}

i.fa-arrow-left, i.fa-arrow-up {
opacity: 1;
}

&.collapsed {
i.fa-bars {
opacity: 1;
transform: rotate(0) scale(1);
}

i.fa-arrow-left, i.fa-arrow-up {
opacity: 0;
transform: rotate(-180deg) scale(.5);
}
}
}


@media (max-width: $breakpoint-md) {
#navbar-toggler {
i.fa-arrow-up {
display: none;
}

i.fa-arrow-left {
}
}
}

@media (min-width: $breakpoint-md) {
#navbar-toggler {
i.fa-arrow-up {
display: none;
}

i.fa-arrow-left {
display: inherit;
}
}
}

// Navbar and topbar sidebar padding should max at 300px
@media (min-width: $breakpoint-md) {
.bd-topbar-whitespace {
max-width: 275px;
}
}
12 changes: 12 additions & 0 deletions src/scss/_utilities.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Helper and utility classes
.visually-hidden {
clip: rect(0,0,0,0)!important;
border: 0!important;
height: 1px!important;
margin: -1px!important;
overflow: hidden!important;
padding: 0!important;
position: absolute!important;
white-space: nowrap!important;
width: 1px!important;
}
1 change: 1 addition & 0 deletions src/scss/_variables.scss
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ $box-border-radius: 0.4em;
scrollbar-width: thin;
&::-webkit-scrollbar {
width: 5px;
height: 5px;
}

&::-webkit-scrollbar {
Expand Down
1 change: 1 addition & 0 deletions src/scss/sphinx-book-theme.scss
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* All rights reserved.
*/
@import 'variables';
@import 'utilities';
@import 'page';
@import 'topbar';
@import 'righttoc';
Expand Down
47 changes: 24 additions & 23 deletions tests/test_build/test_build_book.sphinx3.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<div class="col-12 col-md-3 bd-sidebar site-navigation show" id="site-navigation">
<div class="col-12 col-md-3 bd-sidebar site-navigation" id="site-navigation">
<div class="navbar-brand-box">
<a class="navbar-brand text-wrap" href="#">
<h1 class="site-logo" id="site-title">
Expand Down Expand Up @@ -71,28 +71,29 @@ <h1 class="site-logo" id="site-title">
<a class="reference internal" href="titles/index.html">
4. Testing titles and TOCtree
</a>
<input class="toctree-checkbox" id="toctree-checkbox-2" name="toctree-checkbox-2" type="checkbox"/>
<label for="toctree-checkbox-2">
<i class="fas fa-chevron-down">
</i>
</label>
<ul>
<li class="toctree-l2">
<a class="reference internal" href="titles/page-multipletitles.html">
4.1. A page with multiple top-level titles
</a>
</li>
<li class="toctree-l2">
<a class="reference internal" href="titles/page-onetitle.html">
4.3. A page with one title and sub-headings
</a>
</li>
<li class="toctree-l2">
<a class="reference internal" href="titles/page-onetitlenoheadings.html">
4.4. A page with a title but no sub-headings
</a>
</li>
</ul>
<input class="toctree-checkbox" id="toctree-checkbox-2" name="toctree-checkbox-2" type="checkbox">
<label for="toctree-checkbox-2">
<i class="fas fa-chevron-down">
</i>
</label>
<ul>
<li class="toctree-l2">
<a class="reference internal" href="titles/page-multipletitles.html">
4.1. A page with multiple top-level titles
</a>
</li>
<li class="toctree-l2">
<a class="reference internal" href="titles/page-onetitle.html">
4.3. A page with one title and sub-headings
</a>
</li>
<li class="toctree-l2">
<a class="reference internal" href="titles/page-onetitlenoheadings.html">
4.4. A page with a title but no sub-headings
</a>
</li>
</ul>
</input>
</li>
<li class="toctree-l1">
<a class="reference external" href="https://google.com">
Expand Down
Loading

0 comments on commit ecf0035

Please sign in to comment.