1
משרד עורכי דין
אתר תדמית
שורת קטגוריות מעל גריד. לחיצה מסננת, והפריטים שנשארים מחליקים למקומם החדש במקום להיעלם ולקפוץ. הנעלמים דוהים והחדשים נכנסים.
מתי משתמשים: תיק עבודות, קטלוג מוצרים, תפריט מסעדה, רשימת שירותים, מאמרים, צוות. הרכיב הזה הופיע ביותר ממחצית האתרים שנסרקו.
הדמו כאן עיצובי-ניטרלי בכוונה. כשהמהלך נכנס לפרויקט, מיובאת רק ההתנהגות: הצבעים, הרדיוסים, הפונטים והצללים יורשים את העיצוב של אותו פרויקט.
אתר תדמית
חנות
דף נחיתה
אתר תדמית
חנות
דף נחיתה
אתר תדמית
חנות
דף נחיתה
אין פריטים בקטגוריה הזאת.
הקוד כאן עומד בפני עצמו. כל טוקן עיצוב נושא ברירת מחדל, מחלקות העזר של המאגר מוטמעות בו, ותגי הסקריפט מסודרים לפי הסדר הנכון. פרויקט שמגדיר --accent או --line משלו יורש אותם אוטומטית. הרכיב הזה מסתמך על dir="rtl".
/* מחלקות עזר של המאגר שהרכיב הזה משתמש בהן */
.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}
.ph{display:flex;align-items:center;justify-content:center;color:#fff;font-weight:700;border-radius:var(--r, 14px)}
.ph-a{background:linear-gradient(160deg,#3b5bdb,#748ffc)}
.ph-b{background:linear-gradient(160deg,#5f3dc4,#9775fa)}
.ph-c{background:linear-gradient(160deg,#0b7285,#3bc9db)}
.ph-d{background:linear-gradient(160deg,#2b8a3e,#69db7c)}
.ph-e{background:linear-gradient(160deg,#e8590c,#ffa94d)}
.ph-f{background:linear-gradient(160deg,#c92a2a,#ff8787)}
.ph-l{background:rgba(16,18,43,.72);color:#fff;padding:.18em .7em;border-radius:999px;line-height:1.3;font-size:max(.78em,12px)}
/* B34 · גריד מסונן עם מעבר חלק */
.fg{padding-inline:var(--gutter, clamp(24px, 5vw, 96px))}
.fg-bar{display:flex;gap:8px;flex-wrap:wrap;align-items:center;margin-bottom:clamp(20px,2.4vw,34px)}
.fg-chip{border:1px solid var(--line, #e4e4ee);background:var(--card, #fff);border-radius:999px;padding:10px 18px;font:inherit;font-size:14px;
color:var(--ink, #16182b);cursor:pointer;transition:background .25s,border-color .25s,color .25s}
.fg-chip:hover{border-color:var(--accent, #4a3aff)}
.fg-chip.on{background:var(--ink, #16182b);color:var(--bg, #f7f7fa);border-color:var(--ink, #16182b)}
.fg-count{margin-inline-start:auto;font-size:13px;color:var(--muted, #6a6d85);font-variant-numeric:tabular-nums}
.fg-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--gap, clamp(16px, 1.6vw, 36px));position:relative;background:var(--bg, #f7f7fa)}
.fg-item{background:var(--card, #fff);border:1px solid var(--line, #e4e4ee);border-radius:var(--r, 14px);overflow:hidden}
.fg-item .ph{height:clamp(150px,15vw,210px);border-radius:0;font-size:22px}
.fg-item h3{margin:0;padding:16px 18px 4px;font-size:17px}
.fg-item p{margin:0;padding:0 18px 18px;font-size:13px;color:var(--muted, #6a6d85)}
.fg-item.hide{display:none}
.fg-empty{padding:40px 4px;color:var(--muted, #6a6d85);text-align:center;display:none}
.fg-empty.on{display:block}
@media(max-width:900px){.fg-grid{grid-template-columns:repeat(2,1fr)}}
@media(max-width:560px){.fg-grid{grid-template-columns:1fr}}
<div class="stage tight"><div class="fg">
<div class="fg-bar" role="group" aria-label="סינון לפי קטגוריה">
<button class="fg-chip on" data-f="all">הכל</button>
<button class="fg-chip" data-f="web">אתרי תדמית</button>
<button class="fg-chip" data-f="shop">חנויות</button>
<button class="fg-chip" data-f="lp">דפי נחיתה</button>
<span class="fg-count"></span>
</div>
<div class="fg-grid">
<article class="fg-item" data-c="web"><div class="ph ph-a"><span class="ph-l">1</span></div><h3>משרד עורכי דין</h3><p>אתר תדמית</p></article>
<article class="fg-item" data-c="shop"><div class="ph ph-b"><span class="ph-l">2</span></div><h3>חנות תכשיטים</h3><p>חנות</p></article>
<article class="fg-item" data-c="lp"><div class="ph ph-c"><span class="ph-l">3</span></div><h3>קמפיין קיץ</h3><p>דף נחיתה</p></article>
<article class="fg-item" data-c="web"><div class="ph ph-d"><span class="ph-l">4</span></div><h3>קליניקת שיניים</h3><p>אתר תדמית</p></article>
<article class="fg-item" data-c="shop"><div class="ph ph-e"><span class="ph-l">5</span></div><h3>חנות רהיטים</h3><p>חנות</p></article>
<article class="fg-item" data-c="lp"><div class="ph ph-f"><span class="ph-l">6</span></div><h3>וובינר</h3><p>דף נחיתה</p></article>
<article class="fg-item" data-c="web"><div class="ph ph-c"><span class="ph-l">7</span></div><h3>חברת בנייה</h3><p>אתר תדמית</p></article>
<article class="fg-item" data-c="shop"><div class="ph ph-a"><span class="ph-l">8</span></div><h3>חנות קפה</h3><p>חנות</p></article>
<article class="fg-item" data-c="lp"><div class="ph ph-b"><span class="ph-l">9</span></div><h3>קורס דיגיטלי</h3><p>דף נחיתה</p></article>
</div>
<p class="fg-empty">אין פריטים בקטגוריה הזאת.</p>
</div></div>
gsap.registerPlugin(Flip);
(function(){
const chips=[...document.querySelectorAll(".fg-chip")],items=[...document.querySelectorAll(".fg-item")];
const count=document.querySelector(".fg-count"),empty=document.querySelector(".fg-empty");
const grid=document.querySelector(".fg-grid");
const reduce=matchMedia("(prefers-reduced-motion: reduce)").matches;
function apply(f,animate){
// Flip: מצלמים את המצב לפני, משנים את ה-DOM, והספרייה מנפישה את ההפרש
const state=Flip.getState(items,{props:"opacity"});
const h0=grid.getBoundingClientRect().height;
let shown=0;
items.forEach(it=>{
const vis=f==="all"||it.dataset.c===f;
it.classList.toggle("hide",!vis);
if(vis)shown++;
});
count.textContent=shown+" מתוך "+items.length;
empty.classList.toggle("on",shown===0);
if(reduce||!animate)return; // הקריאה הראשונה רק מסמנת מצב, בלי אנימציה על טעינה
const h1=grid.getBoundingClientRect().height;
// absolute:true מוציא את הכרטיסים מהזרימה, הגריד מתכווץ לאפס, וכל מה שמתחתיו
// עולה למעלה ומציץ מאחורי הכרטיסים המרחפים. מנפישים את גובה הגריד במקביל.
gsap.fromTo(grid,{height:h0},{height:h1,duration:.55,ease:"power2.inOut",
onComplete:()=>gsap.set(grid,{clearProps:"height"})});
Flip.from(state,{duration:.55,ease:"power2.inOut",scale:true,absolute:true,
onEnter:els=>gsap.fromTo(els,{opacity:0,scale:.9},{opacity:1,scale:1,duration:.4}),
onLeave:els=>gsap.to(els,{opacity:0,scale:.9,duration:.25})});
}
chips.forEach(c=>c.addEventListener("click",()=>{
chips.forEach(x=>x.classList.toggle("on",x===c));
apply(c.dataset.f,true);
}));
apply("all",false);
})();