diff --git a/card-one/index.html b/card-one/index.html index 75302dc..94cc6ff 100644 --- a/card-one/index.html +++ b/card-one/index.html @@ -15,18 +15,18 @@ + + + + +
diff --git a/card-two/index.html b/card-two/index.html
index 6ba6414..5b476e1 100644
--- a/card-two/index.html
+++ b/card-two/index.html
@@ -15,18 +15,18 @@
+
+
+
+
+
diff --git a/index.html b/index.html
index f99fcef..ba11ab4 100644
--- a/index.html
+++ b/index.html
@@ -15,17 +15,17 @@
+
+
+
+
+
diff --git a/scripts/nav.js b/scripts/nav.js
new file mode 100644
index 0000000..16996ca
--- /dev/null
+++ b/scripts/nav.js
@@ -0,0 +1,122 @@
+/* Nav construction */
+const cards = [
+ {
+ title: "card one",
+ href: "/card-one/"
+ },
+ {
+ title: "card two",
+ href: "/card-two/"
+ }
+]
+
+const constructMenuLink = function(title, href) {
+ const path = window.location.pathname;
+
+ const a = document.createElement("a");
+ a.href = href;
+ a.title = title;
+ a.innerHTML = title;
+ if (path === href) a.id = "current-page";
+
+ return a;
+}
+
+const constructDropdown = function() {
+ const div = document.createElement("div");
+ div.id = "dropdown";
+
+ const button = document.createElement("button");
+ button.innerHTML = "cards ⮷";
+ button.id="drop-button";
+ button.ariaLabel = "card submenu";
+ button.ariaExpanded = "false";
+ button.setAttribute("aria-controls", "drop-content");
+ div.append(button);
+
+ const ul = document.createElement("ul");
+ ul.id = "drop-content";
+ ul.ariaHidden = "true";
+
+ for (const card of cards) {
+ const li = document.createElement("li");
+ li.append(constructMenuLink(card.title, card.href));
+ ul.append(li);
+ }
+
+ div.append(ul);
+ return div;
+}
+
+const constructNav = function() {
+ const nav = document.getElementById("top-nav");
+ nav.append(constructMenuLink("home", "/"));
+ nav.append(constructDropdown());
+}
+
+constructNav();
+
+/* Dropdown handling */
+
+const dropdown = document.getElementById("dropdown");
+const dropdownButton = document.getElementById("drop-button");
+const dropdownContent = document.getElementById("drop-content");
+
+const dropdownItems = dropdownContent.querySelectorAll("a");
+const firstDropdownItem = dropdownItems[0];
+const lastDropdownItem = dropdownItems[dropdownItems.length - 1];
+
+const openDropdown = function() {
+ dropdownContent.classList.add("show");
+ dropdownContent.setAttribute("aria-hidden", "false");
+ dropdownButton.setAttribute("aria-expanded", "true");
+}
+
+const closeDropdown = function() {
+ if (dropdownButton.ariaExpanded === "true") {
+ dropdownContent.classList.remove("show");
+ dropdownContent.setAttribute("aria-hidden", "true");
+ dropdownButton.setAttribute("aria-expanded", "false");
+
+ /* focus the button again */
+ dropdownButton.focus();
+ }
+}
+
+dropdownButton.addEventListener("click", (event) => {
+ if (dropdownButton.ariaExpanded === "false") openDropdown();
+ else closeDropdown();
+});
+
+dropdownButton.addEventListener("keydown", (event) => {
+ if (event.key === "Enter" || event.key === " ") { // Space or Enter key
+ event.preventDefault(); // Prevent the default action to stop scrolling when pressing Space
+ if (dropdownButton.ariaExpanded === "false") {
+ openDropdown();
+ } else {
+ closeDropdown();
+ }
+ }
+});
+
+firstDropdownItem.addEventListener("keydown", (event) => {
+ if (event.key === "Tab" && event.shiftKey) {
+ event.preventDefault();
+ closeDropdown();
+ }
+});
+
+lastDropdownItem.addEventListener("keydown", (event) => {
+ if (event.key === "Tab" && !event.shiftKey) {
+ event.preventDefault();
+ closeDropdown();
+ }
+});
+
+document.addEventListener("keydown", (event) => {
+ if (event.key === "Escape") closeDropdown();
+});
+
+window.addEventListener("click", (event) => {
+ if (!event.target.matches("#drop-button")) closeDropdown();
+});
diff --git a/styles/main.css b/styles/main.css
index 706691b..e055a53 100644
--- a/styles/main.css
+++ b/styles/main.css
@@ -123,40 +123,9 @@ time {
font-weight: 700;
}
-nav ul {
- display: flex;
- gap: 1rem;
- list-style: none;
- justify-content: center;
- margin: 1rem auto;
-}
-
-nav a {
- font-size: 1.4rem;
- border: 1px solid;
- border-radius: .15rem;
- padding: .15rem .3rem;
- color: var(--color-accent);
- text-decoration: none;
-}
-
-@media (max-width: 650px) {
- nav a {
- font-size: 1.1rem;
- }
-}
-
-@media (any-hover: hover) {
- nav a:hover {
- color: var(--color-bg);
- background-color: var(--color-accent);
- }
-}
-
-nav a:focus-visible {
- outline: none;
- color: var(--color-bg);
- background-color: var(--color-accent);
+button {
+ cursor: pointer;
+ background-color: var(--color-bg);
}
header img {
diff --git a/styles/nav.css b/styles/nav.css
new file mode 100644
index 0000000..5a416b7
--- /dev/null
+++ b/styles/nav.css
@@ -0,0 +1,73 @@
+nav {
+ display: flex;
+ gap: 1rem;
+ justify-content: center;
+ margin: 1rem auto;
+}
+
+nav a,
+nav button {
+ font-size: 1.4rem;
+ border: 1px solid;
+ border-radius: .15rem;
+ padding: .15rem .3rem;
+ color: var(--color-accent);
+ text-decoration: none;
+ line-height: 2rem;
+}
+
+@media (max-width: 650px) {
+ nav a {
+ font-size: 1.1rem;
+ }
+}
+
+@media (any-hover: hover) {
+ nav a:hover,
+ nav button:hover {
+ color: var(--color-bg);
+ background-color: var(--color-accent);
+ border-color: var(--color-accent);
+ }
+}
+
+nav a:focus-visible,
+nav button:focus-visible {
+ outline: none;
+ color: var(--color-bg);
+ background-color: var(--color-accent);
+ border-color: var(--color-accent);
+}
+
+#current-page {
+ border-right-width: .5rem;
+ border-left-width: .5rem;
+}
+
+nav ul {
+ list-style: none;
+ display: none;
+ position: absolute;
+ z-index: 1;
+ margin: 0 0 0 1rem;
+ min-width: 8rem;
+}
+
+#dropdown {
+ position: relative;
+ display: inline-block;
+ min-width: 3rem;
+}
+
+nav ul.show {
+ display: block;
+}
+
+nav ul li {
+ margin: .25rem;
+}
+
+nav ul a {
+ display: inline-block;
+ background-color: var(--color-bg);
+}