Skip to Content

Welcome .


Sign up

Cette question a été signalée
34 Views

Barre de navigation style Apple (glassmorphism) : capsule translucide + bouton rond, flou d’arrière-plan et sélecteur bleu qui glisse avec une animation fluide.

Accessible (ARIA + clavier), responsive, sans dépendances. Ajustez l’intensité via --blur / --sat; le fallback s’active automatiquement si backdrop-filter n’est pas disponible.

<!-- ================= Apple Frosted Tabs + Animated Selector ================= -->
<div class="store-dock">
  <div class="tabs glass" role="tablist" aria-label="Store navigation">
    <!-- Sélecteur bleu animé (passe derrière le tab actif) -->
    <span class="tab-thumb" aria-hidden="true"></span>

    <button class="tab is-active" role="tab" aria-selected="true" data-tab="today">
      <svg class="ico" viewBox="0 0 24 24" aria-hidden="true"><path d="M6 3h12v3H6zM5 7h14v12H5zM8 10h8M8 14h6" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"/></svg>
      <span>Today</span>
    </button>

    <button class="tab" role="tab" aria-selected="false" data-tab="games">
      <svg class="ico" viewBox="0 0 24 24" aria-hidden="true"><path d="M4 13c0-3.9 3.1-7 7-7s7 3.1 7 7M7 13h2M15 13h2M14 10l3-2" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"/></svg>
      <span>Games</span>
    </button>

    <button class="tab" role="tab" aria-selected="false" data-tab="apps">
      <svg class="ico" viewBox="0 0 24 24" aria-hidden="true"><path d="M4 4h7v7H4zM13 4h7v7h-7zM4 13h7v7H4zM13 13h7v7h-7z" fill="currentColor"/></svg>
      <span>Apps</span>
    </button>

    <button class="tab" role="tab" aria-selected="false" data-tab="arcade">
      <svg class="ico" viewBox="0 0 24 24" aria-hidden="true"><path d="M5 16h14M7 16v-2a5 5 0 0 1 10 0v2M8 11h2M14 11h2" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"/></svg>
      <span>Arcade</span>
    </button>
  </div>

  <button class="glass circle" aria-label="Search">
    <svg class="ico" viewBox="0 0 24 24" aria-hidden="true"><path d="M10.5 18a7.5 7.5 0 1 1 5.3-12.8L22 11.4l-2.1 2.1-5.6-5.6A7.5 7.5 0 0 1 10.5 18z" fill="currentColor"/></svg>
  </button>
</div>

<style>
  /* --------- Démo : fond chaud pour bien voir le frosted --------- */
  .store-dock{
    --pad: clamp(10px, 2.5vw, 18px);
    padding: var(--pad);
    display:flex; gap: clamp(10px,2vw,16px); align-items:center;
    background:
      linear-gradient(180deg,#a35f20 0%, #cc8a3a 30%, #b36a27 60%, #8c4f1a 100%);
    border-radius: 18px;
  }

  /* =============== Capsule “frosted” =============== */
  .glass{
    --blur: 24px;
    --sat: 180%;
    --bg1: rgba(255,255,255,.22);
    --bg2: rgba(255,255,255,.12);
    --stroke: rgba(255,255,255,.65);
    --inner: rgba(0,0,0,.18);
    --shadow: rgba(0,0,0,.22);

    position: relative;
    border: 1px solid var(--stroke);
    background: linear-gradient(180deg, var(--bg1), var(--bg2));
    -webkit-backdrop-filter: blur(var(--blur)) saturate(var(--sat));
    backdrop-filter: blur(var(--blur)) saturate(var(--sat));
    box-shadow:
      inset 0 1px 0 rgba(255,255,255,.7),
      inset 0 -1px 0 var(--inner),
      0 14px 26px var(--shadow);
    border-radius: 9999px;
  }
  @supports not (backdrop-filter: blur(1px)){
    .glass{ background: linear-gradient(180deg, rgba(250,250,250,.8), rgba(240,240,240,.6)); }
  }

  /* =============== Tabs capsule =============== */
  .tabs{
    display:grid;
    grid-auto-columns: 1fr;
    grid-auto-flow: column;
    align-items:center;
    position: relative;
    min-height: 64px;
    padding: 8px;
  }

  .tab{
    position: relative;
    z-index: 2; /* au-dessus du thumb */
    display:flex; align-items:center; justify-content:center;
    gap:10px; padding: 12px 18px; border:0; background: none; border-radius:18px;
    font: 600 16px/1 -apple-system, system-ui, "SF Pro Text", Segoe UI, Roboto, Helvetica, Arial;
    color:#1a1a1a; cursor:pointer; user-select:none;
    white-space:nowrap;
  }
  .tab .ico{ width:22px; height:22px; color:#1a1a1a; opacity:.9; }
  .tab.is-active{ color:#007aff; }
  .tab.is-active .ico{ color:#007aff; }

  /* Sélecteur animé (bleu + halo) */
  .tab-thumb{
    --x: 8px;           /* left animée via JS */
    --w: 140px;         /* width animée via JS */
    position:absolute; z-index:1; top:8px; left: var(--x); width: var(--w); height: calc(100% - 16px);
    border-radius: 18px;
    border: 1px solid rgba(255,255,255,.75);
    background:
      radial-gradient(120% 160% at 14% 30%, rgba(0,122,255,.55), rgba(0,122,255,.18) 35%, rgba(0,122,255,0) 65%),
      radial-gradient(90% 140% at 35% 65%, rgba(255,255,255,.35), rgba(255,255,255,0) 55%),
      linear-gradient(180deg, rgba(255,255,255,.40), rgba(255,255,255,.16));
    box-shadow:
      inset 0 1px 0 rgba(255,255,255,.75),
      inset 0 -1px 0 rgba(0,0,0,.18),
      0 8px 18px rgba(0,122,255,.35);
    pointer-events:none;

    /* animation “spring-like” (via transition custom) */
    transition:
      left 420ms cubic-bezier(.2,.8,.16,1),
      width 420ms cubic-bezier(.2,.8,.16,1),
      transform 420ms cubic-bezier(.2,.8,.16,1);
  }

  /* =============== Bouton cercle (recherche) =============== */
  .circle{
    width: 64px; height: 64px; display:grid; place-items:center;
    border-radius: 9999px;
  }
  .circle .ico{ width:26px; height:26px; color:#1a1a1a; opacity:.9; }

  /* Accessibilité */
  @media (prefers-reduced-motion: reduce){
    .tab-thumb{ transition: none !important; }
  }
</style>

<script>
/* ===== Animated selector ===== */
(function(){
  const tabs = document.querySelector('.tabs');
  const thumb = tabs.querySelector('.tab-thumb');
  const btns = [...tabs.querySelectorAll('.tab')];

  function moveThumb(to){
    const rWrap = tabs.getBoundingClientRect();
    const r = to.getBoundingClientRect();
    const x = r.left - rWrap.left;      // position relative
    const w = r.width;

    thumb.style.setProperty('--x', (x) + 'px');
    thumb.style.setProperty('--w', (w) + 'px');

    btns.forEach(b=>{
      const active = b === to;
      b.classList.toggle('is-active', active);
      b.setAttribute('aria-selected', active ? 'true' : 'false');
      b.tabIndex = active ? 0 : -1;
    });
  }

  // init position on load
  moveThumb(btns.find(b => b.classList.contains('is-active')) || btns[0]);

  // click / keyboard
  btns.forEach(b=>{
    b.addEventListener('click', ()=> moveThumb(b));
    b.addEventListener('keydown', e=>{
      if(e.key === 'ArrowRight' || e.key === 'ArrowLeft'){
        e.preventDefault();
        const i = btns.indexOf(document.activeElement);
        const next = e.key === 'ArrowRight'
          ? btns[(i+1) % btns.length]
          : btns[(i-1+btns.length) % btns.length];
        next.focus(); moveThumb(next);
      }
    });
  });

  // responsive: recalc on resize
  addEventListener('resize', ()=> {
    const current = btns.find(b=> b.classList.contains('is-active')) || btns[0];
    moveThumb(current);
  }, {passive:true});
})();
</script>
Ignorer
Related Posts Replies Views Activity
0
Aug 25
45
1
Aug 25
84
0
Aug 25
1
0
Aug 25
46
0
Aug 25
3