Belajar Angular - Accessibility & UX
Episode 17 of 24

Belajar Angular - Accessibility & UX

Episode ini membahas accessibility dan UX: atribut ARIA dan navigasi keyboard, markup semantik dan form yang aksesibel, responsive layout dan dukungan mobile, serta internationalization dan localization.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Pendahuluan

Aplikasi yang baik bisa dipakai oleh semua orang — termasuk pengguna screen reader, pengguna keyboard, dan perangkat dengan layar kecil. Accessibility bukan fitur opsional; ia standar kualitas.

Episode 17 membahas atribut ARIA dan navigasi keyboard, markup semantik dan form yang aksesibel, responsive layout dan dukungan mobile, serta internationalization dan localization. Aksesibilitas yang baik hampir selalu meningkatkan UX untuk semua orang.

ARIA Attributes dan Keyboard Navigation

Menambahkan Atribut ARIA

ARIA (Accessible Rich Internet Applications) memberi informasi tambahan ke assistive technology. Angular Material dan CDK sudah memakai ARIA secara internal; komponen custom perlu menyetelnya sendiri:

HTMLAtribut ARIA di komponen
<button
  (click)="bukaMenu()"
  aria-haspopup="true"
  [attr.aria-expanded]="menuTerbuka">
  Menu
</button>

aria-haspopup memberi tahu screen reader bahwa tombol membuka menu, sementara [attr.aria-expanded] menyatakan status buka-tutup yang mengikuti state menuTerbuka. Angular mengikat atribut ARIA lewat [attr.*].

Aplikasi harus bisa dioperasikan sepenuhnya dengan keyboard: Tab berpindah fokus, Enter atau Space mengaktifkan, dan Escape menutup. CDK a11y menyediakan FocusTrap, FocusMonitor, dan LiveAnnouncer:

JSMengumumkan perubahan ke screen reader
import { Component, inject } from '@angular/core';
import { LiveAnnouncer } from '@angular/cdk/a11y';
 
@Component({ selector: 'app-notif', standalone: true, template: `` })
export class NotifComponent {
  private readonly announcer = inject(LiveAnnouncer);
 
  kirimPesan(pesan: string): void {
    this.announcer.announce(pesan, 'polite');
  }
}

LiveAnnouncer.announce membacakan pesan secara lisan untuk pengguna screen reader tanpa mengganggu alur fokus. Pola ini penting saat konten berubah secara dinamis — misalnya status "Data berhasil disimpan".

Semantic Markup dan Accessible Forms

Gunakan Elemen yang Tepat

Screen reader menavigasi berdasarkan struktur. Gunakan elemen semantik: header, nav, main, h1 sampai h6, button, a, dan label — bukan div dengan role manual. Judul harus membentuk hierarki yang logis.

Form yang Aksesibel

Setiap input harus punya label yang terasosiasi. Tanpa label, pengguna screen reader tidak tahu apa yang harus diisi:

HTMLForm dengan label yang benar
<div>
  <label for="email">Alamat email</label>
  <input id="email" type="email" [attr.aria-invalid]="email.invalid && email.touched" />
</div>

label[for] dan input[id] menghubungkan keduanya. aria-invalid memberi tahu assistive technology bahwa input bermasalah. Hindari placeholder sebagai satu-satunya label — placeholder menghilang saat mengetik dan kontrasnya sering rendah.

Pesan Error yang Terhubung

Hubungkan pesan error dengan input memakai aria-describedby:

HTMLError terhubung ke input
<input id="email" aria-describedby="errEmail" />
<small id="errEmail" role="alert">Format email tidak valid</small>

aria-describedby="errEmail" membuat screen reader membacakan pesan error tersebut ketika input difokus. Ini membuat validasi tidak hanya terlihat, tetapi juga terdengar.

Responsive Layout dan Mobile Support

Desain Mobile-First

Mulai dari ukuran layar kecil, lalu tingkatkan untuk layar besar. CSS grid dan flexbox dengan unit relatif seperti rem dan % membuat layout mengikuti ukuran viewport:

JSGrid responsif dengan SCSS
.kartu-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 16px;
}

repeat(auto-fit, minmax(240px, 1fr)) membuat grid otomatis menyesuaikan jumlah kolom dengan lebar layar — satu kolom di ponsel, beberapa kolom di desktop, tanpa media query untuk setiap breakpoint.

Dukungan Mobile

Perhatikan ukuran target sentuh minimal 44 piksel, hindari hover sebagai satu-satunya cara mengakses fungsi, dan uji di browser mobile yang nyata. Gunakan Angular CDK BreakpointObserver untuk logika layout yang perlu tahu ukuran layar:

JSDeteksi breakpoint dengan CDK
import { Component, inject, signal } from '@angular/core';
import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout';
 
@Component({ selector: 'app-layout', standalone: true, template: `` })
export class LayoutComponent {
  private readonly observer = inject(BreakpointObserver);
  readonly isMobile = signal(false);
 
  constructor() {
    this.observer.observe([Breakpoints.Handset]).subscribe((state) => {
      this.isMobile.set(state.matches);
    });
  }
}

Breakpoints.Handset bernilai true saat viewport berupa ponsel. Hasilnya bisa mengubah menu, jumlah kolom, atau tata letak panel secara reaktif.

Internationalization dan Localization

Mengaktifkan i18n

Angular i18n memakai paket @angular/localize. Tambahkan ke project:

Menambahkan dukungan i18n
ng add @angular/localize

Setelah itu, tandai teks yang perlu diterjemahkan dengan atribut i18n:

HTMLMenandai teks untuk diterjemahkan
<h1 i18n>Selamat datang di toko online</h1>
<p i18n>Belanja mudah dan aman</p>

i18n menandai teks agar bisa diekstrak ke file terjemahan. Jalankan perintah extract untuk menghasilkan file sumber terjemahan:

Mengekstrak teks untuk terjemahan
ng extract-i18n --output-path src/locale

Perintah ini menghasilkan messages.xlf yang dikirim ke penerjemah. Setelah terjemahan tersedia, aplikasi di-build per bahasa dengan --localize.

Multi-locale Build

Bangun aplikasi untuk beberapa bahasa sekaligus:

Build untuk semua locale
ng build --localize

Hasilnya folder terpisah per bahasa di dist. Angular juga menyediakan pipe DatePipe dan CurrencyPipe yang menyesuaikan format dengan locale aktif — jadi angka dan tanggal tampil sesuai kebiasaan setempat.

Penutup

Inti yang harus dibawa pulang:

  • ARIA dan navigasi keyboard membuat aplikasi bisa dipakai semua orang.
  • Gunakan elemen semantik dan label yang terasosiasi dengan input.
  • aria-describedby dan role="alert" menyampaikan error ke screen reader.
  • Grid auto-fit dan BreakpointObserver menghadirkan layout responsif.
  • ng add @angular/localize mengaktifkan dukungan i18n.
  • ng build --localize menghasilkan build terpisah per bahasa.

Di episode 18 selanjutnya kita akan membahas architecture dan patterns — feature modules dan modular architecture, shared, core, dan lazy modules, domain-driven design dengan struktur folder yang scalable, serta clean architecture dan separation of concerns.