Hampir setiap produk perangkat lunak menempatkan dokumentasi tepat di belakang halaman utamanya: pengunjung yang mulai serius memakai produk langsung mencari cara memasang, daftar fitur, dan jawaban atas pertanyaan teknis. Format halaman dokumentasi pun khas dan mudah dikenali — bilah samping berisi daftar topik, artikel panjang di sebelahnya, breadcrumb di bagian atas, dan kolom pencarian yang menyaring daftar topik. Proyek ini membangun satu halaman dokumentasi utuh untuk aplikasi fiktif CatatKu, aplikasi pencatat ringan dari Komunitas Belajar Web.
Hasil Akhir yang Dibangun #
Target akhirnya adalah satu halaman dokumentasi CatatKu dengan fitur berikut:
- Kerangka valid berisi header identitas, main dua kolom konsep (nav sidebar dan article konten), serta footer.
- Navigasi lengkap: daftar topik dengan tautan fragment
#id, breadcrumbol, dan daftar “Di halaman ini”. - Tabel pintasan keyboard dengan
captiondan selthberatributscope. - Tampilan dari styles/style.css: grid dua kolom, sidebar sticky, tipografi
pre/code, dan palet konsisten. - Pencarian sederhana: kolom saring yang menyembunyikan topik tak cocok lewat atribut
hidden.
Prasyarat #
Proyek ini merangkai konsep dari section sebelumnya; baca dahulu bila materinya masih asing:
- Section Struktur Dokumen dan Semantic HTML: kerangka dokumen serta elemen
nav,article, danaddress. - Section Lists dan Tables: daftar navigasi
uldan tabel pintasan. - Section Links dan Navigasi: tautan fragment menuju elemen ber-id.
- Section HTML dan CSS: custom properties, grid, dan posisi sticky.
- Section HTML dan JavaScript:
querySelectordan event listener.
Empat Bagian Proyek #
Kerjakan keempat bagian berurutan; setiap bagian memakai hasil bagian sebelumnya:
| Bagian | Fokus |
|---|---|
| Bagian 1: Menyusun Struktur Dokumentasi | Kerangka valid: header, main dua kolom konsep, footer |
| Bagian 2: Navigasi Dokumentasi | Daftar topik, breadcrumb, dan daftar “Di halaman ini” |
| Bagian 3: Styling Dasar | Stylesheet: grid, sidebar sticky, tipografi kode |
| Bagian 4: Pencarian Sederhana | Kolom saring topik dengan JavaScript |
Memakai File Pendukung #
Tiga folder proyek menyimpan berkas pendukung. Susun salinan lokalnya mengikuti pohon berikut:
halaman-dokumentasi/
├── assets/
│ └── logo-docs.svg
├── styles/
│ └── style.css
├── tests/
│ └── cek-struktur.html
├── part-1-struktur-dokumentasi/
│ └── dokumentasi.html
├── part-2-navigasi-dokumentasi/
│ └── dokumentasi-navigasi.html
├── part-3-styling-dasar/
│ └── dokumentasi-styling.html
└── part-4-pencarian-sederhana/
├── dokumentasi-pencarian.html
└── pencarian.js- assets/logo-docs.svg: ikon dokumen 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 dan ../assets/logo-docs.svg tetap benar.
Referensi resmi untuk pendalaman:
Tahap 1 dari proyek Halaman Dokumentasi.
Buka → # Bagian 2: Navigasi DokumentasiTahap 2 dari proyek Halaman Dokumentasi.
Buka → # Bagian 3: Styling DasarTahap 3 dari proyek Halaman Dokumentasi.
Buka → # Bagian 4: Pencarian SederhanaTahap 4 dari proyek Halaman Dokumentasi.
Buka →Berkas Sumber
Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.
styles/style.css
Unduh berkas/* Stylesheet proyek Halaman Dokumentasi - ditulis pada Bagian 3, dipakai Bagian 3 dan 4 */
:root {
--warna-utama: #1d4ed8;
--warna-teks: #1f2937;
--warna-latar: #f8fafc;
--warna-putih: #ffffff;
--warna-border: #cbd5e1;
--warna-kode: #eef2ff;
--jarak: 16px;
}
* {
box-sizing: border-box;
}
body {
margin: 0;
font-family: system-ui, sans-serif;
line-height: 1.6;
color: var(--warna-teks);
background-color: var(--warna-latar);
}
header {
display: flex;
align-items: center;
gap: var(--jarak);
padding: var(--jarak) calc(var(--jarak) * 2);
background-color: var(--warna-utama);
color: var(--warna-putih);
}
header h1 {
margin: 0;
font-size: 1.25rem;
}
header p {
margin: 0;
font-size: 0.9rem;
}
main {
display: grid;
grid-template-columns: 240px minmax(0, 1fr);
gap: calc(var(--jarak) * 2);
max-width: 1024px;
margin: 0 auto;
padding: calc(var(--jarak) * 2);
}
main > nav {
position: sticky;
top: var(--jarak);
align-self: start;
padding: var(--jarak);
background-color: var(--warna-putih);
border: 1px solid var(--warna-border);
border-radius: 8px;
}
main > nav ul {
list-style: none;
margin: 0;
padding: 0;
}
main > nav li {
margin-bottom: 8px;
}
main > nav a {
color: var(--warna-utama);
text-decoration: none;
}
main > nav a:hover {
text-decoration: underline;
}
/* Kolom saring topik (Bagian 4) */
main > nav label {
display: block;
margin-bottom: 8px;
font-weight: 700;
}
main > nav input {
width: 100%;
margin-bottom: var(--jarak);
padding: 8px;
font: inherit;
border: 1px solid var(--warna-border);
border-radius: 6px;
}
article {
padding: calc(var(--jarak) * 1.5);
background-color: var(--warna-putih);
border: 1px solid var(--warna-border);
border-radius: 8px;
}
article h2 {
margin-top: 0;
padding-bottom: 8px;
border-bottom: 1px solid var(--warna-border);
color: var(--warna-utama);
}
.breadcrumb ol {
display: flex;
flex-wrap: wrap;
gap: 8px;
margin: 0 0 var(--jarak);
padding: 0;
list-style: none;
font-size: 0.9rem;
}
.breadcrumb li + li::before {
content: "›";
margin-right: 8px;
}
.breadcrumb a {
color: var(--warna-utama);
}
.toc {
margin-bottom: calc(var(--jarak) * 1.5);
padding: var(--jarak);
background-color: var(--warna-latar);
border: 1px solid var(--warna-border);
border-radius: 8px;
}
.toc-label {
margin: 0 0 8px;
font-weight: 700;
}
.toc ol {
margin: 0;
padding-left: 20px;
}
table {
width: 100%;
margin: var(--jarak) 0;
border-collapse: collapse;
}
caption {
padding-bottom: 8px;
font-weight: 700;
text-align: left;
}
th,
td {
padding: 8px var(--jarak);
border: 1px solid var(--warna-border);
text-align: left;
}
kbd {
padding: 2px 6px;
font-family: monospace;
font-size: 0.9em;
background-color: var(--warna-latar);
border: 1px solid var(--warna-border);
border-radius: 4px;
}
code {
padding: 2px 4px;
font-family: monospace;
background-color: var(--warna-kode);
border-radius: 4px;
}
pre {
padding: var(--jarak);
overflow-x: auto;
background-color: var(--warna-kode);
border-radius: 8px;
}
pre code {
padding: 0;
background-color: transparent;
}
address {
font-style: normal;
}
footer {
padding: var(--jarak) calc(var(--jarak) * 2);
text-align: center;
background-color: var(--warna-putih);
border-top: 1px solid var(--warna-border);
}
footer p {
margin: 0;
}
@media (max-width: 700px) {
main {
display: block;
}
main > nav {
position: static;
margin-bottom: var(--jarak);
}
}
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 Halaman Dokumentasi</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-docs.svg" alt="Logo Dokumentasi CatatKu" width="48" height="48">
<h1>Checklist Pemeriksaan Halaman Dokumentasi</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"> Header memuat logo ber<code>alt</code> deskriptif serta <code>h1</code> nama dokumentasi</label></li>
<li><label><input type="checkbox" data-cek="4"> Main terbagi dua wilayah: <code>nav</code> daftar topik dan <code>article</code> konten</label></li>
<li><label><input type="checkbox" data-cek="5"> Setiap topik artikel dibuka <code>h2</code> dengan <code>id</code> unik (pengenalan hingga dukungan)</label></li>
<li><label><input type="checkbox" data-cek="6"> Tautan sidebar menunjuk fragment <code>#id</code> yang cocok dengan id bagian</label></li>
<li><label><input type="checkbox" data-cek="7"> Breadcrumb memakai <code>ol</code> dengan <code>aria-current="page"</code> pada posisi terkini</label></li>
<li><label><input type="checkbox" data-cek="8"> Daftar "Di halaman ini" tersedia di awal <code>article</code></label></li>
<li><label><input type="checkbox" data-cek="9"> Halaman terhubung ke stylesheet <code>styles/style.css</code></label></li>
<li><label><input type="checkbox" data-cek="10"> Kolom saring berlabel <code>for</code>/<code>id</code>; butir tak cocok disembunyikan lewat <code>hidden</code></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-halaman-dokumentasi";
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>