Z tego ćwiczenia w Codelabs dowiesz się, jak utworzyć w internecie elastyczny układ z bocznym paskiem nawigacji. Będziemy tworzyć komponent na bieżąco, zaczynając od HTML, potem CSS, a na końcu JavaScript.
Aby dowiedzieć się więcej o funkcjach platformy internetowej CSS, które zostały wybrane do tworzenia tego komponentu, przeczytaj wpis na blogu Tworzenie komponentu menu bocznego.
Konfiguracja
- Kliknij Remix to Edit (Zmiksuj do edycji), aby umożliwić edycję projektu.
- Otwórz pokój
app/index.html
.
HTML
Najpierw musisz poznać podstawy konfiguracji kodu HTML, aby mieć treści i pola, z którymi możesz pracować.
Wklej ten kod HTML do tagu <body>
.
<aside></aside>
<main></main>
Element <aside>
zawiera menu nawigacyjne jako dodatkowy element elementu <main>
, który zawiera główną zawartość strony.
Następnie uzupełnimy te elementy semantyczne pozostałą częścią strony.
Dodaj element nawigacji, kilka linków nawigacyjnych i link do zamknięcia w elemencie <aside>
.
<aside>
<nav>
<h4>My</h4>
<a href="#">Dashboard</a>
<a href="#">Profile</a>
<a href="#">Preferences</a>
<a href="#">Archive</a>
<h4>Settings</h4>
<a href="#">Accessibility</a>
<a href="#">Theme</a>
<a href="#">Admin</a>
</nav>
<a href="#"></a>
</aside>
Linki świetnie sprawdzają się w elementach <nav>
, a elementy <nav>
dobrze wyglądają w bocznych panelach <aside>
.
Mimo to mamy jeszcze kilka ulepszeń.
W głównym elemencie treści dodaj nagłówek i artykuł, które będą semantycznie przechowywać treść układu.
<main>
<header>
<a href="#sidenav-open" class="hamburger">
<svg viewBox="0 0 50 40">
<line x1="0" x2="100%" y1="10%" y2="10%" />
<line x1="0" x2="100%" y1="50%" y2="50%" />
<line x1="0" x2="100%" y1="90%" y2="90%" />
</svg>
</a>
<h1>Site Title</h1>
</header>
<article>
{put some placeholder content here}
</article>
</main>
W nagłówku znajduje się link do menu. Z boku znajduje się przycisk zamykania. Wkrótce będziemy wyświetlać i ukrywać elementy na podstawie rozmiaru widoku.
W elemencie <article>
wklejyliśmy zdanie zastępcze. Zastąp „” własnymi elementami lub wklej kod podany poniżej:
<h2>Totam Header</h2>
<p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Cum consectetur, necessitatibus velit officia ut impedit veritatis temporibus soluta? Totam odit cupiditate facilis nisi sunt hic necessitatibus voluptatem nihil doloribus! Enim.</p>
<p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Fugit rerum, amet odio explicabo voluptas eos cum libero, ex esse quasi optio incidunt soluta eligendi labore error corrupti! Dolore, cupiditate porro.</p>
<h3>Subhead Totam Odit</h3>
<p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Fugit rerum, amet odio explicabo voluptas eos cum libero, ex esse quasi optio incidunt soluta eligendi labore error corrupti! Dolore, cupiditate porro.</p>
<p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Fugit rerum, amet odio explicabo voluptas eos cum libero, ex esse quasi optio incidunt soluta eligendi labore error corrupti! Dolore, cupiditate porro.</p>
<h3>Subhead</h3>
<p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Fugit rerum, amet odio explicabo voluptas eos cum libero, ex esse quasi optio incidunt soluta eligendi labore error corrupti! Dolore, cupiditate porro.</p>
<p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Fugit rerum, amet odio explicabo voluptas eos cum libero, ex esse quasi optio incidunt soluta eligendi labore error corrupti! Dolore, cupiditate porro.</p>
Te treści i ich długość powodują, że strona jest przewijalna, gdy przekracza wysokość widocznego obszaru.
Do tej pory dodałeś/dodałaś element boczny z menu, linkami i opcją zamknięcia menu bocznego. Dodałaś(-eś) też nagłówek, sposób otwierania paska bocznego i artykuł do głównego elementu. Jest to już czyste, semantyczne i dosyć ponadczasowe, ale możemy je jeszcze bardziej uprościć i ulepszyć dla wszystkich. Link do otwierania w nowej karcie na pasku bocznym mógłby być lepiej oznaczony.
Dodaj atrybuty title
i aria-label
do elementu linku otwierającego w nagłówku:
<a href="#sidenav-open" class="hamburger">
<a href="#sidenav-open" title="Open Menu" aria-label="Open Menu" class="hamburger">
Ikona otwartego pliku SVG mogłaby być lepiej oznaczona. Dodaj do elementu SVG w elemencie otwierania linku te atrybuty:
<svg viewBox="0 0 50 40">
<svg viewBox="0 0 50 40" role="presentation" focusable="false" aria-label="trigram for heaven symbol">
Link do zamknięcia w menu bocznym mógłby być lepiej oznaczony.
Dodaj atrybuty title
i aria-label
do elementu link zamykającego na stronie sidenav:
<a href="#"></a>
<a href="#" title="Close Menu" aria-label="Close Menu"></a>
CSS
Czas na ułożenie elementów. Główna treść i menu boczne są bezpośrednimi elementami podrzędnymi tagu <body>
, więc warto zacząć od nich.
Dodaj ten kod CSS do elementu css/sidenav.css
, aby element <body>
rozmieścił elementy podrzędne.
body {
display: grid;
grid: [stack] 1fr / min-content [stack] 1fr;
@media (max-width: 540px) {
& > :matches(aside, main) {
grid-area: stack;
}
}
}
Ten układ mówi zasadniczo: „Utwórz wiersz o nazwie stack
z wszystkimi elementami oraz 2 kolumny w tym wierszu, z których druga ma też nazwę stack
”. Rozmiar pierwszej kolumny powinien być dostosowany do minimalnych potrzeb dotyczących treści, a druga kolumna może zajmować pozostałą część.
Następnie, jeśli widoczny obszar ma wymiary 540px
lub mniejsze, umieść elementy menu bocznego i główne treści w tym samym wierszu i kolumnie, dzięki czemu będą one nakładać się na siebie w siatce 1 x 1.
Dzięki tej funkcji elastycznego łączenia warstwowego możemy teraz korzystać ze stanu paska adresu URL, aby zmieniać widoczność i styl przejścia w bocznym panelu nawigacji.
Zaktualizuj element <aside>
w komponencie app/index.html
:
<aside>
<aside id="sidenav-open">
Umożliwia to CSS dopasowanie elementu i hasza adresu URL. Jest to ważne w przypadku korzystania z :target
.
Teraz identyfikator elementu może odpowiadać haszowi adresu URL, który ustawimy w tagach <a>
.
Aby ułatwić kierowanie kodu JavaScript, dodaj identyfikatory kluczowych elementów, które kontrolują pasek boczny. Najpierw dodaj identyfikator do linku otwierania menu bocznego:
<a href="#sidenav-open" class="hamburger" title="Open Menu" aria-label="Open Menu">
<a href="#sidenav-open" id="sidenav-button" class="hamburger" title="Open Menu" aria-label="Open Menu">
Następnie dodaj identyfikator do linku zamykania paska bocznego:
<a href="#" title="Close Menu" aria-label="Close Menu"></a>
<a href="#" id="sidenav-close" title="Close Menu" aria-label="Close Menu"></a>
W ten sposób makro <body>
elastycznie układa się na stosie i łączy je z paskiem adresu URL.
Kontynuujmy.
<aside>
ma też przejrzysty układ. Zawiera 2 elementy podrzędne: <nav>
, który jest elementem podobnym do papieru, który wysuwa się, oraz zamykający element linku <a>
, który ustawia adres URL na #
.
Link jest niewidoczny po prawej stronie paska nawigacyjnego w trybie rozkładania. Dzięki temu użytkownicy mogą „kliknąć poza” wizualny element, aby go zamknąć.
Dodaj ten kod CSS do pliku css/sidenav.css
:
#sidenav-open {
display: grid;
grid-template-columns: [nav] 2fr [escape] 1fr;
}
Pomyślałem, że proporcje i nazwy były bardzo miłe dla oka, gdzie siatka mogłaby się uwydatnić i dać projektantowi dużą kontrolę.
Następnie muszę warunkowo nałożyć główną zawartość i zatrzymać pozycję podczas przewijania dokumentu. To świetna praca dla position: sticky
i overscroll-behavior
.
Dodaj te style na potrzeby nawigacji bocznej:
#sidenav-open {
display: grid;
grid-template-columns: [nav] 2fr [escape] 1fr;
@media (max-width: 540px) {
position: sticky;
top: 0;
max-height: 100vh;
overflow: hidden auto;
overscroll-behavior: contain;
visibility: hidden; /* not keyboard accessible when closed */
}
}
Te style sprawiają, że pasek boczny ma wysokość widocznego obszaru, przewija się w pionie i zawiera pasek przewijania. Co ważne, ukrywa element. Domyślnie, gdy widoczny obszar ma rozmiar 540px
lub mniejszy, ukryj boczny panel nawigacyjny. Chyba że!
Dodaj do elementu #sidenav-open
pseudoselektor :target
:
#sidenav-open {
@media (max-width: 540px) {
&:target {
visibility: visible;
}
}
}
Jeśli identyfikator tego elementu i paska adresu URL są takie same, ustaw visibility
na visible
. Otwórz menu boczne po przewinięciu strony lub spróbuj przewijać stronę, gdy menu boczne jest otwarte. Co myślisz?
Dodaj ten kod CSS na końcu app/sidenav.css
:
#sidenav-button,
#sidenav-close {
-webkit-tap-highlight-color: transparent;
-webkit-touch-callout: none;
user-select: none;
touch-action: manipulation;
@media (min-width: 540px) {
display: none;
}
}
Te style dotyczą przycisków otwierania i zamykania, określają ich styl dotykania i dotykowe, a także ukrywają je, gdy widok jest 540px
lub większy.
Dodajmy przekształcenia CSS z szacunkową dostępnością.
Dodaj do pliku css/sidenav.css
ten kod CSS:
#sidenav-open {
--easeOutExpo: cubic-bezier(0.16, 1, 0.3, 1);
--duration: .6s;
...
@media (max-width: 540px) {
...
transform: translateX(-110vw);
will-change: transform;
transition:
transform var(--duration) var(--easeOutExpo),
visibility 0s linear var(--duration);
&:target {
visibility: visible;
transform: translateX(0);
transition: transform var(--duration) var(--easeOutExpo);
}
}
@media (prefers-reduced-motion: reduce) {
--duration: 1ms;
}
}
Dodawanie kodu JavaScript
Przycisk Escape
powinien zamknąć menu. Dodaj ten kod JS do pliku js/index.js
:
const sidenav = document.querySelector('#sidenav-open');
sidenav.addEventListener('keyup', e => {
if (e.code === 'Escape') {
document.location.hash = '';
}
});
Nasłuchuje on kluczowego zdarzenia w elemencie menu bocznego.
Jeśli jest Escape
, hasz adresu URL jest pusty, co powoduje przejście z menu bocznego.
Kolejnym elementem UX JS jest zarządzanie obszarem fokusu. Chcę, aby otwieranie i zamykanie było łatwe, więc czekam, aż pasek boczny zakończy przełączanie, a potem sprawdzam to za pomocą hasha adresu URL, aby określić, czy pasek jest otwarty czy zamknięty. Następnie za pomocą JavaScriptu ustawiam fokus na przycisku, który jest uzupełnieniem tego, który został właśnie naciśnięty.
Dodaj do js/index.js
ten kod JavaScript:
const closenav = document.querySelector('#sidenav-close');
const opennav = document.querySelector('#sidenav-button');
sidenav.addEventListener('transitionend', e => {
if (e.propertyName !== 'transform') {
return;
}
const isOpen = document.location.hash === '#sidenav-open';
isOpen
? closenav.focus()
: opennav.focus();
});
Wypróbuj
- Aby wyświetlić podgląd strony, kliknij Wyświetl aplikację. Następnie kliknij Pełny ekran.
Podsumowanie
To wszystko, co chciałam powiedzieć na temat tego komponentu. Możesz go dowolnie modyfikować, sterować nim za pomocą stanu JavaScript zamiast adresu URL i ogółem uczynić go swoim. Zawsze można dodać więcej treści lub omówić więcej przypadków użycia.
Otwórz css/brandnav.css
, aby sprawdzić style niezwiązane z układem, które zastosowałem do tego komponentu. Nie uważam, aby było to ważne w przypadku zestawu funkcji, na którym się skupiałem, i miałem nadzieję, że oddzielenie stylów od układu zachęci do kopiowania i wklejania. Możesz się tam dowiedzieć więcej.
Jak utworzyć wysuwane elastyczne komponenty sidenav? Czy zdarza się, że jest ich więcej niż 1, np. po obu stronach? Chętnie przedstawię Twoje rozwiązanie w filmie w YouTube. Pamiętaj, aby wysłać do mnie tweeta lub dodać komentarz w YouTube z kodem. Pomoże to wszystkim.