Tổng hợp 123 câu hỏi phỏng vấn CSS kèm đáp án chi tiết, song ngữ Việt–Anh — sắp xếp từ cơ bản đến nâng cao. Ôn luyện miễn phí, tự động lưu tiến độ.
Cascade là thuật toán chọn ra giá trị thắng khi nhiều khai báo cùng nhắm vào một thuộc tính của một element. Thứ tự xét, từ trên xuống — dừng ngay khi phân định được: 1. Origin + !important: !important của user agent !important của…
Một số thuộc tính CSS tự truyền xuống element con, số còn lại thì không. Kế thừa Không kế thừa ------ color, font-, line-height, letter-spacing margin, padding, border, background text-align, visibility, cursor, list-style width, height, display, position Quy luật chung: thuộc tính về chữ thì…
Chia làm ba nhóm theo cái mà giá trị phụ thuộc vào. Đơn vị Neo vào Rủi ro --------- px không gì không co theo cỡ chữ người dùng đặt em font-size của element hiện tại nhân dồn khi lồng nhiều lớp rem font-size của…
!important đưa một khai báo lên nhóm ưu tiên riêng, đứng trên mọi specificity trong cùng origin. Vì sao nên tránh: cách duy nhất để ghi đè một !important là một !important khác có specificity cao hơn. Trong một dự án đang chạy, việc đó…
:has() là selector cha — chọn element dựa trên thứ nằm bên trong nó. Trước đây CSS không làm được việc này, phải nhờ JS gắn class. Specificity lấy theo selector mạnh nhất bên trong (giống :is()), không phải 0 như :where(). Hỗ trợ: Baseline…
Bốn combinator mô tả quan hệ giữa hai element: Ký hiệu Tên Quan hệ --------- khoảng trắng descendant con cháu bất kỳ cấp child con trực tiếp + adjacent sibling anh em kế ngay sau ~ general sibling mọi anh em phía sau Dùng thực…
Mỗi element là một hộp gồm bốn lớp, từ trong ra ngoài: content → padding → border → margin. Margin khác ba lớp còn lại ở ba điểm: nằm ngoài viền, luôn trong suốt (không nhận background), và gộp theo chiều dọc với margin liền…
Khác nhau ở width đang đo cái gì. content-box border-box --------- width bao gồm chỉ content content + padding + border Thêm padding element phình ra content co lại Margin không tính trong cả hai không tính trong cả hai Dòng gần như mọi dự…
Khi hai margin theo chiều dọc chạm nhau, browser gộp thành một, lấy giá trị lớn hơn chứ không cộng. Ba tình huống xảy ra: Không xảy ra với: margin ngang, flex item, grid item, element position: absolute/fixed, element tạo block formatting context (overflow: hidden,…
position quyết định element có nằm trong normal flow hay không, và top/right/bottom/left neo vào đâu. Giá trị Còn chiếm chỗ Neo theo --------- static có — relative có (chỗ cũ giữ nguyên) chính nó absolute không tổ tiên gần nhất có position ≠ static…
sticky là relative cho tới khi chạm ngưỡng, sau đó thành fixed trong phạm vi cha. Ba điều kiện phải đủ, thiếu một là không chạy: 1. Có ít nhất một trong top/right/bottom/left. 2. Không tổ tiên nào có overflow: hidden auto scroll — nếu…
z-index quyết định thứ tự xếp chồng, nhưng chỉ so sánh được giữa các element cùng một stacking context. Hai điều kiện để z-index có tác dụng: element phải position khác static, hoặc là flex/grid item (trường hợp này z-index chạy mà không cần position).…
Stacking context là một nhóm xếp chồng độc lập: mọi so sánh z-index chỉ diễn ra bên trong nó, và cả nhóm được xếp như một khối duy nhất so với bên ngoài. Cái gì tạo ra nó: - element gốc <html - position khác…
Flexbox là mô hình layout một chiều: bố trí item dọc theo một trục, và phân chia không gian còn thừa hoặc còn thiếu. Điểm mạnh thật sự là flex trên item — kiểm soát co giãn theo nội dung: Flex hay Grid? Tình huống…
justify-content căn theo trục chính, align-items căn theo trục phụ. Trục nào là chính do flex-direction quyết định. justify-content align-items --------- Trục chính phụ Giá trị riêng space-between, space-around, space-evenly stretch, baseline Chung flex-start, center, flex-end Căn giữa hoàn toàn — cách ngắn nhất: Lưu…
Ba thuộc tính này trả lời ba câu hỏi khác nhau về một flex item: Hiểu flex: 1 vs flex: auto — chỗ hay nhầm nhất: Viết tắt Đầy đủ Kết quả với 2 item nội dung dài ngắn khác nhau --------- flex: 1 1…
flex-wrap quyết định item có được xuống dòng khi hết chỗ hay không. Phân biệt hai thuộc tính hay bị lẫn khi đã wrap: - align-items — căn từng item trong một dòng. - align-content — căn các dòng với nhau trong container. Shorthand gộp…
gap tạo khoảng cách giữa các item, không thêm khoảng thừa ở mép container. So với cách cũ dùng margin: Ưu điểm cụ thể: - Không có margin thừa ở phần tử đầu/cuối, không cần :last-child. - Không bị margin collapsing — flex/grid vốn không…
Grid là layout hai chiều: khai báo cả hàng và cột, và item được đặt vào ô của lưới đó. Flexbox Grid --------- Số chiều một (hàng hoặc cột) hai (hàng và cột) Bố cục quyết định bởi nội dung đẩy ra container định sẵn…
fr (fraction) chia phần không gian còn lại của grid container sau khi đã trừ mọi kích thước cố định và gap. Vì sao hơn %: Kết hợp với minmax() để không co quá nhỏ: Lưu ý: 1fr thực chất là minmax(auto, 1fr), nghĩa là…
Hai thuộc tính này khai báo explicit grid (lưới tường minh): có bao nhiêu track và mỗi track rộng/cao bao nhiêu. Giá trị hay dùng cho một track: <độ dài, %, fr, auto (vừa nội dung), min-content, max-content, minmax(a, b), fit-content(300px). Item vượt quá số…
Cả hai đi cùng repeat() để browser tự tính số cột, khác nhau ở cách xử lý track rỗng. Với container 1000px và chỉ 2 item: Số track tạo ra Kết quả nhìn thấy --------- auto-fill 5 (tạo cả track rỗng) 2 item rộng 200px,…
minmax(min, max) đặt cận dưới và cận trên cho một track của grid. Dòng cuối là công thức được dùng nhiều nhất trong CSS Grid hiện đại: mỗi card tối thiểu 260px, số cột tự tính theo bề rộng, và card giãn ra cho vừa…
grid-template-areas cho phép vẽ bố cục bằng chữ rồi gán item vào từng vùng theo tên. Đổi bố cục cho mobile chỉ cần vẽ lại bức tranh, không đụng tới từng item: Dùng dấu . cho ô cố ý để trống: Lưu ý 1: mỗi…
Responsive design là làm cho một bộ code hiển thị hợp lý trên mọi kích thước màn hình, thay vì dựng site riêng cho mobile. Ba thành phần gốc (Ethan Marcotte, 2010): 1. Lưới co giãn — %, fr, flex thay cho chiều rộng cố…
Mobile-first nghĩa là CSS mặc định viết cho màn hình nhỏ, rồi dùng min-width để bổ sung cho màn lớn hơn. So với desktop-first: Ba lý do chọn mobile-first: 1. Ít ghi đè hơn — mỗi breakpoint thêm thứ mới thay vì huỷ thứ cũ,…
Media query áp một khối CSS khi điều kiện về thiết bị đúng. Ngưỡng hay dùng: 640 / 768 / 1024 / 1280px — nhưng đó là quy ước của Tailwind, không phải chuẩn. Lưu ý 1: đừng đặt breakpoint theo tên thiết bị. Chọn…
clamp(min, ưa-thích, max) khoá một giá trị trong khoảng, và co giãn liên tục ở giữa. Thay thế cho việc nhảy bậc bằng media query: Công thức thường dùng cho fluid typography — trộn rem với vw để vẫn co theo cỡ chữ người dùng…
Container query cho component đáp ứng theo bề rộng của khối cha, không phải theo viewport. Lợi ích thực tế: cùng một component đặt trong sidebar 300px và trong vùng nội dung 900px sẽ tự hiển thị khác nhau — media query không làm được,…
srcset liệt kê nhiều phiên bản ảnh, sizes cho browser biết ảnh sẽ hiển thị rộng bao nhiêu để chọn đúng file. Cách browser quyết định với sizes="(min-width: 1024px) 50vw, 100vw" trên màn 1280px, DPR 2: - Ảnh sẽ rộng 50vw = 640px CSS →…
@keyframes mô tả các mốc trạng thái, animation gắn chúng vào element. Các thuộc tính con của animation: name, duration, timing-function, delay, iteration-count, direction, fill-mode, play-state. fill-mode là thứ hay bị quên: - forwards — giữ trạng thái cuối sau khi chạy xong. - backwards…
will-change báo trước cho browser rằng thuộc tính nào sắp đổi, để nó chuẩn bị (thường là tách element ra một composite layer riêng). Vấn đề: mỗi layer chiếm bộ nhớ GPU. Đặt will-change cho hàng loạt element làm trang chậm hơn thay vì nhanh…
Logical property mô tả vị trí theo hướng viết của ngôn ngữ thay vì theo trái/phải/trên/dưới cố định. Hai trục: - inline — hướng chữ chạy. LTR: trái→phải. RTL (Ả Rập, Do Thái): phải→trái. - block — hướng dòng xếp chồng. Thường là trên→dưới. Physical…
scroll-snap cho phép cuộn dừng đúng vào từng mốc, không cần thư viện JS. Giá trị Hành vi ------ mandatory luôn dừng đúng mốc — hợp carousel toàn màn hình proximity chỉ dính khi dừng gần mốc — hợp danh sách dài, tự nhiên hơn…
BEM là quy ước đặt tên class để một class nói rõ nó thuộc component nào và đóng vai gì. Cái nó giải quyết: selector lồng sâu (.sidebar .card h3 span) rất dễ vỡ khi đổi cấu trúc DOM, và specificity leo thang không kiểm…
Utility-first là viết style bằng nhiều class nhỏ, mỗi class một thuộc tính, ngay trên HTML. Điểm mạnh thật sự không phải "viết nhanh" mà là: 1. Không phải đặt tên — phần lớn thời gian tranh luận CSS trong team là tranh luận tên…
CSS Modules biên dịch mỗi file .module.css thành các class được đổi tên duy nhất, nên style không rò ra ngoài component. Sau khi build, .root trở thành Buttonrootx7f2a — hai component cùng đặt tên .root không đụng nhau. Đặc điểm quan trọng: toàn bộ…
CSS-in-JS viết style bằng JavaScript, gắn thẳng vào component. Ưu: scope tự động, style đổi theo props/state ngay trong cùng file, xoá component là xoá luôn style của nó (không còn CSS chết). Nhược: thư viện runtime phải sinh và chèn CSS trong lúc render…
Critical CSS là phần CSS tối thiểu để vẽ được nội dung ngay trên màn hình đầu tiên, nhúng thẳng vào <head để không phải chờ tải file CSS ngoài. Vấn đề nó giải: <link rel="stylesheet" là render-blocking — browser không vẽ gì cho tới…
font-display quyết định browser xử lý ra sao trong lúc font tuỳ chỉnh chưa tải xong. Giá trị Giai đoạn chờ Kết quả --------- block ~3s ẩn chữ FOIT — trắng chữ, tệ nhất cho cảm nhận tốc độ swap 0s hiện font dự phòng…
backdrop-filter áp filter lên phần nền phía sau element, không phải lên chính element. So với filter: Dùng cho: thanh điều hướng dính trong suốt, lớp phủ modal, thẻ kiểu glassmorphism, overlay trên ảnh. Lưu ý 1: quên nền bán trong suốt. Nền đục hoàn…
Hai công thức, tuỳ số dòng cần giữ. Một dòng: Nhiều dòng: Dù mang tiền tố -webkit-, line-clamp chạy trên mọi browser hiện đại (Chrome, Safari, Firefox 68+, Edge) — đây là một trong số ít tiền tố đã thành chuẩn trên thực tế. Từ…
Variable font là một file chứa cả một trục biến thiên (độ đậm, độ rộng, độ nghiêng) thay vì mỗi kiểu một file riêng. Các trục chuẩn: wght (weight), wdth (width), slnt (slant), ital (italic), opsz (optical size). Trục riêng của từng font truy cập…
prefers-reduced-motion cho biết người dùng đã bật thiết lập giảm chuyển động ở cấp hệ điều hành. Đây không phải sở thích thẩm mỹ: chuyển động lớn gây chóng mặt, buồn nôn thật với người có rối loạn tiền đình. Cách viết được khuyến nghị…
prefers-color-scheme cho biết hệ điều hành đang ở chế độ sáng hay tối. Cách triển khai đúng là khai báo token màu ở :root, rồi chỉ ghi đè token trong dark — không viết lại từng luật CSS: Muốn người dùng tự chọn (sáng /…
<picture cho phép browser chọn giữa các nguồn ảnh khác nhau về định dạng hoặc bố cục, với <img là phương án cuối. Browser duyệt các <source theo thứ tự và dừng ở cái đầu tiên khớp — nên định dạng mới nhất phải đứng…
box-shadow đổ bóng theo hình hộp; filter: drop-shadow() đổ bóng theo hình thật của nội dung, kể cả phần trong suốt. Khác biệt lộ rõ với PNG trong suốt, SVG icon, hoặc element có clip-path: box-shadow drop-shadow() --------- Theo hình hộp + border-radius alpha channel…
Theo nội dung, không theo thiết bị. Lý do đơn giản: danh sách thiết bị đổi mỗi năm — iPhone SE 375px, iPhone Pro Max 430px, tablet gập, cửa sổ desktop chia đôi màn hình. Không có tập "kích thước chuẩn" nào ổn định để…
Composite layer là một mặt phẳng vẽ riêng mà browser giao cho GPU ghép lại ở bước cuối. Element nằm trên layer riêng có thể di chuyển hoặc đổi độ mờ mà không phải vẽ lại phần còn lại của trang. Cái gì khiến một…
Bốn hàm toán, dùng được ở mọi chỗ nhận độ dài, số, góc hay tần số. Mẹo hay dùng — min() thay max-width, max() thay min-width: Cả bốn lồng nhau và cộng trừ với nhau được: Lưu ý 1 — khoảng trắng quanh toán tử.…
Vì oklch đồng đều theo cảm nhận: giữ nguyên L và C, đổi H thì mắt thấy các màu sáng ngang nhau. hsl không có tính chất đó. Hệ quả với design system: 1. Thang màu sinh được bằng công thức. Với oklch, --blue-500 →…
Nguyên tắc gốc: mọi màu đi qua custom property, dark mode chỉ đổi giá trị token chứ không viết lại luật CSS. Ba khối này xử lý đủ ba trạng thái: người dùng chọn sáng, chọn tối, hoặc để theo hệ thống. Bốn điểm về…
touch-action cho browser biết thao tác chạm nào nó được xử lý, phần còn lại nhường cho JS của bạn. Giá trị Browser giữ JS nhận --------- auto tất cả phần còn lại none không gì toàn bộ manipulation pan + pinch double-tap pan-x /…
Flexbox là hệ thống layout một chiều, phân bố item dọc theo một trục (hàng hoặc cột), phù hợp cho navigation bar, danh sách item, hoặc căn chỉnh đơn giản. CSS Grid là hệ thống layout hai chiều, cho phép định nghĩa cả hàng và…
BFC (Block Formatting Context) là một vùng layout độc lập trong CSS, nơi các phần tử bên trong không ảnh hưởng đến layout bên ngoài và ngược lại. Cách tạo BFC gồm: overflow: auto hoặc hidden, display: flex hoặc grid, position: absolute hoặc fixed, float:…
Margin collapsing là hiện tượng margin dọc (vertical) của hai block-level element liền kề bị gộp lại thành một margin duy nhất, lấy giá trị lớn hơn — nên margin 20px + 30px chỉ còn 30px chứ không phải 50px. Margin ngang (horizontal) không bị…
CSS Grid template-areas cho phép đặt tên cho các vùng trong grid và gán phần tử vào bằng property grid-area, tạo ra layout trực quan và dễ đọc. Ví dụ: grid-template-areas: 'header header' 'sidebar main' 'footer footer' rồi gán mỗi phần tử với grid-area: header,…
Stacking context là hệ thống phân lớp trong CSS, mỗi context tạo ra một hệ thống z-index riêng biệt. Các thuộc tính tạo stacking context mới gồm: position kết hợp z-index, opacity nhỏ hơn 1, transform, filter, và nhiều thuộc tính khác. z-index không hoạt…
Semantic HTML trước tiên: <button, <a, <nav, <main, <label, heading đúng cấp — chúng có sẵn role, focus, điều khiển bàn phím, và ý nghĩa cho screen reader. Quy tắc ARIA số 1: đừng dùng ARIA nếu đã có element HTML native làm được (một…
CSS custom property = biến khai báo bằng tiền tố --, đọc lại bằng hàm var(): Đặc điểm quan trọng: - Kế thừa theo cây DOM và có scope: khai báo ở :root là toàn cục; khai báo trong một selector chỉ áp cho phần…
- Pseudo-class (một dấu hai chấm :): chọn phần tử theo trạng thái hoặc vị trí trong cây — chứ không tạo gì mới. Ví dụ: :hover, :focus, :active, :checked, :disabled, :first-child, :nth-child(2n), :not(...). Nó trả lời "phần tử này đang ở trạng thái nào…
- transition: nội suy giữa hai trạng thái — giá trị hiện tại và giá trị mới — khi có gì đó kích hoạt (hover, đổi class, thêm/bớt inline style). Cần một "cú hích" để chạy, chỉ đi một chiều tại một thời điểm, và…
Cả hai xử lý việc trình duyệt có default styles khác nhau (margin <body, cỡ <h1, style <ul...), nhưng theo hai triết lý ngược nhau: - Reset (vd Meyer reset): xoá sạch hầu hết style mặc định về 0 — margin, padding, font-size... Như tờ…
- border: là một phần của box model, vẽ giữa padding và margin, chiếm chỗ nên làm tăng kích thước phần tử và đẩy layout. Đặt được từng cạnh (border-top...) và bo góc theo border-radius. - outline: vẽ bên ngoài border, không chiếm chỗ trong…
flex: 1 là shorthand của flex-grow: 1; flex-shrink: 1; flex-basis: 0%. Điểm mấu chốt là flex-basis: 0%: trình duyệt coi kích thước khởi điểm của item là 0, rồi chia toàn bộ không gian còn lại theo tỉ lệ flex-grow. Kết quả là các item…
Toolbar → Flexbox. Lưới card → Grid. Tiêu chí chọn: Flexbox là layout một chiều — bố trí một hàng (hoặc một cột) và phân phối không gian dư theo nội dung. Grid là layout hai chiều — định nghĩa hàng và cột trước, rồi…
- align-items: căn từng item bên trong dòng (line) của nó, theo trục cross. - align-content: căn cả tập hợp các dòng so với container, cũng theo trục cross. align-content chỉ có tác dụng khi container có nhiều dòng và còn không gian thừa trên…
gap khai báo khoảng cách giữa các item và chỉ áp dụng ở phần ở giữa — không sinh margin thừa ở hai đầu, nên không cần luật bù :last-child. Ưu điểm cụ thể: - Wrap đúng: khi item xuống dòng, gap cũng tạo khoảng…
Nguyên nhân là min-width: auto — giá trị mặc định của flex item theo trục chính. Giá trị này nghĩa là item không được co nhỏ hơn kích thước nội dung tối thiểu (min-content), tức là chữ dài nhất hoặc bề rộng tối thiểu của…
Vì auto-fit thu gọn (collapse) các track rỗng về 0 rồi để các track có nội dung ăn hết phần dư. Còn 1 card thì mọi track khác biến mất, card duy nhất giãn theo 1fr chiếm trọn hàng. auto-fill giữ nguyên các track rỗng.…
Đổi 1fr thành minmax(0, 1fr). 1fr thực chất là viết tắt của minmax(auto, 1fr). Phần auto đặt mức tối thiểu bằng min-content của ô, nên khi bên trong có nội dung không ngắt được, track buộc phải rộng ra và cả grid tràn ngang khỏi…
grid-template-areas đặt tên cho vùng rồi vẽ layout bằng chuỗi ASCII; đổi responsive chỉ cần vẽ lại bản đồ, không đụng tới HTML hay order. Quy tắc cần nhớ: mỗi chuỗi là một hàng, số token mỗi hàng phải bằng nhau, tên lặp lại thì…
Bốn nguyên nhân theo thứ tự hay gặp: 1. Thiếu offset: sticky không làm gì nếu không có ít nhất một trong top / right / bottom / left. Đây là lỗi phổ biến nhất. 2. Tổ tiên có overflow khác visible: bất kỳ cha…
Đó là margin collapsing giữa cha và con đầu tiên: khi không có gì ngăn cách ở cạnh trên (không border, không padding, không nội dung inline), margin-top của con thoát ra ngoài và hợp nhất với margin-top của cha. Giá trị cuối cùng là…
aspect-ratio khai báo trực tiếp tỉ lệ giữa chiều rộng và chiều cao; trình duyệt tự suy ra chiều còn lại từ chiều đã biết. So với kỹ thuật cũ padding-top: 56.25% cộng một lớp con position: absolute; inset: 0: - Không cần phần tử…
Trình duyệt chọn giá trị theo thứ tự ba tầng, chỉ khi hoà ở tầng trên mới xét tầng dưới: 1. Nguồn và mức quan trọng — user-agent < author < !important (đảo ngược thứ tự). 2. Độ cụ thể (specificity) — bộ ba (inline,…
!important không sửa nguyên nhân, nó đi vòng qua cascade. Hệ quả: - Muốn đè lại một khai báo !important chỉ còn cách thêm !important khác cụ thể hơn — file CSS trượt dần vào cuộc đua leo thang. - Style inline từ JS (animation…
@supports là feature query: hỏi trình duyệt xem nó có hiểu một cặp property/value hay không, rồi mới áp dụng khối bên trong. Cú pháp hỗ trợ not, and, or và cả selector() để kiểm tra selector: Lưu ý khi phỏng vấn hay hỏi: -…
Vì custom property theo luật kế thừa của DOM, không phải biến toàn cục như SASS. Khai báo --gap trên .card thì chỉ .card và con cháu của nó đọc được; anh em bên ngoài cây đó nhận var(--gap) là không hợp lệ. Muốn dùng…
Nguyên tắc: component không biết màu, chỉ đọc token. Toàn bộ khác biệt sáng/tối nằm ở một chỗ. - prefers-color-scheme lo mặc định theo hệ điều hành. - Thuộc tính data-theme trên <html lo lựa chọn thủ công và thắng media query nhờ selector cụ…
Hai hàm nhóm selector này giống nhau hoàn toàn về phần khớp, chỉ khác specificity: - :is(...) nhận specificity của selector có độ cụ thể cao nhất trong danh sách. - :where(...) luôn có specificity bằng 0, bất kể bên trong là gì. Hệ quả…
:has() là parent selector: chọn phần tử dựa trên thứ nó chứa hoặc thứ đứng sau nó. Trước đó CSS chỉ đi xuống, nên mọi trạng thái phụ thuộc con đều phải để JS toggle class. Ví dụ hay dùng trong dự án: Lưu ý:…
Logical property mô tả vị trí theo hướng đọc của văn bản thay vì theo trục vật lý trái/phải. Khi dir="rtl", trình duyệt tự lật, không cần một file CSS RTL riêng. Vật lý Logical ------ margin-left margin-inline-start padding-right padding-inline-end text-align: left text-align: start border-top…
Hai cách giải cùng một vấn đề: CSS không có scope, nên phải quy ước để tránh tên class đụng nhau và style rò rỉ. BEM — blockelement--modifier, mỗi class một tầng ý nghĩa: - Specificity phẳng (một class), dễ đoán thứ tự đè. -…
clamp(min, preferred, max) cho giá trị co giãn liên tục theo viewport, thay vì nhảy bậc tại breakpoint: Giá trị giữa phải có thành phần vw thì mới co giãn. Cách suy ra hệ số: chọn hai mốc (vd 360px → 28px, 1280px → 48px),…
Vì mỗi khung hình trình duyệt đi qua các bước style → layout → paint → composite, và thuộc tính bạn đổi quyết định phải chạy lại từ bước nào. - Đổi left, top, width, height, margin → layout lại (reflow) toàn bộ nhánh liên…