Skip to content

Conversation

clydebarrow
Copy link
Contributor

Description:

On a mobile device with a narrow screen the sub-menus get clipped. Revise the css so that on such devices the submenu opens in-line instead of to the left of the top-level menu.

Related issue (if applicable): fixes

Pull request in esphome with YAML changes (if applicable):

  • esphome/esphome#

Checklist:

  • I am merging into next because this is new documentation that has a matching pull-request in esphome as linked above.
    or

  • I am merging into current because this is a fix, change and/or adjustment in the current documentation and is not for a new component or feature.

  • Link added in /components/index.rst when creating new documents for new components or cookbook.

New Component Images

If you are adding a new component to ESPHome, you can automatically generate a standardized black and white component name image for the documentation.

To generate a component image:

  1. Comment on this pull request with the following command, replacing COMPONENT_NAME with your component name in UPPER_CASE format with underscores (e.g., BME280, SHT3X, DALLAS_TEMP):

    @esphomebot generate image COMPONENT_NAME
    
  2. The ESPHome bot will respond with a downloadable ZIP file containing the SVG image.

  3. Extract the SVG file and place it in the images/ folder of this repository.

  4. Use the image in your component's index table entry in /components/index.rst.

Example: For a component called "DHT22 Temperature Sensor", use:

@esphomebot generate image DHT22

@Copilot Copilot AI review requested due to automatic review settings October 2, 2025 01:22
@esphome esphome bot added the current label Oct 2, 2025
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR fixes menu behavior on mobile devices by preventing sub-menus from being clipped on narrow screens. The changes modify both JavaScript and CSS to make sub-menus open inline instead of to the left of the top-level menu on mobile devices.

Key changes:

  • JavaScript refactoring to make mobile detection reusable and fix selector issues
  • CSS media query adjustments to change dropdown positioning behavior on narrow screens
  • Improved mobile menu scrolling and overflow handling

Reviewed Changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
themes/esphome-theme/assets/js/menu.js Converts mobile detection to reusable function and fixes dropdown selector
themes/esphome-theme/assets/css/main.css Reorganizes media queries and changes dropdown positioning for mobile devices

Copy link
Contributor

coderabbitai bot commented Oct 2, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

CSS updates adjust dropdown/menu behavior: restore desktop hover display and add mobile-specific positioning, full-width responsiveness, overflow, and scrollbar handling. JS introduces isMobileScreen() and replaces prior isMobile checks in TOC and dropdown logic, updates dropdown button selector, and conditions behavior based on screen width.

Changes

Cohort / File(s) Summary of changes
CSS: Responsive dropdown and nav updates
themes/esphome-theme/assets/css/main.css
Re-add desktop hover rule to reveal dropdown-content; add mobile rules for dropdown positioning, full-width layout, relative .dropdown, overflow and scrollbar handling for .nav-links; adjust content-container stacking for small viewports; include Firefox/IE scrollbar tweaks.
JS: Mobile detection refactor and selector tweak
themes/esphome-theme/assets/js/menu.js
Add isMobileScreen(); replace isMobile checks in openTOC/closeTOC and dropdown click handler; change dropdown trigger selector to .dropdown button; conditionals now rely on isMobileScreen().

Sequence Diagram(s)

sequenceDiagram
  actor User
  participant Browser as Browser/UI
  participant MenuJS as menu.js
  participant DOM as DOM/CSS

  rect rgba(232, 244, 253, 0.6)
    note over User,DOM: Dropdown interaction
    User->>Browser: Click dropdown button
    Browser->>MenuJS: handleDropdownClick
    MenuJS->>MenuJS: isMobileScreen()
    alt Mobile screen
      MenuJS->>DOM: Toggle dropdown open state (JS)
    else Desktop screen
      note over DOM: Display via CSS :hover
      Browser-->>DOM: Apply hover styles
    end
  end

  rect rgba(232, 244, 253, 0.6)
    note over User,DOM: Table of Contents (TOC)
    User->>Browser: Open/Close TOC
    Browser->>MenuJS: openTOC / closeTOC
    MenuJS->>MenuJS: isMobileScreen()
    alt Mobile screen
      MenuJS->>DOM: Apply mobile-specific open/close behavior
    else Desktop screen
      MenuJS->>DOM: Apply desktop-specific behavior
    end
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed The title "Fix menu behaviour on mobile devices." clearly and concisely summarizes the main change of adjusting the menu’s behavior on narrow screens without extra noise or ambiguity, making it easy to understand at a glance.
Description Check ✅ Passed The description directly explains that sub-menus were clipped on narrow screens and that CSS revisions address this by adjusting submenu positioning, clearly relating to the actual changes in the pull request.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

netlify bot commented Oct 2, 2025

Deploy Preview for esphome ready!

Name Link
🔨 Latest commit 909cd53
🔍 Latest deploy log https://app.netlify.com/projects/esphome/deploys/68ddd3def461380008bfb55f
😎 Deploy Preview https://deploy-preview-5439--esphome.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

Copy link

netlify bot commented Oct 2, 2025

Deploy Preview for esphome ready!

Name Link
🔨 Latest commit 003cf2c
🔍 Latest deploy log https://app.netlify.com/projects/esphome/deploys/68ddd4323c060500084a89ad
😎 Deploy Preview https://deploy-preview-5439--esphome.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
themes/esphome-theme/assets/js/menu.js (2)

140-160: Inconsistent mobile detection—prefer isMobileScreen().

The toggleDropdown and closeAllDropdowns functions use direct window.innerWidth > mobileWidthStop checks, while other parts of the code use the new isMobileScreen() helper. This inconsistency creates maintenance risk.

Apply this diff to use the helper consistently:

 function toggleDropdown(button) {
-    if (window.innerWidth > mobileWidthStop) return;
+    if (!isMobileScreen()) return;
     const isExpanded = button.getAttribute('aria-expanded') === 'true';
     closeAllDropdowns();

     if (!isExpanded) {
         button.setAttribute('aria-expanded', 'true');
         const dropdownContent = button.nextElementSibling;
         dropdownContent.style.display = 'block';
     }
 }

 // Close all dropdowns
 function closeAllDropdowns() {
-    if (window.innerWidth > mobileWidthStop) return;
+    if (!isMobileScreen()) return;
     dropdownButtons.forEach(btn => {
         btn.setAttribute('aria-expanded', 'false');
         const dropdownContent = btn.nextElementSibling;
         if (dropdownContent)
             dropdownContent.style.display = 'none';
     });
 }

177-188: Inconsistent mobile detection in event listeners.

The outside-click handler (line 178) and resize handler (line 185) still use direct window.innerWidth > mobileWidthStop checks instead of isMobileScreen().

Apply this diff for consistency:

 // Close menu on outside click (mobile only)
 document.addEventListener('click', function(e) {
-    if (window.innerWidth > mobileWidthStop) return;
+    if (!isMobileScreen()) return;
     if (!e.target.closest('.hamburger-button') && !e.target.closest('.nav-links')) {
         closeMenu();
     }
 });
 // Close menu on resize to desktop
 window.addEventListener('resize', function() {
-    if (window.innerWidth > mobileWidthStop) {
+    if (!isMobileScreen()) {
         closeMenu();
     }
 });
🧹 Nitpick comments (3)
themes/esphome-theme/assets/css/main.css (3)

1317-1318: Consider accessibility implications of hiding scrollbars.

Hiding scrollbars (scrollbar-width: none for Firefox, -ms-overflow-style: none for IE) reduces visual clutter but may prevent users from realizing that the navigation menu is scrollable, especially on mobile devices with limited viewport height.

Consider scoping the scrollbar hiding specifically to .nav-links.active to match the overflow behavior:

-.nav-links {
+.nav-links.active {
     scrollbar-width: none; /* Firefox */
     -ms-overflow-style: none;  /* Internet Explorer 10+ */
 }

Alternatively, provide a visual cue (fade effect, scroll indicator) to signal scrollable content.


1344-1352: Magic number 200px lacks explanation.

Line 1347 positions the dropdown content with right: 200px on mobile screens (between 700px and 1000px wide). This specific offset is not explained and resembles the previous concern about magic numbers.

Consider:

  1. Adding a CSS comment to explain why 200px is needed
  2. Defining it as a CSS custom property (e.g., --dropdown-offset-mobile) for better maintainability
  3. Verifying whether this offset is optimal across different mobile device widths

Example:

.dropdown-content {
  position: absolute;
  top: 0;
  right: 200px; /* Offset to prevent clipping on medium mobile screens */
  box-shadow: none;
  margin-top: 0.5em;
  padding-left: 1em;
  padding-right: 1em;
}

1254-1268: Review the 700px narrow-screen breakpoint
This custom max-width: 700px tier sits between typical mobile (~600px) and tablet (~768px) thresholds. Ensure your nav truly needs inline dropdowns at this exact point—either justify it with content-driven wrapping tests or align with a more common breakpoint.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 38ff935 and e1e9bb8.

📒 Files selected for processing (2)
  • themes/esphome-theme/assets/css/main.css (2 hunks)
  • themes/esphome-theme/assets/js/menu.js (5 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**

⚙️ CodeRabbit configuration file

  • Do not generate or add any sequence diagrams

Files:

  • themes/esphome-theme/assets/js/menu.js
  • themes/esphome-theme/assets/css/main.css
🔇 Additional comments (3)
themes/esphome-theme/assets/js/menu.js (2)

4-6: LGTM! Clean mobile detection abstraction.

The isMobileScreen() function properly encapsulates the mobile width check by reading the CSS custom property --mobile-width-stop (1000px) and comparing it with the current window width.


90-90: Selector change is correct. .dropdown button matches the existing <button class="dropbtn"> elements and the click handler’s .dropbtn check remains valid—no further updates needed.

themes/esphome-theme/assets/css/main.css (1)

1249-1251: LGTM! Hover behavior restored for desktop.

This correctly restores the hover-based dropdown display for wide screens (min-width: 1001px), ensuring desktop users can interact with dropdowns via mouse hover while mobile users rely on click handlers from the JS file.

Comment on lines +1317 to +1318
scrollbar-width: none; /* Firefox */
-ms-overflow-style: none; /* Internet Explorer 10+ */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Add WebKit scrollbar hiding for Chrome/Safari.

The code hides scrollbars for Firefox (scrollbar-width: none) and IE (-ms-overflow-style: none) but omits WebKit-based browsers (Chrome, Safari, Edge). This creates an inconsistent experience.

Add the WebKit scrollbar rule:

 .nav-links {
     scrollbar-width: none; /* Firefox */
     -ms-overflow-style: none;  /* Internet Explorer 10+ */
 }
+.nav-links::-webkit-scrollbar {
+    display: none; /* Chrome, Safari, Edge */
+}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
scrollbar-width: none; /* Firefox */
-ms-overflow-style: none; /* Internet Explorer 10+ */
.nav-links {
scrollbar-width: none; /* Firefox */
-ms-overflow-style: none; /* Internet Explorer 10+ */
}
.nav-links::-webkit-scrollbar {
display: none; /* Chrome, Safari, Edge */
}
🤖 Prompt for AI Agents
themes/esphome-theme/assets/css/main.css around lines 1317-1318: the CSS hides
scrollbars for Firefox and IE but not for WebKit browsers; add a rule targeting
WebKit scrollbars (the ::-webkit-scrollbar pseudo-element) immediately after the
existing rules to hide the scrollbar for Chrome/Safari/Edge (e.g., set the
scrollbar pseudo-element to not display or zero width/height), keeping it scoped
consistently with the surrounding selector.

Copy link

netlify bot commented Oct 2, 2025

Deploy Preview for esphome ready!

Name Link
🔨 Latest commit e1e9bb8
🔍 Latest deploy log https://app.netlify.com/projects/esphome/deploys/68ddd48a4ba7b8000812c46c
😎 Deploy Preview https://deploy-preview-5439--esphome.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant