diff --git a/projects/random/intersectional-observation/README.md b/projects/random/intersectional-observation/README.md new file mode 100644 index 0000000..2deca35 --- /dev/null +++ b/projects/random/intersectional-observation/README.md @@ -0,0 +1,27 @@ +# Basic Responsive Navigation + +Nearly every website needs a responsive navigation, but they can be confusing to layout. It’s not uncommon for developers to create two separate navigations: one for mobile and one for desktop. But there’s a better way! In this video, I'll show you how to create a fully responsive navigation menu with HTML, CSS, and Vanilla JavaScript. We’ll add aria attributes to achieve a basic accessible navigation. + + +🔗 Key Links 🔗 +- YouTube Video: https://youtu.be/63sxOYm9GwY +- Live Code: https://codinginpublic.dev/projects/responsive-navigation/ + +--------------------------------------- + +📹 Related Videos 📹 +- Intersection Observer playlist: https://www.youtube.com/playlist?list=PLoqZcxvpWzze3Hkult9jLfCvZlzCYLb8G +- Understanding Clamp(): https://youtu.be/Moely7aPYGE + +--------------------------------------- + +🧰 My Tools 🧰 +- VSCode Font/Theme: https://www.youtube.com/watch?v=5uETTXxVj8s +- VSCode Extensions: https://www.youtube.com/watch?v=0ABuzt8X5SA + +--------------------------------------- + +🌐 Connect With Me 🌐 +- Website: https://codinginpublic.dev +- Blog: https://chrispennington.blog +- Twitter: https://twitter.com/cpenned diff --git a/projects/random/intersectional-observation/assets/logomark.svg b/projects/random/intersectional-observation/assets/logomark.svg new file mode 100644 index 0000000..a47c460 --- /dev/null +++ b/projects/random/intersectional-observation/assets/logomark.svg @@ -0,0 +1,11 @@ + \ No newline at end of file diff --git a/projects/random/intersectional-observation/assets/navigation.svg b/projects/random/intersectional-observation/assets/navigation.svg new file mode 100644 index 0000000..69a12ef --- /dev/null +++ b/projects/random/intersectional-observation/assets/navigation.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/projects/random/intersectional-observation/assets/space.jpg b/projects/random/intersectional-observation/assets/space.jpg new file mode 100644 index 0000000..86b1ee5 Binary files /dev/null and b/projects/random/intersectional-observation/assets/space.jpg differ diff --git a/projects/random/intersectional-observation/assets/spaceLg.jpg b/projects/random/intersectional-observation/assets/spaceLg.jpg new file mode 100644 index 0000000..b35fd92 Binary files /dev/null and b/projects/random/intersectional-observation/assets/spaceLg.jpg differ diff --git a/projects/random/intersectional-observation/assets/spaceMd.jpg b/projects/random/intersectional-observation/assets/spaceMd.jpg new file mode 100644 index 0000000..91f1cd1 Binary files /dev/null and b/projects/random/intersectional-observation/assets/spaceMd.jpg differ diff --git a/projects/random/intersectional-observation/assets/spaceSm.jpg b/projects/random/intersectional-observation/assets/spaceSm.jpg new file mode 100644 index 0000000..a91a38b Binary files /dev/null and b/projects/random/intersectional-observation/assets/spaceSm.jpg differ diff --git a/projects/random/intersectional-observation/index.html b/projects/random/intersectional-observation/index.html new file mode 100644 index 0000000..21561e3 --- /dev/null +++ b/projects/random/intersectional-observation/index.html @@ -0,0 +1,168 @@ + + + + + + + + + Responsive Navigation + + + + + + + + + +
+ View of earth from space +
+

The Next Frontier

+

Explore the universe of tomorrow.

+
+
+
+
+

Look to the Stars

+

Lorem ipsum dolor sit, amet consectetur adipisicing elit. Vitae eligendi quibusdam dolor + illum impedit nisi. Eaque sequi necessitatibus voluptatum porro.

+

Lorem ipsum dolor sit, amet consectetur adipisicing elit. Nesciunt fugiat commodi numquam? + Obcaecati magni perferendis eligendi laudantium cum perspiciatis minus animi ipsa placeat adipisci + repellendus, id culpa minima officiis fugiat quidem nisi sint consectetur eius vero velit sunt quas + expedita. Ullam unde optio ad voluptas praesentium animi velit quae dicta?

+

Lorem ipsum dolor sit amet consectetur adipisicing elit. Itaque, temporibus.

+
+
+

Reasons to Travel

+
+
+ + + + + + + + +
+

Stars in the Sky

+

Lorem ipsum dolor sit amet consectetur adipisicing elit. Harum obcaecati, + deserunt optio possimus atque qui!

+
+
+
+ + + + + + +
+

Moon Up Above

+

Lorem ipsum dolor sit amet consectetur adipisicing elit. Harum obcaecati, + deserunt optio possimus atque qui!

+
+
+
+ + + + + + + + + + +
+

Ain’t no Sun Allowed

+

Lorem ipsum dolor sit amet consectetur adipisicing elit. Harum obcaecati, + deserunt optio possimus atque qui!

+
+
+
+
+
+

Space Travel for Everyone

+

Lorem ipsum dolor sit, amet consectetur adipisicing elit. Vitae eligendi quibusdam dolor + illum impedit + nisi. Eaque sequi necessitatibus voluptatum porro.

+

Lorem ipsum dolor sit, amet consectetur adipisicing elit. Nesciunt fugiat commodi numquam? + Obcaecati + magni perferendis eligendi laudantium cum perspiciatis minus animi ipsa placeat adipisci repellendus, id + culpa minima + officiis fugiat quidem nisi sint consectetur eius vero velit sunt quas expedita. Ullam unde optio ad + voluptas + praesentium animi velit quae dicta?

+

Lorem ipsum dolor sit amet consectetur adipisicing elit. Itaque, temporibus.

+
+
+ + + \ No newline at end of file diff --git a/projects/random/intersectional-observation/nav.js b/projects/random/intersectional-observation/nav.js new file mode 100644 index 0000000..876c35f --- /dev/null +++ b/projects/random/intersectional-observation/nav.js @@ -0,0 +1,32 @@ +const navBtn = document.querySelector('#menu-btn'); +const nav = document.querySelector('nav'); +const navLinks = document.querySelector('.nav-links'); + +navBtn.addEventListener('click', () => { + navLinks.classList.add('activated'); + const isExpanded = JSON.parse(navBtn.getAttribute('aria-expanded')); + navBtn.setAttribute('aria-expanded', !isExpanded); + !isExpanded && nav.classList.add('active'); +}) + +//INTERSECTION OBSERVER + +const navObs = new IntersectionObserver((entries) => nav.classList.toggle('active', !entries[0].isIntersecting) +, {threshold: .85}) + +navObs.observe(document.querySelector('header')); + +const fadeUpObserver = new IntersectionObserver((entries) => { + entries.forEach(entry => { + if(entry.isIntersecting){ + entry.target.classList.add('faded'); + fadeUpObserver.unobserve(entry.target) + } + }) +}, { + rootMargin: '-15%' +}) + +document.querySelectorAll('.fade-up').forEach(el => { + fadeUpObserver.observe(el); +}) diff --git a/projects/random/intersectional-observation/style.css b/projects/random/intersectional-observation/style.css new file mode 100644 index 0000000..2178102 --- /dev/null +++ b/projects/random/intersectional-observation/style.css @@ -0,0 +1,300 @@ +*, +*::after, +*::before { + box-sizing: border-box; + margin: 0; + padding: 0; +} + +:root { + --bkg: linear-gradient(to top, #0f0915, #050307); + --dark: #050307; + --text: #f9f6fe; + --accent: #4233e4; +} + +body { + font-family: "Nunito Sans", sans-serif; + font-size: clamp(1.1rem, 2vw + 1rem, 1.4rem); + line-height: 1.55; + background: var(--bkg); + color: var(--text); +} + +nav { + position: fixed; + z-index: 10; + width: 100%; + padding-block: 1.2rem; + background-color: transparent; + transition: background-color 800ms cubic-bezier(0.64, 0.04, 0.26, 0.87); +} + +nav.active { + background-color: var(--dark); +} + +.nav-container { + display: flex; + justify-content: space-between; + align-items: center; +} + +.logo { + color: var(--accent); + margin-inline: 0.5rem; + width: clamp(3rem, 10vw, 7.5rem); + display: grid; + place-items: center; +} + +.logo-link:focus-visible, +.nav-link:focus-visible { + outline: 4px solid var(--accent); + outline-offset: 0.2em; + border-radius: 0.5rem; +} + +.nav-links { + display: flex; + align-items: center; + flex-direction: column; + gap: 1.5rem; + transform: translate3d(0, -200%, 0); + position: absolute; + z-index: -1; + top: 3rem; + left: 0; + right: 0; + background-color: var(--dark); + padding: 1.5rem; + border-bottom: 4px solid var(--accent); + text-align: center; +} + +.nav-links.activated { + transition: transform 0.4s cubic-bezier(0.64, 0.04, 0.26, 0.87); +} + +.btn { + color: var(--text); + text-decoration: none; + padding: 0.3rem 1.5rem; + cursor: pointer; + border-radius: 0.5rem; +} + +.btn--accent { + background-color: var(--accent); + padding: 0.3rem 2rem; +} + +.btn--menu { + color: var(--accent); + background-color: transparent; + border: none; + display: grid; + place-items: center; + padding-inline: 1rem; + transition: transform 0.3s cubic-bezier(0.64, 0.04, 0.26, 0.87); +} + +li[role="none"], +.nav-link { + width: 100%; + display: block; + font-size: 1.1rem; + text-transform: uppercase; +} + +.btn--menu[aria-expanded="true"] { + transform: rotate(-180deg); +} + +.btn--menu[aria-expanded="true"] + .nav-links { + transform: translate3d(0, 0, 0); +} + +@media (min-width: 768px) { + .btn--menu { + display: none; + } + .nav-links { + position: static; + transform: translate3d(0, 0, 0); + flex-direction: row; + border: 0; + z-index: 0; + padding: 0; + inset: 0; + background-color: transparent; + } + li[role="none"], + .nav-link { + width: initial; + } +} + +main { + display: grid; + gap: clamp(4rem, 1.45454537rem + 11.636364vw, 8rem); + position: relative; + top: -10vh; +} + +h1 { + font-size: clamp(2.5rem, 5vw + 1rem, 8rem); + font-size: bolder; + line-height: 1.1; + letter-spacing: 0.02em; +} + +.h2 { + font-size: clamp(1.8rem, 4vw + 1rem, 3.5rem); + font-size: bolder; + line-height: 1.1; + color: var(--accent); +} + +.h3 { + font-size: clamp(1.2rem, 3vw + 1rem, 2.2rem); + line-height: 1.1; + color: var(--accent); +} + +.subheading { + color: var(--text); +} + +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border-width: 0; +} + +header { + min-height: 100vh; + display: grid; + place-items: center; + text-align: center; + position: relative; +} + +.header__img { + position: absolute; + height: 100%; + width: 100%; + object-fit: cover; +} + +.container { + margin-inline: max((100% - 90rem) / 2, 1rem); +} + +.container--sm { + margin-inline: max((100% - 70rem) / 2, 2rem); +} + +.rise { + opacity: 0; + animation: rise 0.8s ease-in-out forwards; +} + +.rise.subheading { + animation: rise 1.2s ease-in-out forwards 0.5s; +} + +@keyframes rise { + 0% { + transform: translateY(2rem); + opacity: 0; + } + 100% { + transform: translateY(0); + opacity: 1; + } +} + +.header-container { + display: grid; + gap: 1rem; + position: relative; + top: -5vh; +} + +.stars { + padding: clamp(1.2rem, 3.5vw, 2.5rem) clamp(1.2rem, 5vw, 3rem) 0; + background-color: var(--dark); + display: grid; + border-radius: 0.5rem; + gap: 1rem; +} + +.moons { + display: grid; + gap: 1rem; +} + +#stars { + text-align: center; +} + +.card-container { + display: flex; + flex-wrap: wrap; + gap: 2.5rem 3.5rem; +} + +.card { + flex: 1 1 100%; + display: grid; + place-items: center; + gap: 1.5rem; + padding: 2.5rem 1.5rem 1.5rem; + border: 5px solid var(--accent); + border-radius: 0.5rem; +} + +@media (min-width: 768px) { + .card { + flex: 1 1 28%; + } +} + +.card__image { + width: clamp(4rem, 10vw, 8rem); +} + +.fade-up { + opacity: 0; + transform: translate3d(0, 5rem, 0); + transition: transform 1s cubic-bezier(0.64, 0.04, 0.26, 0.87), + opacity 0.8s cubic-bezier(0.64, 0.04, 0.26, 0.87); +} + +.fade-up.faded { + opacity: 1; + transform: translate3d(0, 0, 0); +} + +/* Remove all animations, transitions and smooth scroll for people that prefer not to see them */ +@media (prefers-reduced-motion: reduce) { + html:focus-within { + scroll-behavior: auto; + } + + *, + *::before, + *::after { + animation-duration: 0.01ms !important; + animation-iteration-count: 1 !important; + transition-duration: 0.01ms !important; + scroll-behavior: auto !important; + } +}