Profile first: record the animation in Chrome DevTools Performance panel (with CPU throttling), look for long frames, purple Layout / green Paint bars. Jank usually means you're animating layout/paint properties. Fix by switching to `transform`/`opacity`, promoting the element with `will-change`, reducing paint area, debouncing JS-driven animation, and respecting `prefers-reduced-motion`.
A machine-coding task: render an N×M grid where N and M (and often cell state) are dynamic. Key points: derive the grid from state (a 1D or 2D array), drive columns with `grid-template-columns: repeat(N, 1fr)` from a variable, handle cell clicks immutably by index, keep keys stable, and lift configuration (size) to controlled inputs. Watch for re-render cost on large grids.
Build a grid of toggleable cells. The graded concepts are in the title: immutable state updates (copy before write, functional updater), modeling 2D structures (1D array with index math, or 2D array copied carefully), and predictable re-renders (stable keys, memoized cells, lifted state). Show you can update one cell without mutating or over-rendering.
CSS methodologies (BEM, SMACSS, OOCSS, ITCSS) impose naming and structure conventions to keep CSS scalable and avoid specificity wars. BEM (Block__Element--Modifier) keeps selectors flat and components self-contained. Responsive design uses media queries (mobile-first: base styles + `min-width` breakpoints) plus fluid units and modern intrinsic layout (clamp, auto-fill grid).
static = default flow. relative = in flow but offsettable + new positioning context. absolute = removed from flow, anchored to nearest positioned ancestor. fixed = anchored to viewport (or transformed ancestor). sticky = relative until a threshold, then fixed within scroll container.
The cascade resolves conflicts by: origin/importance > specificity > source order. Specificity is a 3-tuple (IDs, classes/attrs/pseudo-classes, type/pseudo-elements). `!important` and inline styles short-circuit the normal flow.
CLS is a Core Web Vital measuring unexpected layout shifts during the page's life — content jumping as images, ads, or fonts load. Good CLS is ≤ 0.1. Control it by always reserving space: width/height (or aspect-ratio) on media, min-height for async content/ads, font-display strategy + size-adjust to limit FOUT shift, and never inserting content above existing content.
Use CSS Grid for the responsive grid: `grid-template-columns: repeat(auto-fill, minmax(min, 1fr))` adapts column count to viewport with zero media queries; add `gap` for spacing. Use Flexbox inside each cell for its internal layout. Layer in `clamp()` for fluid sizing and a few media queries only for major layout changes.
display:none removes from the layout AND a11y tree (no space, not focusable). visibility:hidden reserves space but hides + removes from a11y. opacity:0 reserves space and IS still interactive + announced — usually a bug if you wanted 'hidden'.
Classic multi-source BFS on a grid (a.k.a. 'rotting oranges'). Seed a queue with ALL initial zombie cells at once, then BFS level by level — each level is one time unit. Track minutes as you process levels; mark cells visited as you infect them. At the end, if any human remains, return -1. Time O(rows×cols), space O(rows×cols).
static: default, in normal flow, ignores top/left. relative: in flow but offset from its own position, becomes a positioning context. absolute: removed from flow, positioned against the nearest positioned ancestor. fixed: removed from flow, positioned against the viewport. sticky: hybrid — in flow until it hits a scroll threshold, then sticks.
Flexbox is one-dimensional (a row OR a column). Grid is two-dimensional (rows AND columns at once). Use flex for component layouts and toolbars, grid for page templates, dashboards, and any 2D alignment.
The browser parses HTML into the DOM and CSS into the CSSOM, combines them into the render tree, runs Layout (geometry), Paint (pixels), and Composite (assemble layers). JS can mutate the DOM/CSSOM, so a synchronous <script> blocks parsing; CSS blocks rendering and (without async) blocks the script after it. This is the Critical Rendering Path.
Use a normalize/reset stylesheet, modern layout primitives (flex/grid), feature detection (@supports), autoprefixer + browserslist, polyfills only where needed, and test on real Safari/iOS plus BrowserStack matrix.
Ship less CSS (purge unused, split per route, critical-CSS inline + defer rest), keep selectors flat and cheap, avoid render-blocking and @import chains, animate only transform/opacity, use containment (`content-visibility`, `contain`) to limit layout/paint scope, and minify + compress + cache. CSS is render-blocking, so its size and delivery directly affect FCP/LCP.
Control flex item width with the `flex` shorthand: `flex-grow` (share of extra space), `flex-shrink` (share of overflow reduction), `flex-basis` (starting size). `flex: 1` makes items share space equally; different grow values or explicit `flex-basis`/`width` give different widths. `flex: 0 0 200px` fixes a width; `flex: 2` vs `flex: 1` makes a 2:1 ratio.
Modern answer: `display: grid; place-items: center;` on the parent, or `display: flex; justify-content: center; align-items: center;`. Both center a child along both axes in one rule.
At scale the real problems are global scope, specificity wars, dead code, and theming. Pick a scoping strategy — CSS Modules, CSS-in-JS (runtime or zero-runtime), or utility-first (Tailwind) — layered with design tokens as CSS custom properties for theming. There's no single right answer; the senior move is matching the choice to team size, SSR needs, and performance budget.
Set the divs to `display: inline-block` (or `display: inline`) — they then flow horizontally like text instead of stacking as block elements. The hint's catch: inline-block elements get whitespace gaps from newlines in the HTML; remove them by setting `font-size: 0` on the parent, putting the divs on one line, or using HTML comments between them.
Critical CSS is the minimal set of styles needed to render above-the-fold content. You inline it directly in <head> so first paint doesn't wait on a network round-trip for the full stylesheet, then load the rest of the CSS asynchronously. Tools (Critical, Penthouse, framework plugins) extract it per route; the trade-off is build complexity and keeping it in sync.
Reflow (layout) recalculates element geometry — expensive, can cascade. Repaint redraws pixels without changing geometry — cheaper. Layout thrashing is forcing repeated synchronous reflows by interleaving DOM writes and layout reads in a loop. Fix it by batching: read all layout values first, then write all mutations (read/write separation), or use requestAnimationFrame.
Mobile-first: write base styles for narrow viewports, layer min-width media queries to upgrade. Use rem/em + clamp() for fluid type. Container queries (@container) let components respond to their slot, not the viewport.
CSS custom properties (`--name: value`) are real CSS variables — they cascade, inherit, can be scoped to any selector, read with `var(--name, fallback)`, and changed at runtime via JS or media queries. Unlike Sass variables (compile-time, static), they're live in the browser, which makes them ideal for theming, dark mode, and component APIs.
Flexbox is one-dimensional (lay out items along a single row OR column); Grid is two-dimensional (rows AND columns together). Flexbox is content-driven and great for components (toolbars, nav, centering); Grid is layout-driven and great for page-level structure. They compose — Grid for the macro layout, Flexbox inside the cells.
Every element is a box: content → padding → border → margin, from inside out. `box-sizing: content-box` (default) makes width/height apply to content only, so padding+border add to the rendered size. `box-sizing: border-box` makes width/height include padding+border — far more predictable, which is why most resets set it globally. Margins also collapse vertically.
Start from a baseline: a CSS reset/normalize, then build with well-supported standards and check caniuse. Use feature detection (`@supports`) over browser sniffing, progressive enhancement, autoprefixer for vendor prefixes, fluid/intrinsic layouts that tolerate variation, and a real cross-browser test matrix (BrowserStack + the main engines). Accept pixel-perfect-everywhere is the wrong goal — robust and acceptable is.
Avoid animating layout properties (width, height, top, left, margin, padding) — they trigger reflow + paint every frame on the main thread. Avoid paint-heavy ones (box-shadow, background, border-radius) when possible. Prefer `transform` and `opacity`: they're compositor-only, GPU-accelerated, and run off the main thread, so they stay at 60fps.
Which would you prefer for displaying products in a layout similar to an e-commerce website (e.g., Amazon), with 3 columns and multiple rows—Flexbox or CSS Grid? Why
Animating `width`, `top`, `margin`, etc. triggers layout (reflow) and paint on every frame — expensive, runs on the main thread, and janks. `transform` and `opacity` can be handled by the compositor on the GPU: no layout, no paint, just compositing. So they animate at 60fps even under main-thread load. Promote with `will-change`/`transform: translateZ(0)` when needed.
Tailwind is utility-first (compose from atomic classes); Bootstrap is component-first (pre-built components). Tailwind gives a tiny purged bundle, design consistency via a config-driven token system, no naming or context-switching, and full design freedom. Bootstrap is faster for generic UIs but produces sites that look the same and harder to customize. Traditional CSS scales poorly without conventions.