Membangun Dua Monster Kecil: Kalkulator & Page Builder dengan HTML, CSS, JS Murni

PintarApp Agustus 18, 2026
Membangun Dua Monster Kecil: Kalkulator & Page Builder dengan HTML, CSS, JS Murni

Pernahkah Anda merasa seperti sedang memecahkan teka-teki rumit, tapi ternyata jawabannya sesederhana "oh, cuma butuh satu baris kode ini saja"? Saya ingat betul saat pertama kali mencoba membuat fitur drag-and-drop di sebuah proyek. Berhari-hari saya berkutat dengan berbagai library yang katanya "mudah", tapi hasilnya malah bikin pusing tujuh keliling. Sampai akhirnya, saya mencoba metode manual, mengandalkan event listener dasar dari JavaScript. Dan voila! Ternyata semua kerumitan itu bisa diatasi dengan beberapa baris kode vanila yang bersih dan mudah dipahami. Pengalaman ini mengajari saya bahwa pondasi yang kuat itu jauh lebih berharga daripada solusi instan yang serba instan. Begitulah, kadang kita harus membedah mesinnya sendiri untuk memahami cara kerjanya.

Nah, hari ini, mari kita bedah dua proyek yang mungkin terdengar "wah" tapi sebenarnya sangat bisa kita bangun dengan pondasi HTML, CSS, dan JavaScript murni: sebuah kalkulator web dan sebuah page builder sederhana. Jangan khawatir, kita akan mendekatnya dengan santai, seperti sedang merakit mainan kesayangan, bukan sedang mengerjakan proyek roket ke bulan. Artikel ini akan mengajak Anda menyelami bagaimana ketiga pilar pengembangan frontend ini bisa menciptakan aplikasi yang interaktif dan fungsional, tanpa perlu framework atau library tambahan.

Membangun Kalkulator: Mesin Hitung Saku di Browser Anda

Kalkulator? Ah, itu kan cuma penjumlahan dan pengurangan. Eits, jangan salah. Di balik kesederhanaannya, membangun kalkulator melatih pemahaman kita tentang bagaimana input pengguna diproses, logika program berjalan, dan output ditampilkan. Ibaratnya, kalkulator adalah resep masakan paling dasar: Anda butuh bahan (HTML), bumbu dan tata letak (CSS), serta proses memasak itu sendiri (JavaScript).

1. Struktur HTML: Piring dan Bahan-bahannya

HTML untuk kalkulator itu seperti menyiapkan piring dan menata bahan-bahan. Kita butuh sebuah layar untuk menampilkan angka, dan tombol-tombol untuk angka 0-9, operasi matematika (+, -, *, /), titik desimal, tombol sama dengan, dan tentu saja tombol untuk menghapus (clear).


<div class="calculator">
<input type="text" class="display" readonly>
<div class="buttons">
<button class="btn clear">C</button>
<button class="btn operator">/</button>
<button class="btn operator">*</button>
<button class="btn number">7</button>
<button class="btn number">8</button>
<button class="btn number">9</button>
<button class="btn operator">-</button>
<!-- Tombol lain menyusul -->
<button class="btn equals">=</button>
</div>
</div>

2. Gaya CSS: Sentuhan Estetika

Setelah bahan-bahan tertata, giliran CSS membuat kalkulator kita terlihat menarik dan mudah digunakan. Ini seperti menata hidangan agar terlihat menggugah selera. Kita bisa mengatur ukuran tombol, warna latar belakang, tata letak dengan Flexbox atau Grid, serta efek hover agar pengguna tahu tombol mana yang sedang mereka sentuh.


.calculator {
width: 300px;
margin: 50px auto;
border: 1px solid #ccc;
border-radius: 8px;
padding: 15px;
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
}
.display {
width: calc(100% - 20px);
height: 60px;
font-size: 2.5em;
text-align: right;
margin-bottom: 10px;
padding: 10px;
border: 1px solid #eee;
border-radius: 4px;
background-color: #f9f9f9;
}
.buttons {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 10px;
}
.btn {
padding: 15px;
font-size: 1.5em;
border: none;
border-radius: 5px;
cursor: pointer;
background-color: #e0e0e0;
transition: background-color 0.2s;
}
.btn:hover {
background-color: #d0d0d0;
}

3. Logika JavaScript: Otak di Balik Perhitungan

Inilah bagian terseru, di mana JavaScript berfungsi sebagai koki yang memproses semua bahan. Kita akan mendengarkan setiap klik tombol, memperbarui tampilan, dan melakukan perhitungan. Intinya, kita akan:

  • Mendapatkan referensi ke elemen layar dan semua tombol.
  • Menambahkan event listener ke setiap tombol.
  • Ketika tombol diklik:
    • Jika angka atau operator, tambahkan ke string ekspresi yang akan dihitung.
    • Jika tombol 'C', hapus semua yang ada di layar.
    • Jika tombol '=', evaluasi ekspresi menggunakan fungsi seperti eval() (hati-hati dengan keamanan, tapi untuk kalkulator sederhana ini cukup) dan tampilkan hasilnya.

const display = document.querySelector('.display');
const buttons = document.querySelectorAll('.btn');
let currentExpression = '';
buttons.forEach(button => {
button.addEventListener('click', () => {
const value = button.textContent;
if (value === 'C') {
currentExpression = '';
display.value = '';
} else if (value === '=') {
try {
// Hati-hati dengan eval() di proyek yang lebih kompleks
display.value = eval(currentExpression);
currentExpression = display.value;
} catch (error) {
display.value = 'Error';
currentExpression = '';
}
} else {
currentExpression += value;
display.value = currentExpression;
}
});
});

Membangun Page Builder: Kanvas Digital Impian Anda

Nah, ini dia proyek yang lebih ambisius tapi sangat mengedukasi: page builder. Bayangkan ini seperti Anda punya bengkel otomotif, di mana Anda bisa merakit mobil dari berbagai suku cadang (blok elemen HTML) dan mewarnainya sesuka hati (CSS), kemudian menggabungkan semuanya menjadi kendaraan impian Anda (JavaScript sebagai tangan montir).

1. Pondasi HTML: Suku Cadang dan Area Perakitan

Kita butuh dua area utama: satu untuk daftar "komponen" atau "blok" yang bisa diseret (misalnya, teks, gambar, tombol), dan satu lagi adalah "kanvas" tempat komponen-komponen ini akan dijatuhkan dan disusun.


<div class="page-builder">
<div class="sidebar">
<h3>Drag Me</h3>
<div class="component draggable" draggable="true" data-type="text">
<p>Drag Text</p>
</div>
<div class="component draggable" draggable="true" data-type="image">
<img src="placeholder.jpg" alt="Image" style="pointer-events: none;">
<p>Drag Image</p>
</div>
<div class="component draggable" draggable="true" data-type="button">
<button>Drag Button</button>
</div>
</div>
<div class="canvas" id="canvas">
<h3>Drop components here</h3>
</div>
</div>

2. Sentuhan Desain CSS: Agar Bengkel Terlihat Rapi

Dengan CSS, kita akan membuat sidebar dan canvas terlihat jelas, serta memberikan sedikit efek pada komponen yang bisa diseret agar pengguna tahu bahwa mereka bisa berinteraksi dengannya.


.page-builder {
display: flex;
gap: 20px;
padding: 20px;
height: calc(100vh - 40px);
}
.sidebar {
width: 250px;
border: 1px solid #ddd;
padding: 15px;
background-color: #f9f9f9;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.05);
}
.component {
padding: 10px;
margin-bottom: 10px;
border: 1px dashed #aaa;
background-color: #fff;
cursor: grab;
text-align: center;
border-radius: 4px;
}
.component:hover {
background-color: #e6e6e6;
}
.canvas {
flex-grow: 1;
border: 2px dashed #007bff;
padding: 20px;
background-color: #fefefe;
min-height: 400px;
border-radius: 8px;
}
.canvas.drag-over {
background-color: #eaf5ff;
border-color: #0056b3;
}

3. Jantung JavaScript: Tangan Montir yang Bekerja

Di sinilah keajaiban terjadi. JavaScript akan menangani semua interaksi drag-and-drop. Kita akan menggunakan beberapa event listener kunci:

  • dragstart: Saat elemen mulai diseret, kita simpan informasi tentang elemen tersebut (misalnya, tipe komponennya).
  • dragover: Mencegah perilaku default browser agar elemen bisa dijatuhkan di area kanvas.
  • drop: Saat elemen dijatuhkan, kita ambil informasi yang disimpan, buat elemen HTML yang sesuai, lalu tambahkan ke kanvas.
  • Content Editable & Styling: Untuk mengedit teks langsung, kita bisa menambahkan atribut contenteditable="true". Untuk mengubah styling, kita perlu membuat panel kontrol sederhana yang bisa mengubah properti CSS menggunakan JavaScript.

const draggables = document.querySelectorAll('.draggable');
const canvas = document.getElementById('canvas');
let draggedItem = null;
draggables.forEach(item => {
item.addEventListener('dragstart', (e) => {
draggedItem = e.target;
e.dataTransfer.setData('text/plain', e.target.dataset.type); // Store component type
setTimeout(() => {
e.target.style.opacity = '0.5';
}, 0);
});
item.addEventListener('dragend', (e) => {
e.target.style.opacity = '1';
draggedItem = null;
});
});
canvas.addEventListener('dragover', (e) => {
e.preventDefault(); // Allow drop
canvas.classList.add('drag-over');
});
canvas.addEventListener('dragleave', () => {
canvas.classList.remove('drag-over');
});
canvas.addEventListener('drop', (e) => {
e.preventDefault();
canvas.classList.remove('drag-over');
const componentType = e.dataTransfer.getData('text/plain');
let newElement;
if (componentType === 'text') {
newElement = document.createElement('p');
newElement.textContent = 'Edit this text';
newElement.setAttribute('contenteditable', 'true');
newElement.style.padding = '10px';
newElement.style.border = '1px solid #ddd';
newElement.style.marginBottom = '10px';
newElement.style.cursor = 'text';
} else if (componentType === 'image') {
newElement = document.createElement('img');
newElement.src = 'https://via.placeholder.com/150'; // Placeholder image
newElement.alt = 'Your Image';
newElement.style.maxWidth = '100%';
newElement.style.height = 'auto';
newElement.style.display = 'block';
newElement.style.marginBottom = '10px';
} else if (componentType === 'button') {
newElement = document.createElement('button');
newElement.textContent = 'Click Me';
newElement.style.padding = '10px 20px';
newElement.style.backgroundColor = '#007bff';
newElement.style.color = '#fff';
newElement.style.border = 'none';
newElement.style.borderRadius = '5px';
newElement.style.cursor = 'pointer';
newElement.style.marginBottom = '10px';
}
if (newElement) {
canvas.appendChild(newElement);
}
});

Menggabungkan Kekuatan: Filosofi di Balik Proyek Ini

Membangun kalkulator dan page builder dari nol dengan HTML, CSS, dan JavaScript murni bukan hanya tentang menciptakan aplikasi. Ini adalah tentang memahami pondasi, seperti memahami cara kerja mesin bensin sebelum Anda mencoba mengendarai mobil listrik. Saat Anda membangunnya sendiri, Anda akan menemukan bahwa banyak konsep yang digunakan di framework modern seperti React atau Vue sejatinya berakar pada manipulasi DOM dan event handling di JavaScript murni. Anda akan lebih menghargai kemudahan yang ditawarkan framework, sekaligus tahu cara 'memperbaiki' sesuatu ketika ada masalah yang tidak bisa diselesaikan oleh framework.

Proyek-proyek ini mengajarkan kita tentang modularitas, bagaimana setiap bagian HTML, CSS, dan JS bekerja sama membentuk satu kesatuan. Ini juga mengasah kemampuan problem-solving Anda saat menghadapi tantangan, misalnya bagaimana membuat kalkulator bisa menghitung ekspresi kompleks, atau bagaimana membuat page builder bisa menyimpan tata letak yang telah dibuat.

Penutup: Petualangan Baru Menanti!

Jadi, meskipun terlihat sederhana, membangun kalkulator dan page builder menggunakan HTML, CSS, dan JavaScript murni adalah petualangan yang sangat berharga. Anda tidak hanya akan mendapatkan dua aplikasi fungsional, tetapi juga pemahaman mendalam tentang bagaimana dunia web bekerja di balik layar. Jangan takut bereksperimen, coba tambahkan fitur baru, modifikasi tampilan, atau optimalkan kodenya. Setiap baris kode yang Anda tulis adalah langkah menuju keahlian yang lebih tinggi. Selamat mencoba, para montir digital!