1.7 עיצוב רספונסיבי הרצאה
מה זה עיצוב רספונסיבי - Responsive Design¶
עיצוב רספונסיבי הוא גישה שבה האתר מתאים את עצמו לכל גודל מסך - טלפון, טאבלט, מחשב נייד, ומסך גדול.
למה זה חשוב? כי היום יותר מ-60% מהתנועה באינטרנט מגיעה ממכשירים ניידים. אם האתר שלכם לא נראה טוב בטלפון - איבדתם את רוב הקהל.
בנוסף, גוגל מדרג אתרים לפי הביצועים שלהם בנייד (mobile-first indexing). אתר לא רספונסיבי פשוט לא יופיע בתוצאות חיפוש גבוהות.
תגית viewport¶
כשפותחים אתר בטלפון בלי תגית viewport, הדפדפן מנסה להציג את האתר כאילו הוא מסך רחב ומקטין הכל - מה שגורם לטקסט זעיר שלא ניתן לקרוא.
התגית הזו צריכה להיות בכל עמוד HTML:
מה היא עושה:
- width=device-width - רוחב העמוד יהיה לפי רוחב המכשיר האמיתי
- initial-scale=1.0 - מונע זום אוטומטי
בלי התגית הזו, כל ה-CSS הרספונסיבי שנכתוב פשוט לא יעבוד כמו שצריך במובייל.
גישת Mobile-First מול Desktop-First¶
יש שתי גישות לכתיבת CSS רספונסיבי:
גישת Desktop-First¶
כותבים את ה-CSS לדסקטופ קודם, ואז משתמשים ב-max-width כדי להתאים למסכים קטנים:
/* default: desktop styles */
.container {
display: grid;
grid-template-columns: repeat(3, 1fr);
}
/* tablet and below */
@media (max-width: 768px) {
.container {
grid-template-columns: repeat(2, 1fr);
}
}
/* mobile */
@media (max-width: 480px) {
.container {
grid-template-columns: 1fr;
}
}
גישת Mobile-First (מומלצת)¶
כותבים את ה-CSS למובייל קודם, ואז משתמשים ב-min-width כדי להוסיף סגנונות למסכים גדולים:
/* default: mobile styles */
.container {
display: grid;
grid-template-columns: 1fr;
}
/* tablet and above */
@media (min-width: 768px) {
.container {
grid-template-columns: repeat(2, 1fr);
}
}
/* desktop */
@media (min-width: 1024px) {
.container {
grid-template-columns: repeat(3, 1fr);
}
}
למה mobile-first עדיפה?
- מובייל הוא המקרה הפשוט ביותר (עמודה אחת, פחות מרכיבים מורכבים)
- קל יותר להוסיף מורכבות מאשר לגרוע אותה
- מתאים לאיך שגוגל מדרג אתרים
- מאלץ אותנו לחשוב על מה באמת חשוב באתר
שאילתות מדיה - Media Queries¶
שאילתות מדיה מאפשרות להחיל CSS שונה בהתאם לתנאים - בדרך כלל רוחב המסך.
תחביר בסיסי¶
@media (min-width: 768px) {
/* styles applied when screen is 768px or wider */
.sidebar {
display: block;
}
}
שילוב תנאים¶
/* between 600px and 1024px */
@media (min-width: 600px) and (max-width: 1024px) {
.container {
padding: 20px;
}
}
/* portrait orientation */
@media (orientation: portrait) {
.hero {
height: 50vh;
}
}
נקודות שבירה נפוצות - breakpoints¶
אין "נקודות שבירה נכונות" אוניברסליות, אבל הנה ערכים נפוצים:
/* mobile (small) */
/* up to 599px - default mobile-first styles, no media query needed */
/* tablet */
@media (min-width: 600px) { }
/* laptop */
@media (min-width: 768px) { }
/* desktop */
@media (min-width: 1024px) { }
/* large desktop */
@media (min-width: 1440px) { }
הטיפ הכי חשוב: אל תבחרו breakpoints לפי מכשירים ספציפיים. בחרו breakpoints לפי איפה ה-layout שלכם "נשבר" - כלומר איפה העיצוב מפסיק להיראות טוב.
שילוב media queries עם פלקסבוקס וגריד¶
דוגמה עם פלקסבוקס¶
.nav {
display: flex;
flex-direction: column;
gap: 10px;
}
@media (min-width: 768px) {
.nav {
flex-direction: row;
justify-content: space-between;
}
}
במובייל - תפריט אנכי. בדסקטופ - תפריט אופקי.
דוגמה עם גריד¶
.page {
display: grid;
grid-template-columns: 1fr;
grid-template-areas:
"header"
"main"
"sidebar"
"footer";
}
@media (min-width: 768px) {
.page {
grid-template-columns: 250px 1fr;
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
}
}
ה-layout כולו משתנה - במובייל הכל בעמודה אחת, בדסקטופ sidebar + main.
תמונות רספונסיביות¶
תמונות צריכות טיפול מיוחד כדי להיראות טוב בכל מסך.
הבסיס - max-width¶
זה הכלל הכי חשוב - התמונה לא תהיה רחבה יותר מהמיכל שלה, ותשמור על היחס.
תגית picture - תמונות שונות לגדלים שונים¶
<picture>
<source media="(min-width: 1024px)" srcset="hero-large.jpg">
<source media="(min-width: 600px)" srcset="hero-medium.jpg">
<img src="hero-small.jpg" alt="hero image">
</picture>
הדפדפן יטען את התמונה המתאימה לגודל המסך - מה שחוסך bandwidth במובייל.
תכונת srcset¶
<img
src="photo-400.jpg"
srcset="photo-400.jpg 400w, photo-800.jpg 800w, photo-1200.jpg 1200w"
sizes="(min-width: 1024px) 33vw, (min-width: 600px) 50vw, 100vw"
alt="responsive photo"
>
srcset- רשימת תמונות עם הרוחב שלהןsizes- אומר לדפדפן מה יהיה רוחב התמונה בתצוגה- הדפדפן בוחר אוטומטית את התמונה הכי מתאימה
טיפוגרפיה רספונסיבית¶
הבעיה¶
גודל פונט קבוע לא עובד בכל המסכים. כותרת של 48px מושלמת בדסקטופ אבל עצומה בטלפון.
הפתרון הישן - media queries¶
h1 {
font-size: 24px;
}
@media (min-width: 768px) {
h1 {
font-size: 36px;
}
}
@media (min-width: 1024px) {
h1 {
font-size: 48px;
}
}
הפתרון המודרני - clamp¶
clamp(minimum, preferred, maximum) - הפונט יגדל ויקטן בצורה חלקה:
- לא יהיה קטן מ-1.5rem (24px)
- ינסה להיות 4vw (4% מרוחב המסך)
- לא יהיה גדול מ-3rem (48px)
שורה אחת של CSS במקום 3 media queries, והתוצאה חלקה יותר.
מערכת טיפוגרפיה רספונסיבית שלמה¶
:root {
--text-xs: clamp(0.75rem, 1.5vw, 0.875rem);
--text-sm: clamp(0.875rem, 1.8vw, 1rem);
--text-base: clamp(1rem, 2vw, 1.125rem);
--text-lg: clamp(1.125rem, 2.5vw, 1.5rem);
--text-xl: clamp(1.5rem, 3vw, 2rem);
--text-2xl: clamp(1.75rem, 4vw, 2.5rem);
--text-3xl: clamp(2rem, 5vw, 3.5rem);
}
h1 { font-size: var(--text-3xl); }
h2 { font-size: var(--text-2xl); }
h3 { font-size: var(--text-xl); }
p { font-size: var(--text-base); }
שאילתות מיכל - Container Queries¶
Container queries הם פיצ'ר חדש יחסית שמאפשר לעצב רכיב לפי גודל המיכל שלו, ולא לפי גודל המסך.
.card-container {
container-type: inline-size;
container-name: card;
}
@container card (min-width: 400px) {
.card {
display: flex;
flex-direction: row;
}
}
@container card (max-width: 399px) {
.card {
display: flex;
flex-direction: column;
}
}
למה זה שימושי? כי media queries מסתכלות על גודל המסך כולו. אבל אם יש כרטיס שמופיע גם ב-sidebar צר וגם ב-main רחב - הוא צריך להתנהג אחרת בכל מקום, גם באותו גודל מסך.
container queries פותרות בדיוק את הבעיה הזו - הרכיב מתאים את עצמו לפי הגודל של המיכל שלו.
תבנית תפריט המבורגר - Hamburger Menu¶
בדסקטופ הניווט מוצג אופקית. במובייל, הניווט מוחלף בכפתור (שלושה קווים) שפותח תפריט.
המבנה הבסיסי ב-CSS בלבד (בלי JavaScript):
.nav-links {
display: none;
}
.hamburger {
display: block;
font-size: 1.5rem;
background: none;
border: none;
cursor: pointer;
}
@media (min-width: 768px) {
.nav-links {
display: flex;
gap: 20px;
}
.hamburger {
display: none;
}
}
הכפתור מוצג רק במובייל, והקישורים רק בדסקטופ.
כדי שהכפתור ממש יפתח ויסגור את התפריט - צריך JavaScript (נלמד בהמשך).
אבל אפשר גם לעשות את זה עם טריק של checkbox ב-CSS בלבד:
<nav>
<input type="checkbox" id="menu-toggle" class="menu-checkbox">
<label for="menu-toggle" class="hamburger">☰</label>
<ul class="nav-links">
<li><a href="#">home</a></li>
<li><a href="#">about</a></li>
<li><a href="#">contact</a></li>
</ul>
</nav>
.menu-checkbox {
display: none;
}
.nav-links {
display: none;
flex-direction: column;
gap: 10px;
}
.menu-checkbox:checked ~ .nav-links {
display: flex;
}
@media (min-width: 768px) {
.hamburger {
display: none;
}
.nav-links {
display: flex;
flex-direction: row;
}
}
הטריק: כשלוחצים על ה-label, ה-checkbox נבחר, והסלקטור ~ מפעיל את הצגת התפריט.
טבלאות רספונסיביות¶
טבלאות הן אחד הדברים הקשים ביותר להפוך לרספונסיביים כי הן מעצם טבען רחבות.
אסטרטגיה 1 - גלילה אופקית¶
פשוט עוטפים את הטבלה ב-div עם overflow-x: auto. אם הטבלה רחבה מהמסך, תהיה גלילה אופקית.
אסטרטגיה 2 - שינוי layout¶
@media (max-width: 600px) {
table, thead, tbody, tr, th, td {
display: block;
}
thead {
display: none;
}
td {
padding: 8px;
text-align: right;
}
td::before {
content: attr(data-label);
float: left;
font-weight: bold;
}
}
<tr>
<td data-label="Name">John</td>
<td data-label="Email">john@example.com</td>
<td data-label="Phone">050-1234567</td>
</tr>
במובייל, כל שורה הופכת לכרטיס - כל תא בשורה נפרדת עם label.
תבניות ניווט רספונסיביות¶
ניווט אופקי שנהפך לאנכי¶
.nav {
display: flex;
flex-direction: column;
background: #333;
}
.nav a {
color: white;
padding: 15px 20px;
text-decoration: none;
}
@media (min-width: 768px) {
.nav {
flex-direction: row;
}
.nav a {
padding: 15px 25px;
}
}
ניווט עם לוגו ותפריט¶
.navbar {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
align-items: center;
padding: 10px 20px;
background: #1a1a2e;
}
.logo {
color: white;
font-size: 1.5rem;
font-weight: bold;
}
.nav-links {
display: flex;
gap: 20px;
list-style: none;
margin: 0;
padding: 0;
}
.nav-links a {
color: white;
text-decoration: none;
}
@media (max-width: 768px) {
.nav-links {
flex-basis: 100%;
flex-direction: column;
gap: 10px;
padding-top: 15px;
}
}
בדיקה ב-DevTools Device Mode¶
כלי הפיתוח של הדפדפן מאפשרים לבדוק איך האתר נראה בגדלי מסך שונים.
כדי לפתוח Device Mode:
- לחצו F12 או Ctrl + Shift + I כדי לפתוח את DevTools
- לחצו על אייקון הטלפון/טאבלט (או Ctrl + Shift + M)
- בחרו מכשיר מהרשימה, או גררו את הידיות כדי לשנות גודל
מה שימושי ב-Device Mode:
- בדיקת breakpoints שונים
- סימולציה של מכשירים ספציפיים (iPhone, iPad, Pixel)
- בדיקת touch events
- בדיקת performance בסימולציה של מעבד איטי
טיפ: תמיד בדקו את האתר גם בטלפון אמיתי. הסימולציה של DevTools טובה אבל לא מושלמת.
יחידות CSS לעיצוב רספונסיבי¶
אחוזים - %¶
יחסי לאלמנט ההורה:
יחידות viewport - vw, vh¶
.hero {
height: 100vh; /* full viewport height */
width: 100vw; /* full viewport width */
}
.title {
font-size: 5vw; /* 5% of viewport width */
}
rem¶
יחסי לגודל הפונט של html (ברירת מחדל 16px):
rem מצוין לריווחים ולפונטים - הכל מתנהג באופן עקבי ואפשר לשנות את הגודל הבסיסי ב-media query.
הפונקציה clamp¶
.container {
width: clamp(300px, 80%, 1200px);
/* minimum 300px, prefers 80%, maximum 1200px */
padding: clamp(10px, 3vw, 40px);
/* minimum 10px, prefers 3vw, maximum 40px */
}
clamp() הוא הכלי הכי טוב לרספונסיביות - ערך אחד שמתאים לכל הגדלים.
min ו-max¶
.container {
width: min(90%, 1200px);
/* the smaller of 90% and 1200px */
}
.sidebar {
width: max(200px, 20%);
/* the larger of 200px and 20% */
}
משתני CSS לערכים רספונסיביים¶
אפשר לשלב CSS variables עם media queries ליצירת מערכת רספונסיבית מאורגנת:
:root {
--spacing-sm: 8px;
--spacing-md: 16px;
--spacing-lg: 24px;
--container-width: 100%;
--columns: 1;
}
@media (min-width: 768px) {
:root {
--spacing-sm: 12px;
--spacing-md: 24px;
--spacing-lg: 40px;
--container-width: 750px;
--columns: 2;
}
}
@media (min-width: 1024px) {
:root {
--spacing-lg: 60px;
--container-width: 960px;
--columns: 3;
}
}
.container {
max-width: var(--container-width);
margin: 0 auto;
padding: var(--spacing-md);
}
.grid {
display: grid;
grid-template-columns: repeat(var(--columns), 1fr);
gap: var(--spacing-md);
}
section {
padding: var(--spacing-lg) 0;
}
היתרון: כל הערכים הרספונסיביים מוגדרים במקום אחד. קל לשנות ולתחזק.
סיכום¶
הנקודות החשובות ביותר בעיצוב רספונסיבי:
- תמיד הוסיפו את תגית viewport ב-HTML
- העדיפו גישת mobile-first - כתבו CSS למובייל קודם, והוסיפו min-width media queries
- השתמשו ב-clamp() לטיפוגרפיה ולמרחקים רספונסיביים
- הגדירו max-width: 100% על תמונות
- השתמשו ביחידות יחסיות (%, rem, vw) במקום פיקסלים קבועים
- בדקו את האתר ב-DevTools Device Mode ובמכשירים אמיתיים
- container queries הם הפיצ'ר הבא - מאפשרים לרכיבים להתאים למיכל שלהם
- שלבו CSS variables עם media queries למערכת רספונסיבית מאורגנת