→ לכל המאגר

B39 · תפריט נפתח עם פאנל מונפש

התנהגויות JS · CSS grid-rows ניווט ומבנה ממתין

פריט בתפריט שפותח פאנל רחב עם קישורים מקובצים. נפתח בהובר בדסקטופ ובלחיצה במגע, נסגר ב-Escape או בלחיצה בחוץ, ורק אחד פתוח בכל רגע.

מתי משתמשים: אתרים עם יותר מחמישה עמודים: קטלוג, שירותים לפי תחום, אזור לקוחות. מונע תפריט עמוס ומאפשר להסביר כל קטגוריה במילה.

הדמו כאן עיצובי-ניטרלי בכוונה. כשהמהלך נכנס לפרויקט, מיובאת רק ההתנהגות: הצבעים, הרדיוסים, הפונטים והצללים יורשים את העיצוב של אותו פרויקט.

הדמו

אודות

העבר עכבר על אחד הפריטים, או לחץ עליו במגע. Escape סוגר.

שלושה פרטים: הפאנל נפתח ב-grid-template-rows כדי לקבל גובה אמיתי בלי לחשב פיקסלים, יש השהיית יציאה של 180 מילישניות כדי שהמעבר מהכפתור אל הפאנל לא יסגור אותו, ובמכשירי מגע ההובר מבוטל לגמרי והפתיחה היא בלחיצה. חובה aria-expanded וסגירה ב-Escape.

קוד להדבקה

הקוד כאן עומד בפני עצמו. כל טוקן עיצוב נושא ברירת מחדל, מחלקות העזר של המאגר מוטמעות בו, ותגי הסקריפט מסודרים לפי הסדר הנכון. פרויקט שמגדיר --accent או --line משלו יורש אותם אוטומטית. הרכיב הזה מסתמך על dir="rtl".

פתח קובץ עצמאי ↗
הצג את הקוד כאן

CSS

/* B39 · תפריט נפתח עם פאנל מונפש */
.mm{position:relative;z-index:30;background:var(--card, #fff);border-bottom:1px solid var(--line, #e4e4ee)}
.mm-bar{display:flex;align-items:center;gap:4px;padding:12px var(--gutter, clamp(24px, 5vw, 96px));max-width:1200px;margin-inline:auto}
.mm-logo{font-weight:800;margin-inline-end:18px}
.mm-item{position:relative}
.mm-btn{display:inline-flex;align-items:center;gap:7px;background:none;border:0;font:inherit;font-size:15px;color:var(--ink, #16182b);
  padding:10px 14px;border-radius:999px;cursor:pointer;transition:background .22s}
.mm-btn:hover,.mm-item.open .mm-btn{background:#eceaff}
.mm-btn i{width:5px;height:5px;opacity:.6;border-inline-end:1.5px solid currentColor;border-block-end:1.5px solid currentColor;
  transform:rotate(45deg) translateY(-2px);transition:transform .3s,opacity .22s}
.mm-item.open .mm-btn i{opacity:1}
.mm-item.open .mm-btn i{transform:rotate(225deg) translateY(-2px)}
.mm-panel{position:absolute;inset-inline-start:0;top:calc(100% + 8px);min-width:min(560px,86vw);
  background:var(--card, #fff);border:1px solid var(--line, #e4e4ee);border-radius:18px;box-shadow:0 22px 60px rgba(22,24,43,.14);
  display:grid;grid-template-rows:0fr;opacity:0;visibility:hidden;transform:translateY(-6px);
  transition:grid-template-rows .32s cubic-bezier(.2,.6,.2,1),opacity .25s,transform .32s,visibility .32s}
.mm-item.open .mm-panel{grid-template-rows:1fr;opacity:1;visibility:visible;transform:none}
.mm-panel>div{overflow:hidden}
.mm-grid{display:grid;grid-template-columns:1fr 1fr;gap:6px;padding:16px}
.mm-link{display:block;padding:13px 14px;border-radius:12px;text-decoration:none;color:var(--ink, #16182b);transition:background .2s}
.mm-link:hover{background:var(--bg, #f7f7fa)}
.mm-link b{display:block;font-size:15px;margin-bottom:3px}
.mm-link span{font-size:13px;color:var(--muted, #6a6d85)}
.mm-note{padding:0 16px 16px;font-size:13px;color:var(--muted, #6a6d85)}
.mm-body{padding:var(--sec, clamp(120px, 12vw, 260px)) var(--gutter, clamp(24px, 5vw, 96px));text-align:center;color:var(--muted, #6a6d85)}
@media(max-width:767px){.mm-grid{grid-template-columns:1fr}.mm-panel{min-width:min(420px,88vw)}}
@media (prefers-reduced-motion: reduce){.mm-panel{transition-duration:.01ms}}

HTML

<div class="mm"><div class="mm-bar">
  <span class="mm-logo">לוגו</span>
  <div class="mm-item">
    <button class="mm-btn" aria-expanded="false">שירותים <i aria-hidden="true"></i></button>
    <div class="mm-panel"><div>
      <div class="mm-grid">
        <a class="mm-link" href="#"><b>אתרי תדמית</b><span>אתר שמסביר מי אתם ולמה דווקא אתכם</span></a>
        <a class="mm-link" href="#"><b>דפי נחיתה</b><span>עמוד אחד עם מטרה אחת: פנייה</span></a>
        <a class="mm-link" href="#"><b>חנויות אונליין</b><span>מסלול קנייה קצר ודף מוצר שמוכר</span></a>
        <a class="mm-link" href="#"><b>מערכות פנימיות</b><span>ניהול לקוחות, הצעות מחיר ואוטומציות</span></a>
      </div>
      <p class="mm-note">לא בטוחים מה מתאים? נדבר חמש דקות ונגיד לכם בכנות.</p>
    </div></div>
  </div>
  <div class="mm-item">
    <button class="mm-btn" aria-expanded="false">תחומים <i aria-hidden="true"></i></button>
    <div class="mm-panel"><div>
      <div class="mm-grid">
        <a class="mm-link" href="#"><b>נדל"ן</b><span>תיווך, יזמות ופרויקטים</span></a>
        <a class="mm-link" href="#"><b>קליניקות</b><span>רפואה, אסתטיקה וטיפול</span></a>
        <a class="mm-link" href="#"><b>מסחר</b><span>חנויות ומותגי מוצר</span></a>
        <a class="mm-link" href="#"><b>שירותים</b><span>עורכי דין, יועצים ובעלי מקצוע</span></a>
      </div>
    </div></div>
  </div>
  <a class="mm-btn" href="#" style="text-decoration:none">אודות</a>
</div></div>
<p class="mm-body">העבר עכבר על אחד הפריטים, או לחץ עליו במגע. Escape סוגר.</p>

JS

(function(){
  const items=[...document.querySelectorAll(".mm-item")];
  const hoverable=matchMedia("(hover:hover)").matches;
  let timer=null;
  function open(it){
    items.forEach(o=>{o.classList.toggle("open",o===it);o.querySelector(".mm-btn").setAttribute("aria-expanded",String(o===it));});
  }
  function closeAll(){open(null);}
  items.forEach(it=>{
    const btn=it.querySelector(".mm-btn");
    btn.addEventListener("click",e=>{e.preventDefault();it.classList.contains("open")?closeAll():open(it);});
    if(hoverable){
      // השהיה קטנה ביציאה, אחרת המסלול מהכפתור אל הפאנל סוגר אותו באמצע
      it.addEventListener("pointerenter",()=>{clearTimeout(timer);open(it);});
      it.addEventListener("pointerleave",()=>{clearTimeout(timer);timer=setTimeout(closeAll,180);});
    }
  });
  addEventListener("keydown",e=>{if(e.key==="Escape")closeAll();});
  addEventListener("click",e=>{if(!e.target.closest(".mm-item"))closeAll();});
})();