Tailwind CSS Academy · Lektion

Sammenklappelig mobil-sidebar

Implementér en sidebar som en indskydelig drawer til mobil med en JavaScript-toggle, overlay-baggrund og glidende translate-transition.

Lektion 4 af 413 trin

Sammenklappelig mobil-sidebar er en gratis Tailwind CSS Academy-lektion på CoddyKit. Dette er lektion 4 af 4. Du kan læse hele lektionen gratis nedenfor — og derefter øve dig praktisk i browseren med en indbygget kodeeditor og en AI-vejleder, der er tilgængelig døgnet rundt. Den er en del af læringsforløbet i Tailwind CSS Academy, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. Tailwind CSS Academy-kurset indeholder 4 lektioner i alt.

Hvad er et mobilt sidepanel som udtrækspanel

Et mobilt sidepanel som udtrækspanel glider ind fra skærmens venstre kant, når der trykkes på en hamburgermenu-knap, og glider ud igen, når det lukkes. I modsætning til et desktop-sidepanel, der altid er synligt, er det mobile udtrækspanel som standard skjult uden for skærmen ved hjælp af en CSS-transformering.

Tre elementer arbejder sammen: baggrundslaget, der gør resten af siden mørkere, sidepanelområdet, der glider ind, og skifteknappen i den øverste linje, som åbner og lukker udtrækspanelet.

<!-- Closed state: sidebar off-screen left -->
<aside id="drawer" class="fixed inset-y-0 left-0 w-72 bg-white z-50
                          -translate-x-full transition-transform duration-300">
  <!-- sidebar content -->
</aside>

<!-- Backdrop: hidden until drawer opens -->
<div id="backdrop" class="fixed inset-0 bg-black/50 z-40 hidden"></div>

JavaScript-skiftet til åbning og lukning

Skiftet fungerer ved at fjerne -translate-x-full-klassen fra udtrækspanelet og fjerne hidden-klassen fra baggrundslaget. Lukning udfører de modsatte handlinger.

En enkel hjælpefunktion openDrawer() og closeDrawer() holder logikken overskuelig. Tilføj overflow-hidden til body, når udtrækspanelet er åbent, for at forhindre rulning i sidens indhold bag baggrundslaget.

<script>
  const drawer = document.getElementById('drawer');
  const backdrop = document.getElementById('backdrop');

  function openDrawer() {
    drawer.classList.remove('-translate-x-full');
    backdrop.classList.remove('hidden');
    document.body.classList.add('overflow-hidden');
  }

  function closeDrawer() {
    drawer.classList.add('-translate-x-full');
    backdrop.classList.add('hidden');
    document.body.classList.remove('overflow-hidden');
  }

  // Clicking backdrop closes the drawer
  backdrop.addEventListener('click', closeDrawer);
</script>

Indglidningsovergang med Tailwind

Tailwinds transition-transform duration-300 på udtrækspanelområdet skaber en jævn glideanimation, når -translate-x-full skiftes. duration-300 indstiller en ease-overgang på 300 ms, som føles hurtig uden at virke brat.

Du kan tilpasse easing med ease-in-out og ændre varigheden til duration-200 for en hurtigere oplevelse i enklere brugerflader. Det vigtigste er, at der ikke kræves egne CSS-keyframes — Tailwinds overgangsværktøjer håndterer det hele.

<!-- Drawer with slide transition -->
<aside
  id="drawer"
  class="fixed inset-y-0 left-0 w-72 bg-gray-900 text-white z-50
         -translate-x-full transition-transform duration-300 ease-in-out
         flex flex-col">
  <!-- Header -->
  <div class="flex items-center justify-between px-5 py-4 border-b border-gray-800">
    <span class="font-bold text-white">Menu</span>
    <button onclick="closeDrawer()" class="text-gray-400 hover:text-white">
      <svg class="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>
      </svg>
    </button>
  </div>
</aside>

Styling af baggrundslag

Baggrundslaget dæmper indholdet bag det åbne udtrækspanel og viser visuelt, at udtrækspanelet er et fokuseret område, der kræver opmærksomhed. Brug fixed inset-0 bg-black/50 z-40, så det dækker hele visningsområdet med sort ved 50 % gennemsigtighed.

Baggrundslaget ligger på z-40 (under udtrækspanelets z-50), så udtrækspanelet vises ovenpå. En indtoning med transition-opacity duration-300 får laget til at fremstå mere naturligt.

<div
  id="backdrop"
  class="fixed inset-0 bg-black/50 z-40 hidden
         transition-opacity duration-300">
</div>

Navigationslinks i udtrækspanelet

I udtrækspanelet bruger navigationslinks samme mønster som desktop-sidepanelet, men teksten kan være lidt større, fordi dette er en berøringsbaseret brugerflade: text-base i stedet for text-sm giver bedre læsbarhed på mobilskærme.

Tilføj adfærd svarende til tap-highlight-color: transparent ved at bruge active:bg-gray-800, så brugeren får øjeblikkelig visuel feedback, når der trykkes på et link. Listen kan rulle med flex-1 overflow-y-auto.

<nav class="flex-1 overflow-y-auto px-4 py-6 space-y-1">
  <a href="/" onclick="closeDrawer()"
     class="flex items-center gap-3 px-3 py-3 rounded-lg text-base font-medium
            bg-gray-800 text-white">
    Home
  </a>
  <a href="/features" onclick="closeDrawer()"
     class="flex items-center gap-3 px-3 py-3 rounded-lg text-base font-medium
            text-gray-300 hover:bg-gray-800 hover:text-white
            active:bg-gray-800 transition-colors">
    Features
  </a>
  <a href="/pricing" onclick="closeDrawer()"
     class="flex items-center gap-3 px-3 py-3 rounded-lg text-base font-medium
            text-gray-300 hover:bg-gray-800 hover:text-white
            active:bg-gray-800 transition-colors">
    Pricing
  </a>
</nav>

Hamburgerknap i den øverste linje

På mobilen findes hamburgerknappen i den øverste bjælke, som erstatter sidepanelet. Brug lg:hidden på denne øverste bjælke, så den kun vises på små skærme, hvor sidepanelet er skjult.

Giv knappen et behageligt trykområde på mindst 44×44px ved at bruge p-2 sammen med et ikon på 24px (w-6 h-6), hvilket tilsammen giver de 44px, som anbefales i Apples HIG og Googles Material Design-retningslinjer.

<header class="lg:hidden flex items-center justify-between px-4 py-3 bg-white border-b border-gray-200">
  <span class="font-bold text-gray-900">AppDash</span>
  <button
    onclick="openDrawer()"
    aria-label="Open navigation"
    class="p-2 text-gray-600 hover:bg-gray-100 active:bg-gray-200 rounded-lg">
    <svg class="w-6 h-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
      <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"/>
    </svg>
  </button>
</header>

Lukning med Escape-tasten

Tilgængelighed kræver, at overlejringselementer som skuffe-menuer kan lukkes med Escape-tasten. Tilføj en keydown-lytter til dokumentet, som kontrollerer event.key === 'Escape' og kalder closeDrawer().

Dette er et WCAG 2.1-krav for alle modale flader. Uden understøttelse af Escape bliver brugere, der kun anvender tastaturet, fanget i skuffe-menuen.

<script>
  document.addEventListener('keydown', (event) => {
    if (event.key === 'Escape') {
      closeDrawer();
    }
  });
</script>

Skuffevariant i højre side

Nogle brugergrænseflader bruger en skuffe i højre side til filtre, indstillingspaneler eller detaljevisninger i stedet for navigation. Erstat left-0 med right-0, og ændr den lukkede transformering fra -translate-x-full til translate-x-full, så panelet glider ind fra højre kant.

Det er den samme teknik, som bruges til sidepaneler med indkøbskurve, notifikationspaneler og detaljepaneler i enkeltsidesapplikationer.

<!-- Right drawer -->
<aside
  id="right-drawer"
  class="fixed inset-y-0 right-0 w-80 bg-white shadow-xl z-50
         translate-x-full transition-transform duration-300 ease-in-out
         flex flex-col">
  <div class="flex items-center justify-between px-5 py-4 border-b border-gray-100">
    <h2 class="text-lg font-semibold text-gray-900">Filter Options</h2>
    <button onclick="closeRightDrawer()" class="p-1 text-gray-400 hover:text-gray-600 rounded">
      <svg class="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>
      </svg>
    </button>
  </div>
  <div class="flex-1 overflow-y-auto p-5">
    <!-- Filter controls go here -->
  </div>
</aside>

Typografi til hjælp med lukning ved strygning

På enheder med berøringsskærm forventer brugere ofte at kunne stryge skuffe-menuen lukket. Selvom egentlig registrering af strygning kræver JavaScript (Touch Events API), kan du give et visuelt hint ved at tilføje et trækgreb øverst i skuffe-menuen — en kort vandret bjælke, der signalerer, at den kan stryges.

Typografér det som et lille afrundet rektangel: mx-auto mt-2 w-10 h-1 rounded-full bg-gray-300. Det er en almindelig brugeroplevelseskonvention fra indbyggede mobilapps, som er tilpasset til internettet.

<aside class="fixed inset-y-0 left-0 w-72 bg-gray-900 z-50 flex flex-col -translate-x-full transition-transform duration-300">
  <!-- Drag handle -->
  <div class="flex justify-center pt-3">
    <div class="w-10 h-1 rounded-full bg-gray-600"></div>
  </div>
  <!-- Header -->
  <div class="flex items-center justify-between px-5 py-4 mt-1 border-b border-gray-800">
    <span class="font-bold text-white">Menu</span>
    <button onclick="closeDrawer()" class="text-gray-400 hover:text-white">
      &times;
    </button>
  </div>
</aside>

Fokusfælde for tilgængelighed

Når skuffe-menuen er åben, bør tastaturfokus være fanget inde i den. Det forhindrer Tab-navigation i at nå indhold, der er skjult bag overlejringen, hvilket kan forvirre brugere af skærmlæsere.

Selvom implementering af en fuld fokusfælde kræver JavaScript (cirkulation gennem fokuserbare elementer med Tab og Skift+Tab), skal du altid sikre, at lukkeknappen er det første fokuserbare element i skuffe-menuen og modtager autofocus eller får fokus programmatisk, når skuffe-menuen åbnes.

<script>
  function openDrawer() {
    const drawer = document.getElementById('drawer');
    const backdrop = document.getElementById('backdrop');
    drawer.classList.remove('-translate-x-full');
    backdrop.classList.remove('hidden');
    document.body.classList.add('overflow-hidden');

    // Move focus into drawer for accessibility
    const closeBtn = drawer.querySelector('button[data-close]');
    if (closeBtn) closeBtn.focus();
  }
</script>

<!-- Close button receives focus first -->
<button
  data-close
  onclick="closeDrawer()"
  class="text-gray-400 hover:text-white focus:outline-none focus-visible:ring-2 focus-visible:ring-white rounded"
  aria-label="Close menu">
  <svg class="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>
  </svg>
</button>

Samlet opbygning af skuffe-layoutet

En komplet mobil skuffe-menu integrerer alle delene: en øverste bjælke med hamburgerknappen, skuffe-panelet uden for skærmen med en lukkeknap og navigationslinks samt en baggrundsoverlejring. De tre dele er uafhængige HTML-elementer, som JavaScript forbinder.

På desktop (lg:-breakpointet) skjuler du den øverste bjælke med lg:hidden og viser i stedet det permanente sidepanel. Denne ene opdeling mellem mobil og desktop er grundlaget for alle moderne dashboard-layouts.

<!-- Top bar (mobile only) -->
<header class="lg:hidden sticky top-0 bg-white border-b border-gray-200 z-30 flex items-center justify-between px-4 py-3">
  <span class="font-bold">AppDash</span>
  <button onclick="openDrawer()" aria-label="Open menu" class="p-2 text-gray-600 hover:bg-gray-100 rounded-lg">
    <svg class="w-6 h-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
      <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"/>
    </svg>
  </button>
</header>

<!-- Backdrop -->
<div id="backdrop" class="hidden fixed inset-0 bg-black/50 z-40" onclick="closeDrawer()"></div>

<!-- Drawer panel -->
<aside id="drawer" class="fixed inset-y-0 left-0 w-72 bg-gray-900 text-white z-50 flex flex-col -translate-x-full transition-transform duration-300">
  <div class="flex items-center justify-between px-5 py-4 border-b border-gray-800">
    <span class="font-bold text-white">AppDash</span>
    <button data-close onclick="closeDrawer()" aria-label="Close menu" class="text-gray-400 hover:text-white">&times;</button>
  </div>
  <nav class="flex-1 overflow-y-auto px-4 py-6 space-y-1">
    <a href="/" class="block px-3 py-3 rounded-lg text-base font-medium bg-gray-800 text-white">Home</a>
    <a href="/features" class="block px-3 py-3 rounded-lg text-base font-medium text-gray-300 hover:bg-gray-800 hover:text-white">Features</a>
  </nav>
</aside>

Hurtigt tjek

Test din forståelse af begreberne fra Tailwind CSS Mastery i denne lektion.

Opsummering af lektionen

I denne lektion lærte du: Den mobile skuffe-menu bruger tre elementer — baggrundsoverlejring, indglidende panel og hamburgerudløser; indglidningsanimationen skifter mellem -translate-x-full og transition-transform duration-300; og tilgængelighed kræver understøttelse af Escape-tasten, fokushåndtering ind i skuffe-menuen, når den åbnes, samt en klikbar baggrund, der lukker den. Nu skal vi style tekstinputfelter og tekstområder.

Gratis at komme i gang

Lær HTML med en AI-underviser — gratis

Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.

Kurser
30
Lektioner
120

Ofte stillede spørgsmål

Er lektionen “Sammenklappelig mobil-sidebar” gratis?

Ja — hele teksten til “Sammenklappelig mobil-sidebar” kan læses gratis her på nettet. Hvis du vil øve dig interaktivt med en indbygget kodeeditor og en AI-vejleder døgnet rundt og få adgang til resten af Tailwind CSS Academy-kurset, skal du opgradere til CoddyKit PRO. Tailwind CSS Academy-kurset indeholder 4 lektioner i alt.

Hvad lærer jeg i “Sammenklappelig mobil-sidebar”?

Implementér en sidebar som en indskydelig drawer til mobil med en JavaScript-toggle, overlay-baggrund og glidende translate-transition. Du øver dig i Tailwind CSS Academy med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.

Skal jeg have erfaring for at begynde på Tailwind CSS Academy?

Der kræves ingen tidligere erfaring. Tailwind CSS Academy på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 4 af 4.

Hvor lang tid tager lektionen “Sammenklappelig mobil-sidebar”?

De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.

Kan jeg skrive og køre kode i denne Tailwind CSS Academy-lektion?

Ja. Alle Tailwind CSS Academy-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.

Alle lektioner i dette kursus

  1. Byg en responsiv navigationslinje
  2. Sticky og fast navigation
  3. Layout med lodret sidebar
  4. Sammenklappelig mobil-sidebar
← Tilbage til Tailwind CSS Academy