From c14d78f4ae755603acab21253817ca883d0b29d5 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 16 Jan 2026 16:19:35 +0100 Subject: [PATCH 1/3] Make popover menus content scrollable on mobile devices --- src/librustdoc/html/static/css/rustdoc.css | 25 ++++++++++++++++------ src/librustdoc/html/static/js/main.js | 13 +++++++---- 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index ad7ef9b453cec..486ca9b22539c 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -20,6 +20,7 @@ --src-sidebar-width: 300px; --desktop-sidebar-z-index: 100; --sidebar-elems-left-padding: 24px; + --popover-top-margin: 7px; /* clipboard */ --clipboard-image: url('data:image/svg+xml,\ @@ -1435,7 +1436,7 @@ so that we can apply CSS-filters to change the arrow color in themes */ top: 100%; right: 0; z-index: calc(var(--desktop-sidebar-z-index) + 1); - margin-top: 7px; + margin-top: var(--popover-top-margin); border-radius: 3px; border: 1px solid var(--border-color); background-color: var(--main-background-color); @@ -2659,6 +2660,7 @@ in src-script.js and main.js @media (max-width: 700px) { :root { --impl-items-indent: 0.7em; + --topbar-height: 45px; } /* When linking to an item with an `id` (for instance, by clicking a link in the sidebar, @@ -2666,7 +2668,7 @@ in src-script.js and main.js by the topbar. Anything with an `id` gets scroll-margin-top equal to rustdoc-topbar's size. */ *[id] { - scroll-margin-top: 45px; + scroll-margin-top: var(--topbar-height); } /* We don't display this button on mobile devices. */ @@ -2698,14 +2700,23 @@ in src-script.js and main.js background: var(--main-background-color); border-radius: 0; } - #settings.popover { + #settings.popover, #help.popover { top: 32px; + /* The `+ 1px` part is for the bottom border to be visible. */ + height: calc(100vh - var(--topbar-height) + var(--popover-top-margin) - 1px); + } + #settings.popover { --popover-arrow-offset: 48px; } #help.popover { - top: 32px; --popover-arrow-offset: 12px; } + /* The `overflow-y` property is used on an internal content instead of the top one otherwise the + little arrow at the top can't be displayed. */ + #settings.popover .settings, #help.popover .content { + overflow-y: scroll; + height: 100%; + } .rustdoc { /* Sidebar should overlay main content, rather than pushing main content to the right. @@ -2728,13 +2739,13 @@ in src-script.js and main.js .sidebar { position: fixed; - top: 45px; + top: var(--topbar-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(--topbar-height)); /* resize indicator: hide this when on touch or mobile */ border-right: none; width: 100%; @@ -2799,7 +2810,7 @@ in src-script.js and main.js flex-direction: row; position: sticky; z-index: 10; - height: 45px; + height: var(--topbar-height); width: 100%; left: 0; top: 0; diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index f438fe173810b..42cd321849cf9 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -1692,7 +1692,7 @@ function preLoadCss(cssUrl) { const container = document.createElement("div"); if (!isHelpPage) { - container.className = "popover content"; + container.className = "popover"; } container.id = "help"; @@ -1701,9 +1701,14 @@ function preLoadCss(cssUrl) { side_by_side.appendChild(div_shortcuts); side_by_side.appendChild(div_infos); - container.appendChild(book_info); - container.appendChild(side_by_side); - container.appendChild(rustdoc_version); + const content = document.createElement("div"); + content.className = "content"; + + content.appendChild(book_info); + content.appendChild(side_by_side); + content.appendChild(rustdoc_version); + + container.appendChild(content); if (isHelpPage) { const help_section = document.createElement("section"); From 76ea822db244c38979df47650be185e679b30222 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 16 Jan 2026 16:19:58 +0100 Subject: [PATCH 2/3] Add rustdoc GUI regression test for #151209 --- .../mobile-topbar-menu-popovers.goml | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 tests/rustdoc-gui/mobile-topbar-menu-popovers.goml diff --git a/tests/rustdoc-gui/mobile-topbar-menu-popovers.goml b/tests/rustdoc-gui/mobile-topbar-menu-popovers.goml new file mode 100644 index 0000000000000..1f4adc70101f0 --- /dev/null +++ b/tests/rustdoc-gui/mobile-topbar-menu-popovers.goml @@ -0,0 +1,33 @@ +// Ensure that topbar popover menus content can be scrolled on mobile. +go-to: "file://" + |DOC_PATH| + "/lib2/index.html" +store-value: (window_height, 500) +set-window-size: (400, |window_height|) + +include: "utils.goml" + +// We open the settings menu +call-function: ("open-settings-menu", {}) +// We ensure it's not scrolled down yet. +assert-property: ("#settings .settings", {"scrollTop": 0}) +// We ensure its height is smaller than the window's, but its content's height is bigger. +store-property: ("#settings .settings", {"offsetHeight": menu_height, "scrollHeight": scroll_height}) +assert: |menu_height| < |window_height| && |scroll_height| > |window_height| + +// We scroll to the last element of the menu. +scroll-to: "#settings .setting-line:last-of-type input" +// The item should be visible now, and so the Y scroll value should have changed. +assert-property: ("#settings .settings", {"scrollTop": 295}) + +// Now we open the help menu. +click: ".help-menu a" +wait-for: "#help" +// We ensure it's not scrolled down yet. +assert-property: ("#help .content", {"scrollTop": 0}) +// We ensure its height is smaller than the window's, but its content's height is bigger. +store-property: ("#help .content", {"offsetHeight": menu_height, "scrollHeight": scroll_height}) +assert: |menu_height| < |window_height| && |scroll_height| > |window_height| + +// We scroll to the last element of the menu. +scroll-to: "#help .infos > :last-child" +// The item should be visible now, and so the Y scroll value should have changed. +assert-property: ("#help .content", {"scrollTop": 339}) From d5bacddca9e47836c5c1678ba8669d335a5a8168 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 20 Jan 2026 15:58:34 +0100 Subject: [PATCH 3/3] Update GUI test to new number of settings and add note about it --- tests/rustdoc-gui/mobile-topbar-menu-popovers.goml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/rustdoc-gui/mobile-topbar-menu-popovers.goml b/tests/rustdoc-gui/mobile-topbar-menu-popovers.goml index 1f4adc70101f0..29a2096bba895 100644 --- a/tests/rustdoc-gui/mobile-topbar-menu-popovers.goml +++ b/tests/rustdoc-gui/mobile-topbar-menu-popovers.goml @@ -16,7 +16,8 @@ assert: |menu_height| < |window_height| && |scroll_height| > |window_height| // We scroll to the last element of the menu. scroll-to: "#settings .setting-line:last-of-type input" // The item should be visible now, and so the Y scroll value should have changed. -assert-property: ("#settings .settings", {"scrollTop": 295}) +// Note: The `scrollTop` value will change if settings are added or removed. +assert-property: ("#settings .settings", {"scrollTop": 335}) // Now we open the help menu. click: ".help-menu a"