JavaScript show-hide menu
See comments in the HTML and CSS code for the CSS-only :hover version
- Create a new repo on GitHub for this lab and copy the URL. Using the command-line in your local CTEC3905 folder, clone the CTEC3905 starter code on GitHub with
git clone https://github.com/CTEC3905/starter-code.git, thencdinto the cloned folder. In this lab, you’ll create a basic mobile menu using these files, so change the remote in your local repo to your new repo URL usinggit remote set-url origin your_new_repo_url.git- obviously, replace ‘your_new_repo_url.git’ with your URL(!) - and check that this is correct withgit remote -v - Open the folder in Atom and look at the breakpoints in the CSS file - you’ll see the mobile and global styles at the top, then two media queries beginning
@media, the first for screen widths over 500px and the next for screen widths over 1000px. If you try this oput in the browser by adjusting the wiondow width, you'll see the background colour change for each of the three widths - Create a 3-item menu in HTML (see the menu code from 02-lab) and style it to appear nicely above the mobile size by adding your CSS inside the
@mediamin-width: 500pxbreakpoint - you can carefully use parts of the html markup and some CSS styles from 02-lab if you like - if you addflex-direction: columnto thenavstyles to make the mobile menu vertical. Make sure your browser window is wide enough to show the green or blue background, not the pink (mobile width). Now add adivbefore thenavtag that just contains the word ‘menu’, and give it aclassattribute ofmenu. In the mobile and global styles (top of the CSS file) add a style block for your.menuclass, with a darkbackground-color, a lightercolorfor the text, andline-height: 2emjust to give it some height - in “styles.css” add a style block inside the first
@mediamin-width: 500pxbreakpoint that hides.menuusingdisplay: none;. The word “menu” should now only appear when the background is pink (at the mobile size). In the opposite way, thenavtag now needs hiding at mobile widths so it appears only above 500px, so adddisplay: none;to thenavtag mobile/global styles, then inside themin-width: 500pxbreakpoint - again withnavas the selector - usedisplay: flex(as in the lab 02 flexbox styles) and alsoflex-direction: rowto make the menu items line up horizontally. You can use the Chrome developer tools ‘mobile view’ to check your breakpoints if you like, but it won't respond to hover - Now the (slightly) tricky part (see the adjacent sibling combinator). Add a
:hoverstate in the mobile/global styles for the.menuclass usingdisplay: flex;to show thenavelement when the mouse hovers over the menu div. You need the “adjacent sibling combinator” (a plus “+” sign) to target thenavas an adjacent sibling of the.menu:hoverstate. Test the funcionality in the browser, adjusting width between the mobile (pink) view and above (green or blue) - the menu should be vertical (flex-direction: column;) at mobile but horizontal (flex-direction: row) for wider screens. You should be able to hover over the word “menu” to reveal thenavtag with your menu. Finally, you need to add anav:hoverselector to the same rule (using a comma to separate the two selectors) so that the menu stays visible when you hover over it
- Instead of using
:hover, you’re now going to use JavaScript to show and hide the menu. In the html file, add an ID ofmenu-toggleto themenudiv tag and an ID ofmenu-navto thenavtag. Pull in the JavaScript file just before the closing</body>tag with<script src="js/scripts.js"></script>. In the mobile/global CSS, comment out the entire:hoverstyle block so thatdisplay: flexis no longer applied. You’re going to move this rule to a new class that will be activated by JavaScript - Open the empty .js file (or create one in “js/scripts.js”) and add two
constvariables that storegetElementByIdreferences to the two new IDs, named like them but in “camelCase”:menuToggleandmenuNav(this naming convention is not essential but helps identify things) - Write an ES6 arrow function
toggleMenuthat (for now) will simply send a message to the console:console.log("called toggleMenu"). Below this, add an event listener tomenuTogglethat listens for ‘click’ and calls the functiontoggleMenu. Use the browser inspector mobile view with the console pane open to check that this works - you should see “called toggleMenu” in the console every time you click the menu div (the little counter to the left of the message in the console will increment each time you click) - In the CSS file, you'll be working only in the mobile/global styles at the top. Add a new class
.menu-togglebelow the.menustyle block that contains just one rule:display: flex; - Inside the
toggleMenufunction, add aclassList.toggle()tomenuNavwith the argument"menu-toggle"in quotes. This can only be called if the menu div is visible and therefore clickable. Test it out in the browser at the mobile size, and expand the width of the browser window to make sure “menu” disappears above the mobile width
Nice work! You have now completed the 02 Lab learning outcomes:
- understand how
@mediacontains styles that are activated at specified breakpoints - using CSS hover to create a mobile menu
- ES6 arrow function syntax
- adding and removing a class with JavaScript
If you want to see the menu slide in with a CSS transition, you'll need to use absolute position or margin, as display cannot be animated by CSS.
If you have content blocker on your iPhone you may need to “reload without content blockers” in mobile Safari.
These links will help you with the code: