→ לכל המאגר

B58 · דוק אייקונים שמתנפחים ליד הסמן

התנהגויות vanilla JS · CSS ניווט ומבנהhover ומיקרו ממתין

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

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

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

הדמו

מקור: MagicUI Dock. נכתב מחדש: המרחק מהסמן נמדד ב-mousemove, וכל אייקון מקבל scale לפי עקומה, על transform בלבד. הרוחב לא משתנה, לכן השכנים לא קופצים.

קוד להדבקה

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

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

CSS

/* מחלקות עזר של המאגר שהרכיב הזה משתמש בהן */
.stage{padding:var(--sec, clamp(120px, 12vw, 260px)) var(--gutter, clamp(24px, 5vw, 96px));position:relative}
.stage.tight{padding-block:clamp(48px,5vw,90px)}
.stage.full{padding-inline:0}

/* B58 · דוק אייקונים שמתנפחים ליד הסמן */
.dk-wrap{display:flex;justify-content:center;padding-block:60px 30px}
.dk{display:flex;align-items:flex-end;gap:10px;padding:10px 14px;border-radius:22px;background:var(--card, #fff);border:1px solid var(--line, #e4e4ee);box-shadow:0 18px 50px rgba(0,0,0,.12)}
.dk a{width:52px;height:52px;border-radius:14px;display:grid;place-items:center;background:var(--bg, #f7f7fa);color:var(--ink, #16182b);font-weight:700;font-size:12px;text-decoration:none;
  transform-origin:bottom center;transform:scale(var(--s,1));transition:transform .18s cubic-bezier(.2,.6,.2,1);position:relative}
.dk a::after{content:attr(data-tip);position:absolute;bottom:calc(100% + 10px);left:50%;translate:-50% 4px;background:var(--ink, #16182b);color:var(--bg, #f7f7fa);font-size:12px;padding:5px 9px;border-radius:8px;white-space:nowrap;opacity:0;transition:opacity .2s,translate .2s;pointer-events:none}
@media (hover:hover) and (pointer:fine){.dk a:hover::after{opacity:1;translate:-50% 0}}
.dk a:focus-visible{outline:2px solid var(--accent, #4a3aff);outline-offset:2px}
@media (prefers-reduced-motion: reduce){.dk a{transition:none}}

HTML

<div class="stage tight"><div class="dk-wrap"><nav class="dk" aria-label="ניווט מהיר">
  <a href="#" data-tip="בית">בית</a><a href="#" data-tip="עבודות">עבודות</a><a href="#" data-tip="שירותים">שירות</a><a href="#" data-tip="בלוג">בלוג</a><a href="#" data-tip="אודות">אודות</a><a href="#" data-tip="צור קשר">קשר</a>
</nav></div></div>

JS

(function(){
  if(!matchMedia("(hover:hover) and (pointer:fine)").matches)return;
  const dock=document.querySelector(".dk"),icons=[...dock.querySelectorAll("a")],RANGE=140,MAX=1.7;
  function paint(x){
    icons.forEach(a=>{
      const r=a.getBoundingClientRect(),d=Math.abs(x-(r.left+r.width/2));
      const s=d>RANGE?1:1+(MAX-1)*Math.cos((d/RANGE)*Math.PI/2);   // קוסינוס: רך במרכז, מתאפס בקצה הטווח
      a.style.setProperty("--s",s.toFixed(3));
    });
  }
  dock.addEventListener("mousemove",e=>paint(e.clientX));
  dock.addEventListener("mouseleave",()=>icons.forEach(a=>a.style.setProperty("--s",1)));
})();