Styling di Next.js
Bikin aplikasi Next.js-mu tampil memukau! Pelajari berbagai pendekatan untuk styling, mulai dari CSS global, CSS Modules untuk scope lokal, hingga integrasi dengan utility-first framework seperti Tailwind CSS.
Dandanan Canggih buat Aplikasi Next.js: Dari Global CSS Sampe Tailwind!
Udah berhasil ngebangun fungsionalitas dasar Toko Kue Online kita pake Next.js, React, dan TypeScript? Keren! Tapi, aplikasi web yang bagus itu gak cuma soal fungsionalitas, tapi juga soal tampilan (styling) yang enak diliat dan profesional.
Next.js itu fleksibel banget soal styling. Kamu bisa pake berbagai macam pendekatan, dari yang paling klasik sampe yang paling modern. Di bagian ini, kita bakal ngintip beberapa cara populer buat ngasih style ke aplikasi Next.js-mu.
1. Global CSS - Fondasi Gaya Seluruh Aplikasi
Sama kayak di proyek web biasa, kamu bisa punya file CSS global yang isinya style-style dasar yang berlaku buat seluruh aplikasimu (misalnya, reset CSS, style buat body
, tipografi default, dll.).
- Cara Kerja di App Router:
- Secara konvensi, file CSS global ini biasanya ditaruh di
src/app/globals.css
(kalau kamu pake foldersrc/
). - File ini WAJIB diimpor di Root Layout (
src/app/layout.tsx
) biar bisa diterapin ke semua halaman. Next.js ngasih warning kalau kamu coba impor file CSS global di tempat lain selain Root Layout.tsx // src/app/layout.tsx import './globals.css'; // Impor CSS globalmu di sini! // ... (kode layout lainnya) ... export default function RootLayout({ children }: { children: React.ReactNode }) { return ( <html lang="id"> <body> {/* ... Header, Navbar ... */} {children} {/* ... Footer ... */} </body> </html> ); }
- Secara konvensi, file CSS global ini biasanya ditaruh di
- Isi
globals.css
:- Bisa berisi style reset dasar.
- Style buat elemen HTML umum (
body
,h1
-h6
,p
,a
). - Variabel CSS Custom Properties global (
:root { --warna-utama: blue; }
). - Kalau kamu pake Tailwind CSS (yang akan kita bahas), file ini juga jadi tempat kamu menyimpan directive
@tailwind base; @tailwind components; @tailwind utilities;
.
Contoh src/app/globals.css
(tanpa Tailwind):
/* src/app/globals.css */
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
line-height: 1.6;
background-color: #f4f6f8;
color: #333;
}
a {
color: #0070f3;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
* {
box-sizing: border-box;
}
2. CSS Modules - Styling Lokal Anti Bentrok buat Tiap Komponen!
Kalau kamu mau bikin style yang cuma berlaku buat satu komponen spesifik dan gak bakal "bocor" atau bentrok sama style komponen lain, CSS Modules adalah solusi yang elegan dan udah didukung secara default sama Next.js.
- Cara Kerja:
- Bikin file CSS dengan akhiran
.module.css
(misalnya,Tombol.module.css
,Kartu.module.css
). Simpen file ini di deket file komponennya (misal, di folder komponen yang sama). - Tulis class CSS biasa di dalam file
.module.css
itu (misal,.tombol
,.judulKartu
). - Impor file
.module.css
itu ke file komponen.tsx
-mu. Impornya bakal jadi objek JavaScript. - Pake nama class-nya lewat objek itu di atribut
className
JSX-mu (misal,styles.tombol
,styles.judulKartu
).
- Next.js (lewat build tool-nya) bakal otomatis ngubah nama class-mu jadi unik secara global di belakang layar pas proses build (misal,
.tombol
bisa jadiTombol_tombol__a1b2c
). Ini yang ngejaga style-nya tetep lokal.
- Bikin file CSS dengan akhiran
Contoh Penggunaan CSS Modules:
File src/app/components/TombolUnik.module.css
:
/* Nama class .container dan .tombol ini cuma lokal buat modul ini */
.container {
padding: 1rem;
background-color: #e0e0e0;
}
.tombol {
background-color: rebeccapurple;
color: white;
padding: 0.5em 1em;
border: none;
border-radius: 4px;
cursor: pointer;
}
.tombol:hover {
background-color: darkorchid;
}
File src/app/components/TombolUnik.tsx
:
// src/app/components/TombolUnik.tsx
"use client"; // Jika tombol ini punya event handler
import React from 'react';
import styles from './TombolUnik.module.css'; // Impor CSS Module sebagai objek 'styles'
interface TombolUnikProps {
children: React.ReactNode;
onClick?: () => void;
}
export default function TombolUnik({ children, onClick }: TombolUnikProps) {
return (
<div className={styles.container}> {/* Pake styles.container */}
<button className={styles.tombol} onClick={onClick}> {/* Pake styles.tombol */}
{children}
</button>
</div>
);
}
Kalau kamu inspect elemen tombol ini di browser, class-nya bakal punya nama yang udah di-hash, misalnya TombolUnik_tombol__XyZ123
.
Kelebihan CSS Modules:
- Scoped Locally: Gak ada lagi takut nama class bentrok!
- CSS Biasa: Kamu tetep nulis sintaks CSS standar.
- Komposisi Class: Kamu bisa gabungin beberapa class dari modul yang sama atau modul lain.
3. Tailwind CSS - Utility-First Styling (Pilihan Populer!)
Seperti yang udah kita bahas di panduan Tailwind CSS sebelumnya, Tailwind CSS sangat cocok dan terintegrasi baik dengan Next.js. Kalau kamu milih pake Tailwind pas create-next-app
, konfigurasinya udah otomatis disiapin.
-
Cara Kerja:
- Pastikan Tailwind udah ke-setup di proyekmu (file
tailwind.config.ts
atau.js
, danpostcss.config.js
udah ada, danglobals.css
udah ngimpor layer Tailwind). - Kamu tinggal ngerangkai utility class Tailwind langsung di atribut
className
elemen JSX-mu.
- Pastikan Tailwind udah ke-setup di proyekmu (file
-
Contoh (diambil dari Studi Kasus Toko Kue kita):
tsx // src/app/components/kartu-kue.tsx // ... (import) ... export default function KartuKue({ kue }: KartuKueProps) { return ( <Link href={`/kue/${kue.id}`} className="block group border border-gray-200 rounded-lg shadow-sm hover:shadow-lg transition-shadow duration-300 bg-white overflow-hidden"> <div className="relative w-full h-48"> <Image src={kue.gambarUrl} alt={kue.nama} fill style={{ objectFit: 'cover' }} sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw" /> </div> <div className="p-4"> <h3 className="text-lg font-semibold text-gray-800 group-hover:text-pink-600 transition-colors"> {kue.nama} </h3> {/* ... sisa JSX dengan utility Tailwind ... */} </div> </Link> ); }
-
Kelebihan dan Kekurangan: Sama kayak yang udah kita bahas di panduan Tailwind. Intinya, development cepet, desain konsisten, tapi HTML bisa jadi "rame".
4. CSS-in-JS (Styled Components, Emotion) - Styling Dinamis di JavaScript
Pendekatan ini ngebolehin kamu nulis style CSS langsung di dalam file JavaScript/TypeScript komponenmu pake bantuan library.
-
Cara Kerja (Konsep Umum): Library CSS-in-JS (kayak Styled Components atau Emotion) nyediain cara buat bikin komponen React yang udah "nempel" sama style-nya, seringkali pake template literal JavaScript.
-
Setup di Next.js App Router: Karena banyak library CSS-in-JS butuh akses ke "runtime" CSS di sisi klien, dan App Router defaultnya Server Components, penggunaannya butuh sedikit perhatian ekstra.
- Komponen yang pake CSS-in-JS harus jadi Client Component (ditandain
"use client";
). - Kamu mungkin perlu ngesetup "Style Registry" biar style-nya bisa di-extract dan dikirim dengan bener pas Server-Side Rendering (SSR). Ini agak advance, jadi selalu cek dokumentasi resmi Next.js dan library CSS-in-JS pilihanmu buat cara setup yang bener di App Router.
- Komponen yang pake CSS-in-JS harus jadi Client Component (ditandain
-
Contoh Konseptual (pake Styled Components, asumsi setup udah bener):
tsx // src/app/components/TombolStyled.tsx "use client"; // Harus client component import React from 'react'; import styled from 'styled-components'; interface TombolGayaProps { $primer?: boolean; // Pake $ buat nandain ini prop buat styling, bukan prop HTML asli } const StyledButton = styled.button<TombolGayaProps>` background-color: ${props => (props.$primer ? 'dodgerblue' : 'lightgray')}; color: ${props => (props.$primer ? 'white' : 'black')}; padding: 10px 20px; border-radius: 5px; border: none; cursor: pointer; font-weight: bold; &:hover { opacity: 0.8; } `; export default function TombolStyled({ primer, children }: TombolGayaProps & { children: React.ReactNode }) { return <StyledButton $primer={primer}>{children}</StyledButton>; } // Cara pake: // <TombolStyled primer>Tombol Primer</TombolStyled> // <TombolStyled>Tombol Biasa</TombolStyled>
-
Kelebihan: Style scoped otomatis, gampang bikin style dinamis berdasarkan props/state.
-
Kekurangan: Bisa nambahin runtime overhead, butuh library tambahan, setup di Next.js App Router mungkin perlu langkah ekstra.
5. Inline Styles (Atribut style
di JSX) - Buat Kasus Super Spesifik
Kita udah singgung ini di React dasar. Kamu bisa ngasih style inline langsung ke elemen JSX pake atribut style
.
- Cara Kerja: Atribut
style
nerima objek JavaScript, bukan string CSS. Properti CSS-nya pake camelCase.tsx <div style={{ backgroundColor: 'lightblue', padding: '20px', fontSize: '18px', borderBottomLeftRadius: '10px' // Contoh camelCase }}> Konten dengan style inline. </div>
- Kapan Dipake?
- SANGAT JARANG buat styling utama.
- Mungkin buat style yang bener-bener dinamis banget dan nilainya diitung dari state atau props yang kompleks (misal, posisi absolut elemen yang diitung JavaScript).
- Atau buat override kecil yang sangat spesifik dan cuma berlaku di satu tempat itu aja.
- Kekurangan: Sama kayak inline style di HTML biasa (susah maintain, gak reusable, spesifisitas tinggi, nyampur sama JSX). Hindari sebisa mungkin!
Mana yang Dipilih buat Proyek Next.js-mu?
- Global CSS (
globals.css
): Wajib ada buat style dasar dan reset. - Tailwind CSS: Pilihan yang sangat populer dan powerful, apalagi kalau kamu suka utility-first dan development cepet. Next.js punya integrasi yang bagus. Ini sering jadi pilihan utama banyak developer Next.js modern.
- CSS Modules: Pilihan bagus kalau kamu mau nulis CSS biasa tapi dengan jaminan scope lokal per komponen. Cocok kalau kamu gak terlalu suka "rame"-nya utility class di HTML.
- CSS-in-JS: Bisa jadi pilihan kalau kamu butuh styling yang sangat dinamis dan terintegrasi erat sama logika JavaScript komponen, tapi perhatiin setup dan potensial performanya di Next.js App Router.
- Inline Styles: Hindari kecuali buat kasus yang sangat-sangat spesifik.
Seringkali, orang ngombinasiin beberapa pendekatan. Misalnya, pake Tailwind buat sebagian besar utility dan layout, terus pake CSS Modules buat styling komponen yang sangat kustom dan kompleks.
Yang penting, pilih pendekatan yang paling nyaman buatmu dan timmu, dan yang paling sesuai sama kebutuhan proyek.
Dengan berbagai opsi styling ini, kamu punya banyak cara buat bikin aplikasi Next.js-mu tampil sesuai keinginan. Eksperimenlah dengan berbagai pendekatan ini di proyek Toko Kue kita atau proyek kecil lainnya buat nemuin mana yang paling "klik" sama gaya ngodingmu!