מה calc() עושה
calc() מבצע חשבון בתוך ערך CSS, ויכול לשלב יחידות שמקבלות גודל רק בזמן הפריסה. המקרה הקלאסי הוא "הרוחב המלא פחות סרגל צד קבוע":
100% ידוע רק אחרי שהעמוד נפרס, ו-180px קבוע, כך שאף יחידה בודדת לא יכולה לבטא את זה. calc() מחשב את זה: בתצוגה מקדימה ברוחב 800px השורה היא 784px והעמודה הראשית מקבלת 604px, והשורה שמתחת לפריסה מדפיסה את המספרים האמיתיים. היום flexbox או grid היו עושים את הפריסה הזאת בלי חישוב, אבל אותו חיסור עדיין מופיע בכל מקום: גובה פחות כותרת עליונה, רוחב פחות רווח.
כללי התחביר
width: calc(100% - 2rem); /* + and - need spaces on both sides */
width: calc(100% / 3); /* divide by a plain number */
margin: calc(var(--space) * 2); /* multiply by a plain number */
height: calc(100vh - (64px + 1rem)); /* parentheses group */
| כלל | תקין | לא תקין |
|---|---|---|
רווחים סביב + ו-- | calc(100% - 20px) | calc(100%-20px) |
*: לפחות צד אחד הוא מספר רגיל | calc(2 * 1rem) | calc(2px * 3px) |
/: מחלקים אורך במספר רגיל | calc(100% / 3) | width: calc(300px / 3px) (לא אורך) |
| היחידות חייבות להיות תואמות | calc(1rem + 10px) | calc(1rem + 2s) |
כלל הרווחים קיים כי 100% -20px ייקרא כשני ערכים נפרדים, השני מספר שלילי. כש-calc() לא תקין, כל ההצהרה נזרקת והאלמנט שומר על הערך שהיה לו מכללים קודמים.
נסו ביטוי
הקלידו כל ביטוי לרוחב של התיבה. הדפדפן מדווח אם הוא תקין, ואיזה רוחב הוא חישב:
נסו 100%-200px (לא תקין, אין רווחים), 100% / 3, 50% + 4rem, 2 * 120px, 200px * 2px (לא תקין) ו-(100% - 40px) / 2.
calc() עם משתני CSS
משתנים ו-calc() הולכים יחד: שומרים ערך בסיס פעם אחת וגוזרים ממנו את השאר. משתנה בלי יחידה הופך לאורך כשמכפילים אותו ביחידה אחת:
שנו את --space ל-12px או את --cols ל-4, וכל ערך נגזר מתעדכן בהתאם. עמוד משתני ה-CSS מסביר איך מצהירים עליהם ואיך קובעים את הטווח שלהם.
שימושים נפוצים
| צורך | calc() |
|---|---|
| למלא את המקום ליד אלמנט קבוע | width: calc(100% - 240px) |
| אזור מתחת לכותרת עליונה קבועה | min-height: calc(100vh - 64px) |
| חצי מהרוחב פחות חצי רווח | width: calc(50% - 8px) |
| למרכז תיבה של 100px במיקום absolute | left: calc(50% - 50px) |
| גודל גופן שגדל קצת עם המסך | font-size: calc(1rem + 0.5vw) |
| להפוך משתנה מספרי לאורך | calc(var(--n) * 1px) |
| הערך השלילי של משתנה | calc(var(--space) * -1) |
לערך שחייב להישאר בין גבולות, השתמשו ב-clamp(), שמקבל את אותו חישוב בארגומנטים שלו בלי לכתוב calc().
איפה calc() עובד
בכל מקום שבו מותר אורך, אחוז, מספר, זווית או זמן: width, margin, padding, top, font-size, line-height, גדלים של מסלולי grid, transition-delay, וזוויות בתוך transform. אפשר לקנן אותו, ו-calc() מקונן זהה לסוגריים רגילים.
זוויות הן דוגמה טובה. לכל סימון למטה יש --i משלו (0 עד 11), וכלל אחד הופך אותו לזווית עם calc(var(--i) * 30deg):
סימון 3 מקבל rotate(90deg), ש-Chrome מדווח כמטריצה matrix(0, 1, -1, 0, 0, 0): רבע סיבוב. left: calc(50% - 2px) ממרכז כל סימון על ידי חיסור חצי מהרוחב שלו עצמו, 4px.
טעויות נפוצות
- אין רווחים סביב
-או+.calc(100%-20px)לא תקין ונזרק. - הכפלה של שני אורכים. ל-
calc(10px * 2px)אין משמעות ב-CSS. צד אחד של*חייב להיות מספר רגיל. - שימוש ב-calc() לגובה באחוזים בלי גובה להורה.
calc(100% - 20px)ל-heightצריך הורה עם גובה מוגדר, בדיוק כמוheight: 100%. - שימוש ב-calc() במקום שבו flexbox או grid יספיקו.
width: calc(33.333% - 10px)לעמודות הוא שביר;display: grid; grid-template-columns: repeat(3, 1fr); gap: 15pxלא צריך שום חישוב. - ציפייה להודעת שגיאה. הדפדפן לא מזהיר על calc() לא תקין. בדקו את האלמנט בכלי המפתחים: הצהרה לא תקינה מוצגת עם קו חוצה.
שאלות נפוצות
מה calc() עושה ב-CSS?
הוא מחשב ערך מביטוי עם +, -, * ו-/, ויכול לשלב יחידות שהדפדפן יודע רק בזמן הפריסה. width: calc(100% - 200px) הוא הרוחב המלא של ההורה פחות 200px, לא משנה מה רוחב ההורה.
למה ה-calc() שלי לא עובד?
הסיבה הנפוצה ביותר היא רווחים חסרים: חייב להיות רווח משני הצדדים של + ושל -, ולכן calc(100%-20px) לא תקין. סיבות אחרות הן הכפלה של שני אורכים (10px * 2px) או חילוק באורך, שלא נותן אורך. calc() לא תקין הופך את כל ההצהרה ללא תקינה, והדפדפן מתעלם ממנה.
אפשר להשתמש במשתני CSS בתוך calc()?
כן. calc(var(--gap) * 2) מכפיל משתנה פי שניים, ו-calc(var(--columns) * 1px) הופך מספר בלי יחידה לפיקסלים. הערך של המשתנה מוצב קודם, ורק אז מתבצע החישוב.
צריך רווחים סביב * ו-/ ב-calc()?
לא. רק + ו-- דורשים רווחים, כי בלעדיהם -20px ייקרא כמספר שלילי. רווחים סביב * ו-/ הם אופציונליים, אבל לכתוב אותם בכל מקום הוא הכלל הקל ביותר לזכור.
מה ההבדל בין calc() ל-clamp()?
calc() מחשב ערך אחד מביטוי. clamp(MIN, VAL, MAX) שומר ערך בין שני גבולות. אפשר לשלב אותם: כל ארגומנט של clamp() כבר יכול להכיל חישוב בסגנון calc, למשל clamp(1rem, 1rem + 2vw, 3rem).