Frontend Interview Guide — HTML, CSS & JavaScript
In this tutorial, you'll learn about Frontend Interview Guide. We cover key concepts, practical examples, and best practices to help you understand and apply this topic effectively.
Frontend interviews test your knowledge of browser APIs, CSS layout, JavaScript fundamentals, framework internals, performance optimization, and accessibility best practices. Unlike generic coding interviews, frontend rounds focus on how users experience your code — rendering, interactivity, and responsiveness. Doda Browser engineers must understand every layer of web technology to build a fast, accessible browser.
Learning Path
flowchart LR A[Coding Interview Prep] --> B[Frontend Interview] B --> C[Backend Interview] C --> D[System Design] D --> E[Behavioral Prep] style B fill:#f90,color:#fff
HTML & CSS
Semantic HTML
<!-- BAD: Div soup -->
<div class="header">
<div class="nav"><div class="nav-item">Home</div></div>
</div>
<!-- GOOD: Semantic structure -->
<header>
<nav>
<ul>
<li><a href="/">Home</a></li>
</ul>
</nav>
</header>
CSS Layout — Flexbox & Grid
/* Flexbox: one-dimensional */
.container {
display: flex;
justify-content: space-between;
align-items: center;
gap: 1rem;
}
/* Grid: two-dimensional */
.grid-layout {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
gap: 2rem;
}
Specificity & Cascading
/* Specificity: inline > ID > class > element */
#header { color: red; } /* 0-1-0 */
.header { color: blue; } /* 0-0-1 */
div { color: green; } /* 0-0-0 */
JavaScript Fundamentals
Closures
function createCounter() {
let count = 0;
return {
increment: () => ++count,
decrement: () => --count,
getCount: () => count,
};
}
const counter = createCounter();
counter.increment();
counter.increment();
counter.decrement();
console.log(counter.getCount());
Expected output:
1
Event Loop
console.log('1: Sync');
setTimeout(() => console.log('2: setTimeout'), 0);
Promise.resolve().then(() => console.log('3: Microtask'));
console.log('4: Sync');
// Microtasks (Promise) execute before macrotasks (setTimeout)
Expected output:
1: Sync
4: Sync
3: Microtask
2: setTimeout
Debounce & Throttle
// Debounce — wait for pause before executing
function debounce(fn, delay) {
let timer;
return (...args) => {
clearTimeout(timer);
timer = setTimeout(() => fn(...args), delay);
};
}
// Throttle — execute at most once per interval
function throttle(fn, interval) {
let lastCall = 0;
return (...args) => {
const now = Date.now();
if (now - lastCall >= interval) {
lastCall = now;
fn(...args);
}
};
}
React
Hooks & Lifecycle
function UserProfile({ userId }) {
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
let cancelled = false;
async function fetchUser() {
setLoading(true);
const data = await api.getUser(userId);
if (!cancelled) {
setUser(data);
setLoading(false);
}
}
fetchUser();
return () => { cancelled = true; };
}, [userId]);
if (loading) return <Spinner />;
return <div>{user.name}</div>;
}
Performance Optimization
// Prevent unnecessary re-renders
const ExpensiveList = React.memo(({ items }) => {
return items.map(item => <ListItem key={item.id} item={item} />);
});
// Memoize computed values
function Dashboard({ transactions }) {
const totals = useMemo(() => {
return transactions.reduce((acc, t) => acc + t.amount, 0);
}, [transactions]);
}
// Memoize callbacks
function Parent() {
const handleClick = useCallback((id) => {
console.log('Clicked:', id);
}, []);
}
Accessibility (a11y)
<!-- Accessible button with ARIA -->
<button aria-label="Close dialog" onclick="close()">
<span aria-hidden="true">×</span>
</button>
<!-- Accessible form -->
<label for="email">Email address</label>
<input id="email" type="email" aria-describedby="email-hint" required />
<span id="email-hint">We'll never share your email.</span>
<!-- Skip navigation link -->
<a href="#main-content" class="skip-link">Skip to content</a>
Frontend System Design: Search Component
// Custom hook for debounced search
function useSearch(query) {
const [results, setResults] = useState([]);
const [loading, setLoading] = useState(false);
const debouncedQuery = useDebounce(query, 300);
useEffect(() => {
if (!debouncedQuery) {
setResults([]);
return;
}
setLoading(true);
fetch(`/api/search?q=${debouncedQuery}`)
.then(r => r.json())
.then(data => { setResults(data); setLoading(false); });
}, [debouncedQuery]);
return { results, loading };
}
Common Mistakes
- Not knowing the Rendering Pipeline — Understand DOM → CSSOM → Render Tree → Layout → Paint → Composite.
- Framework-only knowledge — React hooks syntax without understanding re-renders, virtual DOM, and reconciliation.
- Ignoring accessibility — "We'll add it later" is a red flag. Learn ARIA, keyboard navigation, and screen readers.
- No performance awareness — Bundle size, re-renders, lazy loading — every frontend interview covers these.
- Weak CSS — Know Flexbox, Grid, stacking contexts, and Responsive Design beyond copy-pasting Bootstrap.
- No testing — Know Testing Library, component tests, and E2E testing with Playwright or Cypress.
- Over-engineering — Redux for a 3-component app. Start simple, add complexity when needed.
Practice Questions
1. What's the difference between debouncing and throttling? Debouncing waits for a pause before executing. Throttling executes at most once per interval regardless of call frequency.
2. When does React re-render a component? When state changes (useState), when props change, or when a parent re-renders. React.memo and useMemo can prevent unnecessary re-renders.
3. What are Core Web Vitals? LCP (Largest Contentful Paint — loading), INP (Interaction to Next Paint — interactivity), CLS (Cumulative Layout Shift — visual stability).
4. What's the difference between reflow and repaint? Reflow recalculates layout positions (expensive). Repaint redraws pixels without layout changes (cheaper).
5. Challenge: Design and implement an autocomplete search component with debounced API calls, keyboard navigation (arrow keys), loading/error/empty states, and full ARIA accessibility support. Write tests for each interaction.
Real-World Task
Audit a real website (your favorite news site or SaaS) against Core Web Vitals using Chrome DevTools. Identify the top 3 performance issues and propose specific fixes with before/after measurements.
FAQ
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro