dropdown take one needs review
This commit is contained in:
@ -15,18 +15,18 @@
|
|||||||
<meta property="og:description" content="card one's travels | siblinghood of the traveling greeting card" />
|
<meta property="og:description" content="card one's travels | siblinghood of the traveling greeting card" />
|
||||||
<meta property="og:image" content="/img/logo-light.png" />
|
<meta property="og:image" content="/img/logo-light.png" />
|
||||||
<meta property="og:image:alt" content="blue and gold icon showing a greeting card with wings" />
|
<meta property="og:image:alt" content="blue and gold icon showing a greeting card with wings" />
|
||||||
|
|
||||||
<!-- CSS -->
|
<!-- CSS -->
|
||||||
<link rel="stylesheet" href="/styles/main.css">
|
<link rel="stylesheet" href="/styles/main.css">
|
||||||
<link rel="stylesheet" href="/styles/cards.css">
|
<link rel="stylesheet" href="/styles/cards.css">
|
||||||
|
<link rel="stylesheet" href="/styles/nav.css">
|
||||||
|
|
||||||
|
<!-- JS -->
|
||||||
|
<script src="/scripts/nav.js" defer></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<header>
|
<header>
|
||||||
<nav>
|
<nav id="top-nav"><!-- auto populated by nav.js --></nav>
|
||||||
<ul>
|
|
||||||
<li><a href="/">home</a></li>
|
|
||||||
<li><a href="/card-two">card two</a></li>
|
|
||||||
</ul>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<img id="logo-light" src="/img/logo-light.png" alt="blue and gold icon showing a greeting card with wings" />
|
<img id="logo-light" src="/img/logo-light.png" alt="blue and gold icon showing a greeting card with wings" />
|
||||||
<img id="logo-dark" src="/img/logo-dark.png" alt="blue and gold icon showing a greeting card with wings" />
|
<img id="logo-dark" src="/img/logo-dark.png" alt="blue and gold icon showing a greeting card with wings" />
|
||||||
|
|||||||
@ -15,18 +15,18 @@
|
|||||||
<meta property="og:description" content="card two's travels | siblinghood of the traveling greeting card" />
|
<meta property="og:description" content="card two's travels | siblinghood of the traveling greeting card" />
|
||||||
<meta property="og:image" content="/img/logo-light.png" />
|
<meta property="og:image" content="/img/logo-light.png" />
|
||||||
<meta property="og:image:alt" content="blue and gold icon showing a greeting card with wings" />
|
<meta property="og:image:alt" content="blue and gold icon showing a greeting card with wings" />
|
||||||
|
|
||||||
<!-- CSS -->
|
<!-- CSS -->
|
||||||
<link rel="stylesheet" href="/styles/main.css">
|
<link rel="stylesheet" href="/styles/main.css">
|
||||||
<link rel="stylesheet" href="/styles/cards.css">
|
<link rel="stylesheet" href="/styles/cards.css">
|
||||||
|
<link rel="stylesheet" href="/styles/nav.css">
|
||||||
|
|
||||||
|
<!-- JS -->
|
||||||
|
<script src="/scripts/nav.js" defer></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<header>
|
<header>
|
||||||
<nav>
|
<nav id="top-nav"><!-- auto populated by nav.js --></nav>
|
||||||
<ul>
|
|
||||||
<li><a href="/">home</a></li>
|
|
||||||
<li><a href="/card-one">card one</a></li>
|
|
||||||
</ul>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<img id="logo-light" src="/img/logo-light.png" alt="blue and gold icon showing a greeting card with wings" />
|
<img id="logo-light" src="/img/logo-light.png" alt="blue and gold icon showing a greeting card with wings" />
|
||||||
<img id="logo-dark" src="/img/logo-dark.png" alt="blue and gold icon showing a greeting card with wings" />
|
<img id="logo-dark" src="/img/logo-dark.png" alt="blue and gold icon showing a greeting card with wings" />
|
||||||
|
|||||||
12
index.html
12
index.html
@ -15,17 +15,17 @@
|
|||||||
<meta property="og:description" content="Siblinghood of the Traveling Greeting Card" />
|
<meta property="og:description" content="Siblinghood of the Traveling Greeting Card" />
|
||||||
<meta property="og:image" content="/img/logo-light.png" />
|
<meta property="og:image" content="/img/logo-light.png" />
|
||||||
<meta property="og:image:alt" content="blue and gold icon showing a greeting card with wings" />
|
<meta property="og:image:alt" content="blue and gold icon showing a greeting card with wings" />
|
||||||
|
|
||||||
<!-- CSS -->
|
<!-- CSS -->
|
||||||
<link rel="stylesheet" href="/styles/main.css">
|
<link rel="stylesheet" href="/styles/main.css">
|
||||||
|
<link rel="stylesheet" href="/styles/nav.css">
|
||||||
|
|
||||||
|
<!-- JS -->
|
||||||
|
<script src="/scripts/nav.js" defer></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<header>
|
<header>
|
||||||
<nav>
|
<nav id="top-nav"><!-- auto populated by nav.js --></nav>
|
||||||
<ul>
|
|
||||||
<li><a href="/card-one">card one</a></li>
|
|
||||||
<li><a href="/card-two">card two</a></li>
|
|
||||||
</ul>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<img id="logo-light" src="/img/logo-light.png" alt="blue and gold icon showing a greeting card with wings" />
|
<img id="logo-light" src="/img/logo-light.png" alt="blue and gold icon showing a greeting card with wings" />
|
||||||
<img id="logo-dark" src="/img/logo-dark.png" alt="blue and gold icon showing a greeting card with wings" />
|
<img id="logo-dark" src="/img/logo-dark.png" alt="blue and gold icon showing a greeting card with wings" />
|
||||||
|
|||||||
122
scripts/nav.js
Normal file
122
scripts/nav.js
Normal file
@ -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();
|
||||||
|
});
|
||||||
@ -123,40 +123,9 @@ time {
|
|||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
}
|
}
|
||||||
|
|
||||||
nav ul {
|
button {
|
||||||
display: flex;
|
cursor: pointer;
|
||||||
gap: 1rem;
|
background-color: var(--color-bg);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
header img {
|
header img {
|
||||||
|
|||||||
73
styles/nav.css
Normal file
73
styles/nav.css
Normal file
@ -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);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user