Portofolio adalah kartu nama digital bagi pengembang web: satu halaman yang merangkum siapa kita, apa yang telah dibuat, dan bagaimana cara menghubungi. Kali ini proyeknya naik tingkat dari halaman profil tunggal menjadi website satu halaman dengan navigasi antar-section. Melalui tokoh fiktif Siti Rahma, kita melatih tautan anchor, article, serta interaksi navigasi yang halus.
Hasil Akhir yang Dibangun #
Hasil akhirnya adalah satu halaman portofolio untuk Siti Rahma, pengembang web fiktif, dengan seluruh konten dalam satu dokumen. Fitur yang kita bangun secara bertahap:
- Kerangka dokumen valid dengan metadata lengkap.
- Navigasi berupa daftar tautan anchor menuju empat section ber-id.
- Section hero, daftar proyek berbentuk article, keahlian, dan kontak.
- Stylesheet berpalet biru dengan navigasi flexbox dan pengguliran halus.
- Status tautan aktif lewat aria-current serta tombol kembali ke atas.
Prasyarat #
Proyek ini merangkai konsep dari section sebelumnya; baca dahulu bila materinya masih asing:
- Section Struktur Dokumen dan Semantic HTML: kerangka dokumen dan elemen bermakna.
- Section Links dan Navigasi: tautan anchor menuju id elemen.
- Section HTML dan CSS: selector, warna, dan tata letak dasar.
- Section HTML dan JavaScript: event click, classList, dan pemilih DOM.
Empat Bagian Proyek #
Kerjakan keempat bagian berurutan; setiap bagian memakai hasil bagian sebelumnya:
| Bagian | Fokus |
|---|---|
| Bagian 1: Menyusun Struktur Halaman | Kerangka valid: head, header, main, footer |
| Bagian 2: Navigasi dan Section | Nav anchor, hero, article proyek, keahlian, kontak |
| Bagian 3: Styling Dasar | Stylesheet biru: flexbox dan smooth scroll |
| Bagian 4: Interaksi Navigasi | aria-current dan tombol kembali ke atas |
Memakai File Pendukung #
Tiga folder proyek menyimpan berkas pendukung. Susun salinan lokalnya mengikuti pohon berikut:
website-portofolio/
├── assets/
│ └── logo.svg
├── styles/
│ └── style.css
├── tests/
│ └── cek-struktur.html
├── part-1-struktur-halaman/
│ └── portofolio.html
└── part-2-navigasi-dan-section/
└── portofolio-navigasi.html- assets/logo.svg: logo monogram “SR” untuk header setiap tahap.
- styles/style.css: stylesheet final, ditulis pada Bagian 3 dan dipakai Bagian 4.
- tests/cek-struktur.html: checklist sepuluh butir pemeriksaan; kemajuannya tersimpan di localStorage.
Unduh contoh tiap bagian lewat tautan pada header code block, lalu letakkan sesuai pohon di atas agar jalur relatif seperti ../styles/style.css tetap benar.
Referensi resmi untuk pendalaman:
Tahap 1 dari proyek Website Portofolio.
Buka → # Bagian 2: Navigasi dan SectionTahap 2 dari proyek Website Portofolio.
Buka → # Bagian 3: Styling DasarTahap 3 dari proyek Website Portofolio.
Buka → # Bagian 4: Interaksi NavigasiTahap 4 dari proyek Website Portofolio.
Buka →Berkas Sumber
Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.
styles/style.css
Unduh berkas/* Stylesheet proyek Website Portofolio - ditulis pada Bagian 3, dipakai Bagian 3 dan 4 */
:root {
--warna-utama: #2451b3;
--warna-teks: #1f2937;
--warna-latar: #f3f4f6;
--warna-putih: #ffffff;
--jarak: 16px;
}
* {
box-sizing: border-box;
}
html {
scroll-behavior: smooth;
}
body {
margin: 0;
font-family: system-ui, sans-serif;
line-height: 1.6;
color: var(--warna-teks);
background-color: var(--warna-latar);
}
header {
background-color: var(--warna-utama);
color: var(--warna-putih);
padding: var(--jarak);
}
header img {
width: 56px;
height: auto;
border-radius: 50%;
}
nav ul {
display: flex;
flex-wrap: wrap;
gap: var(--jarak);
margin: var(--jarak) 0 0;
padding: 0;
list-style: none;
}
nav a {
color: var(--warna-putih);
text-decoration: none;
font-weight: 600;
}
nav a.aktif {
text-decoration: underline;
text-underline-offset: 4px;
}
main {
max-width: 960px;
margin: 0 auto;
padding: var(--jarak);
}
section {
margin-bottom: calc(var(--jarak) * 2);
padding: var(--jarak);
background-color: var(--warna-putih);
border-radius: 8px;
}
h2 {
margin-top: 0;
color: var(--warna-utama);
}
article {
margin-top: var(--jarak);
padding-top: var(--jarak);
border-top: 1px solid #d1d5db;
}
img {
max-width: 100%;
height: auto;
}
footer {
background-color: var(--warna-utama);
color: var(--warna-putih);
}
footer p {
margin: 0;
padding: var(--jarak);
text-align: center;
}
.tombol-atas {
position: fixed;
right: 16px;
bottom: 16px;
padding: 10px 16px;
border: none;
border-radius: 6px;
background-color: var(--warna-teks);
color: var(--warna-putih);
cursor: pointer;
}
tests/cek-struktur.html
Unduh berkas<!doctype html>
<html lang="id">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Checklist Pemeriksaan Website Portofolio</title>
<style>
body {
font-family: system-ui, sans-serif;
max-width: 720px;
margin: 0 auto;
padding: 16px;
line-height: 1.6;
color: #1f2937;
}
h1 {
font-size: 1.4rem;
}
ul {
padding-left: 20px;
}
li {
margin-bottom: 8px;
}
#progres {
width: 100%;
height: 16px;
}
</style>
</head>
<body>
<header>
<img src="../assets/logo.svg" alt="Logo monogram SR" width="48" height="48">
<h1>Checklist Pemeriksaan Website Portofolio</h1>
</header>
<p>Gunakan halaman ini untuk memeriksa hasil setiap Bagian proyek. Centang butir yang telah dipenuhi; kemajuan tersimpan otomatis di browser.</p>
<p id="ringkasan" aria-live="polite">0 dari 10 butir terpenuhi.</p>
<progress id="progres" value="0" max="10"></progress>
<ul>
<li><label><input type="checkbox" data-cek="1"> Dokumen dimulai dengan <code>doctype</code> dan <code>html lang="id"</code></label></li>
<li><label><input type="checkbox" data-cek="2"> Head memuat <code>meta charset</code>, <code>viewport</code>, <code>title</code>, dan <code>description</code></label></li>
<li><label><input type="checkbox" data-cek="3"> Nav dengan <code>aria-label</code> memuat tautan ke seluruh section</label></li>
<li><label><input type="checkbox" data-cek="4"> Setiap tautan nav menuju id section yang benar-benar ada</label></li>
<li><label><input type="checkbox" data-cek="5"> Section beranda, proyek, keahlian, dan kontak ber-id unik</label></li>
<li><label><input type="checkbox" data-cek="6"> Setiap proyek dibungkus <code>article</code> dengan heading sendiri</label></li>
<li><label><input type="checkbox" data-cek="7"> Logo dan gambar lain memakai teks <code>alt</code> yang menjelaskan isi</label></li>
<li><label><input type="checkbox" data-cek="8"> Halaman terhubung ke stylesheet <code>styles/style.css</code></label></li>
<li><label><input type="checkbox" data-cek="9"> Tautan nav aktif membawa <code>aria-current</code> saat dipilih</label></li>
<li><label><input type="checkbox" data-cek="10"> Tombol kembali ke atas menggulir halaman dengan halus</label></li>
</ul>
<p>Sintaks seluruh file proyek juga dapat diperiksa dengan Nu Html Checker di <a href="https://validator.w3.org/nu/">validator.w3.org/nu</a>.</p>
<script>
const daftar = document.querySelectorAll("input[type='checkbox']");
const progres = document.querySelector("#progres");
const ringkasan = document.querySelector("#ringkasan");
const KUNCI = "cek-website-portofolio";
function simpan() {
const status = [];
daftar.forEach(function (butir) {
status.push(butir.checked);
});
try {
localStorage.setItem(KUNCI, JSON.stringify(status));
} catch (galat) {
// penyimpanan tidak tersedia; status tetap berlaku selama halaman terbuka
}
}
function muat() {
try {
const status = JSON.parse(localStorage.getItem(KUNCI));
if (Array.isArray(status)) {
daftar.forEach(function (butir, indeks) {
butir.checked = status[indeks] === true;
});
}
} catch (galat) {
// biarkan semua butir pada keadaan awalnya
}
}
function perbarui() {
let terisi = 0;
daftar.forEach(function (butir) {
if (butir.checked) {
terisi += 1;
}
});
progres.value = terisi;
ringkasan.textContent = terisi + " dari " + daftar.length + " butir terpenuhi.";
}
muat();
perbarui();
daftar.forEach(function (butir) {
butir.addEventListener("change", function () {
perbarui();
simpan();
});
});
</script>
</body>
</html>