→ לכל המאגר

B43 · מחשבון עם סליידר וגרף חי

התנהגויות input range · JS מספרים ונתוניםטעינה ופידבק ממתין

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

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

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

הדמו

כמה עמודים אתם צריכים?

0
הערכה, לא הצעת מחיר
מספר עמודים5
אפיון
עיצוב
פיתוח
תוכן
בדיקות
ההערכה מתעדכנת בזמן אמת. המחיר הסופי נקבע אחרי שיחה.
input type=range נותן נגישות מלאה בחינם: מקלדת, מגע וקורא מסך, בלי לכתוב סליידר מאפס. הנרמול חשוב, אחרת בערכים גבוהים כל העמודות נדבקות לתקרה ואי אפשר להשוות ביניהן. הסכום עובר דרך toLocaleString כדי לקבל פסיקים, והכיתוב מבהיר שזו הערכה בלבד, כי מחשבון שמתחייב למחיר יוצר ויכוח בשיחה.

קוד להדבקה

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

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

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}
.gbtn{display:inline-flex;align-items:center;justify-content:center;min-height:48px;padding-inline:28px;border-radius:999px;background:var(--accent, #4a3aff);color:var(--accent-ink, #fff);font-weight:500;font-size:16px;border:0;cursor:pointer;font-family:inherit}

/* B43 · מחשבון עם סליידר וגרף חי */
.calc{max-width:min(860px,94vw);margin-inline:auto;background:var(--card, #fff);border:1px solid var(--line, #e4e4ee);border-radius:20px;padding:clamp(22px,3vw,40px)}
.calc-top{display:flex;justify-content:space-between;align-items:flex-end;gap:20px;flex-wrap:wrap;margin-bottom:22px}
.calc-top h3{margin:0;font-size:clamp(20px,2.2vw,30px)}
.calc-out{text-align:end}
.calc-sum{font-size:clamp(30px,4vw,54px);font-weight:800;line-height:1;color:var(--accent, #4a3aff);font-variant-numeric:tabular-nums}
.calc-sub{font-size:13px;color:var(--muted, #6a6d85);margin-top:6px}
.calc-row{display:grid;gap:8px;margin-bottom:22px}
.calc-lbl{display:flex;justify-content:space-between;font-size:14px;color:var(--muted, #6a6d85)}
.calc-lbl b{color:var(--ink, #16182b);font-variant-numeric:tabular-nums}
.calc input[type=range]{width:100%;accent-color:var(--accent, #4a3aff);height:26px}
.calc-bars{display:flex;align-items:flex-end;gap:clamp(8px,1.4vw,18px);height:clamp(140px,18vw,210px);margin-top:8px}
.calc-bar{flex:1;display:flex;flex-direction:column;justify-content:flex-end;align-items:center;gap:8px;height:100%}
.calc-fill{width:100%;border-radius:10px 10px 4px 4px;background:linear-gradient(180deg,#6f63ff,var(--accent, #4a3aff));
  height:100%;transform-origin:50% 100%;transform:scaleY(.1);transition:transform .45s cubic-bezier(.2,.6,.2,1)}
.calc-bar.dim .calc-fill{background:linear-gradient(180deg,#cfcfe4,#b9b9d4)}
.calc-name{font-size:12px;color:var(--muted, #6a6d85);white-space:nowrap}
.calc-foot{display:flex;justify-content:space-between;gap:14px;flex-wrap:wrap;align-items:center;margin-top:24px;
  border-top:1px solid var(--line, #e4e4ee);padding-top:18px}
.calc-note{font-size:13px;color:var(--muted, #6a6d85);max-width:44ch}
@media (prefers-reduced-motion: reduce){.calc-fill{transition:none}}

HTML

<div class="stage tight"><div class="calc">
  <div class="calc-top">
    <h3>כמה עמודים אתם צריכים?</h3>
    <div class="calc-out"><div class="calc-sum">0</div><div class="calc-sub">הערכה, לא הצעת מחיר</div></div>
  </div>
  <div class="calc-row">
    <div class="calc-lbl"><span>מספר עמודים</span><b class="calc-pages">5</b></div>
    <input type="range" min="1" max="20" value="5" class="calc-range" aria-label="מספר עמודים">
  </div>
  <div class="calc-bars">
    <div class="calc-bar"><div class="calc-fill" data-b="3" data-g="0.15" style="height:20%"></div><span class="calc-name">אפיון</span></div>
    <div class="calc-bar"><div class="calc-fill" data-b="2" data-g="0.9" style="height:30%"></div><span class="calc-name">עיצוב</span></div>
    <div class="calc-bar"><div class="calc-fill" data-b="1.5" data-g="1.4" style="height:44%"></div><span class="calc-name">פיתוח</span></div>
    <div class="calc-bar"><div class="calc-fill" data-b="1" data-g="0.5" style="height:16%"></div><span class="calc-name">תוכן</span></div>
    <div class="calc-bar dim"><div class="calc-fill" data-b="1" data-g="0.25" style="height:12%"></div><span class="calc-name">בדיקות</span></div>
  </div>
  <div class="calc-foot"><span class="calc-note">ההערכה מתעדכנת בזמן אמת. המחיר הסופי נקבע אחרי שיחה.</span>
  <button class="gbtn">לקבלת הצעה מדויקת</button></div>
</div></div>

JS

(function(){
  const range=document.querySelector(".calc-range");
  const bars=[...document.querySelectorAll(".calc-fill")];
  const sum=document.querySelector(".calc-sum"),pages=document.querySelector(".calc-pages");
  const BASE=2400,PER=650;
  function render(){
    const n=+range.value;
    pages.textContent=n;
    // לכל מרכיב בסיס קבוע וקצב גידול משלו, ולכן היחס ביניהם משתנה עם מספר העמודים:
    // האפיון כמעט קבוע, והפיתוח הוא זה שמטפס. נרמול לפי הגבוהה כדי שתמיד תמלא את הגובה.
    const vals=bars.map(b=>+b.dataset.b + n * +b.dataset.g);
    const max=Math.max(...vals);
    bars.forEach((b,i)=>{b.style.transform="scaleY("+Math.max(.1,vals[i]/max).toFixed(3)+")";});   // scaleY במקום height: אותו גרף, בלי layout thrash
    const total=BASE+n*PER;
    sum.textContent=total.toLocaleString("he-IL")+" ש\"ח";
  }
  range.addEventListener("input",render);
  render();
})();