From 1d9c99832bf01e3a16a60ab86c61da238ebbf7c8 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Thu, 8 Feb 2024 15:00:29 -0700 Subject: [PATCH] rustdoc: add three-column layout for large desktops This commit adds a floating TOC box to the right, leaving the sibling/module/crate navigation on the left. This kicks in at a size a little below 1920x1080, where desktops with very wide monitors are: it's also around the point where the content area can be full width while allowing two sidebars. It only kicks in if the browser supports grid layouts, but that should be most of them, and we can't get rid of the two-column layout anyway, since it's the layout you get on something like a portrait iPad. This design, where it can be used, is meant to clearly split up the table of contents and the site navigation, so the right side floating box has the same color as the page while the left sidebar does not. It also pushes it down further, so that it's not as high as the search bar, though that's a bit more subtle than the color. --- src/librustdoc/html/static/css/rustdoc.css | 142 ++++++++++++++++-- src/librustdoc/html/static/js/main.js | 30 +++- src/librustdoc/html/templates/page.html | 32 ++-- src/librustdoc/html/templates/sidebar.html | 23 +-- .../rustdoc-gui/sidebar-modnav-position.goml | 31 +++- tests/rustdoc-gui/sidebar.goml | 24 +-- tests/rustdoc/sidebar/module.rs | 8 +- tests/rustdoc/sidebar/top-toc-html.rs | 14 +- tests/rustdoc/sidebar/top-toc-idmap.rs | 12 +- 9 files changed, 243 insertions(+), 73 deletions(-) diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 32077e0b7f98b..e0c5889c1ead4 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -34,6 +34,13 @@ xmlns="http://www.w3.org/2000/svg" fill="black" height="18px">\ '); --button-left-margin: 4px; --button-border-radius: 2px; + /* Used to manage the big screen three column layout */ + --width-limiter-width: 960px; + --desktop-grid-column-gap: 45px; + --container-border-radius: 6px; + /* height of header, plus header margin, plus top logo section */ + --desktop-grid-toc-top: calc((1.25 * 1.5rem) + 76px + 23px); + --desktop-grid-toc-max-width: 512px; } /* See FiraSans-LICENSE.txt for the Fira Sans license. */ @@ -336,7 +343,7 @@ button#toggle-all-docs { main { position: relative; flex-grow: 1; - padding: 10px 15px 40px 45px; + padding: 10px 15px 40px var(--desktop-grid-column-gap); min-width: 0; /* avoid growing beyond the size limit */ } @@ -345,7 +352,7 @@ main { } .width-limiter { - max-width: 960px; + max-width: var(--width-limiter-width); margin-right: auto; } @@ -369,6 +376,7 @@ pre { } pre.item-decl { overflow-x: auto; + border-radius: var(--container-border-radius); } /* This rule allows to have scrolling on the X axis. */ .item-decl .type-contents-toggle { @@ -460,7 +468,7 @@ img { .sidebar-resizing .sidebar { position: fixed; } -.sidebar-resizing > body { +.sidebar-resizing .rustdoc { padding-left: var(--resizing-sidebar-width); } @@ -534,7 +542,7 @@ img { scrollbar-width: initial; scrollbar-color: var(--scrollbar-color); } -.sidebar { +.sidebar, #rustdoc-toc section, #rustdoc-modnav section { scrollbar-width: thin; scrollbar-color: var(--scrollbar-color); } @@ -543,17 +551,24 @@ img { ::-webkit-scrollbar { width: 12px; } -.sidebar::-webkit-scrollbar { +.sidebar::-webkit-scrollbar, +#rustdoc-toc section::-webkit-scrollbar, +#rustdoc-modnav section::-webkit-scrollbar { width: 8px; } ::-webkit-scrollbar-track { -webkit-box-shadow: inset 0; background-color: var(--scrollbar-track-background-color); } -.sidebar::-webkit-scrollbar-track { +.sidebar::-webkit-scrollbar-track, +#rustdoc-toc section::-webkit-scrollbar-track, +#rustdoc-modnav section::-webkit-scrollbar-track { background-color: var(--scrollbar-track-background-color); } -::-webkit-scrollbar-thumb, .sidebar::-webkit-scrollbar-thumb { +::-webkit-scrollbar-thumb, +.sidebar::-webkit-scrollbar-thumb, +#rustdoc-toc section::-webkit-scrollbar-thumb, +#rustdoc-modnav section::-webkit-scrollbar-thumb { background-color: var(--scrollbar-thumb-background-color); } @@ -742,7 +757,7 @@ ul.block, .block li, .block ul { overflow-wrap: break-word; } -.sidebar-crate + .version { +.sidebar > .version { margin-top: -1rem; margin-bottom: 1rem; } @@ -758,7 +773,7 @@ ul.block, .block li, .block ul { } .rustdoc .example-wrap > pre { - border-radius: 6px; + border-radius: var(--container-border-radius); } /* For the last child of a div, the margin will be taken care of @@ -2006,6 +2021,115 @@ However, it's not needed with smaller screen width because the doc/code block is /* Media Queries */ +/* Very-large-screen mode. */ +@supports (display: grid) and (display: contents) { + @media (min-width: 1600px) { + .rustdoc:not(.src) { + display: grid; + grid-template-columns: + var(--desktop-sidebar-width) + var(--width-limiter-width) + minmax(0, 1fr); + grid-template-rows: min-content 1fr; + grid-template-areas: + "sidebar-title main sidebar-cratenav" + "sidebar-modnav main sidebar-toc"; + grid-column-gap: var(--desktop-grid-column-gap); + } + .sidebar-resizing .rustdoc:not(.src) { + padding-left: 0; + } + .hide-sidebar .rustdoc:not(.src) { + grid-template-columns: + var(--width-limiter-width) + minmax(0, 1fr); + grid-template-rows: minmax(min-content, calc(64px + 0.75rem)) 1fr; + grid-template-areas: + "main sidebar-cratenav" + "main sidebar-toc"; + padding-left: var(--desktop-grid-column-gap); + } + .rustdoc:not(.src) .sidebar, + .rustdoc:not(.src) main { + display: contents; + } + .width-limiter { + grid-area: main; + width: var(--width-limiter-width); + --desktop-sidebar-width: 0; + } + .rustdoc:not(.src) nav.sub { + padding-top: 10px; + } + .rustdoc:not(.src) .doc-sidebar-title { + grid-area: sidebar-title; + background: var(--sidebar-background-color); + position: sticky; + top: 0; + } + .rustdoc:not(.src) .sidebar-crate { + margin-bottom: 0.5rem; + } + .rustdoc:not(.src) #rustdoc-toc, + .rustdoc:not(.src) #rustdoc-cratenav { + grid-area: sidebar-toc; + background: var(--main-background-color); + padding-left: 0; + } + .rustdoc:not(.src) #rustdoc-cratenav { + grid-area: sidebar-cratenav; + align-self: middle; + } + .rustdoc:not(.src) #rustdoc-modnav { + grid-area: sidebar-modnav; + background: var(--sidebar-background-color); + padding-left: 0; + } + .rustdoc:not(.src) #rustdoc-modnav .in-crate { + display: none; + } + .rustdoc:not(.src) #rustdoc-toc section, + .rustdoc:not(.src) #rustdoc-modnav section { + position: sticky; + top: 0; + bottom: 0; + overflow-y: scroll; + overscroll-behavior: contain; + max-height: 100vh; + padding-left: 24px; + } + .rustdoc:not(.src) #rustdoc-toc .location, + .rustdoc:not(.src) #rustdoc-modnav h2 { + margin-top: 0; + } + .rustdoc:not(.src) #rustdoc-modnav section { + top: calc(64px + 0.75rem); + height: calc(100vh - 64px - 0.75rem); + background: var(--sidebar-background-color); + } + .rustdoc:not(.src) #rustdoc-modnav section.scrolled { + border-top: solid 1px var(--border-color); + } + .rustdoc:not(.src) #rustdoc-toc section { + max-height: calc(100vh - (2 * var(--desktop-grid-toc-top))); + top: var(--desktop-grid-toc-top); + margin: 0 var(--desktop-grid-column-gap) var(--desktop-grid-column-gap) 0; + border: solid 1px var(--border-color); + padding: 14px 0 14px var(--sidebar-elems-left-padding); + border-radius: var(--container-border-radius); + max-width: var(--desktop-grid-toc-max-width); + } + .rustdoc:not(.src) #rustdoc-cratenav .block:last-child, + .rustdoc:not(.src) #rustdoc-toc .block:last-child { + margin-bottom: 0; + } + .rustdoc:not(.src) #rustdoc-cratenav a:hover, + .rustdoc:not(.src) #rustdoc-toc a:hover { + background-color: var(--sidebar-background-color); + } + } +} + /* Make sure all the buttons line wrap at the same time */ @media (max-width: 850px) { #search-tabs .count { diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index 5a0796e235356..1f65acca08515 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -499,7 +499,7 @@ function preLoadCss(cssUrl) { if (!window.SIDEBAR_ITEMS) { return; } - const sidebar = document.getElementById("rustdoc-modnav"); + const sidebar = document.querySelector("#rustdoc-modnav section"); /** * Append to the sidebar a "block" of links - a heading along with a list (`