Responsiv, ren CSS-fri hamburgermeny utanför canvas

, Author

Senaste uppdateringen gjordes den 21 januari 2019.

Rena CSS-fria hamburgermenyer utanför canvas är inte en ny upptäckt. Chris Coyier skrev trots allt om den här tekniken redan i november 2012.

  • Om det här är ett gammalt trick för dig, så häng med mig en stund. Jag har förbättrat Chris exempel och vill gärna ha din feedback.
  • Om detta är nytt för dig, oroa dig inte. Du har gott om sällskap, eftersom det verkar som om en stor del av webben inte riktigt har fattat det än.

Med detta kommer vi att bygga en enkel, responsiv hamburgermeny utanför canvas med hjälp av endast CSS som kommer att vara lätt att införliva i ditt eget projekt. Men först…

Vad är det för fel på JavaScript?

Inget.

Aaron Gustafson förklarar vikten av Progressive Enhancements och JavaScript:s roll i webbutveckling bättre än vad jag någonsin skulle kunna göra. Du borde läsa hans inlägg. Men för korthetens skull ska jag försöka sammanfatta det:

  • ”Kärnaktiviteter kan alltid utföras utan JavaScript.”
  • Kärnaktiviteter bör utföras på det mest stabila lagret (dvs. inte JavaScript).
  • Progressive Enhancements är inte anti-JavaScript. Det handlar bara om att anamma rätt teknik på rätt lager.
  • ”Eftersom det finns en viss chans att JavaScript inte kommer att fungera måste vi alltid ta hänsyn till den chansen.”
  • Det är aldrig en bra idé att ignorera potentiella användare.
  • Progressive Enhancements är bara bra teknik.

Så, vi kommer att göra så mycket som möjligt med HTML och CSS. Sedan får JavaScript göra sin magi på ett mer lämpligt lager – förbättra det redan befintliga användargränssnittet.

Steg 1: HTML

Som du kanske vet är det första steget alltid att skriva ett gediget, väl genomtänkt grundlager av HTML.

Notera: Jag använder Font Awesome för ikonerna i mitt exempel.

Steg 1: Initial HTML för en ren CSS-responsiv hamburgermeny

Det ser ganska standard ut, eller hur? Vi har:

  • Vårt överordnade <header> element
  • Ikonen för hamburgare (”fa-bars”)
  • En huvudrubrik (eller eventuellt en logotyp)
  • Navigationen i ett <nav> element
  • En ikon för stängning (”fa-close”) i navigationen (mer om detta senare)
  • En ”backdrop” efter navigationen. Varför är det en ankartagg? Det ska jag förklara senare.

Steg 2: Låt oss göra det mer tillgängligt

Tillgänglighet bör aldrig vara en eftertanke – som efter att du har skrivit din applikation. Den bör planeras från början. Att lägga till några grundläggande överväganden nu kommer inte bara att förbättra den övergripande tillgängligheten på din webbplats, utan det kommer också att ge dig (utvecklaren) bättre markeringar att använda i din JavaScript!

Därmed ska vi lägga till ytterligare några attribut och lite text för skärmläsare:

Steg 2: Förbättra HTML för att göra den mer tillgänglig.

Här är en snabb uppdelning av alla dessa attribut och hur de fungerar:

  • Vi har lagt till unika ID:n för att kunna rikta in våra HREF:er (mer om hur detta fungerar senare).
  • Vi har tillhandahållit en informativ etikett för knapparna för skärmläsare med hjälp av .
  • Vi har dolt ikonerna för skärmläsare med , eftersom de är visuella representationer, och lagt till text som endast är avsedd för skärmläsare med <span class=”sr-only”>-elementen.
  • Vi har tagit bort ”bakgrunden” från tabbningsindexet med en . Den är rent visuell till sin natur och vi vill inte förvirra våra synskadade och tangentbordsanvändare.
  • Vi har lagt till attributet amazing för att ställa in det initiala (och semantiska) tillståndet för ”bakgrunden”. Inget mer skräp – så spännande!

Här är resultatet hittills:

Figur 1: Resulterande visning av HTML efter steg 1 och 2.

Steg 3: Låt oss styla det!

Vi kommer att närma oss det här mobilt, så vi tar fram den mobila, ”hamburgerliknande” vyn (den intressanta delen).

Först ska vi bara få ordning på rubrikens layout (utan interaktivitet):

Steg 3: Lägg till lite CSS för att styla rubriken (utan interaktivitet, för tillfället).

Resultatet:

Figur 2: Resultat av visning av HTML & CSS efter steg 3.

Steg 4: Interaktivitet med ren CSS

När du gör widgetar interaktiva med CSS har du ett par alternativ:

  1. Använd radioradioer eller kryssrutor
  2. Använd pseudoklassen :target.

Radioradioer och kryssrutor fungerar otroligt bra för de flesta widgetar, som flikar, modaler, dropdowns och dragspel. Chris Coyier har döpt den här tekniken till ”the checkbox hack”. Flera utvecklare har använt detta ”hack” för sina menyer utanför canvas, som i Paul Lewis handledning för Chrome Dev Summit eller Luis Manuels morphing hamburgermeny.

Pseudoklassen :target är dock mer semantisk i det här användningsfallet, eftersom vi har direkt att göra med navigering. Du kanske inte håller med, och det är helt okej! Det skulle vara otroligt enkelt och helt acceptabelt att byta ut pseudoklassen :target mot en kryssruta.

Båda teknikerna har dock sina begränsningar.

Användning av en kryssruta:

  • Kräver att JavaScript stänger menyn utanför canvas om en av länkarna i menyn var en ankarlänk till ett specifikt avsnitt på samma sida.
  • Kräver att fältet <input> är ett syskon till menyn eller åtminstone ett syskon till menyns föregångare. CSS är med andra ord lite knepigare. Du kan dock ha <label> (även flera etiketter) någon annanstans.
  • <label>-elementet kommer inte att vara direkt fokuserbart eller tabbar, vilket kräver lite knepigare CSS för att hantera fokus på kryssrutan samtidigt som man ändrar det synliga utseendet på <label>.
  • Tangentbordsnavigationen vid öppning/stängning av menyn kommer att vara snurrig. Att påverka en tillståndsändring på en kryssruta sker genom den och inte genom tangenten. Medan blinda användare kanske förstår att widgeten styrs av en kryssruta, kommer synskadade tangentbordsanvändare att bli förvirrade eftersom kryssrutan inte är synlig – något som jag kände var ett problem i det här användningsfallet.

Användning av pseudoklassen :target:

  • Lägger till öppnandet/stängningen av menyn utanför canvas till webbläsarens historik (skjuter in hashen i adressfältet). Det krävs att JavaScript kör Event.preventDefault() för att undvika detta (och det potentiellt irriterande hoppet till toppen av sidan).

Och det kan finnas andra förbehåll som jag missat. Hur som helst är valet av teknik både en fråga om preferenser och beroende på projektets krav. Hur som helst, jag har avvikit…

Här kommer den interaktiva delen av CSS:

Steg 4: Lägg till lite CSS för interaktiviteten.

Resultatet när man klickar:

Figur 3: Resultatet av visningen av hamburgermenyn när den öppnas.

Hur allt detta fungerar

Pseudoklassen :target ger oss i princip ett nytt ”tillstånd” för att styla den målinriktade navigeringen. När main-menu har blivit target (med dess hash som lagts till i URL:en) kan vi nu dra ut menyn. Det är lite som en :focus-pseudoklass för det målinriktade elementet (inte själva länken).

Vi har också tillåtit ”backdrop” att visas när navigeringen är målinriktad.

Du märker att ikonen för huvud-hamburgaren är kopplad till navigeringens ID, medan både stängnings-ikonen och backdrop-knapparna är kopplade till ikonen för huvud-hamburgaren. Detta gör att vi kan klicka på stängningsikonen eller bakgrundsknappen för att ta bort ”fokus” – eller egentligen :target – från navigeringen. Om bakgrunden inte var en länk skulle den inte vara klickbar utan JavaScript.

Jag har också kedjat :target-selektorerna tillsammans med attributet i CSS. Här kommer vi så småningom att successivt förbättra hamburgermenyn med JavaScript så att den inte hoppar till rubriken när man klickar på den – och på så sätt undviker vi den invändning som jag nämnde tidigare. Att JavaScript kapar webbläsarens hashbeteende innebär att pseudoklassen :target inte längre kommer att fungera. När detta händer kommer vi att dra nytta av attributet för att styla växlingen med sant/felaktigt-värden på samma sätt som vi tidigare kunde ha gjort med klasser.

Under tiden fungerar detta dock utmärkt utan JavaScript.

Jag har lagt till @supports media query för att ge den föredragna CSS:en position:fixed till webbläsare (både mobila och stationära) som har stöd för det. I annat fall får lama webbläsare och enheter – jag tittar på dig iOS – position:absolute.

Steg 5: Stilar för större skärmar

Då vi inte vill att hamburgermenyn ska visas för enheter som inte är mobila (eller större skärmar i allmänhet), lägger vi till den nödvändiga mediaquery:n för detta. Sedan stylar vi den så att den ser ut som en horisontell navigation:

Steg 5: CSS för att styla navigationen på större skärmar.

Resultatet:

Figur 4: Resterande visning av navigeringen stylad för större skärmar.

Voila! Vi är klara!

Sätt ihop det hela

Här är den slutliga HTML:

Den slutliga HTML:

Den slutliga HTML:

för den responsiva hamburgermenyn som endast använder CSS.

Här är den slutgiltiga CSS:

Den slutgiltiga CSS:

Den slutgiltiga CSS:

Demo

Att prova min CodePen själv:
→ Ren CSS Hamburger Menu utan JavaScript.

Notera: du kan också demonstrera kryssrutans version av menyn.

Vill du lägga till JavaScript för att göra det smidigare?

Vidare kan vi få off-canvas-menyn att fungera helt och hållet med CSS – vilket förbättrar dess prestanda och tillförlitlighet – men vi kommer fortfarande att behöva JavaScript för att hjälpa till på något sätt för att förbättra interaktiviteten kring båda teknikernas nackdelar. Du kan också använda JavaScript för att förhindra rullning på sidan medan menyn är öppen.

Det är också värt att notera att en hyfsad nivå (och förmodligen den viktigaste nivån) av tillgänglighet kan uppnås utan JavaScript. Det är dock svårt att tillhandahålla en robust nivå av tillgänglighet utan JavaScript:s förmåga att manipulera DOM (t.ex. fokushantering, uppdatering av ARIA-attribut etc.).

För mer information om hur du förbättrar tillgängligheten på din webbplats med hjälp av JavaScript kan du läsa följande artiklar:

  • Användning av ARIA-attribut för JavaScript-tillståndsinställning &styling
  • Skrivning av JavaScript med tillgängligheten i åtanke

Har du andra tankar eller förslag?

Jag skulle gärna vilja höra dina kommentarer till mitt tillvägagångssätt för en ren CSS-hamburgermeny.

Redigeringar och senare funderingar

21 januari 2019: Redigerade artikeln och uppdaterade kodexempel för att ta bort onödiga ARIA-attribut och förbättra tillgängligheten.

När jag har lärt mig mer om att använda ARIA och att utveckla & testning för tillgänglighet i allmänhet har jag insett några saker:

  1. JavaScript har definitivt sin plats och bör vara en del av alla robusta UI-mönster för tillgänglighet.
  2. Med undantag för ARIA-landmärken krävs JavaScript för att använda ARIA på rätt sätt. Och många av de attribut som jag har använt är bättre för JavaScript att lägga till när de har laddats i stället för att lägga till dem direkt i markeringen. Det här konceptet följer god praxis för progressiv förbättring – ARIA-tillstånd och -egenskaper tillsammans med JavaScript är en uppgradering och bör hanteras på ett separat lager.
  3. Förut hanterade jag inte fokus på rätt sätt eftersom fokus försvann när det gick genom de visuellt dolda länkarna (när de var hopfällda). Jag lade till en display: none; till menyns CSS för att åtgärda detta.

Så, om du har implementerat en tidigare version av min Pure CSS Off-Canvas Hamburger Menu, var snäll och överväga att uppdatera den till denna enklare och mer tillgängliga version!

Lämna ett svar

Din e-postadress kommer inte publiceras.