→ לכל המאגר

B63 · שאלות נפוצות כשיחה

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

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

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

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

הדמו

שאלו הכל,אנחנו ספר פתוח

לא מצאתם כאן את השאלה שלכם? כתבו לנו, ותקבלו תשובה אישית תוך יום עבודה.

שלוש החלטות שעושות את זה שיחה ולא אקורדיון צבוע: (1) שני צדדים. השאלה בצד ההתחלה והתשובה בצד השני, כל אחת עם פינה חדה אחת בצד הדובר. (2) תמונה אמיתית של בעל העסק בתשובה. בלי תמונה זה שוב רשימה. (3) לעטיפה של הבועה ריפוד תחתון של 26 פיקסלים: ה-overflow:hidden שמאפשר את פתיחת הגובה חותך גם את הצל, ובלי הריפוד מופיע קו חד מתחת לכל תשובה. (4) הבועה נכנסת 120 מילישניות אחרי שהשורה מתחילה להיפתח, כך שהגובה נפתח קודם והתוכן נוחת לתוכו. בלי העיכוב הבועה קופצת בתוך קופסה שעוד לא קיימת. הגובה עצמו ב-grid-template-rows מ-0fr ל-1fr, כמו ב-b30. ויתרנו במודע על נקודות הקלדה: הן נחמדות בפעם הראשונה ומעכבות את התשובה בכל פעם אחרי זה.

קוד להדבקה

הקוד כאן עומד בפני עצמו. כל טוקן עיצוב נושא ברירת מחדל, מחלקות העזר של המאגר מוטמעות בו, ותגי הסקריפט מסודרים לפי הסדר הנכון. פרויקט שמגדיר --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}
.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)}

/* B63 · שאלות נפוצות כשיחה */
.cq{display:grid;grid-template-columns:minmax(0,.8fr) minmax(0,1.2fr);gap:clamp(28px,6vw,110px);align-items:start;max-width:min(1180px,94vw);margin-inline:auto}
.cq-side{position:sticky;top:clamp(80px,12vh,140px)}
.cq-side h3{font-size:clamp(30px,3.6vw,54px);line-height:1.1;margin:0 0 16px;font-weight:400}
.cq-side h3 b{font-weight:800;display:block}
.cq-side p{margin:0;color:var(--muted, #6a6d85);font-size:17px;line-height:1.6;max-width:36ch}
.cq-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:12px}
.cq-item{display:flex;flex-direction:column;align-items:flex-start}
/* השאלה: הודעה שנשלחה. יושבת בצד ההתחלה (ימין בעברית) עם פינה חדה אחת בצד השולח */
.cq-q{display:inline-flex;align-items:center;gap:12px;max-width:100%;background:none;border:0;padding:4px 0;font:inherit;text-align:start;cursor:pointer;color:inherit}
.cq-txt{padding:16px 26px;border-radius:30px 6px 30px 30px;background:var(--ink, #16182b);color:var(--bg, #f7f7fa);font-size:clamp(16px,1.4vw,19px);font-weight:600;line-height:1.4;
  box-shadow:0 14px 30px -18px color-mix(in srgb,var(--ink, #16182b) 60%,transparent);transition:background-color .3s,color .3s,transform .3s cubic-bezier(.2,.6,.2,1)}
.cq-mark{flex:none;width:44px;height:44px;border-radius:50%;background:var(--ink, #16182b);position:relative;transition:background-color .3s,transform .4s cubic-bezier(.2,.6,.2,1)}
.cq-mark::before,.cq-mark::after{content:"";position:absolute;inset:50% 13px auto;height:2px;margin-top:-1px;border-radius:2px;background:var(--bg, #f7f7fa)}
.cq-mark::after{transform:rotate(90deg)}
.cq-q:hover .cq-txt{transform:translateY(-2px)}
.cq-q:focus-visible{outline:none}
.cq-q:focus-visible .cq-txt{outline:2px solid var(--accent, #4a3aff);outline-offset:3px}
.cq-item.open .cq-txt{background:var(--accent, #4a3aff);color:var(--accent-ink, #fff)}
.cq-item.open .cq-mark{background:var(--accent, #4a3aff);transform:rotate(45deg)}
.cq-item.open .cq-mark::before,.cq-item.open .cq-mark::after{background:var(--accent-ink, #fff)}
/* התשובה: גובה אמיתי ב-grid-template-rows, ובתוכו בועה שקופצת פנימה רק אחרי שהשורה נפתחה */
.cq-a{display:grid;grid-template-rows:0fr;width:100%;transition:grid-template-rows .42s cubic-bezier(.2,.6,.2,1)}
.cq-item.open .cq-a{grid-template-rows:1fr}
.cq-a>div{overflow:hidden}
.cq-reply{display:flex;align-items:flex-end;gap:12px;justify-content:flex-end;padding:10px 4px 26px;
  opacity:0;transform:translateY(12px) scale(.97);transform-origin:left bottom;transition:opacity .25s,transform .25s cubic-bezier(.2,.6,.2,1)}
.cq-item.open .cq-reply{opacity:1;transform:none;transition:opacity .35s .12s,transform .45s .12s cubic-bezier(.2,.6,.2,1)}
.cq-bub{max-width:min(560px,100%);background:var(--card, #fff);color:var(--ink, #16182b);border:1px solid var(--line, #e4e4ee);padding:18px 24px;
  border-radius:26px 26px 26px 6px;font-size:16px;line-height:1.65;box-shadow:0 14px 34px -20px color-mix(in srgb,var(--ink, #16182b) 40%,transparent)}
.cq-bub p{margin:0}
.cq-av{flex:none;width:42px;height:42px;border-radius:50%;box-shadow:0 0 0 3px var(--card, #fff);font-size:15px}
@media (max-width:820px){.cq{grid-template-columns:1fr}.cq-side{position:static}}
@media (prefers-reduced-motion: reduce){.cq-a,.cq-reply,.cq-item.open .cq-reply,.cq-txt,.cq-mark{transition-duration:.01ms;transition-delay:0s}}

HTML

<div class="stage tight"><div class="cq">
  <div class="cq-side">
    <h3>שאלו הכל,<b>אנחנו ספר פתוח</b></h3>
    <p>לא מצאתם כאן את השאלה שלכם? כתבו לנו, ותקבלו תשובה אישית תוך יום עבודה.</p>
  </div>
  <ul class="cq-list">
    <li class="cq-item"><button class="cq-q" aria-expanded="false" aria-controls="cq-a1"><span class="cq-txt">כמה זמן לוקח לבנות אתר?</span><span class="cq-mark" aria-hidden="true"></span></button>
      <div class="cq-a" id="cq-a1" role="region"><div><div class="cq-reply"><div class="cq-bub"><p>דף נחיתה בין שבוע לשבועיים, אתר תדמית מלא בין שלושה לחמישה שבועות. הספירה מתחילה מהרגע שכל החומרים אצלנו.</p></div><span class="cq-av ph ph-a" aria-hidden="true"></span></div></div></div></li>
    <li class="cq-item"><button class="cq-q" aria-expanded="false" aria-controls="cq-a2"><span class="cq-txt">מה צריך להכין מראש?</span><span class="cq-mark" aria-hidden="true"></span></button>
      <div class="cq-a" id="cq-a2" role="region"><div><div class="cq-reply"><div class="cq-bub"><p>לוגו, תמונות וטקסטים ראשוניים. אין לכם? אנחנו כותבים ומצלמים, וזה מתומחר בנפרד.</p></div><span class="cq-av ph ph-a" aria-hidden="true"></span></div></div></div></li>
    <li class="cq-item"><button class="cq-q" aria-expanded="false" aria-controls="cq-a3"><span class="cq-txt">האתר יתאים לטלפון?</span><span class="cq-mark" aria-hidden="true"></span></button>
      <div class="cq-a" id="cq-a3" role="region"><div><div class="cq-reply"><div class="cq-bub"><p>כל אתר נבנה קודם לטלפון ורק אחר כך למחשב, כי שם נמצאים רוב הגולשים שלכם.</p></div><span class="cq-av ph ph-a" aria-hidden="true"></span></div></div></div></li>
    <li class="cq-item"><button class="cq-q" aria-expanded="false" aria-controls="cq-a4"><span class="cq-txt">ומה קורה אחרי שהאתר עולה לאוויר?</span><span class="cq-mark" aria-hidden="true"></span></button>
      <div class="cq-a" id="cq-a4" role="region"><div><div class="cq-reply"><div class="cq-bub"><p>חודש ליווי כלול. אחריו אפשר לבחור חבילת תחזוקה עם גיבויים, עדכוני אבטחה ושינויי תוכן קטנים.</p></div><span class="cq-av ph ph-a" aria-hidden="true"></span></div></div></div></li>
  </ul>
</div></div>

JS

(function(){
  const items=[...document.querySelectorAll(".cq-item")];
  const SINGLE=true; // רק שאלה אחת פתוחה, כמו שיחה. false מאפשר כמה במקביל
  function set(item,open){
    item.classList.toggle("open",open);
    item.querySelector(".cq-q").setAttribute("aria-expanded",String(open));
  }
  items.forEach(item=>{
    item.querySelector(".cq-q").addEventListener("click",()=>{
      const open=!item.classList.contains("open");
      if(SINGLE)items.forEach(o=>o!==item&&set(o,false));
      set(item,open);
    });
  });
  set(items[0],true); // השאלה הראשונה פתוחה, כדי שהגולש יבין מיד שזו שיחה ולא רשימה
})();