לדלג לתוכן

1.6 גריד פתרון

פתרון תרגול גריד


תרגיל 1 - layout של עיתון

<div class="newspaper">
  <header class="np-header">
    <h1>The Daily Grid</h1>
    <p>March 8, 2026</p>
  </header>

  <aside class="np-sidebar">
    <h3>categories</h3>
    <ul>
      <li>news</li>
      <li>sports</li>
      <li>culture</li>
      <li>technology</li>
    </ul>
  </aside>

  <main class="np-main">
    <article class="article-card">
      <h2>CSS Grid Changes Everything</h2>
      <p>Web developers discover the power of two-dimensional layouts. No more float hacks needed.</p>
    </article>
    <article class="article-card">
      <h2>Flexbox and Grid: Best Friends</h2>
      <p>Experts recommend combining both layout systems for the best results in modern web design.</p>
    </article>
    <article class="article-card">
      <h2>Responsive Design Without Media Queries</h2>
      <p>Using auto-fit and minmax, developers create fully responsive grids with a single line of CSS.</p>
    </article>
  </main>

  <footer class="np-footer">
    <p>All rights reserved 2026</p>
  </footer>
</div>
.newspaper {
  display: grid;
  grid-template-columns: 250px 1fr;
  grid-template-rows: auto 1fr auto;
  grid-template-areas:
    "header  header"
    "sidebar main"
    "footer  footer";
  gap: 15px;
  min-height: 100vh;
  padding: 15px;
}

.np-header {
  grid-area: header;
  background: #2c3e50;
  color: white;
  padding: 20px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.np-sidebar {
  grid-area: sidebar;
  background: #34495e;
  color: white;
  padding: 20px;
}

.np-sidebar ul {
  list-style: none;
  padding: 0;
}

.np-sidebar li {
  padding: 10px 0;
  border-bottom: 1px solid #4a6274;
}

.np-main {
  grid-area: main;
  display: grid;
  gap: 15px;
}

.article-card {
  background: #ecf0f1;
  padding: 20px;
  border-radius: 8px;
}

.np-footer {
  grid-area: footer;
  background: #2c3e50;
  color: white;
  padding: 15px;
  text-align: center;
}
  • ה-container הראשי משתמש ב-grid-template-areas כדי להגדיר את ה-layout
  • ה-header וה-footer משתרעים על כל הרוחב
  • ה-sidebar ברוחב קבוע של 250px, ו-main תופס את שאר המרחב עם 1fr
  • בתוך ה-main יש גריד נוסף לכרטיסי הכתבות

תרגיל 2 - גלריית תמונות רספונסיבית

<div class="gallery">
  <div class="gallery-item">
    <img src="https://picsum.photos/400/300?random=1" alt="photo 1">
    <p>photo 1</p>
  </div>
  <div class="gallery-item">
    <img src="https://picsum.photos/400/300?random=2" alt="photo 2">
    <p>photo 2</p>
  </div>
  <div class="gallery-item">
    <img src="https://picsum.photos/400/300?random=3" alt="photo 3">
    <p>photo 3</p>
  </div>
  <div class="gallery-item">
    <img src="https://picsum.photos/400/300?random=4" alt="photo 4">
    <p>photo 4</p>
  </div>
  <div class="gallery-item">
    <img src="https://picsum.photos/400/300?random=5" alt="photo 5">
    <p>photo 5</p>
  </div>
  <div class="gallery-item">
    <img src="https://picsum.photos/400/300?random=6" alt="photo 6">
    <p>photo 6</p>
  </div>
  <div class="gallery-item">
    <img src="https://picsum.photos/400/300?random=7" alt="photo 7">
    <p>photo 7</p>
  </div>
  <div class="gallery-item">
    <img src="https://picsum.photos/400/300?random=8" alt="photo 8">
    <p>photo 8</p>
  </div>
</div>
.gallery {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 15px;
  padding: 20px;
}

.gallery-item {
  overflow: hidden;
  border-radius: 8px;
  background: #f5f5f5;
}

.gallery-item img {
  width: 100%;
  height: 200px;
  object-fit: cover;
  display: block;
}

.gallery-item p {
  padding: 10px;
  margin: 0;
  text-align: center;
  font-weight: bold;
}
  • repeat(auto-fit, minmax(250px, 1fr)) יוצר את הרספונסיביות - מספר העמודות משתנה אוטומטית
  • object-fit: cover גורם לתמונה למלא את המקום בלי עיוות
  • display: block על התמונה מסיר את הרווח הקטן שנוצר מתחת לתמונות inline

תרגיל 3 - dashboard עם grid-template-areas

<div class="dashboard">
  <header class="dash-header">Dashboard</header>

  <nav class="dash-sidebar">
    <a href="#">home</a>
    <a href="#">analytics</a>
    <a href="#">reports</a>
    <a href="#">settings</a>
  </nav>

  <section class="dash-stats">
    <div class="stat-card">
      <h3>users</h3>
      <p>12,453</p>
    </div>
    <div class="stat-card">
      <h3>revenue</h3>
      <p>$84,200</p>
    </div>
    <div class="stat-card">
      <h3>orders</h3>
      <p>1,893</p>
    </div>
  </section>

  <section class="dash-chart">
    <h3>sales chart</h3>
    <div class="chart-placeholder">chart goes here</div>
  </section>

  <section class="dash-table">
    <h3>recent orders</h3>
    <table>
      <tr><th>ID</th><th>amount</th></tr>
      <tr><td>#001</td><td>$120</td></tr>
      <tr><td>#002</td><td>$85</td></tr>
      <tr><td>#003</td><td>$230</td></tr>
      <tr><td>#004</td><td>$65</td></tr>
    </table>
  </section>
</div>
.dashboard {
  display: grid;
  grid-template-columns: 200px repeat(3, 1fr);
  grid-template-rows: 60px auto 1fr 1fr;
  grid-template-areas:
    "header  header  header  header"
    "sidebar stats   stats   stats"
    "sidebar chart   chart   table"
    "sidebar chart   chart   table";
  gap: 15px;
  min-height: 100vh;
  padding: 15px;
  background: #f0f2f5;
}

.dash-header {
  grid-area: header;
  background: #1a1a2e;
  color: white;
  display: flex;
  align-items: center;
  padding: 0 20px;
  border-radius: 8px;
  font-size: 1.3rem;
  font-weight: bold;
}

.dash-sidebar {
  grid-area: sidebar;
  background: #16213e;
  color: white;
  border-radius: 8px;
  padding: 20px 0;
  display: flex;
  flex-direction: column;
}

.dash-sidebar a {
  color: white;
  text-decoration: none;
  padding: 12px 20px;
}

.dash-sidebar a:hover {
  background: #1a1a2e;
}

.dash-stats {
  grid-area: stats;
  display: flex;
  gap: 15px;
}

.stat-card {
  flex: 1;
  background: white;
  border-radius: 8px;
  padding: 20px;
  text-align: center;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.stat-card h3 {
  margin: 0 0 10px;
  color: #666;
  font-size: 0.9rem;
  text-transform: uppercase;
}

.stat-card p {
  margin: 0;
  font-size: 2rem;
  font-weight: bold;
  color: #1a1a2e;
}

.dash-chart {
  grid-area: chart;
  background: white;
  border-radius: 8px;
  padding: 20px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.chart-placeholder {
  background: #f0f2f5;
  height: 100%;
  min-height: 200px;
  border-radius: 8px;
  display: grid;
  place-items: center;
  color: #999;
  font-size: 1.2rem;
}

.dash-table {
  grid-area: table;
  background: white;
  border-radius: 8px;
  padding: 20px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.dash-table table {
  width: 100%;
  border-collapse: collapse;
}

.dash-table th,
.dash-table td {
  padding: 8px;
  text-align: left;
  border-bottom: 1px solid #eee;
}
  • ה-layout מוגדר באמצעות grid-template-areas - ברור ומאוד קריא
  • בתוך ה-stats משתמשים בפלקסבוקס כדי לסדר את כרטיסי הסטטיסטיקה בשורה
  • ה-sidebar משתמש בפלקסבוקס עם flex-direction: column לניווט אנכי
  • שילוב של גריד (layout ראשי) עם פלקסבוקס (רכיבים פנימיים)

תרגיל 4 - גריד רספונסיבי עם media queries

<div class="products">
  <div class="product-card">
    <img src="https://picsum.photos/300/200?random=1" alt="product">
    <h3>product 1</h3>
    <p>Short product description goes here.</p>
    <span class="price">$29.99</span>
    <button>add to cart</button>
  </div>
  <!-- repeat for products 2-6 -->
  <div class="product-card">
    <img src="https://picsum.photos/300/200?random=2" alt="product">
    <h3>product 2</h3>
    <p>Short product description goes here.</p>
    <span class="price">$49.99</span>
    <button>add to cart</button>
  </div>
  <div class="product-card">
    <img src="https://picsum.photos/300/200?random=3" alt="product">
    <h3>product 3</h3>
    <p>Short product description goes here.</p>
    <span class="price">$19.99</span>
    <button>add to cart</button>
  </div>
  <div class="product-card">
    <img src="https://picsum.photos/300/200?random=4" alt="product">
    <h3>product 4</h3>
    <p>Short product description goes here.</p>
    <span class="price">$39.99</span>
    <button>add to cart</button>
  </div>
  <div class="product-card">
    <img src="https://picsum.photos/300/200?random=5" alt="product">
    <h3>product 5</h3>
    <p>Short product description goes here.</p>
    <span class="price">$59.99</span>
    <button>add to cart</button>
  </div>
  <div class="product-card">
    <img src="https://picsum.photos/300/200?random=6" alt="product">
    <h3>product 6</h3>
    <p>Short product description goes here.</p>
    <span class="price">$24.99</span>
    <button>add to cart</button>
  </div>
</div>
.products {
  display: grid;
  grid-template-columns: 1fr;
  gap: 20px;
  padding: 20px;
  max-width: 1200px;
  margin: 0 auto;
}

@media (min-width: 600px) {
  .products {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (min-width: 1024px) {
  .products {
    grid-template-columns: repeat(3, 1fr);
  }
}

.product-card {
  background: white;
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  display: flex;
  flex-direction: column;
}

.product-card img {
  width: 100%;
  height: 200px;
  object-fit: cover;
}

.product-card h3 {
  margin: 15px 15px 5px;
}

.product-card p {
  margin: 0 15px;
  color: #666;
  flex-grow: 1;
}

.product-card .price {
  margin: 10px 15px;
  font-size: 1.4rem;
  font-weight: bold;
  color: #e74c3c;
}

.product-card button {
  margin: 0 15px 15px;
  padding: 10px;
  background: #3498db;
  color: white;
  border: none;
  border-radius: 8px;
  cursor: pointer;
  font-size: 1rem;
}

.product-card button:hover {
  background: #2980b9;
}
  • גישת mobile-first: מתחילים עם עמודה אחת, ומוסיפים עמודות עם media queries
  • בתוך כל כרטיס משתמשים בפלקסבוקס אנכי - flex-grow: 1 על הפסקה דוחף את המחיר והכפתור לתחתית
  • max-width ו-margin: 0 auto ממרכזים את הגריד בעמודים רחבים

תרגיל 5 - פריטים שמשתרעים על כמה תאים

<div class="span-grid">
  <div class="span-item item-1">1</div>
  <div class="span-item item-2">2</div>
  <div class="span-item item-3">3</div>
  <div class="span-item item-4">4</div>
  <div class="span-item item-5">5</div>
  <div class="span-item item-6">6</div>
  <div class="span-item item-7">7</div>
  <div class="span-item item-8">8</div>
</div>
.span-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-auto-rows: minmax(150px, auto);
  gap: 10px;
  padding: 20px;
}

.span-item {
  display: grid;
  place-items: center;
  font-size: 2rem;
  font-weight: bold;
  color: white;
  border-radius: 8px;
}

.item-1 { background: #e74c3c; grid-column: span 2; }
.item-2 { background: #3498db; }
.item-3 { background: #2ecc71; }
.item-4 { background: #f39c12; grid-row: span 2; }
.item-5 { background: #9b59b6; }
.item-6 { background: #1abc9c; grid-column: span 2; grid-row: span 2; }
.item-7 { background: #e67e22; }
.item-8 { background: #34495e; }
  • grid-column: span 2 גורם לפריט לתפוס 2 עמודות
  • grid-row: span 2 גורם לפריט לתפוס 2 שורות
  • אפשר לשלב את שניהם על אותו פריט
  • grid-auto-rows: minmax(150px, auto) מבטיח גובה מינימלי אבל מאפשר צמיחה לפי תוכן

תרגיל 6 - תשובות לשאלות תיאורטיות

1. ההבדל בין auto-fit ל-auto-fill:
שניהם יוצרים עמודות באופן אוטומטי. ההבדל מתגלה כשיש פחות אלמנטים ממה שנכנס למרחב.
- auto-fit מכווץ את העמודות הריקות ל-0 ומותח את הקיימות
- auto-fill שומר עמודות ריקות במרחב

דוגמה: אם יש מרחב ל-4 עמודות אבל רק 2 פריטים, עם auto-fit שני הפריטים יתרחבו למלא הכל. עם auto-fill יהיו 4 עמודות (2 עם תוכן, 2 ריקות).

2. מתי Grid ומתי Flexbox:
- גריד: layout של עמוד שלם, גלריית תמונות, dashboard, טבלת מחירים, כל דבר דו-מימדי
- פלקסבוקס: תפריט ניווט, שורת כפתורים, סידור תוכן בתוך כרטיס, מרכוז אלמנט בודד, כל דבר חד-מימדי

3. justify-items מול justify-content:
- justify-items - מיישר כל פריט בתוך התא שלו (ציר אופקי)
- justify-content - מיישר את הגריד כולו בתוך המיכל (כשלגריד יש רוחב קבוע קטן מהמיכל)

4. מה זה implicit grid:
כשיש יותר פריטים ממה שמוגדר ב-grid-template, הגריד יוצר שורות או עמודות חדשות אוטומטית. אפשר לשלוט על גודלן עם grid-auto-rows ו-grid-auto-columns.

5. מרכוז עם גריד:

.center {
  display: grid;
  place-items: center;
  min-height: 100vh;
}