Luyện Phỏng Vấn IT — 2000+ Câu Hỏi Phỏng Vấn IT Có Đáp Án 2026
CSS
Cơ chế quyết định style nào được áp dụng khi có xung đột.
- Thứ tự ưu tiên đầy đủ (từ thấp đến cao): @layer order < specificity < source order < origin (browser default < user styles < author styles) < !important < inline styles.
- CSS 2021 thêm
@layerđể quản lý nhóm styles — styles trong layer sau override layer trước bất kể specificity, và styles ngoài @layer có ưu tiên cao hơn mọi layer. - Cascade giúp quản lý styles phức tạp.
Specificity tính theo 4 cột (inline, ID, class, element): inline styles (1,0,0,0) > ID (0,1,0,0) > class/pseudo-class/attribute (0,0,1,0) > element/pseudo-element (0,0,0,1).
So sánh từ trái sang phải, cột nào lớn hơn thắng. !important override tất cả (tránh dùng).
Một số CSS properties tự động kế thừa từ parent sang child (color, font-family, font-size, line-height).
- Các properties về box model (margin, padding, border) KHÔNG kế thừa.
- Dùng
inherit,initial,unsetđể override.
px: tuyệt đối. em: relative với font-size parent. rem: relative với root (html) font-size. %: relative với parent. vw/vh: % viewport width/height. rem được khuyến nghị cho responsive design. 2023+: svh/dvh/lvh (small/dynamic/large viewport height) xử lý địa chỉ bar mobile tốt hơn vh truyền thống; cqi/cqb cho container query units.
- Override tất cả specificity rules.
- Nên tránh vì: khó debug, khó maintain, phá vỡ cascade tự nhiên.
- Chỉ dùng cho utility classes hoặc override third-party styles khi không có cách khác.
Pseudo-class chọn state của element (:hover, :focus, :first-child, :nth-child).
- Pseudo-element tạo/chọn phần ảo (::before, ::after, ::first-line).
- Pseudo-class dùng 1 dấu hai chấm, pseudo-element dùng 2.
4 lớp từ trong ra: content (nội dung), padding (khoảng đệm), border (viền), margin (khoảng cách ngoài).
- Mặc định width/height chỉ tính content.
- Dùng
box-sizing: border-boxđể tính luôn padding + border.
content-box (mặc định): width/height chỉ tính content, padding+border cộng thêm. border-box: width/height bao gồm content+padding+border. border-box dễ quản lý hơn, nên dùng * { box-sizing: border-box }.
display: none: xóa khỏi layout, không chiếm không gian. visibility: hidden: ẩn nhưng vẫn chiếm không gian. opacity: 0: trong suốt, vẫn chiếm không gian VÀ nhận events. display: none truyền thống không animatable — tuy nhiên CSS @starting-style (Chrome 117+, Firefox 129+) cho phép animate từ display: none bằng transition.
static (mặc định, theo flow). relative (offset từ vị trí gốc, vẫn chiếm space). absolute (thoát flow, relative với positioned ancestor). fixed (relative với viewport). sticky (hybrid relative+fixed).
Layout 1 chiều (row hoặc column) cho phép căn chỉnh, phân bổ không gian linh hoạt giữa items.
- Dùng cho: navigation bars, card layouts, centering, form layouts.
- Grid phù hợp hơn cho layout 2 chiều.
justify-content căn chỉnh theo main axis (mặc định horizontal): flex-start, center, flex-end, space-between, space-around, space-evenly. align-items căn theo cross axis (mặc định vertical): stretch, center, flex-start, flex-end, baseline.
Layout 2 chiều (rows VÀ columns cùng lúc).
- Flexbox cho 1 chiều (row hoặc column).
- Grid tốt cho page layout tổng thể, Flexbox cho component layout.
- Có thể kết hợp cả hai.
Fractional unit - đơn vị tỷ lệ trong Grid. grid-template-columns: 1fr 2fr = cột 2 gấp đôi cột 1.
- Fr phân bổ không gian còn lại sau khi trừ fixed sizes.
- Linh hoạt hơn % vì tự tính gap.
Thiết kế web tự điều chỉnh giao diện theo kích thước màn hình (desktop, tablet, mobile).
- Dùng fluid layouts (%, fr), flexible images, media queries.
- Mobile-first approach được khuyến nghị.
Viết CSS cho mobile trước (base styles), dùng min-width media queries thêm styles cho màn hình lớn hơn.
Ưu điểm: performance tốt hơn trên mobile, progressive enhancement, code gọn hơn.
@media (min-width: 768px) { ... } áp dụng styles khi viewport >= 768px.
- Có thể kết hợp:
@media (min-width: 768px) and (max-width: 1024px). - Breakpoints phổ biến: 640, 768, 1024, 1280px.
Biến trong CSS: --primary: #2563eb.
- Truy cập:
var(--primary). - Khai báo trong
:rootcho global. - Có cascade/inheritance, thay đổi runtime bằng JS.
- Hỗ trợ fallback:
var(--color, blue).
Naming convention CSS: block__element--modifier. Tránh nesting sâu, dễ maintain.
- Block: component độc lập —
.card - Element: phần trong block —
.card__title - Modifier: biến thể —
.card--featured
Parent selector trong CSS (trước đây không có). Chọn element có chứa selector con.
Ví dụ: article:has(img) chọn article có chứa img. div:has(> p) chọn div có p là direct child. Practical use case: :has(input:focus) để style form field khi input bên trong đang được focus.
Lưu ý: :has() có thể tốn performance khi dùng trong dynamic selectors phức tạp. Browser support: baseline 2023 (Chrome 105+, Safari 15.4+, Firefox 121+).
Space (descendant): bất kỳ con cháu nào. > (child): chỉ con trực tiếp. + (adjacent sibling): anh em liền kề ngay sau. ~ (general sibling): tất cả anh em sau.
Ví dụ: div > p vs div p.
Khi 2 vertical margins tiếp xúc nhau, chúng merge thành 1 margin (lấy giá trị lớn hơn).
- Xảy ra giữa siblings, parent-child (không có padding/border ngăn cách).
- Không xảy ra với horizontal margins, flexbox, grid items.
- Kết hợp relative và fixed.
- Element scroll bình thường cho đến khi đạt threshold (top/bottom), sau đó 'dính' tại vị trí đó.
- Cần set ít nhất 1 trong top/right/bottom/left.
- Parent phải có overflow visible.
Kiểm soát thứ tự xếp chồng (stacking order) của positioned elements. Giá trị cao hơn nằm trên. Chỉ hoạt động với position khác static. Tạo stacking context mới với: z-index + positioned, opacity < 1, transform, filter, isolation: isolate, transform-style: preserve-3d.
Lưu ý: isolation: isolate là cách tạo stacking context không cần z-index — hữu ích khi muốn ngăn z-index "rò rỉ" ra ngoài component.
Nhóm 3D ảo chứa các elements cùng xếp chồng. Được tạo bởi: root element, positioned + z-index, opacity < 1, transform, filter, will-change (bất kỳ giá trị tạo layer), isolation: isolate, contain: layout/paint, mix-blend-mode (khác normal). Z-index chỉ so sánh trong cùng stacking context, không xuyên qua.
Khi debug z-index không hoạt động: kiểm tra xem có stacking context "cha" nào đang giới hạn z-index của element không.
flex-basis: kích thước ban đầu (trước grow/shrink). flex-grow: tỷ lệ phân bổ không gian thừa (0 = không grow). flex-shrink: tỷ lệ co lại khi thiếu space (0 = không shrink).
Shorthand: flex: grow shrink basis.
nowrap (mặc định, tất cả trên 1 dòng, co lại nếu cần). wrap (xuống dòng khi hết space). wrap-reverse (xuống dòng ngược).
Khi wrap, dùng align-content căn chỉnh các dòng.
Tạo khoảng cách giữa flex items mà không cần margin. gap: 16px (cả 2 chiều), row-gap và column-gap riêng.
Ưu điểm: không gây margin collapse, không có khoảng cách thừa ở edge.
Định nghĩa số lượng và kích thước columns/rows.
Ví dụ: grid-template-columns: 200px 1fr 1fr = 1 cột 200px + 2 cột equal. Dùng repeat(3, 1fr) cho 3 cột bằng nhau. Kết hợp minmax(), auto-fit, auto-fill.
Cả hai dùng với repeat() để tự động tạo columns. auto-fill: tạo tracks rỗng nếu còn space. auto-fit: collapse tracks rỗng, items stretch fill space. auto-fit phổ biến hơn cho responsive grids.
Giới hạn min/max kích thước track. minmax(200px, 1fr) = tối thiểu 200px, tối đa bằng nhau.
Kết hợp auto-fit: repeat(auto-fit, minmax(250px, 1fr)) tạo responsive grid không cần media queries.
Đặt tên cho vùng trong grid bằng strings: grid-template-areas: 'header header' 'sidebar main' 'footer footer'.
- Items dùng
grid-area: header. - Trực quan, dễ đọc.
- Dùng
.cho ô trống.
clamp(min, preferred, max) giới hạn giá trị trong khoảng.
Ví dụ: font-size: clamp(1rem, 2.5vw, 2rem) = fluid typography tự co giãn. Thay thế nhiều media queries, tạo responsive sizing mượt.
Responsive theo kích thước container thay vì viewport. @container (min-width: 400px) { ... }. Container phải có container-type: inline-size (và tuỳ chọn container-name để query có tên khi dùng nhiều containers lồng nhau).
Ngoài size queries, CSS 2023 còn hỗ trợ container style queries — query giá trị custom property: @container style(--featured: true) { ... }. Browser support: baseline 2023. Lợi thế so với media queries: cùng component có thể hiển thị khác nhau tùy vị trí đặt, không cần biết viewport.
srcset cung cấp nhiều phiên bản ảnh. sizes cho browser biết ảnh chiếm bao nhiêu viewport để chọn đúng ảnh. Có 2 descriptor: pixel density (2x, 3x) và width (400w, 800w).
Khi dùng width descriptor với sizes, browser tính toán: srcset="img-400.jpg 400w, img-800.jpg 800w" sizes="(min-width: 768px) 50vw, 100vw" — sizes phải khớp với CSS layout width thực tế, nếu không browser chọn sai ảnh. Tiết kiệm bandwidth đáng kể trên thiết bị nhỏ.
Định nghĩa animation steps: @keyframes fadeIn { from { opacity: 0 } to { opacity: 1 } }.
- Dùng % cho nhiều bước:
0% { } 50% { } 100% { }. - Áp dụng:
animation: fadeIn 0.5s ease forwards.
Hint cho browser chuẩn bị trước cho animation/transition. will-change: transform tạo composite layer riêng, dùng GPU.
- Chỉ dùng khi thực sự cần, xóa khi animation xong.
- Lạm dụng tốn memory.
Hai loại biến trong CSS ecosystem với cách hoạt động khác nhau:
- Custom Properties: runtime, tham gia cascade/inherit, thay đổi bằng JS, scope theo DOM. Mạnh hơn cho theming và responsive.
- SASS variables: compile-time, flat scope, không thay đổi runtime. Tốt hơn cho calculations phức tạp.
CSS logical properties thay thế physical properties (left, right, top, bottom) bằng giá trị logic để CSS tự động thích ứng theo hướng viết của ngôn ngữ.
Ví dụ mapping:
- margin-inline-start thay margin-left — tự đổi sang phải khi RTL
- padding-block-start thay padding-top
- border-inline-end thay border-right
Quan trọng cho i18n: cùng một component hoạt động đúng với LTR (tiếng Anh) và RTL (tiếng Ả Rập) mà không cần viết thêm CSS.
CSS scroll-snap tạo hiệu ứng scroll "bắt dính" vào vị trí cố định mà không cần JavaScript. Container khai báo scroll-snap-type: x mandatory (hoặc y); mỗi item con khai báo scroll-snap-align: start (hoặc center, end).
mandatory: scroll buộc dừng chính xác tại điểm snap. proximity: chỉ snap khi dừng đủ gần.
Dùng cho carousels, image galleries, full-page scroll sections mà không cần thư viện JS.
Methodology viết styles bằng utility classes nhỏ trực tiếp trong HTML: class="flex items-center gap-4 p-4 bg-white rounded-lg". Tailwind CSS là framework phổ biến nhất.
Ưu điểm: phát triển nhanh, design consistent, không đặt tên class, tree-shake tự động xóa unused CSS (bundle nhỏ). Nhược: HTML verbose, learning curve ban đầu. So với BEM: ít abstraction hơn, productivity cao hơn cho hầu hết teams.
File CSS scoped theo component, class names tự động unique (hash). import styles from './Button.module.css'.
- Tránh conflicts, dùng với React/Next.js.
- Compile time, không runtime overhead.
CSS-in-JS viết CSS trực tiếp trong JavaScript (styled-components, Emotion).
Ưu điểm: styles scoped tự động theo component, dynamic styling dựa trên props/state, CSS co-located với component logic.
Nhược điểm: runtime cost (generate CSS khi chạy), tăng bundle size, SSR phức tạp hơn.
Xu hướng mới: zero-runtime CSS-in-JS như Vanilla Extract, Panda CSS — compile CSS tại build time, không có runtime overhead.
CSS tối thiểu cần thiết để render above-the-fold content (phần user nhìn thấy đầu tiên).
- Cách dùng: inline critical CSS trong
<style>tag ở<head>, phần CSS còn lại load async bằng<link rel="preload">hoặc JS injection. - Giải quyết vấn đề render-blocking CSS.
- Tools: Critical (npm), Critters (Webpack plugin).
- Cải thiện FCP và LCP đáng kể, đặc biệt trên mobile/3G.
auto (browser quyết định). block (ẩn text đến khi font load). swap (hiện fallback, swap khi ready - khuyến nghị). fallback (swap nhanh hoặc giữ fallback). optional (dùng nếu cached, không nếu chưa). swap tốt cho hiển thị nhanh (tránh FOIT) nhưng có thể gây CLS nếu không dùng size-adjust.
Dùng optional nếu ưu tiên CLS.
backdrop-filter áp dụng filter effects (blur, brightness, contrast, grayscale) cho phần background phía sau element, không phải chính element đó.
Ví dụ frosted glass: backdrop-filter: blur(10px) + background: rgba(255,255,255,0.3). Element phải có background semi-transparent để phần nền phía sau nhìn xuyên qua được.
Ứng dụng:
- Navigation bar trong suốt
- Modal overlays
- Glassmorphism card designs
Hai pattern tùy theo số dòng:
Single line:
.truncate {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}Multi-line (ví dụ 3 dòng):
.clamp {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3;
overflow: hidden;
}Mặc dù mang prefix -webkit-, line-clamp đã được hỗ trợ rộng rãi trên tất cả browsers hiện đại (Chrome 6+, Firefox 68+, Safari 5+).
1 file font chứa nhiều variations (weight, width, slant) thay vì nhiều files riêng.
- Giảm requests và file size.
- Dùng
font-variation-settingshoặc CSS properties (font-weight: 100-900 liên tục). - Smooth animations giữa weights.
Tôn trọng accessibility settings của user muốn giảm animations. Quan trọng cho users có vestibular disorders (chuyển động mạnh gây buồn nôn).
Best practice: dùng no-preference guard thay vì cắt toàn bộ animations:
@media (prefers-reduced-motion: no-preference) {
.animated { animation: slideIn 0.3s ease; }
}Hoặc giảm thay vì xóa hoàn toàn: animation-duration: 0.001ms để giữ logic nhưng không có visual motion.
Tránh pattern * { animation: none } quá aggressive — có thể ảnh hưởng UX cần thiết.
Media query prefers-color-scheme cho phép phát hiện người dùng đang sử dụng chế độ dark hay light mode trên hệ điều hành, từ đó áp dụng styles phù hợp.
Ví dụ: @media (prefers-color-scheme: dark) { body { background: #1a1a1a; color: #eee; } }. Cách triển khai phổ biến nhất là kết hợp với CSS custom properties: khai báo biến màu ở :root cho light mode (base styles), rồi override trong media query dark để đổi bảng màu. Ngoài ra có thể dùng class-based toggle (thêm class .dark vào <html>) để cho phép user tự chọn theme và lưu preference vào localStorage.
<picture> chứa nhiều <source> với media conditions hoặc type khác nhau, fallback <img>.
- Art direction: thay đổi ảnh khác nhau theo viewport.
- Format: cung cấp WebP/AVIF với fallback JPEG.
- Browser tự chọn source phù hợp nhất.
box-shadow theo hình chữ nhật (box). drop-shadow theo shape thực tế (hỗ trợ transparent PNG, clip-path). drop-shadow không hỗ trợ spread value và inset. box-shadow nhanh hơn.
- Nên theo content.
- Resize browser và thêm breakpoint khi layout 'vỡ'.
- Không phụ thuộc device-specific sizes (thay đổi liên tục).
- Content-based breakpoints linh hoạt hơn, future-proof.
Browser tách elements thành layers riêng, composite chúng bằng GPU.
- Trigger composite layer: transform, opacity, will-change, position: fixed.
- Tách layer = animate mượt hơn nhưng tốn memory.
- Kiểm tra trong DevTools > Layers.
calc(): tính toán (mixed units: calc(100% - 2rem)). min(): giá trị nhỏ nhất. max(): giá trị lớn nhất. clamp(min, preferred, max): giới hạn trong khoảng.
Kết hợp: width: min(90%, 1200px) thay max-width.
oklch là perceptually uniform — khi giữ nguyên lightness và chroma mà chỉ thay đổi hue, mắt người cảm nhận độ sáng như nhau. hsl không đảm bảo điều này (vàng trông sáng hơn xanh dương cùng lightness).
Điều này cực kỳ quan trọng cho design systems: primary/secondary/error colors có perceived brightness đồng đều, UI nhất quán.
Ngoài ra, oklch hỗ trợ gamut rộng hơn sRGB (P3 displays) — màu sắc sống động hơn trên màn hình hiện đại.
Dùng CSS custom properties cho tất cả màu — khai báo --bg: #fff; --text: #1a1a1a ở :root, override trong dark mode.
Hai cách detect:
- @media (prefers-color-scheme: dark) — tự động theo system setting
- Class-based toggle (.dark trên <html>) — cho user tự chọn + lưu vào localStorage
Color palette: dùng oklch để perceived brightness đồng đều, kiểm tra contrast WCAG AA (4.5:1). Tránh pure black (#000) cho background — dùng dark gray (#1a1a1a) để giảm mỏi mắt.
touch-action kiểm soát cách browser xử lý touch gestures.
none: vô hiệu hóa hoàn toàn zoom và scroll — dùng cho canvas drawing, games, custom gesture handlersmanipulation: chỉ cho phép pan và pinch-zoom, disable double-tap zoom — loại bỏ 300ms click delay trên mobilepan-x: chỉ scroll ngangpan-y: chỉ scroll dọcpinch-zoom: chỉ cho phép zoom
Quan trọng cho các UI tương tác nhiều trên touch devices.
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à cột cùng lúc, phù hợp cho layout trang, dashboard, hoặc bố cục phức tạp.
- Trong thực tế thường kết hợp cả hai: Grid cho bố cục tổng thể của trang, Flexbox cho layout bên trong từng component.
- Quy tắc đơn giản: nếu chỉ cần sắp xếp theo một hướng thì dùng Flexbox, nếu cần kiểm soát cả hai chiều thì dùng Grid.
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: left hoặc right.
BFC hữu ích để giải quyết nhiều vấn đề CSS phổ biến như: ngăn margin collapse giữa parent và child, chứa float element bên trong container, và ngăn text bọc quanh float element. Hiểu BFC giúp debug layout CSS hiệu quả hơn nhiều.
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ị collapse.
- Để ngăn collapse, có thể tạo BFC bằng overflow: hidden hoặc dùng padding thay thế.
- Ngoài ra flexbox và grid cũng không bị margin collapse, nên khi dùng display: flex hoặc grid thì margin luôn cộng đúng như mong đợi.
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, grid-area: sidebar, v.v. Để responsive, chỉ cần dùng @media query thay đổi grid-template-areas mà không cần sửa HTML — ví dụ trên mobile chuyển thành layout một cột. Đây là ưu điểm lớn nhất: thay đổi bố cục hoàn toàn chỉ bằng CSS, giữ nguyên cấu trúc HTML, dễ bảo trì và dễ hiểu.
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 động thường vì hai phần tử nằm trong hai stacking context khác nhau — lúc này z-index chỉ so sánh trong cùng context, không xuyên qua được context cha.
Giải pháp là kiểm tra stacking context của các phần tử cha, điều chỉnh cho chúng nằm cùng context, hoặc sắp xếp lại thứ tự HTML.
:is() và :where() đều match danh sách selectors, nhưng :is() giữ specificity cao nhất trong danh sách, :where() luôn specificity = 0. :not() loại trừ selector.
Cả ba giúp viết CSS ngắn gọn hơn.
Có nhiều cách center với Flexbox/Grid:
Flexbox: display: flex; justify-content: center; align-items: center; trên container. Shorthand: place-items: center (Grid) hoặc dùng margin: auto trên child trong flex container.
Grid: display: grid; place-items: center; — shorthand cho cả align-items + justify-items. place-content: center hoạt động kể cả khi không set explicit height.
Với single element: display: grid; place-items: center; trên container là cách ngắn gọn nhất.
Cho phép grid item kế thừa track definitions từ parent grid. grid-template-columns: subgrid.
- Giải quyết vấn đề align content giữa các grid items.
- Firefox 71+, Safari 16+, Chrome 117+.
- Hiện đã widely supported.
grid-column: 1 / 3 = từ line 1 đến line 3 (span 2 columns). grid-row: 1 / -1 = full height. span 2 = chiếm 2 tracks.
- Dùng named lines hoặc numbers.
- Negative values đếm từ cuối.
transform và opacity chỉ trigger composite step (GPU). top/left trigger layout + paint + composite (CPU-intensive).
- Layout recalculation tốn thời gian vì ảnh hưởng tất cả elements.
- Luôn ưu tiên transform: translate() cho di chuyển.
Ba bước render pipeline của browser, xếp theo mức độ tốn tài nguyên:
- Reflow (layout): tính toán lại vị trí/kích thước elements — tốn nhất. Gây ra bởi: thay đổi width/height.
- Repaint: vẽ lại pixels — ít tốn hơn. Gây ra bởi: thay đổi color.
- Composite: ghép layers — ít tốn nhất. Gây ra bởi: transform.
oklch/oklab: perceptually uniform color spaces - thay đổi lightness/chroma/hue đều đặn hơn sRGB.
- Gamut rộng hơn (P3 displays).
color: oklch(70% 0.15 250). - Tốt hơn cho design systems, gradients không bị muddy.
CSS Nesting cho phép viết selectors lồng nhau trực tiếp trong CSS thuần, không cần preprocessor. & đại diện cho selector cha:
.card {
& .title { font-size: 1.5rem; }
&:hover { box-shadow: 0 4px 8px rgba(0,0,0,0.1); }
}Với relaxed syntax (Chrome 120+, Safari 17.2+, Firefox 117+), có thể bỏ & khi nesting element selectors: .card { h2 { ... } }.
Giảm lặp selector, giảm nhu cầu dùng SASS chỉ vì nesting.
Quản lý specificity theo layers: @layer base, components, utilities. Styles trong layer có thứ tự ưu tiên rõ ràng bất kể specificity. Layer sau override layer trước.
Quan trọng: styles ngoài @layer (unlayered) có ưu tiên CAO HƠN mọi layer — đây là gotcha phổ biến nhất. Với !important, thứ tự đảo ngược: layer sau ít quan trọng hơn. Giải quyết specificity wars khi dùng third-party CSS.
Đọc layout property (offsetHeight) rồi ngay lập tức ghi style → browser phải recalculate layout liên tục.
Tránh bằng: batch reads trước writes, dùng transform thay top/left, dùng requestAnimationFrame.
Scroll-driven animations gắn animation theo vị trí scroll thay vì theo thời gian. Hai loại timeline:
animation-timeline: scroll()— liên kết với scroll progress (ví dụ progress bar 0–100% khi cuộn trang)animation-timeline: view()— kích hoạt khi element vào/rời viewport
.progress {
animation: grow linear;
animation-timeline: scroll();
}Thay thế JS scroll event listeners tốn performance.
Chrome 115+, Firefox 128+.
CSS Anchor Positioning cho phép định vị một element tương đối so với một element khác (anchor) mà không cần JavaScript. Giải quyết vấn đề tooltip/popover cần tính toán tọa độ bằng JS.
Cách dùng:
/* Anchor element */
.trigger { anchor-name: --my-anchor; }
/* Positioned element */
.tooltip {
position-anchor: --my-anchor;
position: absolute;
position-area: top;
}Dùng @position-try để khai báo fallback khi không đủ không gian.
- Browser support: Chrome 125+, chưa có Firefox.
- Dùng cho tooltips, popovers, dropdown menus.
Rule @property cho phép đăng ký CSS custom property với kiểu dữ liệu cụ thể, giá trị mặc định và quy tắc kế thừa.
Ví dụ: @property --hue { syntax: '<angle>'; initial-value: 0deg; inherits: false; } khai báo biến --hue có kiểu là góc. Lợi ích lớn nhất là cho phép animate các custom properties — bình thường browser không biết cách interpolate custom properties nên không thể transition, nhưng với @property khai báo kiểu <color> hoặc <angle>, browser có thể animate mượt mà giữa các giá trị. Ứng dụng phổ biến nhất là animate gradient colors và tạo hiệu ứng chuyển màu phức tạp.
View Transitions API tạo hiệu ứng chuyển đổi mượt mà giữa DOM states hoặc giữa các trang. Khi gọi document.startViewTransition(), browser snapshot trạng thái trước, áp dụng thay đổi DOM, rồi animate sự khác biệt.
Hai loại:
- Same-document (Chrome 111+): list reordering, tab switching, morph animations
- Cross-document (Chrome 126+): chuyển trang trong MPA
Tạo trải nghiệm page transitions giống native app mà trước đây cần nhiều JavaScript phức tạp.
Popover API là tính năng native HTML tạo popover, tooltip, dropdown mà không cần JS cho logic hiển thị/ẩn.
- Cách dùng: thêm
popovervào element,popovertargettrên trigger:<button popovertarget="my-pop">Open</button><div id="my-pop" popover>Content</div> - Browser tự xử lý: top layer (trên mọi z-index), light dismiss (click ngoài để đóng), focus management.
- CSS styling:
:popover-openkhi đang mở,::backdropcho overlay phía sau. - Thay thế nhiều thư viện JS popover phức tạp trước đây.
Grid: 2D layout, responsive native (auto-fit, minmax), semantic, overlap dễ, gap spacing.
- Float: hack từ text wrapping, clearfix issues, fragile.
- Position: thoát flow, không responsive.
- Grid là standard hiện đại, được tất cả browsers hỗ trợ.
Fluid typography để font-size tự co giãn mượt mà theo viewport thay vì nhảy đột ngột qua media queries. Dùng clamp(): font-size: clamp(1rem, 0.5rem + 1.5vw, 2rem) — tối thiểu 1rem, tối đa 2rem, tuyến tính ở giữa.
Công thức tính preferred value: minSize + (maxSize - minSize) * ((100vw - minViewport) / (maxViewport - minViewport)).
Tính nhanh: dùng utopia.fyi — nhập min/max size + viewport range, tool generate sẵn clamp value.
Design tokens là các giá trị thiết kế cơ bản (colors, spacing, typography, shadows) được đặt tên và lưu trữ platform-agnostic, thường là JSON:
{ "color-primary": "#2563eb", "spacing-md": "16px" }Tokens được transform sang CSS custom properties, SASS variables, hoặc JS objects — single source of truth cho design system. Khi designer thay đổi một token, tất cả platforms (web, iOS, Android) cập nhật theo.
Tools: Style Dictionary (Amazon), Figma Tokens plugin.
Skip rendering off-screen elements hoàn toàn.
- Browser chỉ render khi element gần viewport.
- Cải thiện initial rendering performance đáng kể cho long pages.
- Cần
contain-intrinsic-sizeđể giữ scroll height chính xác.
:focus trigger mọi lúc element nhận focus (cả mouse click). :focus-visible chỉ khi focus cần visible indicator (keyboard navigation).
Dùng :focus-visible cho focus rings: chỉ hiện khi dùng keyboard, không khi click.
color-mix() trộn hai màu theo tỷ lệ chỉ định ngay trong CSS.
Ví dụ: color-mix(in srgb, red 30%, blue) = 30% đỏ + 70% xanh.
Ứng dụng thực tế:
- Hover states: color-mix(in oklch, var(--primary), white 20%) để lighten
- Auto-generate color palettes từ base color
- Opacity-like effect không cần rgba
Hỗ trợ srgb, oklch, lab — oklch cho kết quả trộn tự nhiên và đồng đều nhất.
Tối ưu CLS (Cumulative Layout Shift — đo mức layout bị dịch chuyển bất ngờ) bằng 4 kỹ thuật chính:
- Images/video: luôn khai báo
width+heighthoặcaspect-ratiođể browser reserve space trước khi tải xong - Dynamic content: reserve không gian cố định cho ads/embeds bằng
min-height - Web fonts: dùng
font-display: swap+size-adjusttrong@font-faceđể fallback font có kích thước gần giống font chính - Tránh inject content: không thêm nội dung mới phía trên viewport (banner notifications) vì đẩy toàn bộ nội dung xuống
Mỗi phương pháp phù hợp với từng tình huống khác nhau.
- CSS-in-JS (styled-components, Emotion) phù hợp khi cần dynamic theming phức tạp dựa trên props/state và xây dựng component libraries, nhưng có runtime cost.
- CSS Modules phù hợp khi cần scoped styles đơn giản, SSR-friendly và zero runtime overhead — rất tốt cho Next.js projects.
- Tailwind CSS phù hợp cho rapid development, giữ design consistent qua design tokens, và cho bundle size nhỏ nhờ tree-shaking tự động.
- Xu hướng hiện tại đang nghiêng về zero-runtime solutions (Tailwind, CSS Modules) vì performance tốt hơn so với runtime CSS-in-JS, đặc biệt với Server Components trong React.
Media queries = viewport-level: thay đổi layout tổng thể theo kích thước màn hình (sidebar collapse trên mobile, grid columns).
Container queries = component-level: component tự điều chỉnh layout dựa trên không gian được cấp, bất kể nằm ở đâu trên trang.
Kết hợp cả hai trong thực tế: media queries cho page layout, container queries cho reusable components (card hiển thị horizontal hay vertical tùy container width).
Container queries giải quyết vấn đề chính của media queries: cùng một component trong sidebar nhỏ và main content rộng cần layout khác nhau.
Tối ưu LCP bằng CSS gồm: inline critical CSS, preload hero assets, tránh @import, font-display: swap, và dùng <img> thay background-image cho LCP element.
- Inline critical CSS vào
<head>: browser render above-the-fold ngay, không chờ file CSS ngoài - Preload hero images + fonts:
<link rel="preload"> - Tránh
@import: tạo serial loading chain — dùng nhiều<link>tags song song thay thế font-display: swap: text hiện ngay với fallback font- Dùng
<img>thay background-image: browser phát hiện<img>sớm hơn khi parse HTML
Các chiến lược giảm CSS bundle size:
- PurgeCSS / Tailwind JIT: loại bỏ unused CSS — giảm đến 90% với Tailwind
- CSS Modules / scoped CSS: tree-shake styles không dùng theo component
- cssnano: minification — xóa whitespace, shorten colors, merge rules
- Shorthand properties:
margin: 10px 20pxthay vì 4 dòng riêng - Code-split CSS theo route: mỗi trang chỉ load CSS cần thiết
- Brotli/gzip compression: bật ở server level
- DevTools Coverage tab: audit và phát hiện CSS thừa