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
- Inspect grid container
- Click Grid badge di Elements panel
- Enable grid overlay untuk melihat lines
- 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
- CSS Grid Generator - cssgrid-generator.netlify.app
- Grid Garden - cssgridgarden.com (game belajar)
- Firefox Grid Inspector - terbaik untuk debug grid
- Chrome DevTools - grid overlay yang baik
Latihan Praktis
Coba buat:
- Dashboard layout dengan header, sidebar, main, dan widgets
- Magazine layout dengan asymmetric design
- Photo gallery dengan varying image sizes
- Card grid yang responsive tanpa media queries
- 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!