ike Posted September 13, 2018 Share Posted September 13, 2018 I'm trying to use the responsive navbar and sticky code but the dropdown will not show when the sticky kicks in. I tried removing the overflow: hidden; on the .dropdown but that didn't help. Also I can't get the responsive menu to work, seems like there is a conflict with the two different scripts. <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>stickydropdown.html</title> <style> body { margin:0; font-family:Arial } .header{ width: 100%; height: 125px; background-color: #999; } .body-content{ width: 100%; min-height: 1025px; background-color: #fff; } .footer{ width: 100%; height: 175px; background-color: #000; } .topnav { background-color: #333; overflow: hidden; } .topnav a { float: left; display: block; color: #f2f2f2; text-align: center; padding: 14px 16px; text-decoration: none; font-size: 17px; } .active { background-color: ; color: white; } .topnav .icon { display: none; } .dropdown { float: left; overflow: ; } .dropdown .dropbtn { font-size: 17px; border: none; outline: none; color: white; padding: 14px 16px; background-color: #333; font-family: inherit; margin: 0; } .dropdown-content { display: none; position: absolute; background-color: #f9f9f9; min-width: 160px; box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2); z-index: 1; } .dropdown-content a { float: none; color: black; padding: 12px 16px; text-decoration: none; display: block; text-align: left; } .topnav a:hover, .dropdown:hover .dropbtn { background-color: #555; color: white; } .dropdown-content a:hover { background-color: #ddd; color: black; } .dropdown:hover .dropdown-content { display: block; } /* Page content */ .content { padding: 16px; } /* The sticky class is added to the navbar with JS when it reaches its scroll position */ .sticky { position: fixed; top: 0; width: 100%; } /* Add some top padding to the page content to prevent sudden quick movement (as the navigation bar gets a new position at the top of the page (position:fixed and top:0) */ .sticky + .content { padding-top: 60px; } @media screen and (max-width: 600px) { .topnav a:not(:first-child), .dropdown .dropbtn { display: none; } .topnav a.icon { float: right; display: block; } } @media screen and (max-width: 600px) { .topnav.responsive {position: relative;} .topnav.responsive .icon { position: absolute; right: 0; top: 0; } .topnav.responsive a { float: none; display: block; text-align: left; } .topnav.responsive .dropdown {float: none;} .topnav.responsive .dropdown-content {position: relative;} .topnav.responsive .dropdown .dropbtn { display: block; width: 100%; text-align: left; } } </style> </head> <body> <div class="header"></div> <div class="topnav" id="myTopnav"> <a href="stickydropdown.html" class="active">Home</a> <div class="dropdown"> <button class="dropbtn">Products <i class="fa fa-caret-down"></i> </button> <div class="dropdown-content"> <a href="plinkone.html">Link 1</a> <a href="#">Link 2</a> <a href="#">Link 3</a> </div> </div> <div class="dropdown"> <button class="dropbtn">Services <i class="fa fa-caret-down"></i> </button> <div class="dropdown-content"> <a href="slinkone.html">Link 1</a> <a href="#">Link 2</a> <a href="#">Link 3</a> </div> </div> <a href="a.html">About</a> <a href="news.html">News</a> <a href="c.html">Contact</a> <a href="javascript:void(0);" style="font-size:15px;" class="icon" onclick="myFunction()">☰</a> </div> <div class="body-content"> <div style="padding-left:16px"> <h2>Home</h2> <p>Resize the browser window to see how it works.</p> <p>Hover over the dropdown button to open the dropdown menu.</p> </div> </div> <div class="footer"></div> <script> function myFunction() { var x = document.getElementById("myTopnav"); if (x.className === "topnav") { x.className += " responsive"; } else { x.className = "topnav"; } } </script> <script> // When the user scrolls the page, execute myFunction window.onscroll = function() {myFunction()}; // Get the topnav var topnav = document.getElementById("myTopnav"); // Get the offset position of the navbar var sticky = topnav.offsetTop; // Add the sticky class to the navbar when you reach its scroll position. Remove "sticky" when you leave the scroll position function myFunction() { if (window.pageYOffset >= sticky) { topnav.classList.add("sticky") } else { topnav.classList.remove("sticky"); } } </script> </body> </html> Link to comment Share on other sites More sharing options...
dsonesuk Posted September 13, 2018 Share Posted September 13, 2018 (edited) You can't have two identical function names, it will only act on one, change sticky function name call on window scroll event and make sure the sticky function name matches. window.onscroll = function() {myFunctionSticky()}; function myFunctionSticky() { if (window.pageYOffset >= sticky) { topnav.classList.add("sticky") } else { topnav.classList.remove("sticky"); } } Edited September 13, 2018 by dsonesuk Link to comment Share on other sites More sharing options...
ike Posted September 13, 2018 Author Share Posted September 13, 2018 Thanks for the replay. I made the suggested changes and it kind of works. If reduce the page width and scroll all the way to the bottom the navbar moves to the top of the page however, when I click the menu icon, the menu disappears or jumps out of view now. If I reduce the width but do not scroll all the way to the bottom of the page and click on the menu icon the dropdown works. Link to comment Share on other sites More sharing options...
dsonesuk Posted September 13, 2018 Share Posted September 13, 2018 (edited) Ahh that's because one function removes all classes with 'topnav' remaining, removing the 'sticky' class. Also you require to override the '.topnav.responsive' class style of position relative, if 'sticky' class present, to remain position: fixed; try <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>stickydropdown.html</title> <style> body { margin:0; font-family:Arial } .header{ width: 100%; height: 125px; background-color: #999; } .body-content{ width: 100%; min-height: 1025px; background-color: #fff; } .footer{ width: 100%; height: 175px; background-color: #000; } .topnav { background-color: #333; overflow: hidden; } .topnav a { float: left; display: block; color: #f2f2f2; text-align: center; padding: 14px 16px; text-decoration: none; font-size: 17px; } .active { background-color: ; color: white; } .topnav .icon { display: none; } .dropdown { float: left; overflow: ; } .dropdown .dropbtn { font-size: 17px; border: none; outline: none; color: white; padding: 14px 16px; background-color: #333; font-family: inherit; margin: 0; } .dropdown-content { display: none; position: absolute; background-color: #f9f9f9; min-width: 160px; box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2); z-index: 1; } .dropdown-content a { float: none; color: black; padding: 12px 16px; text-decoration: none; display: block; text-align: left; } .topnav a:hover, .dropdown:hover .dropbtn { background-color: #555; color: white; } .dropdown-content a:hover { background-color: #ddd; color: black; } .dropdown:hover .dropdown-content { display: block; } /* Page content */ .content { padding: 16px; } /* The sticky class is added to the navbar with JS when it reaches its scroll position */ .sticky,.topnav.responsive.sticky { position: fixed; top: 0; width: 100%; } /* Add some top padding to the page content to prevent sudden quick movement (as the navigation bar gets a new position at the top of the page (position:fixed and top:0) */ .sticky + .content { padding-top: 60px; } @media screen and (max-width: 600px) { .topnav a:not(:first-child), .dropdown .dropbtn { display: none; } .topnav a.icon { float: right; display: block; } } @media screen and (max-width: 600px) { .topnav.responsive {position: relative;} .topnav.responsive .icon { position: absolute; right: 0; top: 0; } .topnav.responsive a { float: none; display: block; text-align: left; } .topnav.responsive .dropdown {float: none;} .topnav.responsive .dropdown-content {position: relative;} .topnav.responsive .dropdown .dropbtn { display: block; width: 100%; text-align: left; } } </style> </head> <body> <div class="header"></div> <div class="topnav" id="myTopnav"> <a href="stickydropdown.html" class="active">Home</a> <div class="dropdown"> <button class="dropbtn">Products <i class="fa fa-caret-down"></i> </button> <div class="dropdown-content"> <a href="plinkone.html">Link 1</a> <a href="#">Link 2</a> <a href="#">Link 3</a> </div> </div> <div class="dropdown"> <button class="dropbtn">Services <i class="fa fa-caret-down"></i> </button> <div class="dropdown-content"> <a href="slinkone.html">Link 1</a> <a href="#">Link 2</a> <a href="#">Link 3</a> </div> </div> <a href="a.html">About</a> <a href="news.html">News</a> <a href="c.html">Contact</a> <a href="javascript:void(0);" style="font-size:15px;" class="icon" onclick="myFunction()">☰</a> </div> <div class="body-content"> <div style="padding-left:16px"> <h2>Home</h2> <p>Resize the browser window to see how it works.</p> <p>Hover over the dropdown button to open the dropdown menu.</p> </div> </div> <div class="footer"></div> <script> function myFunction() { var x = document.getElementById("myTopnav"); if (!x.classList.contains("responsive")) { x.classList.add("responsive"); } else { x.classList.remove("responsive"); } } </script> <script> // When the user scrolls the page, execute myFunction window.onscroll = function() {myFunctionSticky()}; // Get the topnav var topnav = document.getElementById("myTopnav"); // Get the offset position of the navbar var sticky = topnav.offsetTop; // Add the sticky class to the navbar when you reach its scroll position. Remove "sticky" when you leave the scroll position function myFunctionSticky() { if (window.pageYOffset >= sticky) { topnav.classList.add("sticky") } else { topnav.classList.remove("sticky"); } } </script> </body> </html> Edited September 13, 2018 by dsonesuk Link to comment Share on other sites More sharing options...
ike Posted September 14, 2018 Author Share Posted September 14, 2018 Thanks a bunch. I understand this change, /* The sticky class is added to the navbar with JS when it reaches its scroll position */ .sticky,.topnav.responsive.sticky { position: fixed; top: 0; width: 100%; } but would never have figured out the changes you made to the first script. The dropdowns still will not work once the navbar gets stuck unless you reduce the screen size so the responsive kicks in. I thought it was the overflow: hidden; on the .dropdown but I removed that and it still does not work. Any suggestions on that? Thanks again for all your help! Link to comment Share on other sites More sharing options...
dsonesuk Posted September 14, 2018 Share Posted September 14, 2018 (edited) Remove overflow: hidden; as you have done and add .topnav::after { clear: both; content: ""; display: block; } A block element container, with floated child elements such as the anchors and div's is not able to detect the area they occupy so the height becomes 0, overflow: hidden is used to fixed this, that becomes a problem when used with a menu, BUT! using content:""; this will add a sort of textual block element which has clear: both, 0 height running below the menu elements that the container CAN detect, so it envelopes the menu again as it did with overflow: hidden. Edited September 14, 2018 by dsonesuk Link to comment Share on other sites More sharing options...
ike Posted September 14, 2018 Author Share Posted September 14, 2018 I finally got it working by giving the .topnav a fixed height and removing the overflow: hidden;. .topnav {background-color: #333; overflow: ;height: 48px;} However, now if you reduce the screen size when you click the menu icon the bottom three menu items do not have the dark background color. Link to comment Share on other sites More sharing options...
ike Posted September 14, 2018 Author Share Posted September 14, 2018 Your suggestion has things working properly now. Thank you very much! I hope I can understand things better someday, as the smallest changes can make such a dramatic impact. Forgot we are going to need a sub menu on one of the dropdowns. Any chance of creating a sub menu with in the current dropdown menu? Seems like I might have to switch to a different menu type using unordered list & li's to accomplish this which will probably blow everything apart. Link to comment Share on other sites More sharing options...
dsonesuk Posted September 14, 2018 Share Posted September 14, 2018 That's not removing! that's a possible breaking the css and likely to affect css following it! Remove it completely, comment it out completely never leave it half done. The container envelopes all the menus to give them a background colour, by restricting the height, it no longer adjusts in height envelope anymore, the menu items and text are there, they just have contrasting background to show them anymore. Link to comment Share on other sites More sharing options...
ike Posted September 14, 2018 Author Share Posted September 14, 2018 I created a sub menu on one of my dropdowns which seems to be working. However, i'm struggling on how the get the Sub Menu Text aligned to the left. Currently it's centered and I'd like it to line up with the other links. Also, is there a way to have an arrow pointing to the right on the Sub Menu? <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"> <title></title> <style> body { margin:0; font-family: Arial; } .header{ width: 100%; height: 125px; background-color: #999; } .body-content{ width: 100%; min-height: 1025px; background-color: #fff; } .footer{ width: 100%; height: 175px; background-color: #000; } .topnav { background-color: #333; overflow: ; } .topnav::after { clear: both; content: ""; display: block; } .topnav a { float: left; display: block; color: #f2f2f2; text-align: center; padding: 14px 16px; text-decoration: none; font-size: 17px; } .active { background-color: ; color: white; } .topnav .icon { display: none; } .dropdown { float: left; overflow: ; } .dropdown .dropbtn { font-size: 17px; border: none; outline: none; color: white; padding: 14px 16px; background-color: #333; font-family: inherit; margin: 0; } .dropdown-content { display: none; position: absolute; background-color: #f9f9f9; min-width: 160px; box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2); z-index: 1; } .dropdown-content a { float: none; color: black; padding: 12px 16px; text-decoration: none; display: block; text-align: left; } .subdropdown .subdropbtn { font-size: 17px; border: none; outline: none; color: white; padding: 14px 16px; background-color: #555 ; font-family: inherit; width: 160px; } .subdropdown-content { display: none; position: absolute; height: 0px; background-color: #f9f9f9; min-width: 160px; box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2); z-index: 1; } .subdropdown-content a { float: none; color: black; padding: 14px 16px; text-decoration: none; display: block; text-align: left; position: relative; top: -48px; left: 160px; background-color: #f9f9f9; box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2); z-index: 1; } .topnav a:hover, .dropdown:hover .dropbtn { background-color: #555; color: white; } .dropdown-content a:hover { background-color: #ddd; color: black; } .subdropdown-content a:hover { background-color: #ddd; color: black; } .dropdown:hover .dropdown-content { display: block; } .subdropdown:hover .subdropdown-content { display: block; } /* Page content */ .content { padding: 16px; } /* The sticky class is added to the navbar with JS when it reaches its scroll position */ .sticky,.topnav.responsive.sticky { position: fixed; top: 0; width: 100%; } /* Add some top padding to the page content to prevent sudden quick movement (as the navigation bar gets a new position at the top of the page (position:fixed and top:0) */ .sticky + .content { padding-top: 60px; } @media screen and (max-width: 600px) { .topnav a:not(:first-child), .dropdown .dropbtn { display: none; } .topnav a.icon { float: right; display: block; } } @media screen and (max-width: 600px) { .topnav.responsive {position: relative;} .topnav.responsive .icon { position: absolute; right: 0; top: 0; } .topnav.responsive a { float: none; display: block; text-align: left; } .topnav.responsive .dropdown {float: none;} .topnav.responsive .dropdown-content {position: relative;} .topnav.responsive .dropdown .dropbtn { display: block; width: 100%; text-align: left; } } </style> </head> <body> <div class="header"></div> <div class="topnav" id="myTopnav"> <a href="home2.html" class="active">Home</a> <a href="a2.html">About</a> <div class="dropdown"> <button class="dropbtn">Products <i class="fa fa-caret-down"></i> </button> <div class="dropdown-content"> <a href="plone.html">Link 1</a> <a href="#">Link 2</a> <a href="#">Link 3</a> </div> </div> <div class="dropdown"> <button class="dropbtn">Services <i class="fa fa-caret-down"></i> </button> <div class="dropdown-content"> <a href="slone.html">Link 1</a> <a href="#">Link 2</a> <div class="subdropdown"> <button class="subdropbtn">Sub Menu <i class="fa fa-caret-down"></i> </button> <div class="subdropdown-content"> <a href="smlone.html">Sub Menu Link 1</a> <a href="#">Sub Menu Link 2</a> <a href="#">Sub Menu Link 3</a> </div> </div> </div> </div> <a href="news2.html">News</a> <a href="c2.html">Contact</a> <a href="javascript:void(0);" style="font-size:15px;" class="icon" onclick="myFunction()">☰</a> </div> <div class="body-content"> <div style="padding-left:16px"> <h2>Home</h2> <p>Resize the browser window to see how it works.</p> <p>Hover over the dropdown button to open the dropdown menu.</p> </div> </div> <div class="footer"></div> <script> function myFunction() { var x = document.getElementById("myTopnav"); if (!x.classList.contains("responsive")) { x.classList.add("responsive"); } else { x.classList.remove("responsive"); } } </script> <script> // When the user scrolls the page, execute myFunction window.onscroll = function() {myFunctionSticky()}; // Get the topnav var topnav = document.getElementById("myTopnav"); // Get the offset position of the navbar var sticky = topnav.offsetTop; // Add the sticky class to the navbar when you reach its scroll position. Remove "sticky" when you leave the scroll position function myFunctionSticky() { if (window.pageYOffset >= sticky) { topnav.classList.add("sticky") } else { topnav.classList.remove("sticky"); } } </script> </body> </html> Link to comment Share on other sites More sharing options...
housler98 Posted September 15, 2018 Share Posted September 15, 2018 Just add text-align:left under .subdropdown .subdropbtn As for the arrow, in the HTML change the <i class="fa fa-caret-down"></i> to <i class="fa fa-caret-right"></i> Link to comment Share on other sites More sharing options...
ike Posted September 15, 2018 Author Share Posted September 15, 2018 I could have sworn I tried that but must have mucked it up somehow as it working now along with the right arrow. Many thanks! I see most navigation menus are made up of unordered lists and list items. Are there benefits of creating it that way opposed to the div structure I used? Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now