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
, thencd
into 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
@media
min-width: 500px
breakpoint - you can carefully use parts of the html markup and some CSS styles from 02-lab if you like - if you addflex-direction: column
to thenav
styles 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 adiv
before thenav
tag that just contains the word ‘menu’, and give it aclass
attribute ofmenu
. In the mobile and global styles (top of the CSS file) add a style block for your.menu
class, with a darkbackground-color
, a lightercolor
for the text, andline-height: 2em
just to give it some height - in “styles.css” add a style block inside the first
@media
min-width: 500px
breakpoint that hides.menu
usingdisplay: none;
. The word “menu” should now only appear when the background is pink (at the mobile size). In the opposite way, thenav
tag now needs hiding at mobile widths so it appears only above 500px, so adddisplay: none;
to thenav
tag mobile/global styles, then inside themin-width: 500px
breakpoint - again withnav
as the selector - usedisplay: flex
(as in the lab 02 flexbox styles) and alsoflex-direction: row
to 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
:hover
state in the mobile/global styles for the.menu
class usingdisplay: flex;
to show thenav
element when the mouse hovers over the menu div. You need the “adjacent sibling combinator” (a plus “+
” sign) to target thenav
as an adjacent sibling of the.menu:hover
state. 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 thenav
tag with your menu. Finally, you need to add anav:hover
selector 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-toggle
to themenu
div tag and an ID ofmenu-nav
to thenav
tag. 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:hover
style block so thatdisplay: flex
is 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
const
variables that storegetElementById
references to the two new IDs, named like them but in “camelCase”:menuToggle
andmenuNav
(this naming convention is not essential but helps identify things) - Write an ES6 arrow function
toggleMenu
that (for now) will simply send a message to the console:console.log("called toggleMenu")
. Below this, add an event listener tomenuToggle
that 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-toggle
below the.menu
style block that contains just one rule:display: flex;
- Inside the
toggleMenu
function, add aclassList.toggle()
tomenuNav
with 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
@media
contains 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: