Mengungkap Rahasia di Balik Layar: Membangun Kalkulator Cerdas dan Page Builder Kreatif dengan HTML, CSS, JS

PintarApp Agustus 12, 2026
Mengungkap Rahasia di Balik Layar: Membangun Kalkulator Cerdas dan Page Builder Kreatif dengan HTML, CSS, JS

Selamat datang, para calon maestro web! Pernahkah kamu merasa buntu saat mencoba memahami framework yang begitu banyak dan kompleks di dunia web development? Saya ingat betul, dulu rasanya seperti mencoba merakit mesin V8 turbo sendirian padahal saya baru belajar cara memegang kunci pas. Penuh keringat dan kebingungan. Tapi percayalah, fondasi paling kokoh justru datang dari alat-alat sederhana: HTML, CSS, dan JavaScript murni.

Hari ini, kita akan berpetualang membangun dua aplikasi web yang kelihatannya "wow" tapi sebenarnya sangat mendasar: sebuah kalkulator fungsional dan sebuah page builder sederhana. Kedua proyek ini akan membuktikan bahwa kamu tidak perlu framework raksasa untuk menciptakan sesuatu yang interaktif dan berguna. Cukup dengan modal tiga serangkai sakti itu, kamu bisa jadi arsitek digital yang ulung!

Mengukir Logika Angka: Membangun Aplikasi Kalkulator

Membangun kalkulator itu seperti merakit mainan LEGO. Kamu perlu menyiapkan balok-baloknya (tombol angka, operator, tampilan hasil), lalu mewarnainya agar menarik, dan terakhir, menghubungkan semua balok agar bisa bergerak dan berfungsi sesuai keinginan. Mari kita mulai!

1. Pondasi Kuat dengan HTML (Kerangka Kalkulator)

Anggap saja ini rangka mobil sport yang akan kita bangun. Tanpa rangka, kita tidak bisa menaruh mesin atau bahkan tempat duduk. Dalam kasus kalkulator, kita butuh elemen untuk menampilkan hasil dan sekumpulan tombol. Dulu, saya sering lupa menyertakan atribut id atau class yang jelas, akhirnya pas mau "pasang kabel" (JavaScript), kok malah bingung mau nyambungin ke mana. Pastikan setiap elemen penting punya identitasnya ya!


<div class="calculator">
<input type="text" class="display" readonly>
<div class="buttons">
<button class="btn" data-value="7">7</button>
<button class="btn" data-value="8">8</button>
<button class="btn" data-value="9">9</button>
<button class="btn operator" data-value="/">/</button>
<button class="btn" data-value="4">4</button>
<button class="btn" data-value="5">5</button>
<button class="btn" data-value="6">6</button>
<button class="btn operator" data-value="*">*</button>
<button class="btn" data-value="1">1</button>
<button class="btn" data-value="2">2</button>
<button class="btn" data-value="3">3</button>
<button class="btn operator" data-value="-">-</button>
<button class="btn clear" data-value="C">C</button>
<button class="btn" data-value="0">0</button>
<button class="btn" data-value=".">.</button>
<button class="btn operator equals" data-value="=">=</button>
<button class="btn operator" data-value="+">+</button>
</div>
</div>

2. Memoles Tampilan dengan CSS (Bodywork Kalkulator)

Nah, setelah rangka jadi, kita butuh bodywork yang cantik dan cat yang menarik. Di sinilah CSS berperan. Kita bisa mengatur ukuran, warna, tata letak, bahkan memberikan efek interaktif saat tombol ditekan. Saya pernah membuat kalkulator tanpa CSS sama sekali, hasilnya seperti melihat papan sirkuit telanjang, berfungsi sih tapi mata sakit lihatnya. Jangan lupa sedikit sentuhan display: grid untuk menata tombol agar rapi ya!


.calculator {
width: 300px;
background-color: #333;
padding: 20px;
border-radius: 10px;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.5);
margin: 50px auto;
}
.display {
width: calc(100% - 20px);
height: 50px;
background-color: #222;
color: #fff;
font-size: 2em;
text-align: right;
padding: 10px;
border: none;
border-radius: 5px;
margin-bottom: 15px;
}
.buttons {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 10px;
}
.btn {
width: 100%;
height: 60px;
font-size: 1.5em;
background-color: #555;
color: #fff;
border: none;
border-radius: 5px;
cursor: pointer;
transition: background-color 0.2s;
}
.btn:hover {
background-color: #777;
}
.operator {
background-color: #f1a33c;
}
.operator:hover {
background-color: #e0942b;
}
.equals {
background-color: #28a745;
grid-column: span 2; /* Contoh untuk tombol = yang lebih lebar */
}
.equals:hover {
background-color: #218838;
}
.clear {
background-color: #dc3545;
}
.clear:hover {
background-color: #c82333;
}

3. Jantung yang Berdetak dengan JavaScript (Mesin Kalkulator)

Inilah "mesin" yang akan membuat kalkulator kita hidup. JavaScript akan mendengarkan setiap ketukan tombol, memproses angka dan operator, lalu menampilkan hasilnya. Ini seperti mekanik yang menyambungkan semua kabel dan sensor agar mobil bisa berjalan. Dulu, saya sering pusing kenapa hasilnya selalu NaN (Not a Number) saat mencoba menjumlahkan string. Ternyata lupa pakai parseFloat() atau parseInt()! Ingat, JavaScript itu pintar, tapi butuh instruksi yang jelas.


const display = document.querySelector('.display');
const buttons = document.querySelectorAll('.btn');
let currentInput = '';
let operator = null;
let firstOperand = null;
let waitingForSecondOperand = false;
function updateDisplay() {
display.value = currentInput;
}
buttons.forEach(button => {
button.addEventListener('click', (event) => {
const { value } = event.target.dataset;
if (event.target.classList.contains('operator') && value !== '=') {
if (firstOperand === null) {
firstOperand = parseFloat(currentInput);
} else if (operator) {
const result = operate(firstOperand, parseFloat(currentInput), operator);
currentInput = String(result);
firstOperand = result;
}
operator = value;
waitingForSecondOperand = true;
updateDisplay();
return;
}
if (value === '=') {
if (firstOperand === null || operator === null || currentInput === '') {
return;
}
const result = operate(firstOperand, parseFloat(currentInput), operator);
currentInput = String(result);
firstOperand = null;
operator = null;
waitingForSecondOperand = false;
updateDisplay();
return;
}
if (value === 'C') {
currentInput = '';
firstOperand = null;
operator = null;
waitingForSecondOperand = false;
updateDisplay();
return;
}
if (waitingForSecondOperand) {
currentInput = value;
waitingForSecondOperand = false;
} else {
currentInput = currentInput === '0' ? value : currentInput + value;
}
updateDisplay();
});
});
function operate(operand1, operand2, op) {
switch (op) {
case '+':
return operand1 + operand2;
case '-':
return operand1 - operand2;
case '*':
return operand1 * operand2;
case '/':
return operand1 / operand2;
default:
return operand2;
}
}

Mengukir Kanvas Digital: Membangun Page Builder Sederhana

Sekarang, mari kita tingkatkan levelnya. Membangun page builder sederhana itu seperti menyiapkan bengkel modifikasi mobil. Kamu punya berbagai suku cadang (blok teks, gambar, tombol), area kerja (kanvas), dan alat-alat untuk memasang dan mengeditnya. Tujuan kita adalah membiarkan pengguna "merakit" tata letak halaman web sendiri.

1. Alat dan Kanvas dengan HTML

Untuk page builder, kita butuh "toolbox" berisi elemen-elemen yang bisa ditarik, dan sebuah "kanvas" tempat elemen itu akan diletakkan. Ini seperti rak perkakas dan meja kerja di bengkel kita. Saya sering melihat orang lupa bahwa elemen yang mau di-drag harus punya draggable="true". Tanpa itu, bagaimana mau ditarik, kan?


<div class="page-builder-container">
<div class="sidebar">
<h3>Drag & Drop Elements</h3>
<div class="draggable-element" draggable="true" data-type="text">Text Block</div>
<div class="draggable-element" draggable="true" data-type="image">Image Block</div>
<div class="draggable-element" draggable="true" data-type="button">Button Block</div>
</div>
<div class="canvas" id="pageCanvas">
<h3>Drop elements here</h3>
</div>
</div>

2. Desain Elemen dan Kanvas dengan CSS

Kita perlu membuat sidebar perkakas dan kanvas terlihat jelas. CSS akan memberikan bentuk, warna, dan batas pada elemen-elemen ini. Ini ibarat mengecat dinding bengkel dan memberikan garis batas pada meja kerja. Kita juga perlu menambahkan sedikit gaya untuk elemen yang bisa di-drag dan di-drop agar pengguna tahu apa yang sedang terjadi.


.page-builder-container {
display: flex;
margin-top: 30px;
height: 600px;
border: 1px solid #ddd;
box-shadow: 0 0 10px rgba(0,0,0,0.1);
}
.sidebar {
width: 200px;
background-color: #f4f4f4;
padding: 15px;
border-right: 1px solid #eee;
}
.draggable-element {
background-color: #007bff;
color: white;
padding: 10px;
margin-bottom: 10px;
cursor: grab;
border-radius: 5px;
text-align: center;
}
.draggable-element:hover {
background-color: #0056b3;
}
.canvas {
flex-grow: 1;
background-color: #fff;
padding: 20px;
border: 2px dashed #ccc;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
overflow-y: auto;
}
.canvas.drag-over {
border-color: #007bff;
background-color: #e6f7ff;
}
.canvas-element {
background-color: #f9f9f9;
border: 1px solid #ddd;
padding: 10px;
margin-bottom: 10px;
width: 90%;
min-height: 50px;
text-align: center;
position: relative;
}
.canvas-element.text-block { /* Styling khusus untuk elemen text */ }
.canvas-element.image-block { /* Styling khusus untuk elemen image */ }
.canvas-element.button-block { /* Styling khusus untuk elemen button */ }

3. Sihir Interaktif dengan JavaScript

Ini adalah inti dari page builder kita. JavaScript akan mengelola fungsionalitas drag-and-drop, menambahkan elemen ke kanvas, dan memungkinkan kita berinteraksi dengannya. Proses ini seperti teknisi yang merancang sistem robotik untuk memindahkan suku cadang dan merakitnya secara otomatis. Saya pernah mengalami error di mana elemen tidak mau jatuh di kanvas, ternyata lupa mencegah perilaku default event dragover dan drop. Kecil tapi fatal!


const draggables = document.querySelectorAll('.draggable-element');
const pageCanvas = document.getElementById('pageCanvas');
let draggedElementData = null;
draggables.forEach(draggable => {
draggable.addEventListener('dragstart', (e) => {
draggedElementData = {
type: e.target.dataset.type,
content: e.target.textContent
};
e.dataTransfer.setData('text/plain', JSON.stringify(draggedElementData));
e.target.classList.add('dragging');
});
draggable.addEventListener('dragend', (e) => {
e.target.classList.remove('dragging');
});
});
pageCanvas.addEventListener('dragover', (e) => {
e.preventDefault(); // Penting! Mencegah perilaku default browser
pageCanvas.classList.add('drag-over');
});
pageCanvas.addEventListener('dragleave', () => {
pageCanvas.classList.remove('drag-over');
});
pageCanvas.addEventListener('drop', (e) => {
e.preventDefault();
pageCanvas.classList.remove('drag-over');
const data = JSON.parse(e.dataTransfer.getData('text/plain'));
const newElement = document.createElement('div');
newElement.classList.add('canvas-element');
newElement.setAttribute('draggable', 'true'); // Agar elemen di kanvas bisa di-drag lagi (misal: untuk reorder)
if (data.type === 'text') {
newElement.innerHTML = `<p contenteditable="true">${data.content}</p>`;
newElement.classList.add('text-block');
} else if (data.type === 'image') {
newElement.innerHTML = `<img src="https://via.placeholder.com/150" alt="Placeholder Image" style="max-width:100%;">`;
newElement.classList.add('image-block');
} else if (data.type === 'button') {
newElement.innerHTML = `<button>Click Me</button>`;
newElement.classList.add('button-block');
}
// Menghilangkan pesan "Drop elements here" jika ada
const placeholderMessage = pageCanvas.querySelector('h3');
if (placeholderMessage && placeholderMessage.textContent === 'Drop elements here') {
placeholderMessage.remove();
}
pageCanvas.appendChild(newElement);
// Tambahkan event listener untuk drag-and-drop antar elemen di kanvas (opsional, tapi keren!)
newElement.addEventListener('dragstart', (ev) => {
ev.stopPropagation(); // Mencegah event parent canvas juga terpicu
ev.dataTransfer.setData('text/html', ev.target.outerHTML);
ev.dataTransfer.effectAllowed = 'move';
setTimeout(() => {
ev.target.style.display = 'none';
}, 0);
});
newElement.addEventListener('dragend', (ev) => {
ev.target.style.display = 'block';
});
// Ini adalah bagian yang lebih kompleks untuk re-order elemen di dalam canvas
// Anda bisa mengimplementasikan logika di sini menggunakan `insertBefore`
// atau library pihak ketiga seperti SortableJS untuk kemudahan.
});
pageCanvas.addEventListener('dragover', (e) => {
e.preventDefault();
const afterElement = getDragAfterElement(pageCanvas, e.clientY);
const draggable = document.querySelector('.dragging');
if (draggable && draggable.parentNode === pageCanvas) { // Hanya reorder jika elemen asalnya dari canvas
if (afterElement == null) {
pageCanvas.appendChild(draggable);
} else {
pageCanvas.insertBefore(draggable, afterElement);
}
}
});
function getDragAfterElement(container, y) {
const draggableElements = [...container.querySelectorAll('.canvas-element:not(.dragging)')];
return draggableElements.reduce((closest, child) => {
const box = child.getBoundingClientRect();
const offset = y - box.top - box.height / 2;
if (offset < 0 && offset > closest.offset) {
return { offset: offset, element: child };
} else {
return closest;
}
}, { offset: -Number.MAX_VALUE }).element;
}

Catatan: Bagian page builder ini adalah versi yang sangat sederhana. Untuk fungsionalitas lengkap seperti menyimpan layout, mengedit properti, atau drag-and-drop yang lebih canggih (misalnya reordering antar elemen di kanvas), kamu akan membutuhkan lebih banyak JavaScript dan mungkin sedikit bantuan dari library pihak ketiga seperti SortableJS atau draggable polyfills. Namun, fondasinya sudah ada di sini!

Kesimpulan: Kekuatan Ada di Tanganmu

Melihat betapa banyak yang bisa kita bangun hanya dengan HTML, CSS, dan JavaScript murni sungguh menakjubkan, bukan? Dari kalkulator sederhana yang memproses angka, hingga page builder yang memungkinkan orang lain mendesain halaman, semuanya berawal dari pemahaman dasar ini. Saya selalu percaya, tidak ada salahnya mempelajari framework, tapi menguasai pondasi adalah investasi terbaik untuk karir programmer. Ibaratnya, kamu bisa pakai mobil balap tercanggih, tapi kalau tidak tahu cara dasar mengemudi dan merawat mesin, akan sia-sia.

Jadi, jangan ragu untuk bereksperimen. Buka editor kodemu, coba ubah warna tombol, tambahkan operator baru di kalkulator, atau buat elemen baru untuk page builder. Setiap baris kode yang kamu tulis adalah langkah maju. Dunia web development sangat luas, dan kamu punya semua alat yang dibutuhkan untuk mulai menjelajahinya. Selamat ngoding, para arsitek digital!