Tutorial css

CSS Grid

CSS Grid adalah sistem layout 2 dimensi yang memberikan kontrol penuh atas rows dan columns. Grid adalah teknologi layout paling powerful dalam CSS untuk membuat layout kompleks dengan mudah.

Mengapa CSS Grid?

Grid menyelesaikan masalah layout yang sulit:

  • Complex layouts seperti magazine atau dashboard
  • Perfect alignment dalam 2 dimensi
  • Responsive grids tanpa framework
  • Overlapping elements dengan mudah
  • Asymmetric layouts yang fleksibel

Grid vs Flexbox

| CSS Grid | CSS Flexbox | | -------------------------- | --------------------------- | | 2 dimensi (rows + columns) | 1 dimensi (row atau column) | | Layout-first | Content-first | | Complex layouts | Simple layouts | | Magazine, dashboard | Navigation, cards |

Konsep Dasar Grid

Grid Container dan Grid Items

<div class="grid-container">
  <div class="grid-item">Item 1</div>
  <div class="grid-item">Item 2</div>
  <div class="grid-item">Item 3</div>
  <div class="grid-item">Item 4</div>
</div>
.grid-container {
  display: grid; /* Aktifkan grid */
}

Grid Lines dan Grid Tracks

Grid Lines (garis pemisah):
    1   2   3   4
1 ┌───┬───┬───┐
  │   │   │   │ ← Grid Tracks (jalur)
2 ├───┼───┼───┤
  │   │   │   │
3 └───┴───┴───┘

Grid Cells (sel individual)
Grid Areas (area gabungan)

Grid Container Properties

Grid Template Columns

.grid-3-columns {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr; /* 3 kolom sama lebar */
}

.grid-mixed {
  grid-template-columns: 200px 1fr 100px; /* Fixed, flex, fixed */
}

.grid-repeat {
  grid-template-columns: repeat(4, 1fr); /* 4 kolom sama lebar */
}

.grid-auto-fit {
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  /* Responsive columns */
}

.grid-auto-fill {
  grid-template-columns: repeat(auto-fill, 200px);
  /* Fill dengan kolom 200px */
}

Grid Template Rows

.grid-rows {
  display: grid;
  grid-template-rows: 100px 200px 100px; /* 3 baris berbeda tinggi */
}

.grid-auto-rows {
  display: grid;
  grid-auto-rows: minmax(100px, auto); /* Minimal 100px */
}

.grid-implicit {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: 200px; /* Baris otomatis */
}

Grid Gap

.grid-gap {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px; /* Gap semua arah */
}

.grid-gap-specific {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  row-gap: 20px; /* Gap vertikal */
  column-gap: 30px; /* Gap horizontal */
}

Grid Template Areas

.layout {
  display: grid;
  grid-template-areas:
    "header header header" "sidebar main aside"
    "footer footer footer";
  grid-template-columns: 200px 1fr 150px;
  grid-template-rows: 80px 1fr 60px;
  gap: 10px;
  min-height: 100vh;
}

.header {
  grid-area: header;
}
.sidebar {
  grid-area: sidebar;
}
.main {
  grid-area: main;
}
.aside {
  grid-area: aside;
}
.footer {
  grid-area: footer;
}

Grid Item Properties

Grid Column

.item-1 {
  grid-column: 1 / 3; /* Dari kolom 1 ke 3 */
}

.item-2 {
  grid-column-start: 2; /* Mulai kolom 2 */
  grid-column-end: 4; /* Sampai kolom 4 */
}

.item-3 {
  grid-column: span 2; /* Span 2 kolom */
}

.item-4 {
  grid-column: 1 / -1; /* Full width */
}

Grid Row

.item-tall {
  grid-row: 1 / 3; /* Dari baris 1 ke 3 */
}

.item-span {
  grid-row: span 2; /* Span 2 baris */
}

.item-full {
  grid-row: 1 / -1; /* Full height */
}

Grid Area

.item-area {
  grid-area: 2 / 1 / 4 / 3; /* row-start / col-start / row-end / col-end */
}

.item-named {
  grid-area: header; /* Menggunakan named area */
}

Alignment dalam Grid

Justify Items (Horizontal)

.grid-justify {
  display: grid;
  justify-items: start; /* start | end | center | stretch */
}

Align Items (Vertical)

.grid-align {
  display: grid;
  align-items: center; /* start | end | center | stretch */
}

Place Items (Shorthand)

.grid-place {
  display: grid;
  place-items: center; /* align-items justify-items */
}

Justify/Align Self

.item-self {
  justify-self: end; /* Item individual horizontal */
  align-self: start; /* Item individual vertical */
  place-self: center; /* Shorthand */
}

Justify/Align Content

.grid-content {
  display: grid;
  justify-content: space-between; /* Seluruh grid horizontal */
  align-content: center; /* Seluruh grid vertical */
  place-content: center; /* Shorthand */
}

Contoh Layout: Dashboard

<div class="dashboard">
  <header class="header">Dashboard</header>
  <nav class="sidebar">Navigation</nav>
  <main class="main">Main Content</main>
  <aside class="widgets">Widgets</aside>
  <footer class="footer">Footer</footer>
</div>
.dashboard {
  display: grid;
  grid-template-areas:
    "header header header" "sidebar main widgets"
    "footer footer footer";
  grid-template-columns: 250px 1fr 300px;
  grid-template-rows: 70px 1fr 50px;
  gap: 15px;
  min-height: 100vh;
  padding: 15px;
  background-color: #f5f5f5;
}

.header {
  grid-area: header;
  background-color: #2c3e50;
  color: white;
  display: flex;
  align-items: center;
  padding: 0 2rem;
  border-radius: 8px;
}

.sidebar {
  grid-area: sidebar;
  background-color: #34495e;
  color: white;
  padding: 1rem;
  border-radius: 8px;
}

.main {
  grid-area: main;
  background-color: white;
  padding: 2rem;
  border-radius: 8px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}

.widgets {
  grid-area: widgets;
  background-color: white;
  padding: 1rem;
  border-radius: 8px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}

.footer {
  grid-area: footer;
  background-color: #95a5a6;
  color: white;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 8px;
}

Contoh Layout: Magazine

<article class="magazine">
  <h1 class="title">Article Title</h1>
  <img class="hero-image" src="hero.jpg" alt="Hero" />
  <p class="intro">Introduction paragraph...</p>
  <div class="content">Main content...</div>
  <aside class="sidebar">Related links...</aside>
  <div class="ads">Advertisement</div>
  <footer class="article-footer">Author info</footer>
</article>
.magazine {
  display: grid;
  grid-template-columns: 1fr 1fr 300px;
  grid-template-rows: auto auto 1fr auto;
  gap: 2rem;
  max-width: 1200px;
  margin: 0 auto;
  padding: 2rem;
}

.title {
  grid-column: 1 / -1; /* Full width */
  font-size: 3rem;
  text-align: center;
  margin-bottom: 0;
}

.hero-image {
  grid-column: 1 / 3; /* Span 2 columns */
  width: 100%;
  height: 400px;
  object-fit: cover;
  border-radius: 8px;
}

.intro {
  grid-column: 1 / 3; /* Span 2 columns */
  font-size: 1.2rem;
  font-weight: 500;
  color: #555;
}

.content {
  grid-column: 1 / 3; /* Main content area */
  line-height: 1.7;
}

.sidebar {
  grid-column: 3; /* Right sidebar */
  grid-row: 3 / 5; /* Span 2 rows */
  background-color: #f8f9fa;
  padding: 1.5rem;
  border-radius: 8px;
}

.ads {
  grid-column: 1 / 3;
  background-color: #e9ecef;
  padding: 2rem;
  text-align: center;
  border-radius: 8px;
}

.article-footer {
  grid-column: 1 / -1; /* Full width */
  background-color: #f1f3f4;
  padding: 1.5rem;
  border-radius: 8px;
}

Responsive Grid

Auto-Fit dan Auto-Fill

.responsive-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 2rem;
}

/* Auto-fit: kolom stretch untuk mengisi ruang */
/* Auto-fill: kolom tetap ukuran minimum */

.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, 250px);
  justify-content: center;
  gap: 1.5rem;
}

Media Queries dengan Grid

.responsive-layout {
  display: grid;
  gap: 1rem;

  /* Mobile: 1 column */
  grid-template-columns: 1fr;
  grid-template-areas: "header" "main" "sidebar" "footer";
}

@media (min-width: 768px) {
  .responsive-layout {
    /* Tablet: 2 columns */
    grid-template-columns: 1fr 300px;
    grid-template-areas: "header header" "main sidebar" "footer footer";
  }
}

@media (min-width: 1024px) {
  .responsive-layout {
    /* Desktop: 3 columns */
    grid-template-columns: 250px 1fr 300px;
    grid-template-areas:
      "header header header" "nav main sidebar"
      "footer footer footer";
  }
}

Grid dengan Flexbox

.hybrid-layout {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 2rem;
}

.card {
  display: flex; /* Flexbox dalam grid item */
  flex-direction: column;
  background: white;
  border-radius: 8px;
  overflow: hidden;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}

.card-header {
  padding: 1.5rem;
  background-color: #f8f9fa;
}

.card-body {
  flex: 1; /* Flexbox: take remaining space */
  padding: 1.5rem;
}

.card-footer {
  padding: 1rem 1.5rem;
  background-color: #f8f9fa;
  border-top: 1px solid #e9ecef;
}

Contoh Advanced: Photo Gallery

<div class="gallery">
  <div class="photo photo-large">
    <img src="photo1.jpg" alt="Photo 1" />
  </div>
  <div class="photo">
    <img src="photo2.jpg" alt="Photo 2" />
  </div>
  <div class="photo">
    <img src="photo3.jpg" alt="Photo 3" />
  </div>
  <div class="photo photo-wide">
    <img src="photo4.jpg" alt="Photo 4" />
  </div>
  <div class="photo">
    <img src="photo5.jpg" alt="Photo 5" />
  </div>
  <div class="photo photo-tall">
    <img src="photo6.jpg" alt="Photo 6" />
  </div>
</div>
.gallery {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  grid-auto-rows: 250px;
  gap: 15px;
  padding: 20px;
}

.photo {
  background-color: #f0f0f0;
  border-radius: 8px;
  overflow: hidden;
  transition: transform 0.3s ease;
}

.photo:hover {
  transform: scale(1.02);
}

.photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.photo-large {
  grid-column: span 2;
  grid-row: span 2;
}

.photo-wide {
  grid-column: span 2;
}

.photo-tall {
  grid-row: span 2;
}

@media (max-width: 768px) {
  .gallery {
    grid-template-columns: 1fr 1fr;
  }

  .photo-large,
  .photo-wide {
    grid-column: span 1;
    grid-row: span 1;
  }

  .photo-tall {
    grid-row: span 1;
  }
}

Overlapping Elements

.overlap-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 200px 200px;
}

.item-1 {
  grid-area: 1 / 1 / 2 / 2; /* Normal position */
  background-color: #3498db;
  z-index: 1;
}

.item-2 {
  grid-area: 1 / 2 / 3 / 3; /* Overlapping */
  background-color: #e74c3c;
  z-index: 2;
  transform: translateX(-50px); /* Offset untuk overlap */
}

.item-3 {
  grid-area: 2 / 1 / 3 / 2;
  background-color: #2ecc71;
  z-index: 3;
}

Debug Grid

Visualisasi Grid Lines

.debug-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 100px);
  gap: 10px;

  /* Debug styling */
  background-color: rgba(255, 0, 0, 0.1);
  position: relative;
}

.debug-grid::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-image: linear-gradient(rgba(0, 0, 0, 0.1) 1px, transparent 1px),
    linear-gradient(90deg, rgba(0, 0, 0, 0.1) 1px, transparent 1px);
  background-size: calc(100% / 3) calc(100% / 3);
  pointer-events: none;
}

Browser DevTools

  1. Inspect grid container
  2. Click Grid badge di Elements panel
  3. Enable grid overlay untuk melihat lines
  4. Use Layout panel untuk kontrol visual

Common Grid Patterns

Holy Grail Layout

.holy-grail {
  display: grid;
  grid-template-areas:
    "header header header" "nav main aside"
    "footer footer footer";
  grid-template-columns: 200px 1fr 150px;
  grid-template-rows: auto 1fr auto;
  min-height: 100vh;
}

Card Grid dengan Equal Heights

.equal-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 2rem;
}

.card {
  display: grid; /* Nested grid */
  grid-template-rows: auto 1fr auto; /* Header, content, footer */
  background: white;
  border-radius: 8px;
  overflow: hidden;
}

Sidebar Layout

.sidebar-layout {
  display: grid;
  grid-template-columns: minmax(250px, 300px) 1fr;
  gap: 2rem;
  min-height: 100vh;
}

@media (max-width: 768px) {
  .sidebar-layout {
    grid-template-columns: 1fr;
    grid-template-rows: auto 1fr;
  }
}

Performance Tips

1. Avoid Complex Grid

/* ❌ Too complex */
.complex-grid {
  grid-template-columns: repeat(12, minmax(0, 1fr));
  grid-template-rows: repeat(20, minmax(50px, auto));
}

/* ✅ Simpler */
.simple-grid {
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  grid-auto-rows: minmax(200px, auto);
}

2. Use Subgrid (When Available)

.parent-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1rem;
}

.child-grid {
  display: grid;
  grid-template-columns: subgrid; /* Inherit parent columns */
  gap: 0.5rem;
}

Grid dengan CSS Custom Properties

:root {
  --grid-columns: 3;
  --grid-gap: 2rem;
  --grid-min-width: 300px;
}

.dynamic-grid {
  display: grid;
  grid-template-columns: repeat(var(--grid-columns), 1fr);
  gap: var(--grid-gap);
}

.responsive-dynamic {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(var(--grid-min-width), 1fr));
  gap: var(--grid-gap);
}

@media (max-width: 768px) {
  :root {
    --grid-columns: 2;
    --grid-gap: 1rem;
    --grid-min-width: 250px;
  }
}

Best Practices

1. Start with Content

/* ✅ Define grid based on content needs */
.content-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 2rem;
}

2. Use Semantic Grid Areas

.semantic-layout {
  grid-template-areas: "header header" "nav main" "footer footer";
}

/* Better than: grid-area: 1 / 1 / 2 / 3; */

3. Progressive Enhancement

.fallback-flex {
  display: flex; /* Fallback */
  flex-wrap: wrap;
}

@supports (display: grid) {
  .fallback-flex {
    display: grid; /* Enhancement */
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  }
}

Tools untuk Grid

  1. CSS Grid Generator - cssgrid-generator.netlify.app
  2. Grid Garden - cssgridgarden.com (game belajar)
  3. Firefox Grid Inspector - terbaik untuk debug grid
  4. Chrome DevTools - grid overlay yang baik

Latihan Praktis

Coba buat:

  1. Dashboard layout dengan header, sidebar, main, dan widgets
  2. Magazine layout dengan asymmetric design
  3. Photo gallery dengan varying image sizes
  4. Card grid yang responsive tanpa media queries
  5. Landing page dengan complex grid layout

Kesimpulan

CSS Grid adalah tool paling powerful untuk layout dalam CSS. Dengan Grid, Anda dapat:

  • Membuat layout kompleks dengan mudah
  • Perfect control atas positioning
  • Responsive design yang natural
  • Clean, semantic code dengan named areas

Grid dan Flexbox bekerja sama - gunakan Grid untuk layout utama dan Flexbox untuk komponen individual!

Selanjutnya kita akan mempelajari Responsive Design - cara membuat website yang sempurna di semua device!