→ From Coder to Shipper
From Coder to Shipper · Frontend

Frontend — HTML · CSS · Bootstrap · JS

Phía trình duyệt của web, trong một mô hình tư duy duy nhất. AI sẽ viết các file này cho bạn — bộ slide này là bản đồ để bạn đọc, đánh giá và sửa chúng.

← / → để chuyển slide · chuyển EN/VI bên dưới

Toàn cảnh

Một trang web = ba việc

Mọi trang bạn từng dùng — web bán hàng, dashboard, app ngân hàng — đều chia công việc ra ba file này.

HTML — cấu trúc & nội dung

Chữ, ảnh, nút bấm và thứ tự của chúng. Bộ khung, cùng những gì nằm bên trong.

CSS — kiểu dáng & bố cục

Màu, khoảng cách, chỗ đặt từng thứ. Biến xấp ô vuông thô thành một trang được thiết kế.

JS — hành vi

Điều xảy ra khi bạn click, gõ hay cuộn. Trang không còn là bức tranh tĩnh mà bắt đầu phản hồi.

Toàn cảnh

Trang đến màn hình bạn như thế nào

Frontend là phía client. Việc của server kết thúc ngay khi bàn giao ba loại file — mọi thứ sau đó xảy ra trong trình duyệt của bạn.

1 · Server

Gửi trang dưới dạng file thuần: HTML + CSS + JS.

2 · Browser

Phân tích HTML thành một cái cây, áp dụng CSS, chạy JS.

3 · You

Nhìn thấy các pixel — và click vào chúng. Frontend là mọi thứ nằm giữa server và mắt bạn.

server ──(html · css · js)──▶ browser ──(pixels)──▶ your eyes

Toàn cảnh · vòng lặp

Điều gì xảy ra khi bạn mở một URL

Bốn nhịp. Sau nhịp 3 trang đã 'sống' trong trình duyệt của bạn — và nhịp 4 lặp lại ở mỗi lần click.

  1. 1

    Bạn mở một URL

    Trình duyệt của bạn hỏi một server: 'đưa cho tôi trang này'.

  2. 2

    Server trả lời bằng các file

    Nó gửi HTML + CSS + JS. Toàn bộ câu trả lời chỉ là các file text.

  3. 3

    Trình duyệt dựng trang

    HTML thành một cây phần tử, CSS tô và xếp chúng vào chỗ, JS bắt đầu chạy.

  4. 4

    Bạn click — vòng lặp lặp lại

    JS phản hồi ngay tại chỗ; cần dữ liệu mới, nó hỏi server lần nữa (một API call) — không cần tải lại.

Toàn cảnh · vai trò của bạn

AI viết. Bạn chỉ đường.

Bộ slide này là tấm bản đồ đó — nhận ra, đánh giá, sửa.

AI mang đến cho bạn

Các file hoạt động được: HTML có cấu trúc thật, CSS trông chuyên nghiệp, JS biết phản hồi. Bạn hiếm khi tự tay gõ chúng.

Việc của bạn

Đọc cấu trúc, đánh giá thiết kế, thử hành vi. Bạn cần tấm bản đồ — chứ không phải bằng lái.

Bốn slide ngăn cách tiếp theo chính là bản đồ: HTML, CSS, Bootstrap, JS.

01
Phần 1

HTML — bộ khung

Các thẻ có ý nghĩa, lồng nhau thành một cái cây. File duy nhất quyết định trang web LÀ gì.

HTML · cấu tạo

Cả một trang, 11 dòng

Hai nửa: <head> là metadata và link (không thấy), <body> là mọi thứ bạn nhìn thấy.

index.html
<!doctype html>
<html>
  <head>                      ← invisible: title, CSS links
    <title>My page</title>
    <link rel="stylesheet" href="style.css">
  </head>
  <body>                      ← everything the user sees
    <h1>Hello, world</h1>
    <p>This is the first paragraph.</p>
    <p id="status"></p>
  </body>
</html>
Trực tiếp — thử ngay

Hello, world

This is the first paragraph.

click vào đây — bạn có thể sửa tôi

Bên phải là bản render trực tiếp của chính trang này — click vào dòng status, bạn có thể sửa nó. Thẻ đi theo cặp: <h1>…</h1>.

HTML · nó hoạt động thế nào

Ba quy tắc — đó là toàn bộ cú pháp

HTML gần như không có cú pháp. Giữ ba điều này là bạn đọc được mọi trang.

Thẻ đi theo cặp

<div> mở, </div> đóng. Thứ nằm giữa là nội dung của thẻ.

Thẻ lồng nhau thành cây

Thẻ nằm trong thẻ, luôn đóng đúng chỗ. Thứ tự lồng chính là cấu trúc của trang.

Thuộc tính thêm chi tiết

Thông tin thêm trong thẻ mở: <a href="/shop">. href nói link đi tới đâu.

HTML · từ vựng

Những thẻ bạn sẽ nhận ra ở khắp nơi

Bạn không cần học thuộc HTML — cần nhận ra nó khi bạn (hoặc AI của bạn) đọc.

ThẻNó làm gì
h1 – h6Tiêu đề, lớn → nhỏ. Mỗi trang một h1, còn lại là phân cấp.
p · a · imgĐoạn văn · liên kết · ảnh — ba trụ cột của nội dung.
div · spanÔ chứa chung — những ô không mang nghĩa, dùng để gói mọi thứ vào.
ul / liDanh sách gạch đầu dòng và các mục của nó.
button · input · formBộ ba tương tác: bấm · gõ vào · gửi đi.
nav · header · main · footerCác vùng chuẩn của trang: menu · trên cùng · nội dung · dưới cùng.
HTML · ví dụ

Một thanh menu, bằng HTML thuần

Một logo, một danh sách link, một nút. Chưa có CSS — chỉ có cấu trúc.

navbar.html
<nav>
  <a class="logo">MyShop</a>
  <ul>
    <li><a href="/shop">Shop</a></li>
    <li><a href="/about">About</a></li>
  </ul>
  <button>Log in</button>
</nav>
Trực tiếp — thử ngay

Bên phải chạy thật — click Shop, About hay Log in để thấy phản hồi. Mọi thanh menu bạn từng thấy đều là phiên bản của <nav> này.

HTML · khung trang

Một trang điển hình, dưới dạng cây

Gần như mọi web app bạn từng dùng đều có đúng hình dạng này: thanh trên cùng, cột bên trái, nội dung ở giữa.

layout.html
<body>
├── <nav>          menu bar — logo, links, 'login'
├── <div class="layout">
│   ├── <aside>    sidebar — filters, sub-menu
│   └── <main>     content — what the page is about
└── <footer>       links, copyright

# every element above is just a <div> or its friends —
# the layout you see is CSS placed on this tree

Đọc cái cây này từ trên xuống và bạn mô tả được cấu trúc của gần như mọi dashboard.

HTML · thành phần UI

UI quen thuộc — thực ra được làm từ gì

Nhận ra mẫu hình, đừng học thuộc cú pháp. Phần lớn UI 'sang' chỉ là HTML thường khoác thêm CSS.

Nút bấm

Một <button>, hoặc <a> được CSS hóa cho giống nút. Một phần tử, một việc.

Công tắc / switch

Một <input type='checkbox'> được CSS hóa thành công tắc — hoặc nút bấm đổi class.

Ô chọn ngày

Một input kèm popup do JS hiện ra. Cái lịch thực ra chỉ là lưới các nút nhỏ.

Carousel

Một hàng <img> trong flexbox; JS quyết định bạn đang xem slide nào.

Card (ảnh + chữ)

<img> + <div> + một đường viền. 'Card' là biệt danh cho một ô được style.

Form

Các input nằm trong <form>, thêm một <button type='submit'>. Nút gửi mới là ý chính.

HTML · ví dụ

Một form đăng nhập, 7 phần tử

UI phổ biến nhất trên web: một ô để gõ, và một nút để gửi.

login.html
<form>
  <label>Email</label>
  <input type="email" placeholder="you@example.com">

  <label>Password</label>
  <input type="password">

  <button type="submit">Log in</button>
</form>
Trực tiếp — thử ngay

Bên phải chạy thật — bấm Log in để form phản hồi (JS sẽ chặn ở đây). Mỗi <label> mô tả cho <input> bên cạnh.

HTML · đặt tên

id vs class — hai cách đặt tên phần tử

id — tên duy nhất

#status trỏ đúng một phần tử trên trang. Như số nhà: một địa chỉ một số.

class — nhãn dùng chung

class="card" có thể nằm trên 50 phần tử cùng lúc. Như huy hiệu của đội. Bootstrap hoạt động hoàn toàn bằng những cái này.

CSS và JS dùng đúng những tên này để tìm phần tử — nơi ba file gặp nhau lần đầu.

HTML · vì sao quan trọng

Thẻ ngữ nghĩa mang nghĩa, không chỉ hình dạng

<div> chẳng nói lên điều gì. <nav>, <main>, <article> nói vùng đó LÀ gì.

Cho người dùng & trình đọc màn hình

Người dùng trình đọc màn hình di chuyển theo điểm mốc: họ nhảy thẳng tới <main> và bỏ qua các menu.

Cho công cụ tìm kiếm

Công cụ tìm kiếm đọc ngữ nghĩa để lập chỉ mục cho trang. HTML ngữ nghĩa chính là SEO miễn phí.

Cho bạn & AI của bạn

AI đọc markup có ngữ nghĩa tốt hơn hẳn một 'bát canh div' — và chính bạn sau ba tháng nữa cũng vậy.

HTML · ví dụ

Một card sản phẩm, bằng HTML thuần

Mọi card trên web — sản phẩm, hồ sơ, bài viết — đều có hình dạng này: ảnh trên cùng, tiêu đề, chữ, hành động.

card.html
<div>
  <img src="product.jpg" alt="Espresso machine">
  <h3>Espresso Machine</h3>
  <p>Pulls a proper shot at home.</p>
  <button>Add to cart</button>
</div>
Trực tiếp — thử ngay
Espresso machine

Espresso Machine

Pulls a proper shot at home.

Bên phải là card chạy thật — bấm Add to cart. Chính markup này sẽ thành Bootstrap card ở phần kế tiếp, chỉ bằng cách thêm class.

HTML · đánh giá & sửa

Những lỗi HTML đáng để bắt

Những lỗi mà AI (và người) vẫn thường để lọt. Bạn không cần tìm ra tất cả — chỉ cần nhận ra bốn cái này.

Thẻ chưa đóng / lệch cặp

<div>…</span> — cái cây vỡ, và bố cục bên dưới nó loạn lên.

id trùng nhau

Hai phần tử cùng id="status" — JS lấy cái đầu tiên, nên chữ cập nhật vào sai chỗ.

Thiếu alt cho ảnh

Trình đọc màn hình không nghe thấy gì. Mỗi <img> cần alt="…" mô tả ảnh.

Nút & link chết

Nút không có handler, link trỏ tới "" — trang trông như xong mà bấm vào không có gì xảy ra.

02
Phần 2

CSS — kiểu dáng & bố cục

CSS trả lời hai câu hỏi: nó trông như thế nào, và nó nằm ở đâu?

CSS · mô hình hộp

Mọi thứ trên trang đều là một cái hộp

Mỗi phần tử là một hình chữ nhật có bốn lớp đồng tâm. Chỉ một mô hình này giải thích phần lớn CSS.

Nội dung

Chính chữ hay ảnh — lớp trong cùng.

Đệm

Khoảng trống giữa nội dung và viền. Khoảng thở, vẫn nằm trong hộp.

Viền

Vạch bao quanh. border-radius (bo góc) cũng nằm ở đây.

Lề

Khoảng trống bên ngoài viền — khoảng cách tới các hộp lân cận.

CSS · tìm phần tử

CSS tìm cái cần tô kiểu bằng cách nào

Mỗi luật CSS = một địa chỉ + một danh sách thuộc tính. Ba kiểu địa chỉ bao quát 95% CSS.

Thẻ — theo loại

button { … } tô kiểu mọi nút trên trang. Thô, nhưng tức thì.

Class & id — theo tên

.card { … } trúng những phần tử mang class="card"; #status trúng đúng một phần tử.

Cùng địa chỉ mà JS dùng để tìm phần tử — cái bắt tay đầu tiên giữa ba file.

CSS · nếm thử

'Kiểu dáng' thực ra có nghĩa là gì

Một luật CSS = chọn một phần tử, rồi gán cho nó các thuộc tính. Đó là toàn bộ cú pháp.

style.css
button {
  padding: 10px 18px;     /* room inside */
  background: #34d399;    /* colour */
  border: none;
  border-radius: 8px;     /* rounded corners */
  color: white;
  font-size: 15px;
}
Trực tiếp — thử ngay

Bên phải chạy thật — đó là chính CSS trong hộp áp lên nút. Đưa chuột lên nó. AI viết cái này; biết padding / border / radius là cách bạn đọc lại.

CSS · bố cục

Ba công cụ bố cục, một công việc

Bố cục = quyết định các phần tử nằm ở đâu. CSS có đúng ba công cụ lớn cho việc đó.

Flexbox — một chiều

Xếp các phần tử thành hàng ngang hoặc cột dọc, chia khoảng cách đều. Thanh menu, hàng card.

Grid — hai chiều

Hàng VÀ cột cùng lúc. Dashboard, bức tường ảnh, bố cục cả trang.

Media query — responsive

'Nếu màn hình hẹp hơn 768px thì làm thế này.' Một codebase, cả điện thoại lẫn máy tính đều chạy.

CSS · flexbox

Flexbox, vẽ ra

display: flex xếp các phần tử thành một hàng. Hai trục làm toàn bộ việc — mọi thuộc tính flex khác chỉ là nút vặn trên một trong hai trục này.

MAIN AXIS
1 2 3
CROSS AXIS

justify-content dịch phần tử dọc trục CHÍNH · align-items dịch dọc trục NGANG

CSS · flexbox · trục chính

justify-content — phân bố khoảng trống dọc trục chính

Các ô là thật: mỗi hàng là một flex container thực sự mang đúng thuộc tính đó. Đây là thứ trình duyệt tính ra.

justify-content:
flex-start
123
justify-content:
center
123
justify-content:
space-between
123
justify-content:
space-around
123

space-between: phần tử dính vào hai đầu, chỉ có khoảng trống ở giữa · space-around: mọi phần tử có khoảng trống đều nhau, hai đầu nhận nửa

CSS · flexbox · thêm vài nút vặn

Wrap, grow, direction

Ba thuộc tính nữa bao quát phần lớn flex layout thực tế. Cả ba ô dưới đây đều là flex container chạy thật.

flex-wrap: wrap
12345

items too big → new row

flex-grow: 1
A B · flex:1 C

B eats the leftover space

flex-direction: column
1 2 3

main axis turns vertical

wrap: phần tử dư bắt đầu hàng mới · grow: một phần tử lấp đầy phần còn lại · column: hàng trở thành cột

CSS · grid

Grid — hàng VÀ cột cùng lúc

Trái: chín ô trong lưới 3×3. Phải: các ô trải rộng. Cùng một ý tưởng, ít code hơn hẳn việc chất chồng flexbox.

grid-template-columns: repeat(3, 1fr)
123 456 789
items can span
1 2 · span 2 cols 3 · span 2 rows 4 5

col-3 của Bootstrap chính là lưới này với 12 cột: col-3 = 3/12 = một phần tư hàng

CSS · responsive

Một codebase, hai bố cục

Media query là một công tắc: cùng phần tử, cách xếp khác nhau theo kích thước màn hình.

responsive.css
/* desktop: sidebar next to content */
.layout { display: flex; }

/* phone: sidebar stacks on top */
@media (max-width: 768px) {
  .layout { flex-direction: column; }
}
Trực tiếp — thử ngay
sidebar
content
window: 820px → row

Bên phải là một cửa sổ chạy thật — kéo slider qua 768px và sidebar xếp chồng. Dưới 768px, cùng trang tự xếp lại; đó là 'responsive'.

03
Phần 3

Bootstrap — đừng tự style từ đầu

Một framework CSS: hàng nghìn kiểu dáng có sẵn, bật bằng tên class — và ba slide kế tiếp chạy nó trực tiếp.

Bootstrap · vì sao

Cùng một nút, hai cách làm

Đó chính là điểm mấu chốt: sự nhất quán miễn phí, để bạn dành thời gian cho trang — chứ không phải pixel.

Tự viết

Bạn tự quyết mọi pixel: padding, màu, viền, trạng thái hover, kích thước trên mobile. Rồi làm lại với mọi nút trên mọi trang.

Với Bootstrap

Thêm một class: class="btn btn-primary". Nút được style sẵn, kèm hover và hành vi mobile. Card, navbar, modal cũng vậy.

Bootstrap · demo trực tiếp

Cùng markup — class chính là phép màu

HTML giống hệt, cùng một tấm ảnh. Bên phải chỉ thêm tên class — và bỗng trông như được thiết kế.

plain html — no classes
Espresso machine

Espresso Machine

Pulls a proper shot at home.

same markup + bootstrap classes
Espresso machine
Espresso Machine

Pulls a proper shot at home.

card · card-img-top · card-body · card-title · card-text · btn btn-primary

Bootstrap · demo trực tiếp

Những component bạn sẽ thấy ở khắp nơi

Mọi thứ bên dưới là Bootstrap 5 thật, được render ngay trong slide này. Mỗi mảnh chỉ là một hoặc hai tên class.

Aero chair
Aero Chair

Ergonomic. Breathable. Actually comfortable.

View product
New Beta Live Down

navbar · card · alert · badge · btn — bộ từ vựng của hàng nghìn dashboard

Bootstrap · demo trực tiếp

Form hết trông 'mặc định' nữa

Cùng những input bạn đã thấy ở phần HTML — giờ có thêm class form-*. Trạng thái focus và khoảng cách đã được lo sẵn.

form-label · form-control · form-select · form-check form-switch · btn

Bootstrap · nếm thử

Một trang với 11 dòng class

Không có khối <style> nào — diện mạo cả trang hoàn toàn đến từ các tên class.

index.html
<link href="bootstrap.min.css" rel="stylesheet">

<nav class="navbar">…logo + links…</nav>

<div class="container">
  <div class="row">
    <div class="col-3">sidebar</div>
    <div class="col-9">main content</div>
  </div>
  <button class="btn btn-primary">Click me</button>
</div>

col-3 / col-9 là lưới: 12 cột, 3+9 lấp đầy một hàng. Đổi số — bố cục đổi theo.

Bootstrap · từ vựng

Những class đáng nhận ra

Bạn sẽ không học thuộc Bootstrap — nhưng sáu cái này xuất hiện trong gần như mọi trang làm bằng nó.

ClassBạn nhận được gì
btn btn-primaryNút bấm được style — kèm sẵn trạng thái hover và focus
container · row · col-*Lưới 12 cột: col-3 + col-9 lấp đầy một hàng
navbarThanh menu responsive — tự co gọn trên điện thoại
cardÔ có viền cho ảnh + chữ + nút
modalCửa sổ popup — mở/đóng được lo sẵn
form-controlÔ nhập liệu được style
Bootstrap · lưới

Lưới 12 cột, trong một slide

Mọi bố cục Bootstrap là những hàng gồm 12 ô bằng nhau. Bạn chọn mỗi khối chiếm mấy ô.

row = 12 ô

<div class="row"> là một kệ chia 12 phần bằng nhau. col-3 lấy 3, col-9 lấy 9 — lấp đầy kệ.

Con số là bố cục

col-6 + col-6 = hai nửa, col-4 × 3 = ba phần. Đổi số và trang tự chảy lại — không cần CSS khác.

Breakpoint = responsive miễn phí

col-md-6 nghĩa là 'màn hình medium trở lên thì 6 cột, nhỏ hơn thì xếp chồng'. Cùng một row là cả bố cục điện thoại lẫn desktop.

04
Phần 4

JavaScript — làm trang biết PHẢN HỒI

HTML là bức tranh, CSS là bộ đồ — JS là phản xạ.

JavaScript · mẫu cốt lõi

Một listener, một lần cập nhật

Mẫu hình đằng sau mọi tương tác trên web: chờ một sự kiện, rồi thay đổi trang.

app.js
const btn = document.querySelector("#save");

btn.addEventListener("click", () => {
  document.querySelector("#status")
          .textContent = "Saved ✓";
});
Trực tiếp — thử ngay
console

Bên phải chạy thật — click Save và virtual console ghi lại toàn bộ sự kiện. Giờ nút đã LÀM được việc thật: click xảy ra, JS sửa trang.

JavaScript · nó mang lại gì

Bốn việc mọi app đều làm

JS đọc và sửa DOM — cái cây phần tử đang sống của trang — nên mọi việc dưới đây đều là 'chỉnh' cái cây đó.

Hiện / ẩn

Tab, menu thả xuống, thông báo toast — cùng một phần tử, bật rồi tắt.

Kiểm tra form

Kiểm tra email trông có đúng không trước khi gửi. Hiện lỗi, chặn nút gửi.

Lấy dữ liệu từ API

Hỏi server lấy JSON — danh sách đơn, giá, bài viết — rồi vẽ chúng vào trang.

Đọc & sửa DOM

Tìm, đọc, sửa, thêm phần tử trên trang. Trang là dữ liệu mà bạn có thể thao tác.

JavaScript · bảng tra DOM

Những method bạn sẽ thấy trong mọi câu trả lời của AI

Bạn không cần học thuộc — nhưng khi AI viết chúng, bạn phải nhận ra từng dòng đang làm gì.

MethodNó làm gì
document.querySelector("#x")Tìm phần tử đầu tiên theo địa chỉ CSS — cùng tên #x / .x mà CSS dùng.
document.querySelectorAll(".x")Tìm mọi phần tử khớp — một danh sách để lặp.
el.textContent = "…"Gán chữ thuần — an toàn, không parse HTML.
el.innerHTML = "…"Gán markup HTML — trình duyệt parse và render nó.
el.addEventListener("click", fn)Chạy fn khi sự kiện xảy ra. Một phần tử có thể nghe nhiều sự kiện.
el.classList.toggle("open")Thêm class nếu thiếu, bỏ đi nếu có — một công tắc.
input.valueĐọc điều người dùng gõ — hoặc gán giá trị mặc định.
createElement + appendTạo phần tử mới từ đầu rồi gắn vào trang.
JavaScript · sự kiện

Ba sự kiện bao quát phần lớn UI

Mẫu hình lúc nào cũng vậy: listener → handler → sửa trang. Chỉ tên sự kiện đổi.

click

Cái kinh điển — nút, link, tab. Xảy ra khi người dùng kích hoạt phần tử.

input — mỗi lần gõ phím

Xảy ra ở mỗi lần gõ phím. Chìa khóa của ô tìm kiếm trực tiếp và gợi ý tự động — không cần nút 'Tìm'.

submit — và e.preventDefault()

Xảy ra khi form được gửi. Gọi e.preventDefault() trong handler để chặn trang tải lại — rồi JS tiếp quản.

JavaScript · state

Một bộ đếm — state sống trong biến

Hai nút, một con số. Biến JS là sự thật; trang chỉ là tấm gương của nó.

counter.js
let count = 0;
const out = document.querySelector("#count");

document.querySelector("#plus")
  .addEventListener("click", () => {
    count += 1;
    out.textContent = count;
  });

document.querySelector("#reset")
  .addEventListener("click", () => {
    count = 0;
    out.textContent = count;
  });
Trực tiếp — thử ngay
0
console

Bên phải chạy thật — click +1 / Reset; console phản ánh thứ tự 'dữ liệu rồi vẽ'. Thứ tự đó là ý tưởng nền của mọi framework.

JavaScript · hiện / ẩn

Tabs — mẫu hiện/ẩn thật sự

Hiện/ẩn gần như luôn chỉ là lật một class CSS. JS không đụng trực tiếp 'display'.

tabs.js
const tabs = document.querySelectorAll(".tab");

tabs.forEach(tab => tab.addEventListener("click", () => {
  tabs.forEach(t => t.classList.remove("active"));
  tab.classList.add("active");
  // CSS: .tab.active shows its panel, the rest hide
}));
Trực tiếp — thử ngay
Bảng hồ sơ
console

Bên phải chạy thật — click một tab; console cho thấy class .active chuyển. Mánh y hệt này đứng sau dropdown, toast, accordion.

JavaScript · form

Kiểm tra form, cách thực sự

Chặn submit, kiểm tra giá trị, hiện hoặc xóa lỗi — không tải lại trang.

validate.js
const form = document.querySelector("#signup");

form.addEventListener("submit", (e) => {
  e.preventDefault();                   // don't reload

  const email = document.querySelector("#email").value;
  const err = document.querySelector("#err");

  if (!email.includes("@")) {
    err.textContent = "That email looks wrong.";
  } else {
    err.textContent = "";              // clear it
    form.reset();
  }
});
Trực tiếp — thử ngay
console

Bên phải chạy thật — gửi email sai rồi email đúng; console ghi mỗi nhánh. Đây là bộ khung của mọi thông báo 'email hợp lệ'.

JavaScript · mẫu lọc

Tìm trong danh sách mỗi lần gõ phím

input → lọc dữ liệu → vẽ lại danh sách. Chính mẫu này đứng sau mọi giao diện lọc bạn từng dùng.

filter.js
const foods = ["Pizza", "Pho", "Sushi", "Banh mi", "Tacos"];
const input = document.querySelector("#search");
const list = document.querySelector("#list");

input.addEventListener("input", () => {
  const hits = foods.filter(f =>
    f.toLowerCase().includes(input.value.toLowerCase()));

  list.innerHTML = hits
    .map(f => "<li>" + f + "</li>")
    .join("");
});
Trực tiếp — thử ngay
  • Pizza
  • Pho
  • Sushi
  • Banh mi
  • Tacos
console

Bên phải chạy thật — gõ vào ô và console ghi mỗi lần lọc. filter() chọn phần khớp, map() tạo dòng, join() gắn lại.

JavaScript · fetch

fetch — và luôn lường trước thất bại

Mạng hay hỏng: server sập, wifi rớt, route không tồn tại. Khối catch là một phần của tính năng.

fetch.js
async function loadOrders() {
  const list = document.querySelector("#orders");
  try {
    const res = await fetch("/api/orders");
    const orders = await res.json();
    list.innerHTML = orders
      .map(o => "<li>" + o.name + "</li>")
      .join("");
  } catch (err) {
    list.textContent = "Couldn't load orders — retry?";
  }
}
Trực tiếp — thử ngay
  • — bấm Load orders —
console

Bên phải mô phỏng mạng (không có endpoint thật) — Load orders, hoặc tick Simulate failure để chạm catch. Đánh giá mọi fetch của AI qua khối catch.

JavaScript · async

fetch không chặn trang

Đây là lý do web app vẫn 'sống' khi đang tải — và cũng là lý do lỗi async trông kỳ quái.

Yêu cầu chạy ở nền

fetch bắn ra và JS đi tiếp ngay. Trang vẫn cuộn, vẫn hoạt hình trong khi server đang suy nghĩ.

.then / await = 'khi dữ liệu về'

Các callback xếp hàng: 'khi dữ liệu về, làm điều này.' Thứ tự quan trọng — không thể vẽ dữ liệu chưa về tới.

Đó là lý do có vòng spinner

Giao diện vẫn sống trong lúc chờ. Spinner là cách giao diện thú nhận 'tôi vẫn đang tải'.

Lỗi async trông kỳ quái

'Dữ liệu tôi đi đâu rồi?' thường là 'tôi dùng nó trước khi nó về'. Kỷ luật await/then tồn tại đúng vì điều đó.

JavaScript · ý tưởng lớn

State + render() — hạt mầm của React & Vue

Hai mảnh: một nguồn sự thật duy nhất, và một hàm vẽ lại trang từ nguồn đó.

pattern.js
// one source of truth
let state = { open: 3, cart: [] };

// the page is a picture of the state
function render() {
  document.querySelector("#open").textContent = state.open;
  document.querySelector("#cart").textContent =
    "Cart: " + state.cart.length;
}

state.open += 1;   // 1. change the data
render();          // 2. repaint the page
Trực tiếp — thử ngay
đang mở: 3 Cart: 0
console

Bên phải chạy thật — hai nút đổi state, render() vẽ lại, console ghi lại. Đây chính là thứ React & Vue tự động hóa.

Mối kết nối

Một phần tử, ba file

HTML, CSS và JS cùng nói về một phần tử — mỗi file làm việc của mình.

HTML — định nghĩa nó

<p id="status"></p> — phần tử tồn tại, vẫn còn trống.

CSS — tô kiểu cho nó

#status { color: red; } — hễ nó có chữ, chữ sẽ màu đỏ.

JS — thay đổi nó

document.querySelector("#status") được điền chữ ngay khoảnh khắc bạn click nút.

Việc của server kết thúc khi gửi đi. Mọi thứ bạn nhìn thấy và click đều là HTML, CSS và JS đang chạy trong trình duyệt của bạn.
— toàn bộ frontend trong một câu

HTML dựng. CSS làm đẹp. JS cho nó động.

Giờ bạn sẽ để AI sinh các file này — việc của bạn là đọc, đánh giá và sửa chúng.