August 7, 201610 yr Hi guys, I've used this CSS menu and changed it to how I want it, but I can't for the life of me work out how to center it on the page Please help http://medialoot.com/blog/how-to-create-a-responsive-navigation-menu-using-only-css/ Many thanks Andy
August 8, 201610 yr Author I decided to start from scratch again, here is the HTML and the CSS: HTML: <!doctype html><html lang="en"><head> <meta charset="UTF-8"> <title>CSS Only Navigation Menu</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="./css/navstyles.css"></head><body> <label for="show-menu" class="show-menu">Show Menu</label> <input type="checkbox" id="show-menu" role="button"> <ul id="menu"> <li><a href="#">Home</a></li> <li> <a href="#">About ↓</a> <ul class="hidden"> <li><a href="#">Who We Are</a></li> <li><a href="#">What We Do</a></li> </ul> </li> <li> <a href="#">Portfolio ↓</a> <ul class="hidden"> <li><a href="#">a</a></li> <li><a href="#">b</a></li> <li><a href="#">c</a></li> </ul> </li> <li><a href="#">News</a></li> <li><a href="#">Contact</a></li> </ul></body></html> CSS file: @charset "utf-8";/* CSS Document *//*Strip the ul of padding and list styling*/ul { list-style-type:none; margin-left:300px; padding:0; position: absolute;}/*Create a horizontal list with spacing*/li { display:inline-block; float: left; margin-right: 1px;}/*Style for menu links*/li a { display:block; min-width:140px; height: 50px; text-align: center; line-height: 50px; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; color: #fff; background: #f00; text-decoration: none;}/*Hover state for top level links*/li:hover a { background: #cc0000;}/*Style for dropdown links*/li:hover ul a { background: #f3f3f3; color: #2f3036; height: 40px; line-height: 40px;}/*Hover state for dropdown links*/li:hover ul a:hover { background: #19c589; color: #fff;}/*Hide dropdown links until they are needed*/li ul { display: none;}/*Make dropdown links vertical*/li ul li { display: block; float: none;}/*Prevent text wrapping*/li ul li a { width: auto; min-width: 100px; padding: 0 20px;}/*Display the dropdown on hover*/ul li a:hover + .hidden, .hidden:hover { display: block;}/*Style 'show menu' label button and hide it by default*/.show-menu { font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; text-decoration: none; color: #fff; background: #19c589; text-align: center; padding: 10px 0; display: none;}/*Hide checkbox*/input[type=checkbox]{ display: none;}/*Show menu when invisible checkbox is checked*/input[type=checkbox]:checked ~ #menu{ display: block;}/*Responsive Styles*/@media screen and (max-width : 760px){ /*Make dropdown links appear inline*/ ul { position: static; display: none; } /*Create vertical spacing*/ li { margin-bottom: 1px; } /*Make all menu links full width*/ ul li, li a { width: 100%; } /*Display 'show menu' link*/ .show-menu { display:block; }} I've stripped it back to basically what is in the link above, when I add the line of code highlighted in red above it moves, but the drop down menu's are then off Please help Andy
August 9, 201610 yr The absolute positioning is the bugbear with this. Unfortunately once position:absolute; rears its head things can start to get a bit tricky. Tried this and it seems to work. Add a <nav> element around the <ul id="menu"> Now add the following CSS nav{ width:700px; margin:0 auto; } This works fine because the buttons are set to min-width:140px; and five buttons are therefore 700px wide. However if one button is longer it won't work due to the fixed widths. In that case add an ID to the nav element, remove the width from the CSS and add the following bit of JS which measures the total width of the <ul> element. <script> function sizeElement(el1,el2) { var elmnt2 = document.getElementById(el2); var w = elmnt2.offsetWidth + "px"; var h = elmnt2.offsetHeight + "px"; document.getElementById(el1).style.width = w; document.getElementById(el1).style.height = h; } window.addEventListener("load", sizeElement('nav','menu')); </script> So the end result would be something like <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <title></title> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" type="text/css" href="style.css"> <style> /* Page specific styles can go here */ </style> </head> <body> <label for="show-menu" class="show-menu">Show Menu</label> <input type="checkbox" id="show-menu" role="button"> <nav id="nav"> <ul id="menu"> <li><a href="#">Home</a></li> <li><a href="#">About ↓</a> <ul class="hidden"> <li><a href="#">Who We Are</a></li> <li><a href="#">What We Do</a></li> </ul> </li> <li><a href="#">Portfolio ↓</a> <ul class="hidden"> <li><a href="#">a much longer bit of text just as a test</a></li> <li><a href="#">b</a></li> <li><a href="#">c</a></li> </ul> </li> <li><a href="#"> Latest News and Reviews</a></li> <li><a href="#">Contact</a></li> </ul> </nav> <script> function sizeElement(el1,el2) { var elmnt2 = document.getElementById(el2); var w = elmnt2.offsetWidth + "px"; var h = elmnt2.offsetHeight + "px"; document.getElementById(el1).style.width = w; document.getElementById(el1).style.height = h; } window.addEventListener("load", sizeElement('nav','menu')); </script> </body> </html> and the CSS /* */ *,*:after,*:before{ -webkit-box-sizing:border-box; -moz-box-sizing:border-box; box-sizing:border-box; } body{ margin:0; padding:0; } nav { margin:0 auto; }/*Strip the ul of padding and list styling*/ ul { list-style-type:none; padding:0; margin:0; position:absolute; }/*Create a horizontal list with spacing*/ li { float:left; margin-right: 1px; }/*Style for menu links*/ li a { display:inline-block; min-width:140px; height: 50px; text-align: center; line-height: 50px; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; color: #fff; background: #f00; text-decoration: none; margin:0; padding:0 10px; }/*Hover state for top level links*/ li:hover a { background: #cc0000; }/*Style for dropdown links*/ li:hover ul a { background: #f3f3f3; color: #2f3036; height: 40px; line-height: 40px; }/*Hover state for dropdown links*/ li:hover ul a:hover { background: #19c589; color: #fff; }/*Hide dropdown links until they are needed*/ li ul { display: none; }/*Make dropdown links vertical*/ li ul li { display: block; float: none; }/*Prevent text wrapping*/ li ul li a { width: auto; min-width: 100px; padding: 0 20px; }/*Display the dropdown on hover*/ ul li a:hover + .hidden, .hidden:hover { display: block; }/*Style 'show menu' label button and hide it by default*/ .show-menu { font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; text-decoration: none; color: #fff; background: #19c589; text-align: center; padding: 10px 0; display: none; }/*Hide checkbox*/ input[type=checkbox]{ display: none; }/*Show menu when invisible checkbox is checked*/ input[type=checkbox]:checked ~ #menu{ display: block; }/*Responsive Styles*/ @media screen and (max-width : 760px){ /*Make dropdown links appear inline*/ ul { position: static; display: none; } /*Create vertical spacing*/ li { margin-bottom: 1px; } /*Make all menu links full width*/ ul li, li a { width: 100%; } /*Display 'show menu' link*/ .show-menu { display:block; } } I added a little padding to the buttons and made one of them longer to show it works with buttons of unequal length. It is vanilla JS so there is no need to load 100KB of JQuery. The function itself isn't 'hard wired' to any elements so more window load events or even click events on elements could be set to use it. Just remember that el1 is the object to be sized and el2 the object to be measured. You would need to test it thoroughly for use with a responsive layout
August 9, 201610 yr Author Thank you so much dude! The only issue I have is that when on a smaller screen the drop down menu doesn't work and I can't see why Many thanks Andy
August 9, 201610 yr Mobile devices don't do hover so the dropdowns are highly unlikely to work. You either need to trigger the dropdowns by JS/JQuery or by using the CSS checkbox 'hack' or using a focus event on the dropdown parent. Focus events can be applied to elements other than input and other form elements by giving them a tabindex. However depending on the application you want to apply them to there could be problems using this method.
August 10, 201610 yr Author Hi dude, I fully appreciate what your saying about hover on mobile devices, but it used to work when you tapped on it, and I can't see whats changed to shop that happening, despite looking at code for a couple of hours yesterday :-/ Andy
August 10, 201610 yr Hi dude, I fully appreciate what your saying about hover on mobile devices, but it used to work when you tapped on it, and I can't see whats changed to shop that happening, despite looking at code for a couple of hours yesterday :-/ Andy Tapped on what exactly the red menu button or the green Show Menu
August 10, 201610 yr Tapped on what exactly the red menu button or the green Show Menu yes OK so red or green or both?
August 10, 201610 yr Mobile devices do register hover events. It gets triggered with an onTouch event. but so too will a click event.
August 10, 201610 yr By the way there's way too much useage of element selectors in that CSS. You definitely don't want to add that kind of styling to all unordered lists for example. Use classes for non-global styling and element selectors only when you want those particular styles to be applied across an entire codebase. http://csswizardry.com/2012/11/code-smells-in-css/#dangerous-selectors I'd also recommend reading the rest of that article as there are a number of issues in the CSS posted above. Despite it working it is always worthwhile trying to avoid smells in your CSS. It will save a lot of headaches going forwards.
August 10, 201610 yr Mobile devices do register hover events. It gets triggered with an onTouch event. but so too will a click event. Some might but I wouldn't like to make the assumption that all will do so. I reckon the root cause of the problems are the absolute positioning and all the dimensions in pixels.
August 10, 201610 yr Some might but I wouldn't like to make the assumption that all will do so. I reckon the root cause of the problems are the absolute positioning and all the dimensions in pixels. With the way that CSS hover events are triggered I'd say it is safe to assume that all modern touch screens will register a CSS hover event. Any that doesn't has not implemented the standard APIs correctly and that would be very odd indeed. It would be odd to style things based on this for say a link as like I pointed out earlier the click event will also fire which will mean the link is followed so in that sense the hover state has no use. I have used it in the past to reveal tool tips on hover and I can confirm that worked across a huge array of mobile devices as I was running automated tests using Selenium via Sauce Labs. I got no errors there for that feature. I wouldn't say it's an assumption seen as it's been tested using battle-tested software. As for the CSS issues, yes in terms of layout in this case they might cause problems, although positioning and pixels used appropriately are very useful tools. The selector issues I was pointing out was just in terms of selector architecture which is important when building real projects. Edited August 10, 201610 yr by rbrtsmith
August 11, 201610 yr Well it doesn't work like that in my Vodafone Smart First. Whether that is down to the individual phone or down to the individual finger jabbing away at it I'm not sure. My, a former heavy hammer engineer, idea of a light touch is probably most people's idea of a blow with that heavy hammer. I've found touch/hover emulation in the dev tools in Chrome and Firefox to be iffy at best so overall I would not rely on hover events working as intended in touch screen devices.
Create an account or sign in to comment