Mengukir Dunia Digital Sendiri: Dari Kalkulator Cerdas Hingga Page Builder Interaktif dengan HTML, CSS, dan JavaScript

PintarApp Juli 17, 2026
Mengukir Dunia Digital Sendiri: Dari Kalkulator Cerdas Hingga Page Builder Interaktif dengan HTML, CSS, dan JavaScript

Dulu, saya pernah mengalami momen "aha!" yang cukup menggelitik saat masih bergelut dengan baris-baris kode di awal perjalanan ngoding. Waktu itu, saya sedang mencoba membangun kalkulator sederhana. Niatnya sih biar bisa menjumlahkan angka, tapi kok hasilnya aneh. Setiap kali saya masukkan "5" dan "5", bukannya keluar "10", malah yang muncul "55". Kepala rasanya mau pecah. Setelah bermenit-menit (atau mungkin berjam-jam) merenung sambil menatap monitor seperti detektif yang kehilangan jejak, baru sadar kalau saya lupa mengubah tipe data input dari string menjadi angka! Jadi, alih-alih menjumlahkan, JavaScript saya malah mengira saya mau menggabungkan teks. Dari pengalaman sepele itu, saya belajar satu hal: hal dasar sekalipun punya peran krusial dan kadang detail kecil bisa jadi biang kerok utama. Ini juga yang membuat saya semakin jatuh cinta pada bagaimana kita bisa mengontrol setiap detail dengan HTML, CSS, dan JavaScript.

Dan hari ini, kita akan menyelami lebih dalam dunia frontend development yang seru ini, dengan membangun dua aplikasi web yang cukup berbeda namun sama-sama powerful: sebuah kalkulator dan sebuah page builder interaktif. Keduanya akan kita racik murni dengan trio serangkai yang tak pernah lekang oleh waktu: HTML untuk strukturnya, CSS untuk penampilannya, dan JavaScript untuk otaknya. Siap untuk membuat browser Anda bekerja keras?

Memulai Petualangan: Merakit Kalkulator Cerdas Anda Sendiri

Membangun kalkulator mungkin terdengar sepele, tapi ini adalah gerbang emas untuk memahami interaksi pengguna, manajemen state, dan logika dasar JavaScript. Anggap saja kalkulator ini seperti kotak perkakas dasar di bengkel otomotif. Setiap tombol adalah kunci pas atau obeng dengan fungsi spesifik. Layar adalah indikator di dashboard mobil, dan otak di baliknya adalah ECU (Electronic Control Unit) yang memproses semua perintah.

Pondasi Kalkulator: HTML

Pertama, kita siapkan rangkanya dengan HTML. Kita butuh sebuah layar untuk menampilkan angka dan hasil, serta tombol-tombol untuk angka (0-9), operator (+, -, *, /), desimal, sama dengan, dan tombol reset. Kita bisa menggunakan elemen div untuk wadah utama dan button untuk tombol-tombolnya.


<div class="calculator">
<div class="display">0</div>
<div class="buttons">
<button class="operator" data-operator="clear">AC</button>
<button class="operator" data-operator="/">&divide;</button>
<button class="operator" data-operator="*">&times;</button>
<button class="operator" data-operator="-">&minus;</button>
<button class="number">7</button>
<button class="number">8</button>
<button class="number">9</button>
<button class="operator" data-operator="+">+</button>
<button class="number">4</button>
<button class="number">5</button>
<button class="number">6</button>
<button class="equal">=</button>
<button class="number">1</button>
<button class="number">2</button>
<button class="number">3</button>
<button class="number zero">0</button>
<button class="decimal">.</button>
</div>
</div>

Menghias Kalkulator: CSS

Dengan CSS, kita bisa membuat kalkulator ini tampil menarik layaknya smartphone modern. Gunakan CSS Grid untuk menata tombol-tombol agar rapi dan responsif. Berikan sentuhan warna, ukuran font yang nyaman, dan efek hover agar terasa interaktif.


.calculator {
border: 1px solid #ccc;
border-radius: 5px;
width: 300px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
.display {
background-color: #333;
color: #fff;
font-size: 2.5em;
padding: 20px;
text-align: right;
border-top-left-radius: 5px;
border-top-right-radius: 5px;
}
.buttons {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-gap: 1px;
}
button {
padding: 20px;
font-size: 1.5em;
border: none;
background-color: #eee;
cursor: pointer;
}
button.operator { background-color: #f79236; color: white; }
button.equal { background-color: #2196f3; color: white; grid-column: span 1; grid-row: span 2; } /* Contoh pengaturan grid */

Menggerakkan Kalkulator: JavaScript

Inilah bagian paling seru! JavaScript akan menjadi otak di balik kalkulator kita. Kita perlu:

  • Mendapatkan semua tombol dan layar.
  • Menambahkan event listener ke setiap tombol untuk mendeteksi klik.
  • Membuat logika untuk mengelola angka yang dimasukkan, operator yang dipilih, dan perhitungan final.
  • Memastikan tampilan layar selalu diperbarui sesuai input.
Ini mirip seperti seorang mekanik yang menyambungkan kabel-kabel sensor ke ECU mobil agar semua komponen bisa berkomunikasi dan bekerja sesuai fungsinya.


const display = document.querySelector('.display');
const buttons = document.querySelector('.buttons');
let currentInput = '0';
let firstOperand = null;
let operator = null;
let waitingForSecondOperand = false;
buttons.addEventListener('click', (event) => {
const { target } = event;
if (!target.matches('button')) return;
if (target.classList.contains('number')) {
if (waitingForSecondOperand) {
currentInput = target.textContent;
waitingForSecondOperand = false;
} else {
currentInput = currentInput === '0' ? target.textContent : currentInput + target.textContent;
}
display.textContent = currentInput;
return;
}
if (target.classList.contains('decimal')) {
if (!currentInput.includes('.')) {
currentInput += '.';
display.textContent = currentInput;
}
return;
}
if (target.classList.contains('operator')) {
handleOperator(target.dataset.operator);
return;
}
if (target.classList.contains('equal')) {
performCalculation();
display.textContent = currentInput;
firstOperand = null;
operator = null;
waitingForSecondOperand = false;
return;
}
});
function handleOperator(nextOperator) {
const inputValue = parseFloat(currentInput);
if (operator && waitingForSecondOperand) {
operator = nextOperator;
return;
}
if (firstOperand === null) {
firstOperand = inputValue;
} else if (operator) {
const result = operate(firstOperand, inputValue, operator);
currentInput = `${parseFloat(result.toFixed(7))}`;
firstOperand = result;
}
waitingForSecondOperand = true;
operator = nextOperator;
display.textContent = currentInput;
}
function operate(num1, num2, operator) {
if (operator === '+') return num1 + num2;
if (operator === '-') return num1 - num2;
if (operator === '*') return num1 * num2;
if (operator === '/') return num1 / num2;
return num2; // Default
}
function performCalculation() {
const inputValue = parseFloat(currentInput);
if (firstOperand === null || operator === null) return;
currentInput = `${operate(firstOperand, inputValue, operator)}`;
}

Tentu saja, kode di atas adalah versi yang sangat disederhanakan. Anda bisa menambahkan validasi error (misalnya pembagian nol), dukungan keyboard, dan fitur-fitur lainnya.

Melangkah Lebih Jauh: Merangkai Page Builder Interaktif

Jika kalkulator adalah kunci pas, maka page builder adalah bengkel modifikasi mobil kustom. Anda tidak hanya memperbaiki, tapi juga merakit, mengatur, dan mendesain ulang secara fundamental. Ini memungkinkan pengguna untuk "membangun" halaman web dengan menyeret dan meletakkan elemen-elemen, tanpa perlu menyentuh kode. Konsep utamanya adalah Drag and Drop API dan manipulasi DOM (Document Object Model) dengan JavaScript.

Struktur Dasar Page Builder: HTML

Kita akan butuh dua area utama:

  • Toolbox: Panel di mana elemen-elemen yang bisa diseret (misalnya, teks, gambar, tombol) berada.
  • Canvas (Area Desain): Area tempat pengguna akan menjatuhkan dan mengatur elemen-elemen tersebut.


<div class="page-builder-container">
<div class="toolbox">
<div class="draggable-item" draggable="true" data-type="text">Text Block</div>
<div class="draggable-item" draggable="true" data-type="image">Image Block</div>
<div class="draggable-item" draggable="true" data-type="button">Button Block</div>
</div>
<div class="canvas" id="drop-zone">
<p>Drag items here!</p>
</div>
</div>

Mempercantik Page Builder: CSS

CSS akan membuat toolbox dan canvas terlihat fungsional dan menarik. Kita akan menata layout, memberikan indikator visual untuk area yang bisa dijatuhkan, dan gaya dasar untuk elemen-elemen yang bisa diseret.


.page-builder-container {
display: flex;
gap: 20px;
height: 80vh;
border: 1px solid #ddd;
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
}
.toolbox {
width: 200px;
background-color: #f8f8f8;
padding: 15px;
border-right: 1px solid #eee;
overflow-y: auto;
}
.draggable-item {
padding: 10px;
margin-bottom: 10px;
background-color: #fff;
border: 1px solid #ccc;
border-radius: 4px;
cursor: grab;
text-align: center;
box-shadow: 0 1px 2px rgba(0,0,0,0.05);
}
.canvas {
flex-grow: 1;
border: 2px dashed #ccc;
background-color: #fff;
padding: 20px;
display: flex;
flex-direction: column;
gap: 10px;
overflow-y: auto;
}
.canvas.hovered {
border-color: #2196f3; /* Indikator saat item di atas canvas */
}

Memberikan Nyawa Pada Page Builder: JavaScript

Ini adalah jantung dari page builder. Kita akan memanfaatkan HTML Drag and Drop API.

  • Setiap elemen di toolbox akan memiliki atribut draggable="true".
  • Kita akan menangani event dragstart pada elemen yang diseret untuk menyimpan informasi tentang elemen tersebut (misalnya, tipenya).
  • Pada canvas, kita akan menangani dragover (untuk mengizinkan drop) dan drop (untuk membuat elemen baru berdasarkan data yang disimpan dan menambahkannya ke DOM).
Ini seperti seorang arsitek yang mengambil blueprint dari katalog komponen dan menempatkannya ke dalam denah bangunan, lalu secara ajaib komponen fisik muncul di sana.


const toolbox = document.querySelector('.toolbox');
const dropZone = document.getElementById('drop-zone');
let draggedItemData = null;
toolbox.addEventListener('dragstart', (e) => {
if (e.target.classList.contains('draggable-item')) {
draggedItemData = e.target.dataset.type;
e.dataTransfer.setData('text/plain', draggedItemData); // Penting untuk cross-browser
}
});
dropZone.addEventListener('dragover', (e) => {
e.preventDefault(); // Mencegah perilaku default (yang tidak mengizinkan drop)
dropZone.classList.add('hovered'); // Menambahkan visual feedback
});
dropZone.addEventListener('dragleave', () => {
dropZone.classList.remove('hovered');
});
dropZone.addEventListener('drop', (e) => {
e.preventDefault();
dropZone.classList.remove('hovered');
const itemType = e.dataTransfer.getData('text/plain'); // Mengambil data yang disimpan
let newElement;
switch (itemType) {
case 'text':
newElement = document.createElement('p');
newElement.textContent = 'This is a new text block.';
newElement.style.padding = '10px';
newElement.style.border = '1px dashed #aaa';
newElement.style.backgroundColor = '#f9f9f9';
break;
case 'image':
newElement = document.createElement('img');
newElement.src = 'https://via.placeholder.com/150'; // Placeholder image
newElement.alt = 'Placeholder Image';
newElement.style.maxWidth = '100%';
newElement.style.display = 'block';
newElement.style.margin = '0 auto';
break;
case 'button':
newElement = document.createElement('button');
newElement.textContent = 'Click Me!';
newElement.style.padding = '10px 20px';
newElement.style.backgroundColor = '#007bff';
newElement.style.color = 'white';
newElement.style.border = 'none';
newElement.style.borderRadius = '5px';
newElement.style.cursor = 'pointer';
break;
default:
return;
}
// Memberikan kemampuan drag lagi untuk elemen yang sudah di drop di canvas
newElement.setAttribute('draggable', 'true');
newElement.classList.add('dropped-item'); // Untuk styling tambahan di canvas
// Tambahkan event listener untuk memindahkan item di dalam canvas
newElement.addEventListener('dragstart', (ev) => {
ev.stopPropagation(); // Mencegah event dragstart menyebar ke item lain
draggedItemData = { type: 'existing', element: newElement };
ev.dataTransfer.setData('text/plain', 'existing-item');
});
dropZone.appendChild(newElement);
});

Untuk fitur seperti mengatur ulang elemen di dalam canvas (sortable), Anda perlu menambahkan logika yang lebih kompleks untuk menangani dragover dan drop di antara elemen-elemen yang sudah ada, mungkin dengan memanfaatkan e.target dan e.relatedTarget untuk menentukan posisi drop yang tepat. Anda juga bisa menambahkan fitur pengeditan elemen (misalnya, mengubah teks blok teks atau URL gambar) dengan klik kanan atau tombol edit kecil yang muncul saat elemen dipilih.

Penutup: Kekuatan Kreativitas di Ujung Jari

Dari kalkulator sederhana hingga page builder yang kompleks, kita telah melihat bagaimana HTML, CSS, dan JavaScript secara fundamental memungkinkan kita untuk menciptakan pengalaman web yang interaktif dan dinamis. Ini bukan hanya tentang sintaksis kode, tapi lebih kepada memahami bagaimana setiap komponen bekerja bersama, seperti sebuah orkestra yang harmonis.

Dengan HTML sebagai fondasi yang kokoh, CSS sebagai kuas yang mewarnai, dan JavaScript sebagai dirigen yang menggerakkan segalanya, Anda memiliki kekuatan tak terbatas untuk mewujudkan ide-ide paling gila sekalipun di browser. Jangan takut mencoba, bereksperimen, dan tentu saja, jangan panik jika menemukan error seperti saya dulu dengan kalkulator "55" saya. Setiap error adalah guru terbaik yang akan membawa Anda selangkah lebih maju dalam petualangan ngoding Anda!