Skip to content

Commit a5e4a7c

Browse files
committed
Completed lesson 26
1 parent 7f457dc commit a5e4a7c

1 file changed

Lines changed: 66 additions & 0 deletions

File tree

26 - Stripe Follow Along Nav/index-START.html

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,13 @@ <h2>Cool</h2>
9999
padding-top: .8em;
100100
}
101101

102+
/*
103+
The perspective CSS property determines the distance
104+
between the z=0 plane and the user in order to give a
105+
3D-positioned element some perspective.
106+
107+
https://developer.mozilla.org/en-US/docs/Web/CSS/perspective
108+
*/
102109
nav {
103110
position: relative;
104111
perspective: 600px;
@@ -129,6 +136,15 @@ <h2>Cool</h2>
129136
justify-content: center;
130137
}
131138

139+
140+
/*
141+
If the position property is absolute, the containing block
142+
is formed by the edge of the padding box of the nearest
143+
ancestor element that has a position value other than static
144+
(fixed, absolute, relative, or sticky).
145+
146+
https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_Block
147+
*/
132148
.dropdown {
133149
opacity: 0;
134150
position: absolute;
@@ -220,6 +236,56 @@ <h2>Cool</h2>
220236
</style>
221237

222238
<script>
239+
let triggers = document.querySelectorAll('.cool li');
240+
let background = document.querySelector('.dropdownBackground');
241+
let nav = document.querySelector('.top');
242+
243+
function handleEnter() {
244+
245+
// .trigger-enter sets display to block
246+
this.classList.add('trigger-enter');
247+
248+
// .trigger-enter-active is added 150 ms later (if still active)
249+
// .tigger-enter-active sets the opacity from 0 to 1
250+
// This two step process allows the browser to animate the transition
251+
// This 2-step is how React & Angular handle animation
252+
setTimeout(() => {
253+
if(this.classList.contains('trigger-enter')) {
254+
this.classList.add('trigger-enter-active');
255+
}
256+
}, 150);
257+
258+
// Set the backgrounds opacity to 1
259+
background.classList.add('open');
260+
261+
// Get dropdown for the active trigger (li)
262+
let dropdown = this.querySelector('.dropdown');
263+
264+
// Calculate coordinates for the nav bar and the active dropdown
265+
let navCoords = nav.getBoundingClientRect();
266+
let dropdownCoords = dropdown.getBoundingClientRect();
267+
268+
// Calculate coordinates for the background
269+
const coords = {
270+
height: dropdownCoords.height,
271+
width: dropdownCoords.width,
272+
top: dropdownCoords.top - navCoords.top,
273+
left: dropdownCoords.left - navCoords.left
274+
}
275+
276+
// Set background styles
277+
background.style.setProperty('width', `${coords.width}px`);
278+
background.style.setProperty('height', `${coords.height}px`);
279+
background.style.setProperty('transform', `translate(${coords.left}px, ${coords.top}px`);
280+
}
281+
282+
function handleLeave() {
283+
this.classList.remove('trigger-enter', 'trigger-enter-active');
284+
background.classList.remove('open');
285+
}
286+
287+
triggers.forEach(trigger => trigger.addEventListener('mouseenter', handleEnter));
288+
triggers.forEach(trigger => trigger.addEventListener('mouseleave', handleLeave));
223289
</script>
224290

225291
</body>

0 commit comments

Comments
 (0)