Instructor: Let's now transform
or simple navigation bar into a mobile navigation.
And this is gonna be no easy task
and it's gonna require a lot of code.
And so let's get started right away.
So basically what we want to happen
is that once we reach our breakpoint here,
so this one right here,
we want all of this menu here to disappear
and instead we want a menu button to show up right here.
So just as I said before,
this is something that I'm sure you have seen
on other webpages and also on mobile applications, right?
And so let's actually start with that.
So adding that menu button right here.
So let's go to our HTML.
So this button of course needs to be in our HTML
from the very beginning.
So that's here in the header.
And let's put that after this navigation.
So we have this logo, then the navigation,
and then a button
which I'm gonna call button for the mobile-nav.
So mobile navigation.
And now here inside,
we simply want an icon with the menu.
So let's come here again to our Ionicons.
And so this here is kind of the standard icon for menus.
So copying that.
All right, let's add a class
of icon-mobile-nav.
And actually, we will also want an icon
for closing the navigation.
So let's quickly get that, so close.
Okay, let's duplicate this.
And actually, I remember it was just close here.
So we're adding these two icons here
because basically what we will do
is that the default icon is going to be this one
with the menu.
And then when the user hits this button,
then the mobile navigation will show
and then we will hide this first icon
and display the close icon, all right?
So when the navigation is hidden,
we show the menu icon.
And then when it's visible,
we show the close icon
to give the user the option to close it.
Okay, let's copy this here
because of course, we will need to style it.
And the other one is icon-mobile-nav.
So that's at the very top of the file here.
So yeah, right here.
Let's just add a small comment here.
So this one and icon.
And let's see what it looks like by default.
So we have this button here.
Let's make it at 100%.
And of course, thanks to flexbox,
it is also vertically aligned.
And since we have justified content set to space between,
now this part here is centered between these two, right?
But of course,
we will then make this part here invisible
and only show our button.
But anyway, let's now format this button here.
That's right here.
So we need to get rid of the border
and also of the background color.
So we usually set simply background to none,
and we also wanted to have this pointer cursor.
Okay, and then quickly also the icon here.
So let's see what we have here.
So let's make it 4.8rem of height
and also of width
and the color.
Let's use our darkest gray.
Now, okay, so that looks nice.
But of course, by default
we want one of them here to be hidden, all right?
So we want to now select this one here,
so the closing one, and then hide that.
So how are we going to do that?
So here in our HTML,
we could now of course add another class here
and call this one here like the menu button
and this one, the close button.
However, here I want to show you another selector.
So just because now we don't have it here
side by side, I'm copying all this,
but you don't have to.
And I'm gonna paste that here
into a comment just so we can see the code, okay?
And so I will now use this selector here again.
And then what I want to do
is to select this element
based on this name attribute that is here.
So that's what's distinguishing these two icons here.
So this one has menu-outline
and this one has a close-outline, right?
And so we can actually select in CSS based on attributes.
So for example, like this name one here.
So the way we do that is with these square brackets,
and then we simply write this.
So we can simply write name equal menu-outline, right?
And actually the one that we want to hide here now
is the close one,
so the second one.
So we don't need this anymore,
so display: none.
So now this is turned off.
So that close icon is gone.
But then later, once the user clicks on this button,
we will switch from the menu icon
to the close icon, all right?
Now of course, by default,
this should here be completely hidden, right?
This should not exist.
And so by default, of course,
we need to turn this off.
So make it hidden, right?
So this entire button right now.
So diplay: none once again.
And so then of course it is gone, okay?
So by default for normal width,
we want it to be gone.
But then of course,
once we reach this media query here
that we have been working on,
we now want to show that button.
So mobile navigation.
So display,
and let's display it as a block level element.
So let's wait for it.
And there it is.
Great, so that part was easy,
but now comes the harder part of actually styling
and creating a mobile navigation.
So this mobile navigation will need to work
for this width and for all the other width
that will come later.
So for example, even on a small phone.
So something like this,
which right now doesn't really work
because of this white space here.
So let's just go with this one here.
So what I want to do now is to basically overlay
the navigation over this entire screen here.
So creating like an overlay
and then having these menu items here
one after another display here vertically.
So first how it works, then below the Meals,
Testimonials, Pricing,
and then that call to action button.
And again, having all of that
on top basically on the page, all right?
So the way we are going to do that
is to basically remove this element from here
using CSS with absolute positioning.
So let me show you how we could do that.
First of all, we need to, of course,
take a look what elements we're actually talking about.
So it's this main-nav, right?
So this is the one that we basically
want to now position absolutely
and make it so that it basically occupies the entire screen.
So main-nav.
Let's copy that.
Let's first give it a background-color
so we see what we are doing here.
Let's say blue.
And now we want to position it absolutely.
Let's put it at the top and a left of zero for now.
And now as always, when we position an element absolutely,
we first need to make the parent element,
position relative, right?
However, that might not really be necessary
because actually we don't want to position this
in relation to the header,
but really to the entire view port.
And so we can simply leave it as it is for now
and just test it out.
Now, okay.
And so this element has already been taken
out of the flow here.
So it's basically no longer a flex item like it used to be.
And instead, it is indeed here in the corner.
Let's actually give it a white background
so we can see it a bit better.
And so now let's make it occupy the entire screen.
So first of all, width: 100% and then the height,
remember how we can make it stretch
all the way from top to bottom?
Well, we can give it a height of exactly 100%
of the view port.
So 100 view port height units.
Remember that?
So let's see what that's going to look like.
And indeed, that's already looking quite nice, okay?
And now let's make the text bigger here,
center everything here inside of this container.
So putting it here in the middle
and also stack these navigation items.
So having one after the other
as I mentioned in the beginning.
Now in case you're wondering
why we are doing the design like this
and covering up here, almost all of the hero section,
this is of course just temporary what we're doing here.
So by default,
this navigation here will of course be hidden
and it will only be shown
once the user clicks this button, okay?
So again, this is just going to be the open state.
But by default, of course, we will be able
to see the hero section that is underneath, okay?
And to demonstrate that,
let's actually change the color here
to something transparent.
So clicking here,
and let's do something really small or really big.
So actually a very little transparency here,
but it's going to be enough to see the effect.
And so now let's, as I was saying, center everything.
And for that, we're going to use display set to flex,
because I think that right now
this navigation is not a flex container.
But let's check that out.
main-nav,
oh, and actually we hadn't yet done anything on it.
And so it was not a flex container yet.
So align-items: center and justify-content: center.
So as always,
centering both horizontally and vertically
using this flexbox trick, okay?
But now this main-nav-list,
which is the actual ul element.
So this one here.
Now this is already a flex element
because we used it to put these list items here
side-by-side, right?
So right here.
But now what we want to do
is to change the flex-direction.
But now what we want to do is to simply change
the flex-direction there.
So to have them stacked on top of each other.
So flex-direction and set it to column,
and let's maybe increase the gap back.
So we reduced it I think here before
to, well, maybe we didn't.
But I do think that we did.
Yeah, so here we changed it to 3.2.
Let's put it back to 4.8 now,
4.8rem.
Let's give it a save, and nice.
So that's looking a lot better than before already.
And of course, it is nicely centered.
And well, now we still have some elements here
which are giving us too much space.
So that's this here.
So that's why we cannot go this low,
but it'll work also later once we can do that, all right.
Now let's just increase this text here a lot.
And that should then be enough.
So that's this code right here.
So font-size: 3rem.
Now, okay, beautiful.
Now this might appear to be way too big here,
but if you actually see this on a mobile device
like a phone, then it'll look just right.
All right, so this was the easiest part.
So hopefully you were able to follow up until this point.
Because now we actually need to hide this here,
so all of this container in a correct way.
And also come up with basically a mechanism
that we can use later in JavaScript
to create the effect of showing
and displaying this navigation.
So we will not be able to do that functionality.
So when we click here
that the navigation actually show with CSS alone,
but what we can do is to already prepare everything
and basically do that manually.
So let me show you what I mean with that.
So first of all, we need a way of hiding this navigation.
So because by default, of course,
it should be hidden, right?
So hide the navigation.
Now we have used this before.
So doing display: none, right?
And so if you take a look,
then of course it is gone.
Now the problem with display: none
is that when we use this on an element,
we can do no animations.
So transitions will not work
when we have display set to none.
So that's really, really annoying.
And so we will need to find a way around this.
So let me write that here
Allows NO transitions at all.
Now we moved down here.
So I wanted to actually comment it just like this.
And so the first thing that we will do here
is to set the opacity to zero.
So this I think we have also done before
in order to hide an element,
but this does not exactly hide it.
So this is not enough
to just set opacity to zero,
but more about that in a bit later
because let's now actually animate this value here.
Because this is a value that we can indeed animate,
while display: none we cannot animate.
So as I just said before, right?
So if we check out,
then the element is still gone, right?
And that's because it has the opacity of zero.
If it had like 20%,
then it would be a little bit visible, right?
So it's barely visible now here on top.
But again, let's set it to zero, okay?
But anyway, now it's time to actually start thinking
about the mechanism that we're going to use
to show and hide the navigation.
And so what we're gonna do now
is exactly what we did in the component section.
So in section number six,
where we built that accordion.
So back then, remember we added a class
to the element that we wanted to be open.
And so then based on that class,
we applied different styles.
So we styled the element to then be open
and show a small box beneath the main part.
So remember that.
And if not, then that's not a big problem.
So let me just show it to you here in our code.
So here, we are going to do the same thing
and we will add a class to the header
whenever the navigation is open.
So let's call that class nav-open here.
And so this is the class
that will be added and removed using JavaScript.
And so whenever the navigation is open,
nav-open will be present here
on this header element, all right?
So that's a very, very common technique
when we build components like this,
which need to change their state a little bit
based on JavaScript later.
So we're gonna be able to write
some very, very simple JavaScript
which we'll simply add and remove this class here
depending on whether the user
has clicked the navigation button or not.
But anyway, let's not pretend
that the navigation is currently open.
And so then we can apply styles based on that.
So see how this nav-open here
is now a parent of main-nav, right?
And so we can use that in our CSS like this.
So nav-open and then main-nav,
then the opacity should be back to one, all right?
And so if we check this out now,
then here it goes.
So now it's back.
So let's see that in the inspector here.
So indeed here is the nav-open class,
and so therefore we now have this code
that we just written.
So basically when the nav-open exists,
then this main-nav style here can be applied.
But of course, if we were to remove this class from here,
then the selector here would no longer apply.
And we can actually simulate that here
by simply deleting it,
hitting Enter, and then that style is gone, all right.
Simply because that selector now does no longer apply.
So this one here,
it cannot apply if this class is not on the page, right?
And so that is the whole idea
behind this trick, okay?
Now let's add an animation here.
Let's do that before.
So transition all and 0.5 seconds, okay?
And to show you that
we actually need to reload
to make that class back.
And now if I remove it here,
then actually the animation should already be showing.
So you saw that it faded out here a little bit
over that half second.
So that part, we already have it working, all right?
But now remember how I said
that this is actually not enough
to hide the navigation?
So to hide the navigation properly
without using display: none,
we need to do a couple of steps.
So this one is the first one, which is to hide it,
so hide the element visually.
Then second, we need to make it
unaccessible to mouse and to keyboard.
Because otherwise if we do not this,
then if we hit the Tab key for example,
it will still go to the links
that are in that hidden element.
So because that element is really still on the page.
So display: none does really remove the element
from the page's flow.
It is as if the element does not exist.
But with opacity set to zero,
all that happens is that it becomes invisible, all right?
But things like keyboard Tabs,
they can still then end up there.
So even if it's visually hidden.
And so in order to prevent that,
we need to set pointer-events to none, all right?
And then finally the third step
is to also hide it from screen readers.
So basically telling screen readers
that this element is really hidden.
So we do that by setting visibility to hidden.
And so this is the correct way of hiding an element
without using display: none, okay?
But then of course when we want to open the navigation,
we need to set all of that back to normal.
So pointer-events to auto
and visibility to visible.
Now these CSS properties here,
they probably look a bit strange like a bit obscure,
like this one here especially
because this is one of those
that you will very rarely use, right?
So if you need to build something like this,
you just come here and basically copy this line of code,
and that's it.
This is one of those properties
you will probably never like memorize, all right.
Now, okay.
So let's put it back here.
And again, we could now remove this here to test it,
but that's not really necessary.
Because what I want to do now is to actually change
this menu here to the close, right?
So that's what we said in the beginning,
that whenever the navigation
is actually open that then here
we want to show that other icon
that by default is hidden, right?
So that's right here.
So remember how we did hide that closing icon, right?
But now the time has come
where we want to actually make it visible.
So let's copy this,
paste this here.
Now here, let's display: block.
And here we can use display
because we don't need any animations here
for this icon, all right.
Now, when do we want this to happen?
Well, only when the navigation is open.
So only when this class here
does actually exist in our HTML.
So only if that class exists,
then this selector here does apply
and it will then show the close icon.
So you see that?
Now it is here,
but of course then also that one is there.
So let's quickly hide that.
And that's very simple.
We just copy the same code.
This one is called
probably menu or something, yeah.
So the menu-outline.
This one should have display: none.
And again, here we can use it
because animations are not necessary.
Just to make sure, let's reload.
And indeed, that looks just like we want it to be.
So I'm cutting this here or copying it then removing.
And you see that it turned now into the menu
and everything is gone.
But now let's double click again, add a space
and add it back on.
And then once I hit Enter,
see how the menu will appear back here
and also how this icon here will change.
So let's see.
And there we go, beautiful.
So that's really amazing, right?
So just the power of a simple trick like this
of adding and removing this class here.
And again, we will, in the next section,
use JavaScript to very easily do that, okay?
So we could call it a day here
and actually say that we are ready
because this is already working quite nice.
But actually I want to just add one more thing here,
which is another really, really cool effect,
which is to basically have this whole navigation here
come sliding in from the right side.
And again, I'm sure that you know exactly
what that effect looks like
from other webpages or other mobile applications.
So let's think about how we could do that.
Well, we could simply basically move this entire thing here
completely out of the page,
so basically here to the right side.
And then once the navigation becomes visible,
then we slide that back in here.
So move it basically here with some animation.
And the way we can do that is to, once again,
use the transform property.
Okay, so let's do that on the default state,
which is basically this one here,
which is also the one that has the transition.
So let's add that maybe here.
So transform and then translate.
And this one,
do we want to translate it horizontally or vertically?
Well, of course, in this case here horizontally.
And so that is the x-axis, all right?
So basically we want to move it out of the screen completely
by exactly its own width.
And so that is 100%, right?
So let's see.
But now the problem is that we can still see it
by scrolling to the right.
You see that?
So I'm basically scrolling here to the right.
Could do that also by clicking here.
And so of course that is not what we want.
So this should be really hidden here on the side
and then simply move in, right?
So let's do that.
And for that, we need to use yet another new property.
So let's come here to general.
And this is something that we always do actually
when we build a page like this.
And so what I mean is that here we will set the overflow.
But not just overflow, but overflow-x,
so horizontally to hidden.
And so what this means is that all the elements
that overflow the view port in the x-axis,
so horizontally will simply be hidden, all right?
And so with this,
well, it should be gone actually.
Well, it's not.
And so let's also set it on the HTML.
So many times we need to set it on both, all right?
So not just on body, but exactly on body and on HTML.
So let's see that.
Reload here.
But well, that is still not really fixed.
Oh, but the reason for that is that this element here
is positioned relatively,
basically to the view port, okay?
So remember that we set this here with position absolute,
but we didn't then declare the header
to being position relative.
Remember that?
So I said that maybe it wasn't necessary,
but actually it is necessary.
So one more little bit strange thing about CSS.
So basically this only works
if there is nothing
absolutely positioned in relation to body.
And so that's what right now our main navigation is.
So instead we need to set it to its closest parent.
So the header here, right?
So back here in the top,
let's set the position here to relative.
And so that should now be fixed.
So we should have done that right in the beginning.
So as I said, whenever we position something absolutely,
we should always put position relative
on the parent element
in relation to which we want to position this one here.
So I skipped that.
And so now that created this problem.
But now you see as I try to scroll vertically,
it doesn't work, all right?
And just wanted to show you something else,
which is if we set this here
actually to completely overflow, so not just x,
then we wouldn't be able to scroll at all.
So in no direction.
So I'm trying to scroll right now,
which you cannot see, but I am trying.
And so the page is not moving at all.
Of course, that's not what we want
only in this x direction.
All right, great.
So we moved the whole navigation here
to the right using translate,
and now let's set it back basically to the initial state
once the navigation is open.
So we want to transform: translate it to zero, okay?
And it's actually very important
that we use the transform property
to do this animation
because this is way more performant than, for example,
doing the same thing using the left property.
So we could also have used the left property
to create this animation,
but then the animation would not be as smooth
as it should be.
So again, transform is a very, very common property
that should be used for transitions
because well, these kind of animations,
they have been optimized by CSS
for this property and a couple of others
such as opacity, okay?
So now let's try that.
Just making sure here.
Let's copy that, remove it,
and beautiful.
So you saw how that moved out there.
Let's put it back.
And there it is.
Beautifully moved in here now.
Okay, and with this we are done basically.
I just want to show you here.
Now finally, the third value
that we can specify in transition.
So I mentioned way back
that I was gonna tell you more about
the transition property.
So let's quickly do that now.
So remember that the first value here
is which property we want to animate,
then it's the duration,
and third is the type of the animation.
So if we don't specify anything,
then by default the transition is linear.
But we can also specify like a transition curve,
which is how we call it.
So for example, we can choose ease
or ease-in or ease-in-out or this one.
So let's try ease-out,
and let's try it over two seconds
to see the effect a bit better.
And so again,
I will now remove this here
just so we can see it happening.
And maybe you saw that the animation
was a little bit faster in the beginning.
So if I set it back here now,
then see how it was a bit fast in the beginning
and then it slowed down significantly.
So let's do it again by hitting Command or Ctrl + Z, right?
And then put it back.
So that's a trick that I actually just found out
for the first time, right?
But now let's try it maybe a bit faster
and let's try it with ease-in.
So reloading actually.
And then I'm removing it.
And so did you see that it was a bit slower
this time in the beginning
and then in the end it speeded up.
And so easing in basically means
that it starts low and then it moves faster in the end.
So you saw that?
It was against low in the beginning,
and then it speeded up.
We can also use ease-in-out.
And the best thing to do here
would actually be for you to experiment
with this on your own,
because that would be the easiest way of seeing this
than me just showing these different things here.
So this one basically makes it fast in the beginning
and in the end, and slows down a little bit in the middle.
And again, it's not so easy to see that,
but I'm showing you this
because here I actually want to use ease-in.
And then in fact with half a second.
And so this is the effect I was going for.
So having it move fast in the beginning
and then slowing down at the end.
Now, okay, and with this,
we actually finally finished this mobile navigation.
So that was a lot of work.
Maybe some confusing things that we did here as well.
And so please make sure
to review everything that we did here
in order to make sure that you understood
what's going on here,
so that in the future you can implement
a mobile navigation like this on your own.
And maybe you will even be able to customize this,
so you don't have to create exactly
the same kind of navigation
for yourself in the future, right?
But the overall logic will be the same.
For example, things like this additional class here
and the way that you hide it in the beginning.
So again, make sure to understand this.
And then let's move on to our next category
of breakpoints in media queries in the next lecture.