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.
Menulis styles/style.css #
Buat folder styles/ pada akar proyek, lalu simpan file berikut sebagai 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:
- Blok
:root: tujuh token warna, satu token lebar, dan dua token jenis huruf. Nilai65chpada--lebar-bacamemakai satuanch— lebar karakter angka nol — sehinggamax-width: 65chmenghasilkan baris sekitar 60-70 karakter, kisaran yang dianjurkan untuk keterbacaan. - Aturan
body: latar krem lembut, teks hijau tua keabu-abuan, jenis huruf serif untuk isi artikel, danline-height: 1.7yang memberi jarak antarbaris 70 persen dari ukuran huruf — jauh lebih lega daripada bawaan browser. - Aturan
navdanarticle: keduanya dikunci padamax-width: var(--lebar-baca)lalu dipusatkan denganmargin-inline: auto, sehingga baris teks tidak membentang di layar lebar. - Aturan
.lead: paragraf pengantar diperbesar dan diberi warna lembut, membedakannya dari isi utama tanpa tambahan markup. - Aturan
figure img:max-width: 100%denganheight: automenjaga gambar tetap di dalam kolom baca pada layar sempit — pasangan deklarasi yang sama dengan pola responsive images pada section Images dan Media. - 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:
<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:
- Buka
artikel-navigasi.htmldi browser setelah barislinkditambahkan. Latar krem, lebar kolom terkendali, dan jenis huruf serif harus langsung terlihat; bila tidak, periksa kembalihref="../styles/style.css"serta posisi folderstyles/. - Persempit jendela browser hingga setengah layar dan pastikan gambar serta teks ikut menyusut tanpa scrollbar horizontal.
- 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/* 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<!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// 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();
}