Skip to content

Make impl section headers sticky #133717

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 57 additions & 17 deletions src/librustdoc/html/static/css/rustdoc.css
Original file line number Diff line number Diff line change
@@ -38,6 +38,11 @@ xmlns="http://www.w3.org/2000/svg" fill="black" height="18px">\
--code-block-border-radius: 6px;
--impl-items-indent: 0.3em;
--docblock-indent: 24px;
--mobile-top-navbar-height: 45px;
--collapse-toggle-left: -24px;
--main-top-padding: 10px;
--search-top-margin: 4px;
--sidebar-button-size: 34px;
}

/* See FiraSans-LICENSE.txt for the Fira Sans license. */
@@ -365,7 +370,7 @@ button#toggle-all-docs {
main {
position: relative;
flex-grow: 1;
padding: 10px 15px 40px 45px;
padding: var(--main-top-padding) 15px 40px 45px;
min-width: 0; /* avoid growing beyond the size limit */
}

@@ -746,7 +751,8 @@ ul.block, .block li, .block ul {
/* extend click target to far edge of screen (mile wide bar) */
border-left: solid var(--sidebar-elems-left-padding) transparent;
background-clip: border-box;
margin: 0 calc(-24px + 0.25rem) 0 calc(-0.2rem - var(--sidebar-elems-left-padding));
margin: 0 calc(var(--collapse-toggle-left) + 0.25rem) 0
calc(-0.2rem - var(--sidebar-elems-left-padding));
/* Align the sidebar crate link with the search bar, which have different
font sizes.

@@ -1002,7 +1008,7 @@ div.where {
nav.sub {
flex-grow: 1;
flex-flow: row nowrap;
margin: 4px 0 0 0;
margin: var(--search-top-margin) 0 0 0;
display: flex;
align-items: center;
}
@@ -1869,13 +1875,22 @@ a.tooltip:hover::after {
display: flex;
margin-right: 4px;
position: fixed;
left: 6px;
height: 34px;
width: 34px;
background-color: var(--main-background-color);
z-index: 1;
}
.hide-sidebar #sidebar-button {
left: 0;
/* We need to do all this so this button is positioned correctly but also to hide everything
going under beneath it. */
height: calc(var(--sidebar-button-size) + var(--main-top-padding) + var(--search-top-margin));
/* 6px is the left padding */
width: calc(var(--sidebar-button-size) + 6px);
padding-left: 6px;
padding-top: calc(var(--main-top-padding) + var(--search-top-margin));
}
.src #sidebar-button {
height: var(--sidebar-button-size);
width: var(--sidebar-button-size);
left: 8px;
z-index: calc(var(--desktop-sidebar-z-index) + 1);
}
@@ -2163,13 +2178,13 @@ details.toggle > summary.hideme::before {

details.toggle > summary:not(.hideme)::before {
position: absolute;
left: -24px;
left: var(--collapse-toggle-left);
top: 4px;
}

.impl-items > details.toggle > summary:not(.hideme)::before {
position: absolute;
left: -24px;
left: var(--collapse-toggle-left);
}

/* We indent items of an impl block to have a visual marker that these items are part
@@ -2181,6 +2196,26 @@ details.toggle > summary:not(.hideme)::before {
margin-left: var(--impl-items-indent);
}

h2.section-header + div > details.implementors-toggle > summary,
details.toggle.big-toggle > summary {
position: sticky;
top: 0;
background: var(--main-background-color);
z-index: 1;
padding-left: calc(var(--collapse-toggle-left) * -1);
margin-left: var(--collapse-toggle-left);
}
h2.section-header + div > details.implementors-toggle > summary:not(.hideme)::before,
details.toggle.big-toggle > summary:not(.hideme)::before {
left: -4px;
}
h2.section-header + div > details.implementors-toggle > summary .anchor {
left: calc(-0.5rem - var(--collapse-toggle-left));
}
details.toggle.big-toggle > summary .anchor {
left: -0.8rem;
}

details.big-toggle > summary:not(.hideme)::before {
left: -34px;
top: 9px;
@@ -2272,14 +2307,15 @@ in src-script.js and main.js
@media (max-width: 700px) {
:root {
--impl-items-indent: 0.7em;
--collapse-toggle-left: -11px;
}

/* When linking to an item with an `id` (for instance, by clicking a link in the sidebar,
or visiting a URL with a fragment like `#method.new`, we don't want the item to be obscured
by the topbar. Anything with an `id` gets scroll-margin-top equal to .mobile-topbar's size.
*/
*[id] {
scroll-margin-top: 45px;
scroll-margin-top: var(--mobile-top-navbar-height);
}

/* We don't display this button on mobile devices. */
@@ -2327,13 +2363,13 @@ in src-script.js and main.js

.sidebar {
position: fixed;
top: 45px;
top: var(--mobile-top-navbar-height);
/* Hide the sidebar offscreen while not in use. Doing this instead of display: none means
the sidebar stays visible for screen readers, which is useful for navigation. */
left: -1000px;
z-index: 11;
/* Reduce height slightly to account for mobile topbar. */
height: calc(100vh - 45px);
height: calc(100vh - var(--mobile-top-navbar-height));
width: 200px;
}

@@ -2390,7 +2426,7 @@ in src-script.js and main.js
position: sticky;
z-index: 10;
font-size: 2rem;
height: 45px;
height: var(--mobile-top-navbar-height);
width: 100%;
left: 0;
top: 0;
@@ -2418,11 +2454,6 @@ in src-script.js and main.js
display: none !important;
}

#main-content > details.toggle > summary::before,
#main-content > div > details.toggle > summary::before {
left: -11px;
}

/* sidebar button becomes topbar button */
#sidebar-button > a:before {
content: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" \
@@ -2493,6 +2524,11 @@ in src-script.js and main.js
margin: 0 0 -25px 0;
padding: var(--nav-sub-mobile-padding);
}

h2.section-header + div > details.implementors-toggle > summary,
details.toggle.big-toggle > summary {
top: var(--mobile-top-navbar-height);
}
}


@@ -2552,6 +2588,10 @@ in src-script.js and main.js
.search-form {
align-self: stretch;
}

#main-content > details.toggle > summary::before {
left: var(--collapse-toggle-left);
}
}

.variant,
2 changes: 1 addition & 1 deletion tests/rustdoc-gui/anchor-navigable.goml
Original file line number Diff line number Diff line change
@@ -8,4 +8,4 @@ go-to: "file://" + |DOC_PATH| + "/test_docs/struct.Foo.html"
// We check that ".item-info" is bigger than its content.
move-cursor-to: ".impl"
assert-property: (".impl > a.anchor", {"offsetWidth": "8"})
assert-css: (".impl > a.anchor", {"left": "-8px"})
assert-css: (".impl > a.anchor", {"left": "16px"})
6 changes: 3 additions & 3 deletions tests/rustdoc-gui/deref-block.goml
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@ go-to: "file://" + |DOC_PATH| + "/lib2/struct.Derefer.html"
assert-text: (".big-toggle summary", "Methods from Deref<Target = str>§")
// We ensure it doesn't go over `§`.
assert-css: (".big-toggle summary::before", {
"left": "-34px",
"left": "-4px",
"top": "9px",
})
// It should NOT have the same X or Y position as the other toggles.
@@ -17,13 +17,13 @@ compare-elements-position-false: (
// We now check that if we're in mobile mode, it gets back to its original X position.
set-window-size: (600, 600)
assert-css: (".big-toggle summary::before", {
"left": "-11px",
"left": "-4px",
"top": "9px",
})
// It should have a slightly different X position as the other toggles.
store-position: (".big-toggle summary::before", {"x": big_toggle})
store-position: (".method-toggle summary::before", {"x": small_toggle})
assert: |big_toggle| < |small_toggle|
assert: |big_toggle| > |small_toggle|
// Margin is 0.5em so around 8 px.
assert: |small_toggle| - |big_toggle| < 10
// But still shouldn't have the same Y position.
8 changes: 4 additions & 4 deletions tests/rustdoc-gui/toggle-docs-mobile.goml
Original file line number Diff line number Diff line change
@@ -14,7 +14,7 @@ assert-attribute: (".top-doc", {"open": ""})
// Assert the position of the toggle on the top doc block.
assert-position: (".top-doc summary::before", {"x": 4})
// Assert the position of the toggle on the impl block.
assert-position: ("#implementations-list > details > summary::before", {"x": 4})
assert-position: ("#implementations-list > details > summary::before", {"x": 11})
// Assert the position of the toggle on a method.
assert-position: (
"#trait-implementations-list .impl-items .method-toggle > summary::before",
@@ -24,10 +24,10 @@ assert-position: (
// Now we do the same but with a little bigger width
set-window-size: (600, 600)
assert-attribute: (".top-doc", {"open": ""})
click: (4, 270) // New Y position since all search elements are back on one line.
click: (30, 270) // New Y position since all search elements are back on one line.
assert-attribute-false: (".top-doc", {"open": ""})
click: (4, 270)
click: (30, 270)
assert-attribute: (".top-doc", {"open": ""})
// To ensure that the toggle isn't over the text, we check that the toggle isn't clicked.
click: (3, 270)
click: (31, 270)
assert-attribute: (".top-doc", {"open": ""})