Afrikaans
Akan
Albanian
Amharic
Arabic
Armenian
Azerbaijani
Basque
Belarusian
Bemba
Bengali
Bihari
Bosnian
Breton
Bulgarian
Cambodian
Catalan
Cebuano
Cherokee
Chichewa
Chinese (Simplified)
Chinese (Traditional)
Corsican
Croatian
Czech
Danish
Dutch
English
Esperanto
Estonian
Ewe
Faroese
Filipino
Finnish
French
Frisian
Ga
Galician
Georgian
German
Greek
Guarani
Gujarati
Haitian Creole
Hausa
Hawaiian
Hebrew
Hindi
Hmong
Hungarian
Icelandic
Igbo
Indonesian
Interlingua
Irish
Italian
Japanese
Javanese
Kannada
Kazakh
Kinyarwanda
Kirundi
Kongo
Korean
Krio (Sierra Leone)
Kurdish
Kurdish (Soranรฎ)
Kyrgyz
Laothian
Latin
Latvian
Lingala
Lithuanian
Lozi
Luganda
Luo
Luxembourgish
Macedonian
Malagasy
Malay
Malayalam
Maltese
Maori
Marathi
Mauritian Creole
Moldavian
Mongolian
Myanmar (Burmese)
Montenegrin
Nepali
Nigerian Pidgin
Northern Sotho
Norwegian
Norwegian (Nynorsk)
Occitan
Oriya
Oromo
Pashto
Polish
Portuguese (Brazil)
Portuguese (Portugal)
Punjabi
Quechua
Romanian
Romansh
Runyakitara
Russian
Samoan
Scots Gaelic
Serbian
Serbo-Croatian
Sesotho
Setswana
Seychellois Creole
Shona
Sindhi
Sinhalese
Slovak
Slovenian
Somali
Spanish
Spanish (Latin American)
Sundanese
Swahili
Swedish
Tajik
Tamil
Tatar
Telugu
Thai
Tigrinya
Tonga
Tshiluba
Tumbuka
Turkish
Turkmen
Twi
Uighur
Ukrainian
Urdu
Uzbek
Vietnamese
Welsh
Wolof
Xhosa
Yiddish
Yoruba
Zulu
Hello there, and welcome back
to implementing our last effect,
which has also the coolest effect of all.
And this one is going to be a so-called sticky navigation.
So as I had mentioned, by the end of the last video,
a sticky navigation bar is basically that
this navigation here stays on top as we scroll
across our entire page.
So let's say we are here or really anywhere on the page,
and then we always have our navigation bar here,
nicely sitting at the top.
And once more, I'm pretty sure
that you have seen a navigation bar like this
many, many times before
because it is actually really helpful
to have that on our page.
All right, now let's start by actually creating
the style for that
because the JavaScript part is basically only then
adding and removing that style.
So basically similar to what we did before,
also with the mobile navigation.
All right.
So again, I'm going to start by creating a new class,
which we will then style to make the navigation sticky.
So let's do that in the style.css file,
which is where our navigation should be.
So here we have the mobile navigation,
and now let's add the sticky navigation.
So let's call it sticky, which makes sense.
And so now there is a new type of value
that we can specify for position.
So that's something that we hadn't done before.
So all we did until this point was position relative
and position absolute,
but now what we actually want is position fixed.
And so this will then fix this element,
basically in the viewport,
and we'll not move it as we scroll.
So let's put it at top zero and bottom zero,
and also let's make sure that it will fill
the entire viewport.
And just so we see it,
let's give it a white background color
and to let see what happens.
Well, of course nothing happened
because we didn't even add this here anywhere.
So let's add this actually to the entire header
because of course the header is the entire part,
which contains the logo and also the navigation.
So right now all of that,
so that entire bar should stay at the top.
Right, and there we can already see it.
Let me just reload.
And so there it is.
So this is kind of already what we are looking for.
There is just as problem that we gave these images here
a higher Z index value.
So let's inspect that.
So, well, maybe this entire thing,
or maybe just to one of these.
Well, in any way, what we need to fix here
is the Z index value of this entire header,
so off the sticky class, right?
So let's again add some really high value here,
so Z index.
And remember how we used this one here for the button.
Now, the button, we will want to always stay on top
of everything, and so let's just do 999 for this one here.
All right.
Also we can use the same background color
with some transparency that we used
for the mobile navigation.
So that's in the queries.
So yeah, just this one here.
Okay.
Give it a save, and beautiful.
So that looks really, really nice,
but we can see that some space has been lost here before.
So that is because the header,
so this entire element, has been taken out of the flow,
just like with position absolute.
So remember that when we position an element
with position absolute,
it is taken out of the flow of the page,
and therefore, it is as if it doesn't even exist.
And so then the rest of the element
fill the remaining space.
And so with position fixed, the exact same thing happens.
And so now basically, the page starts here at this element.
So at the hero section.
So you'll see that it now starts right there at the top.
So we will have to fix that at some point,
but for now, let's actually leave it like this
so that you can later see the problem that it causes.
Now, I also want to add some shadow here,
and we also need to make this a bit smaller.
So like this, it takes up a little bit too big
of the screen, I would say.
So we need to make all of this smaller.
And actually I wanted to give this navigation bar
a fixed height.
So right here.
So let's say 80 pixels, so 8rem,
and then we need to remove the padding
from the top and the bottom.
So we can say padding-top zero
and padding-bottom zero as well.
And so with this, the left and right,
they simply stay unchanged.
Okay.
And I will tell you a bit later in the JavaScript part,
why it is important to have this fixed height.
Okay.
But for now let's add that box shadow
that I was talking about.
And something just very, very subtle.
So horizontally, as always, nothing.
Then just 1.2 REM and then the spread.
Let's give it like 3.2.
And then here, our black color can be something
really subtle, and even less than this.
Let's say just 3%.
Okay.
That looks really nice.
So now it's not too high anymore I would say.
And it still is everything vertically centered here
because of flexbox.
But of course, we don't always want this navigation
to be sticky like this.
So we want us to start basically after this hero section.
Right, so basically, when we start the content itself,
then that's a good time to make it sticky.
So basically right here,
after we leave the hero section behind.
So once that scrolls out of the viewport, right.
And so now we can use JavaScript to do exactly that.
So basically, to add the sticky class,
as soon as the hero section is no longer visible.
All right.
So let's do that, remove it from here.
And does this going to be the most tricky part of all
that we're going to do here.
And so from now on, if you want,
you can just skip the rest of this video
and simply grab the code from the final files
of the section.
All right.
But again, if you're interested in how this works,
then just stick around just like the sticky navigation.
Okay.
And the way we will do this is by using a very modern way,
which is called the intersection observer.
So there would be multiple ways of doing this,
but this is the most performant way,
and also the most modern and the best way I would say.
So intersection observer.
And so here, we now need to specify two things.
First, what we want to happen.
So here we will define a function,
and then second, some options here.
But I will not yet specify these two things.
So not the function and not the options,
but instead I will start by saving
this new intersection observer into a variable.
So calling this one here, the observer, simply
because now we need to actually do observer.observe.
So this sounds very confusing, I know,
but just bear with me here.
So we just need to write a little bit of code
and then things will make more sense.
Okay.
So this one here could have any other name.
Let me call it OBS maybe as an abbreviation,
just to make it less confusing with the OBS.
Okay.
So here we now need to basically observe some element
in the HTML using this observer that we specify here.
And so the element that we want to observe is, in this case,
the hero section, so section hero,
and this is the section that we want to observe
because we will want to make the navigation sticky
as soon as this section here moves out of the viewport.
So that's what we also said before, right.
So basically as soon as this hero section here
moves out of the viewport is to when we want to make
the navigation sticky.
And so that's why that is the element
that we're going to observe.
All right, so let me select that
and create that here first maybe.
So section hero element and then document.
So as always, just selecting it
using document.query selector.
Okay, and so this is the element that we want to observe.
So section hero.
So this was the first part.
So using this observer here to observe a certain element,
which in this case is the section,
and now we need to define the options here.
So for that, we have this so-called object here.
And the first thing is the root.
And the root is basically simply where this element
should be appearing or not.
So that sounds confusing, but it's really not.
So we're just setting it to null here.
And what that means is that we will observe
this hero section inside of the viewport.
So basically, as it moves through the viewport, all right.
So usually that's always what we do here,
but we could also observe some elements
basically scrolling inside of something else,
but this is most helpful just in the viewport.
So basically, inside of the entire browser window.
Okay, next we need to set a threshold.
and this one we set at zero.
And zero basically means that this will fire.
So basically, it means that we will have like an event
as soon as 0% of the hero section is inside of the viewport.
So again, a little bit confusing, I know.
And here we could actually specify multiple values.
So it could also be one,
and then we would get the event
whenever the hero section is completely
inside of the viewport.
And so that's why we set to null here.
So null means the viewport.
But again, we want it to be zero
because we want to get an event as soon as the hero section
moves out completely of the viewport.
So again, that is this event right here, so this situation.
Okay, and for now that is it.
And so now we need to actually specify
what we want to happen when this is the case,
so whenever we have the threshold of zero in the viewport.
Okay.
Let's move this into another line here.
And this one as well.
And here we get access to basically
something called an array of entries,
and there's going to be one entries
for each threshold value.
But here we just have one,
and so we can just say that const ent is equal
the very first entry,
and so that is zero.
So this is, again, something called an array,
which has a collection of multiple elements,
but this one has just one.
And so the element number one is called the number zero,
in fact, in JavaScript.
And so here we are taking that out
and storing it into a new variable.
And so now to start working in this function,
let's take a look actually at this entry here.
So in the console, basically.
And so if we can see something in the console,
then it means that or main code is already working.
So especially these options that we specified here.
Okay.
So let's come to the console, and let's reload,
but I can already see something happening here.
So here we get to now the intersection ratio,
which is basically 62%, all right,
and we get is intersecting.
So these are the two important values.
So this first event here always happens, no matter what,
but now let's wait for it,
and I will actually clear the output here.
And so now, as soon as we move out,
so as soon as this section here moves out of the viewport,
we should get a new event there, right.
So let's wait for it, and there it is.
So now the intersection ratio is zero
and is intersecting is false.
All right, and so we now need to test for this, basically.
So we will want, this is intersecting to be equal to false.
OkaY, so let's write that.
So if ent, which is that event that we just saw,
so which stands here for entry.isintersecting
is equal to false,
then we want to add our sticky class.
So let's select the header here,
and I will do it here all in one go this time
because actually we will have to change this in a minute.
Oh yeah, right here.
So document.querySelector.header.
And so before we always did it in a separate variable,
so we stored this into a variable,
and then on that variable, we did the dot, right.
But we can do it all in one go, so all directly.
And so let's grab the class list
and then we want to add the sticky class here.
So this time we are not using toggle,
but instead simply adding it.
So just called sticky.
Now there is a better way of writing this.
So instead of this, we would usually just this, all right.
But I'll actually leave it like this
to make the code a little bit easier for you to understand.
All right, and so this would actually,
let's reload here once again,
and well, nothing happened.
So, well, let's,
so let's add these curly braces here
to create a block of code so we can have multiple lines.
And so I will only lock this event here
so this entry, when this condition here is true.
So in other words, when ent.intersection
or isintersecting is false.
And actually, I think that I did this wrong here,
isIntersecting.
So I think this is the correct name.
Oh, and now it is actually already working.
So let's see.
So right now, nothing is happening.
And actually let's move this back out.
Okay, so I did this here
because I thought there was a bigger problem.
All right, so here we already have our first entry,
but it has this percentage and it is intersecting.
And so now the sticky class is not yet being added,
but let's wait for it,
and there it is, beautiful.
Okay, now of course, we don't have yet a way of removing it,
but we will take care of that in a minute.
Now, what matters here is that we have this big jump.
So watch closely what happens as the sticky class is added.
So you will notice a big jump here in the page.
So you saw that.
So we basically skipped this entire part here.
And the reason for that is basically
what I explained to you before,
which is the fact that this entire header here
has now been taken out of the flow
because it is now absolutely positioned.
Okay, and so we need to fix that by basically compensating
for this lost height and add some margin
to the top of this header,
so of this hero section, actually.
So here, we now basically need to add
exactly the same margin as is the original height
of the header.
So let's reload, and let's get that height.
So I'll inspect it here, and you see that by default,
it is 96 pixels.
So that's 9.6rem.
All right, and so now whenever the header class
has been added, we want to add some margin to this one here,
so a margin top to the section hero.
All right.
So let's do that here,
right here.
And so how can we actually do that?
So let's first write to code here,
but of course it will not work yet.
So margin top of 9.6rem,
but how does this relate now to the sticky class?
I mean, we only want this to happen whenever
basically the header has the sticky class, right.
So let's make this here a smaller, right.
So again, this style here should basically only apply
whenever sticky is right here on the header, right.
However, that is not possible
because the header is not a parent of section hero.
All right.
And so instead, what we will have to do is to always add
the sticky class, not to the header, but to the body.
All right, and so then we can do this.
So we will then apply all these styles
actually to the header,
but only if the sticky class is a parent of it.
So just like this.
And so then this is exactly what we did
multiple times before,
and in particular with the mobile navigation, right.
So here we had this code where this style only applied
to the main nav if enough open class was present
on one of the parent elements,
and so here we are doing the same.
So we will apply all these styles here to the header
if sticky is a one of its parent elements.
And so that will then be the body.
And so here we can then do the same.
All right.
And finally, then in our JavaScript,
we also need to add the sticky, not to the header,
but to the body.
So that we do by saying document.body
and yeah, that's it.
So just like this, and let's reload manually here.
And let's see if there is the same jump now,
but it shouldn't.
And indeed, we fixed that.
So beautiful, you saw the sticky class being added here,
and so it then should have added.
Well, it's added all these tiles here to the header
and then here to the section hero
it will have added that margin, right,
so that margin top of 9.6.
All right.
So, beautiful.
And of course, if we take that sticky class away,
then we go back to normal.
So we are almost done here.
Just two more things.
So first, let's take a look again at our effect.
So you see, or you will see,
now that, of course, this sticky
exactly as we moved out of the hero section, right.
now, the problem that is that
it will then overlap this first section here.
And so that means basically that this happens
a little bit too late.
So actually we want it to happen kind of like here.
So exactly here.
All right.
And so we can do that in our code.
So here we can add a third option, which is the root margin.
And so that margin is then basically applied
outside of this root.
So here we can say minus 80 pixels.
So here it has to be pixels.
It doesn't work to use percentages or REM.
And it needs to be a string like this, so inside of quotes.
And so here we use these 80 pixels
because that's exactly what we set
the height of the navigation bar to.
So these eight REM here are basically 80 pixels.
And so this is the reason why it was important
to set the height here manually.
So that then right here, we could use that 80 pixels.
And so let's reload just to make sure.
With JavaScript, sometimes it's better to reload.
And so now it should happen,
yeah, exactly as we reach that.
You saw it?
So that is now almost it.
And so now the only missing part is to remove it
as soon as the hero is still visible.
So once we enter this again, we should get another event.
So I now exited the hero again,
but now as we enter it, we will get a new event.
And so now is intersecting is back to being true.
Okay, and so we can use that to then remove it.
So we can say if true, then remove, okay.
And now here, this true is not necessary at all
because basically this condition here,
as soon as it is true, then this here will get executed.
So this is not necessary.
And that's also the reason why here,
we could set this
because if this is false,
then this one here will basically switch from false to true,
and so therefore, then this code here can execute.
All right, but again, I will leave it here like this
for you to understand the code a little bit better.
But anyway, again, reloading here.
There it is, and there it leaves.
And of course, now it is back up.
So let's see that also in the code.
So here, so now it is sticky,
and now it's gone, and it's back, and it's gone.
So, working really nice.
Let's just try it also in Safari
because things in Safari tends to work a little bit worse,
but still, it is working perfectly.
Very, very nice.
So, as I said in the beginning,
I know that this code here is quite tricky,
but hopefully you were at least able to follow the logic
of what I explained to you here throughout this lecture.
Because if you did that, then you might be able
to adapt this in the future to your own page.
And that is really the main goal
that I have with these few videos here.
All right, but enough talk because it works great.
And so in the next video we will create
our last piece of JavaScript,
or actually we will just use what we already have here
because we now need to fix
the flexbox gap property in Safari.
Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.