Menu

CSS Media Queries: נקודות שבירה, min-width ו-max-width

media query מחילה CSS רק כשתנאי מתקיים, כמו רוחב מסך מינימלי, ערכת צבעים כהה או סמן של עכבר. למדו את התחביר של @media, נקודות שבירה ב-mobile first, תחביר הטווחים, prefers-color-scheme, את matchMedia ב-JavaScript ו-container queries.

בדף הזה יש עורכים שאפשר להריץ - לערוך, להריץ ולראות את הפלט מיד.

media query בדוגמה אחת

media query עוטפת CSS בתנאי. הכללים שבתוך @media (min-width: 600px) חלים רק כל עוד רוחב ה-viewport הוא לפחות 600px:

התצוגה המקדימה היא מסגרת, ו-media query בתוכה מודדת את המסגרת, לא את המסך שלכם. במחשב שולחני היא רחבה בערך כמו עמודת המאמר הזאת, בדרך כלל יותר מ-600px, ולכן הקופסה כחולה. צמצמו את חלון הדפדפן עד שהמסגרת יורדת מתחת ל-600px והיא הופכת לענברית; השורה שמתחת לקופסה מדווחת את רוחב המסגרת בזמן אמת. בטלפון המסגרת כבר צרה, ולכן תראו את הגרסה הענברית.

התחביר של @media

@media (min-width: 600px) { ... }                        /* one condition */
@media (min-width: 600px) and (max-width: 899px) { ... } /* both must be true */
@media (max-width: 599px), print { ... }                 /* either one (comma = or) */
@media not print { ... }                                 /* negation */
@media screen and (orientation: landscape) { ... }       /* media type plus a feature */
@media (width >= 600px) { ... }                          /* range syntax */
@media (600px <= width < 900px) { ... }                  /* a range with both ends */

and צריך רווח משני הצדדים: (min-width: 600px)and(max-width: 900px) לא תקין וכל ה-query נזנחת. תחביר הטווחים (width >= 600px) נתמך בגרסאות הנוכחיות של Chrome, Firefox ו-Safari, וקריא יותר מ-min-width, במיוחד עבור "עד, אבל לא כולל".

התכונות שתשתמשו בהן הכי הרבה:

תכונהתואמת כאשרדוגמה
min-width / width >=ה-viewport רחב לפחות כמו הערך(min-width: 768px)
max-width / width <=ה-viewport רחב לכל היותר כמו הערך(max-width: 767px)
orientationportrait (גבוה מרחב) או landscape(orientation: landscape)
hoverהסמן הראשי יכול לרחף (hover) או לא (none, רוב מסכי המגע)(hover: hover)
pointerהסמן הראשי הוא fine (עכבר) או coarse (אצבע)(pointer: coarse)
prefers-color-schemeהמשתמש בחר ערכת נושא dark או light(prefers-color-scheme: dark)
prefers-reduced-motionהמשתמש ביקש מהמערכת פחות תנועה(prefers-reduced-motion: reduce)
print (סוג מדיה)הדף מודפס או נשמר כ-PDF@media print

Mobile first: נקודות שבירה עם min-width

כתבו את פריסת הטלפון כ-CSS הבסיסי, ואז הוסיפו queries עם min-width שמשנות את הפריסה ככל שיש יותר מקום. כל query צריכה לתאר רק את מה שמשתנה:

בחלון רחב של מחשב שולחני התצוגה המקדימה רחבה מ-720px, ולכן תראו שלוש עמודות; השורה שמתחת לרשת מדווחת את הרוחב ואת מספר העמודות. צמצמו את החלון והיא יורדת לשתיים מתחת ל-720px ולאחת מתחת ל-480px. הסדר של שתי ה-queries חשוב: שתיהן מתקיימות במסך רחב, והמאוחרת מנצחת, ולכן queries עם min-width הולכות מהקטנה לגדולה. (עם queries של max-width זה הפוך: הגדולה קודם.)

בחירת נקודות שבירה

אין רשימה רשמית. אלה ערכים נפוצים ומה שהם מפרידים בדרך כלל:

נקודת שבירהבדרך כלל
min-width: 640pxטלפונים גדולים לרוחב, טאבלטים קטנים
min-width: 768pxטאבלטים לאורך
min-width: 1024pxטאבלטים לרוחב, מחשבים ניידים קטנים
min-width: 1280pxמחשבים שולחניים

שיטה טובה יותר: התחילו מהפריסה הצרה, הרחיבו את החלון עד שמשהו נראה לא טוב (שורות ארוכות מדי, כרטיסים רחבים מדי), ושימו שם נקודת שבירה. שתיים או שלוש נקודות שבירה מספיקות לרוב הדפים. לעתים קרובות לא צריך אף אחת: repeat(auto-fit, minmax(200px, 1fr)) ב-grid, flex-wrap ו-clamp() מתאימים את עצמם באופן רציף.

כל דף צריך את תגית ה-meta של viewport

בלי התגית הזאת בתוך <head>, דפדפנים בטלפון פורסים את הדף כאילו רוחב המסך הוא בערך 980px ואז מקטינים את התצוגה, כך שה-query של min-width: 480px תמיד מתקיימת ופריסת הטלפון שלכם אף פעם לא מוצגת:

<meta name="viewport" content="width=device-width, initial-scale=1">

הדף על meta viewport מסביר כל ערך בה.

מצב כהה עם prefers-color-scheme

prefers-color-scheme עוקבת אחרי ההגדרה הבהירה או הכהה של מערכת ההפעלה. הדרך הנקייה ביותר להשתמש בה היא לשמור את הצבעים במשתני CSS ולשנות רק את המשתנים בתוך ה-query:

בתצוגה המקדימה הזאת ה-query יכולה להדפיס false גם כשהמערכת שלכם מוגדרת למצב כהה: Chrome לא מעביר את הגדרת המערכת למסגרת sandbox כמו זו. הכפתור מגדיר את אותם משתנים ידנית, וכך עובד מתג ערכת הנושא של אתר. :root[data-theme] ספציפי יותר מה-:root הפשוט שבתוך ה-query, ולכן הבחירה של הקורא מנצחת את המערכת. שמרו את הדוגמה כקובץ ופתחו אותו כדי לראות את ה-query עוקבת אחרי המערכת שלכם.

הסקריפט מראה את החצי השני של media queries: matchMedia() מריץ את אותה query מ-JavaScript, מחזיר אם היא תואמת עכשיו, ומפעיל אירוע change כשהתשובה משתנה. השתמשו בו כשהתנהגות (ולא רק עיצוב) תלויה במסך, כמו פתיחת תפריט בצורה שונה במכשירי מגע.

תנועה עובדת באותה דרך. עטפו אנימציות גדולות או חוזרות בבדיקה של prefers-reduced-motion, כמו שמוצג בדף על אנימציה.

Container queries: כשהרכיב צריך להחליט

media query מכירה רק את ה-viewport. כרטיס שיושב גם בעמודה ראשית רחבה וגם בסרגל צד צר באותו דף צריך לדעת את המקום שלו במקום זאת. זו container query: סמנו את ההורה עם container-type: inline-size, ואז השתמשו ב-@container עם אותם תנאים.

גררו את הפינה של הקופסה האפורה כדי לשנות את הגודל שלה. הכרטיס מחליף פריסה ב-360px של רוחב הקופסה, בלי קשר לגודל החלון:

ברוחב ההתחלתי של 480px התמונה יושבת לצד הטקסט. גררו את הקופסה לרוחב צר מ-376px (360px של תוכן ועוד 8px של ריפוד בכל צד) והתמונה עוברת מעל הטקסט. container queries עובדות בכל הדפדפנים הגדולים הנוכחיים.

סגנונות להדפסה

@media print חלה רק כשהדף מודפס או נשמר כ-PDF. הסתירו ניווט וכפתורים, והשתמשו בטקסט כהה על רקע לבן:

@media print {
  nav, .ad, button { display: none; }
  body { color: black; background: white; }
  a::after { content: " (" attr(href) ")"; } /* print the URL after each link */
}

טעויות נפוצות

  • אין תגית meta של viewport. טלפונים מדווחים אז על viewport פריסה רחב, ו-queries של מסכים קטנים אף פעם לא תואמות.
  • queries בסדר הלא נכון. שתי queries מתקיימות עם אותו סלקטור: המאוחרת מנצחת. סדרו queries של min-width מקטנה לגדולה.
  • גבולות חופפים או עם פער. max-width: 768px ו-min-width: 768px תואמות שתיהן ברוחב של 768px בדיוק. השתמשו ב-767px באחת מהן, או בתחביר הטווחים (width < 768px) ו-(width >= 768px).
  • אין רווח אחרי and. and( לא תקין וה-query נזנחת בשקט.
  • בדיקה רק על ידי שינוי גודל של חלון במחשב. בדקו גם בטלפון אמיתי או במצב המכשיר של הדפדפן, שמחיל את ה-viewport, יחס הפיקסלים והמגע של הטלפון.
  • יותר מדי נקודות שבירה. אם כל רכיב צריך נקודה משלו, נסו במקום זאת auto-fit ב-grid, flex-wrap או container queries.

שאלות נפוצות

מה זה media query ב-CSS?

כלל שמחיל את ה-CSS שבתוכו רק כשתנאי לגבי המכשיר או החלון מתקיים. @media (min-width: 600px) { ... } מחיל את הסגנונות שלו רק כשרוחב ה-viewport הוא לפחות 600px, וכך דף אחד מתאים את עצמו מטלפונים ועד מחשבים שולחניים.

האם להשתמש ב-media queries עם min-width או עם max-width?

רוב האתרים נכתבים ב-mobile first: ה-CSS הבסיסי מיועד למסכים קטנים, ו-queries עם min-width מוסיפות פריסה ככל שהמסך גדל. queries עם max-width עובדות בכיוון ההפוך, ומתחילות מפריסת המחשב השולחני. שתי הדרכים עובדות; ערבוב של שתיהן על אותו אלמנט מוביל לחפיפות ולפערים בגבולות.

מהן נקודות השבירה הסטנדרטיות ל-media queries?

אין תקן רשמי. בחירות נפוצות הן בסביבות 640px, 768px, 1024px ו-1280px, אבל הכלל הטוב יותר הוא להוסיף נקודת שבירה במקום שבו הפריסה שלכם מתחילה להיראות לא טוב, ולשמור על מספר קטן של נקודות שבירה.

למה ה-media query שלי לא עובדת בטלפון?

הסיבה הנפוצה ביותר היא תגית meta של viewport שחסרה. בלי <meta name="viewport" content="width=device-width, initial-scale=1">, דפדפנים בנייד מעמידים פנים שרוחב הדף הוא בערך 980px, כך ש-queries של רוחב קטן אף פעם לא תואמות. בדקו גם שה-query מופיעה אחרי הכללים שהיא דורסת.

איך כותבים media query למצב כהה?

השתמשו ב-@media (prefers-color-scheme: dark) { ... }. היא תואמת כשמערכת ההפעלה או הדפדפן של המשתמש מוגדרים לערכת נושא כהה, ואפשר לדרוס בתוכה צבעים או משתני CSS.

מה ההבדל בין media queries ל-container queries?

media query בודקת את ה-viewport (כל החלון). container query, שנכתבת עם @container, בודקת את הגודל של אלמנט הורה שמסמנים עם container-type: inline-size. השתמשו ב-container queries לרכיב שמופיע גם במקומות רחבים וגם במקומות צרים באותו דף.

איור של שפות התכנות ב-Coddy

ללמוד תכנות עם Coddy

להתחיל