Struktur artikel dari dua bagian pertama tampil dengan gaya bawaan browser: huruf satu ukuran, teks membentang selebar jendela, dan satu-satunya warna adalah hitam-putih. Bacaan panjang dengan bentuk seperti itu melelahkan mata. Pada Bagian ketiga ini kita menulis styles/style.css, stylesheet pertama proyek yang mengatur tipografi artikel agar nyaman dibaca: lebar baris yang terkendali, jarak antarbaris yang lega, dan palet warna yang konsisten di seluruh halaman.

Token Desain dengan Custom Properties #

Sebelum menyentuh elemen mana pun, kita menetapkan token desain — sekumpulan nilai bernama di dalam custom properties pada selector :root. Custom properties diperkenalkan pada section HTML dan CSS; kekuatannya baru terasa pada proyek: warna aksen yang kini tersebar di sepuluh aturan cukup diubah satu kali di :root, dan seluruh halaman ikut menyesuaikan.

Buat folder styles/ pada akar proyek, lalu simpan file berikut sebagai style.css:

css styles/style.css
/* styles/style.css — Aneka Baca
   Stylesheet bersama proyek Website Artikel.
   Ditulis pada Bagian 3, dipakai seluruh halaman sampai akhir proyek. */

/* Token desain: ubah nilai di sini, seluruh halaman ikut menyesuaikan. */
:root {
  --warna-teks: #26312b;
  --warna-teks-lembut: #5c6b62;
  --warna-latar: #faf7f1;
  --warna-aksen: #1a6b54;
  --warna-garis: #ddd5c7;
  --lebar-baca: 65ch;
  --font-artikel: Georgia, "Times New Roman", serif;
  --font-antarmuka: "Segoe UI", Arial, sans-serif;
}

body {
  margin: 0;
  background-color: var(--warna-latar);
  color: var(--warna-teks);
  font-family: var(--font-artikel);
  line-height: 1.7;
}

nav {
  max-width: var(--lebar-baca);
  margin-inline: auto;
  padding: 1rem 1rem 0;
}

nav ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem 1.25rem;
  font-family: var(--font-antarmuka);
  font-size: 0.95rem;
}

nav a {
  color: var(--warna-aksen);
}

article {
  max-width: var(--lebar-baca);
  margin-inline: auto;
  padding: 1.5rem 1rem 3rem;
}

h1,
h2 {
  font-family: var(--font-antarmuka);
  line-height: 1.25;
}

h1 {
  font-size: 2rem;
}

.lead {
  font-size: 1.125rem;
  color: var(--warna-teks-lembut);
}

figure {
  margin: 2rem 0;
}

figure img {
  max-width: 100%;
  height: auto;
  border-radius: 8px;
}

figcaption {
  margin-top: 0.5rem;
  font-size: 0.9rem;
  color: var(--warna-teks-lembut);
}

article > footer {
  margin-top: 2.5rem;
  padding-top: 1rem;
  border-top: 1px solid var(--warna-garis);
  font-size: 0.95rem;
  color: var(--warna-teks-lembut);
}

details {
  border: 1px solid var(--warna-garis);
  border-radius: 8px;
  padding: 0.75rem 1rem;
  margin: 0 0 2rem;
  font-family: var(--font-antarmuka);
}

details ul {
  margin: 0.5rem 0 0.25rem;
  padding-left: 1.25rem;
}

#tombol-bookmark {
  font-family: var(--font-antarmuka);
  font-size: 1rem;
  background-color: var(--warna-aksen);
  color: #ffffff;
  border: 0;
  border-radius: 999px;
  padding: 0.5rem 1.25rem;
  cursor: pointer;
}

#tombol-bookmark[aria-pressed="true"] {
  background-color: var(--warna-garis);
  color: var(--warna-teks);
}

Dua aturan terakhir sengaja ditulis sejak sekarang: details dan #tombol-bookmark baru berguna pada Bagian 4, tetapi menyediakannya di sini membuat stylesheet berhenti berubah setelah tahap ini. Mari kita bedah aturan-aturan kuncinya:

  1. Blok :root: tujuh token warna, satu token lebar, dan dua token jenis huruf. Nilai 65ch pada --lebar-baca memakai satuan ch — lebar karakter angka nol — sehingga max-width: 65ch menghasilkan baris sekitar 60-70 karakter, kisaran yang dianjurkan untuk keterbacaan.
  2. Aturan body: latar krem lembut, teks hijau tua keabu-abuan, jenis huruf serif untuk isi artikel, dan line-height: 1.7 yang memberi jarak antarbaris 70 persen dari ukuran huruf — jauh lebih lega daripada bawaan browser.
  3. Aturan nav dan article: keduanya dikunci pada max-width: var(--lebar-baca) lalu dipusatkan dengan margin-inline: auto, sehingga baris teks tidak membentang di layar lebar.
  4. Aturan .lead: paragraf pengantar diperbesar dan diberi warna lembut, membedakannya dari isi utama tanpa tambahan markup.
  5. Aturan figure img: max-width: 100% dengan height: auto menjaga gambar tetap di dalam kolom baca pada layar sempit — pasangan deklarasi yang sama dengan pola responsive images pada section Images dan Media.
  6. Aturan article > footer: pemilih anak langsung memastikan hanya footer milik artikel yang diberi garis pemisah, bukan footer lain yang mungkin muncul kelak.

Menghubungkan Stylesheet ke Halaman #

File style.css berada di folder styles/ pada akar proyek, sedangkan halaman artikel berada satu tingkat di bawahnya. Karena itu href pada elemen link memakai awalan ../ untuk naik satu folder terlebih dahulu:

html Potongan head artikel-navigasi.html
<link rel="stylesheet" href="../styles/style.css">

Tambahkan baris tersebut ke head artikel-navigasi.html (dan kelak ke halaman Bagian 4), tepat sebelum penutup head. Bila path salah, halaman tetap tampil tetapi tanpa gaya sama sekali — gejala yang mudah dikenali dan menunjuk langsung ke nilai href.

Langkah Pemeriksaan #

Tuntaskan Bagian ini dengan urutan berikut:

  1. Buka artikel-navigasi.html di browser setelah baris link ditambahkan. Latar krem, lebar kolom terkendali, dan jenis huruf serif harus langsung terlihat; bila tidak, periksa kembali href="../styles/style.css" serta posisi folder styles/.
  2. Persempit jendela browser hingga setengah layar dan pastikan gambar serta teks ikut menyusut tanpa scrollbar horizontal.
  3. Jalankan ../tests/cek-struktur.html, lalu centang butir-butir pada kelompok File pendukung yang terkait stylesheet.

Tipografi beres dan warna kini konsisten di seluruh halaman. Bagian 4 menambahkan lapisan terakhir proyek: daftar isi yang dapat dibuka-tutup dan tombol bookmark yang mengingat pilihan pengunjung menggunakan JavaScript.

Referensi resmi untuk pendalaman:

Berkas Sumber

Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.

styles/style.css

Unduh berkas
css
/* styles/style.css — Aneka Baca
   Stylesheet bersama proyek Website Artikel.
   Ditulis pada Bagian 3, dipakai seluruh halaman sampai akhir proyek. */

/* Token desain: ubah nilai di sini, seluruh halaman ikut menyesuaikan. */
:root {
  --warna-teks: #26312b;
  --warna-teks-lembut: #5c6b62;
  --warna-latar: #faf7f1;
  --warna-aksen: #1a6b54;
  --warna-garis: #ddd5c7;
  --lebar-baca: 65ch;
  --font-artikel: Georgia, "Times New Roman", serif;
  --font-antarmuka: "Segoe UI", Arial, sans-serif;
}

body {
  margin: 0;
  background-color: var(--warna-latar);
  color: var(--warna-teks);
  font-family: var(--font-artikel);
  line-height: 1.7;
}

nav {
  max-width: var(--lebar-baca);
  margin-inline: auto;
  padding: 1rem 1rem 0;
}

nav ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem 1.25rem;
  font-family: var(--font-antarmuka);
  font-size: 0.95rem;
}

nav a {
  color: var(--warna-aksen);
}

article {
  max-width: var(--lebar-baca);
  margin-inline: auto;
  padding: 1.5rem 1rem 3rem;
}

h1,
h2 {
  font-family: var(--font-antarmuka);
  line-height: 1.25;
}

h1 {
  font-size: 2rem;
}

.lead {
  font-size: 1.125rem;
  color: var(--warna-teks-lembut);
}

figure {
  margin: 2rem 0;
}

figure img {
  max-width: 100%;
  height: auto;
  border-radius: 8px;
}

figcaption {
  margin-top: 0.5rem;
  font-size: 0.9rem;
  color: var(--warna-teks-lembut);
}

article > footer {
  margin-top: 2.5rem;
  padding-top: 1rem;
  border-top: 1px solid var(--warna-garis);
  font-size: 0.95rem;
  color: var(--warna-teks-lembut);
}

details {
  border: 1px solid var(--warna-garis);
  border-radius: 8px;
  padding: 0.75rem 1rem;
  margin: 0 0 2rem;
  font-family: var(--font-antarmuka);
}

details ul {
  margin: 0.5rem 0 0.25rem;
  padding-left: 1.25rem;
}

#tombol-bookmark {
  font-family: var(--font-antarmuka);
  font-size: 1rem;
  background-color: var(--warna-aksen);
  color: #ffffff;
  border: 0;
  border-radius: 999px;
  padding: 0.5rem 1.25rem;
  cursor: pointer;
}

#tombol-bookmark[aria-pressed="true"] {
  background-color: var(--warna-garis);
  color: var(--warna-teks);
}

tests/cek-struktur.html

Unduh berkas
html
<!doctype html>
<html lang="id">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Cek Struktur — Proyek Website Artikel</title>
  <link rel="stylesheet" href="../styles/style.css">
  <script src="cek-struktur.js" defer></script>
  <style>
    .cek {
      list-style: none;
      padding-left: 0;
    }

    .cek li {
      margin-bottom: 0.5rem;
    }

    .cek input {
      margin-right: 0.5rem;
    }

    #progres {
      font-weight: 700;
    }
  </style>
</head>
<body>
  <main>
    <header>
      <h1>Cek Struktur Proyek Website Artikel</h1>
      <p>Halaman ini membantu memeriksa hasil setiap Bagian proyek Aneka Baca secara mandiri. Centang butir yang terpenuhi; progres tersimpan otomatis di browser dan tidak perlu dicentang ulang.</p>
      <p id="progres">0 dari 14 butir terpenuhi</p>
    </header>

    <fieldset>
      <legend>Struktur semantik (Bagian 1)</legend>
      <ul class="cek">
        <li><input type="checkbox" id="cek-s1" data-cek="s1"><label for="cek-s1">Dokumen memakai doctype, <code>html lang="id"</code>, <code>meta charset</code>, dan <code>title</code> gabungan judul artikel plus nama situs</label></li>
        <li><input type="checkbox" id="cek-s2" data-cek="s2"><label for="cek-s2">Seluruh konten dibungkus satu elemen <code>article</code></label></li>
        <li><input type="checkbox" id="cek-s3" data-cek="s3"><label for="cek-s3">Artikel memakai <code>header</code> berisi satu <code>h1</code> dan paragraf lead berclass</label></li>
        <li><input type="checkbox" id="cek-s4" data-cek="s4"><label for="cek-s4">Gambar berada di dalam <code>figure</code> dengan <code>figcaption</code> berbahasa Indonesia</label></li>
        <li><input type="checkbox" id="cek-s5" data-cek="s5"><label for="cek-s5">Setiap bagian isi memakai <code>section</code> dengan <code>h2</code> sendiri</label></li>
        <li><input type="checkbox" id="cek-s6" data-cek="s6"><label for="cek-s6">Footer artikel berisi penulis dan <code>time</code> dengan atribut <code>datetime</code> format YYYY-MM-DD</label></li>
        <li><input type="checkbox" id="cek-s7" data-cek="s7"><label for="cek-s7">Nav berisi daftar tautan dengan <code>aria-label</code> pembeda</label></li>
      </ul>
    </fieldset>

    <fieldset>
      <legend>Metadata head (Bagian 2)</legend>
      <ul class="cek">
        <li><input type="checkbox" id="cek-m1" data-cek="m1"><label for="cek-m1"><code>meta name="description"</code> berisi ringkasan satu-dua kalimat</label></li>
        <li><input type="checkbox" id="cek-m2" data-cek="m2"><label for="cek-m2"><code>link rel="canonical"</code> menunjuk alamat resmi halaman</label></li>
        <li><input type="checkbox" id="cek-m3" data-cek="m3"><label for="cek-m3"><code>og:title</code> dan <code>og:description</code> terisi dengan nilai berbeda dari kosong</label></li>
      </ul>
    </fieldset>

    <fieldset>
      <legend>File pendukung (Bagian 3)</legend>
      <ul class="cek">
        <li><input type="checkbox" id="cek-f1" data-cek="f1"><label for="cek-f1">File <code>assets/hero.svg</code> tersedia dan tampil pada halaman artikel</label></li>
        <li><input type="checkbox" id="cek-f2" data-cek="f2"><label for="cek-f2">File <code>styles/style.css</code> terhubung lewat <code>link</code> dengan path <code>../styles/style.css</code></label></li>
        <li><input type="checkbox" id="cek-f3" data-cek="f3"><label for="cek-f3">Warna dan jenis huruf diatur lewat token <code>:root</code>, bukan nilai lepas di tiap aturan</label></li>
      </ul>
    </fieldset>

    <fieldset>
      <legend>Interaksi (Bagian 4)</legend>
      <ul class="cek">
        <li><input type="checkbox" id="cek-i1" data-cek="i1"><label for="cek-i1">Daftar isi <code>details</code> tampil, dapat dibuka, dan tautannya melompat ke section terkait</label></li>
        <li><input type="checkbox" id="cek-i2" data-cek="i2"><label for="cek-i2">Tombol bookmark mengubah label dan <code>aria-pressed</code> saat diklik</label></li>
        <li><input type="checkbox" id="cek-i3" data-cek="i3"><label for="cek-i3">Status bookmark bertahan setelah halaman dimuat ulang</label></li>
      </ul>
    </fieldset>

    <p><img src="../assets/hero.svg" alt="" width="112" height="63"></p>
    <p>Halaman pemeriksaan ini juga memakai stylesheet proyek dan gambar aset melalui path relatif <code>../</code>, sekaligus menjadi contoh rujukan lintas folder.</p>
  </main>
</body>
</html>

tests/cek-struktur.js

Unduh berkas
javascript
// cek-struktur.js — checklist mandiri proyek dengan progres tersimpan.
// Digunakan bersama cek-struktur.html pada folder tests/ proyek.

const KUNCI_SIMPAN = "cek:website-artikel";

function bacaTersimpan() {
  try {
    return JSON.parse(localStorage.getItem(KUNCI_SIMPAN)) || {};
  } catch (galat) {
    return {};
  }
}

function tulisTersimpan(nilai) {
  try {
    localStorage.setItem(KUNCI_SIMPAN, JSON.stringify(nilai));
  } catch (galat) {
    // Penyimpanan tidak tersedia; checklist tetap berfungsi tanpa persist.
  }
}

function perbaruiProgres() {
  const kotak = Array.from(document.querySelectorAll("[data-cek]"));
  const terpenuhi = kotak.filter(function (item) {
    return item.checked;
  }).length;
  const progres = document.querySelector("#progres");
  if (progres) {
    progres.textContent = terpenuhi + " dari " + kotak.length + " butir terpenuhi";
  }
}

function pasang() {
  const tersimpan = bacaTersimpan();
  const kotak = Array.from(document.querySelectorAll("[data-cek]"));
  kotak.forEach(function (item) {
    item.checked = tersimpan[item.dataset.cek] === true;
    item.addEventListener("change", function () {
      const nilai = bacaTersimpan();
      nilai[item.dataset.cek] = item.checked;
      tulisTersimpan(nilai);
      perbaruiProgres();
    });
  });
  perbaruiProgres();
}

if (document.readyState === "loading") {
  document.addEventListener("DOMContentLoaded", pasang);
} else {
  pasang();
}