Tutorial: Membuat Halaman Login Modern untuk Pemula (HTML + Tailwind CSS)
Bagi seorang pemula dalam pengembangan web, membuat halaman Login adalah salah satu proyek terbaik untuk memulai. Halaman ini mencakup elemen-elemen fundamental: struktur layout, formulir input, tombol, dan styling agar enak dipandang.
Dalam tutorial ini, kita tidak akan menggunakan CSS konvensional yang panjang. Kita akan menggunakan Tailwind CSS, sebuah framework utility-first yang memungkinkan kita mendesain website dengan sangat cepat langsung di dalam file HTML.
Apa yang Akan Kita Buat?
Kita akan membangun halaman login yang:
-
Responsif: Tampil bagus di HP maupun Laptop.
-
Estetik: Menggunakan shadow, rounded corners, dan warna modern.
-
Interaktif: Memiliki efek hover pada tombol dan fokus pada input.
Langkah 1: Persiapan (Tanpa Instalasi Rumit)
Untuk pemula, cara termudah menggunakan Tailwind adalah lewat CDN. Anda tidak perlu menginstal Node.js atau npm. Cukup tambahkan satu baris script di bagian <head> HTML Anda.
<script src="[https://cdn.tailwindcss.com](https://cdn.tailwindcss.com)"></script>
Langkah 2: Struktur Layout (Centering)
Tantangan pertama biasanya adalah menaruh kotak login tepat di tengah layar. Dengan Tailwind, ini sangat mudah menggunakan Flexbox.
Kita memberikan class pada elemen pembungkus (body atau main div):
-
min-h-screen: Tinggi minimal setara layar penuh. -
flex: Mengaktifkan Flexbox. -
items-center: Menengahkan secara vertikal. -
justify-center: Menengahkan secara horizontal. -
bg-gray-100: Memberikan warna latar belakang abu-abu muda.
Langkah 3: Membuat Kartu Login (The Card)
Di dalam pembungkus tadi, kita buat "kartu" putih tempat form berada.
<div class="bg-white p-8 rounded-lg shadow-lg w-full max-w-md">
<!-- Isi form di sini -->
</div>
-
bg-white: Latar putih. -
p-8: Padding (jarak dalam) yang lega. -
rounded-lg: Sudut yang membulat (modern). -
shadow-lg: Memberikan efek bayangan agar kartu terlihat "melayang". -
w-full max-w-md: Lebar penuh di HP, tapi maksimal lebar medium di layar besar.
Langkah 4: Styling Form Input
Input form standar browser terlihat kaku. Kita akan mempercantiknya.
Untuk input field: w-full px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500
Perhatikan bagian focus:. Ini adalah fitur keren Tailwind. Saat pengguna mengklik input, kita bisa mengubah warna border atau memberikan efek cincin (ring) biru, memberikan indikasi visual yang jelas.
Langkah 5: Tombol (Button) dengan Efek Hover
Tombol login harus menonjol.
w-full bg-blue-600 text-white py-2 rounded-lg hover:bg-blue-700 transition duration-300
-
hover:bg-blue-700: Saat mouse diarahkan ke tombol, warnanya menjadi lebih gelap. -
transition duration-300: Perubahan warna terjadi secara halus (animasi) selama 0.3 detik.
Kesimpulan
Dengan Tailwind CSS, Anda tidak perlu berpindah-pindah antara file HTML dan CSS. Anda bisa melihat struktur dan gaya secara bersamaan. Kode yang dihasilkan mungkin terlihat agak panjang di dalam HTML, namun kecepatan pengembangan yang Anda dapatkan sangatlah berharga.
Kode Lengkap (Siap Copy-Paste)
Berikut adalah kode lengkap dari aplikasi login yang sudah kita bahas, termasuk styling tambahan untuk animasi dan script JavaScript untuk fungsionalitas tombol mata (show password). Anda bisa menyalin seluruh kode ini ke dalam file baru bernama index.html dan membukanya di browser.
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Login Page Modern</title>
<!-- Menggunakan Tailwind CSS via CDN untuk kemudahan penggunaan tanpa instalasi -->
<script src="[https://cdn.tailwindcss.com](https://cdn.tailwindcss.com)"></script>
<style>
/* Animasi kustom untuk notifikasi */
@keyframes slideIn {
from { transform: translateY(-100%); opacity: 0; }
to { transform: translateY(0); opacity: 1; }
}
@keyframes fadeOut {
from { opacity: 1; }
to { opacity: 0; }
}
.notification-enter {
animation: slideIn 0.5s ease-out forwards;
}
.notification-exit {
animation: fadeOut 0.5s ease-out forwards;
}
</style>
</head>
<body class="bg-slate-100 min-h-screen flex items-center justify-center p-4 font-sans text-slate-800">
<!-- Notifikasi Toast (Tersembunyi secara default) -->
<div id="toast" class="fixed top-5 right-5 bg-green-500 text-white px-6 py-3 rounded-lg shadow-xl hidden z-50 flex items-center gap-2">
<svg xmlns="[http://www.w3.org/2000/svg](http://www.w3.org/2000/svg)" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"></path><polyline points="22 4 12 14.01 9 11.01"></polyline></svg>
<span>Login Berhasil! Mengalihkan...</span>
</div>
<!-- Container Utama Kartu Login -->
<div class="bg-white rounded-2xl shadow-xl w-full max-w-md overflow-hidden">
<!-- Header: Logo atau Judul -->
<div class="px-8 pt-8 pb-4 text-center">
<div class="inline-flex items-center justify-center w-12 h-12 rounded-full bg-blue-100 text-blue-600 mb-4">
<svg xmlns="[http://www.w3.org/2000/svg](http://www.w3.org/2000/svg)" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4"></path><polyline points="10 17 15 12 10 7"></polyline><line x1="15" y1="12" x2="3" y2="12"></line></svg>
</div>
<h2 class="text-2xl font-bold text-slate-800">Selamat Datang</h2>
<p class="text-slate-500 text-sm mt-1">Silakan masukkan akun Anda untuk melanjutkan</p>
</div>
<!-- Form Section -->
<form id="loginForm" class="px-8 py-6 space-y-5">
<!-- Input Email -->
<div class="space-y-1">
<label for="email" class="block text-sm font-medium text-slate-700">Email Address</label>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none text-slate-400">
<svg xmlns="[http://www.w3.org/2000/svg](http://www.w3.org/2000/svg)" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="4" width="20" height="16" rx="2"></rect><path d="m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7"></path></svg>
</div>
<input type="email" id="email" required placeholder="nama@email.com"
class="w-full pl-10 pr-4 py-2 border border-slate-300 rounded-lg focus:outline-none focus:border-blue-500 focus:ring-2 focus:ring-blue-200 transition-all duration-200 placeholder-slate-400 text-sm">
</div>
</div>
<!-- Input Password -->
<div class="space-y-1">
<div class="flex justify-between items-center">
<label for="password" class="block text-sm font-medium text-slate-700">Password</label>
<a href="#" class="text-xs text-blue-600 hover:text-blue-700 hover:underline">Lupa Password?</a>
</div>
<div class="relative">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none text-slate-400">
<svg xmlns="[http://www.w3.org/2000/svg](http://www.w3.org/2000/svg)" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="11" width="18" height="11" rx="2" ry="2"></rect><path d="M7 11V7a5 5 0 0 1 10 0v4"></path></svg>
</div>
<input type="password" id="password" required placeholder="••••••••"
class="w-full pl-10 pr-10 py-2 border border-slate-300 rounded-lg focus:outline-none focus:border-blue-500 focus:ring-2 focus:ring-blue-200 transition-all duration-200 placeholder-slate-400 text-sm">
<!-- Toggle Show/Hide Password -->
<button type="button" id="togglePassword" class="absolute inset-y-0 right-0 pr-3 flex items-center text-slate-400 hover:text-slate-600 cursor-pointer focus:outline-none">
<!-- Icon Eye (Default) -->
<svg id="eyeIcon" xmlns="[http://www.w3.org/2000/svg](http://www.w3.org/2000/svg)" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7Z"></path><circle cx="12" cy="12" r="3"></circle></svg>
<!-- Icon Eye Off (Hidden) -->
<svg id="eyeOffIcon" class="hidden" xmlns="[http://www.w3.org/2000/svg](http://www.w3.org/2000/svg)" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9.88 9.88a3 3 0 1 0 4.24 4.24"></path><path d="M10.73 5.08A10.43 10.43 0 0 1 12 5c7 0 10 7 10 7a13.16 13.16 0 0 1-1.67 2.68"></path><path d="M6.61 6.61A13.526 13.526 0 0 0 2 12s3 7 10 7c.68 0 1.37-.09 2-.26"></path><line x1="2" y1="2" x2="22" y2="22"></line></svg>
</button>
</div>
</div>
<!-- Checkbox Remember Me -->
<div class="flex items-center">
<input id="remember-me" name="remember-me" type="checkbox" class="h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300 rounded cursor-pointer">
<label for="remember-me" class="ml-2 block text-sm text-slate-600 cursor-pointer select-none">Ingat saya</label>
</div>
<!-- Submit Button -->
<button type="submit" class="w-full bg-blue-600 text-white py-2.5 rounded-lg font-medium hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 transition-colors duration-300 shadow-md hover:shadow-lg transform active:scale-[0.98]">
Masuk Sekarang
</button>
</form>
<!-- Divider -->
<div class="relative px-8">
<div class="absolute inset-0 flex items-center px-8">
<div class="w-full border-t border-slate-200"></div>
</div>
<div class="relative flex justify-center text-sm">
<span class="px-2 bg-white text-slate-500">Atau masuk dengan</span>
</div>
</div>
<!-- Social Login (Mockup) -->
<div class="px-8 pt-4 pb-8 grid grid-cols-2 gap-3">
<button class="flex items-center justify-center px-4 py-2 border border-slate-200 rounded-lg text-sm font-medium text-slate-600 hover:bg-slate-50 transition-colors">
<svg class="h-5 w-5 mr-2" viewBox="0 0 24 24" fill="currentColor"><path d="M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z" fill="#4285F4"/><path d="M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z" fill="#34A853"/><path d="M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z" fill="#FBBC05"/><path d="M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z" fill="#EA4335"/></svg>
Google
</button>
<button class="flex items-center justify-center px-4 py-2 border border-slate-200 rounded-lg text-sm font-medium text-slate-600 hover:bg-slate-50 transition-colors">
<svg class="h-5 w-5 mr-2" fill="currentColor" viewBox="0 0 24 24"><path fill-rule="evenodd" d="M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z" clip-rule="evenodd"/></svg>
Github
</button>
</div>
<!-- Footer -->
<div class="bg-slate-50 px-8 py-4 text-center">
<p class="text-sm text-slate-500">Belum punya akun? <a href="#" class="text-blue-600 font-medium hover:underline">Daftar sekarang</a></p>
</div>
</div>
<!-- JavaScript untuk Interaktivitas -->
<script>
// Logika Toggle Password
const toggleButton = document.getElementById('togglePassword');
const passwordInput = document.getElementById('password');
const eyeIcon = document.getElementById('eyeIcon');
const eyeOffIcon = document.getElementById('eyeOffIcon');
toggleButton.addEventListener('click', () => {
const type = passwordInput.getAttribute('type') === 'password' ? 'text' : 'password';
passwordInput.setAttribute('type', type);
// Toggle Icons
eyeIcon.classList.toggle('hidden');
eyeOffIcon.classList.toggle('hidden');
});
// Logika Submit Form (Simulasi)
const loginForm = document.getElementById('loginForm');
const toast = document.getElementById('toast');
loginForm.addEventListener('submit', (e) => {
e.preventDefault(); // Mencegah reload halaman
// Tampilkan state loading pada tombol (optional, good for UX)
const submitBtn = loginForm.querySelector('button[type="submit"]');
const originalText = submitBtn.innerText;
submitBtn.innerText = 'Memproses...';
submitBtn.disabled = true;
submitBtn.classList.add('opacity-75', 'cursor-not-allowed');
// Simulasi delay proses login
setTimeout(() => {
// Kembalikan tombol
submitBtn.innerText = originalText;
submitBtn.disabled = false;
submitBtn.classList.remove('opacity-75', 'cursor-not-allowed');
// Tampilkan Toast Notifikasi
toast.classList.remove('hidden');
toast.classList.add('notification-enter');
// Sembunyikan Toast setelah 3 detik
setTimeout(() => {
toast.classList.remove('notification-enter');
toast.classList.add('notification-exit');
setTimeout(() => {
toast.classList.add('hidden');
toast.classList.remove('notification-exit');
}, 500);
}, 3000);
// Reset form
loginForm.reset();
}, 1500);
});
</script>
</body>
</html>