← All topics

HTML & CSS Interview Questions and Answers

HTML, CSS, Flexbox, Grid, Tailwind, responsive design, accessibility and styling performance.

225 questions for HTML & CSS interviews with answers and explanations - Junior, Middle and Senior levels. Sample questions, online quizzes and coding tasks.

Questions by level

Sample questions

A few questions from each level with the correct answer and an explanation.

HTML & CSS · Junior

  1. Why do HTML documents start with <!DOCTYPE html>?

    Correct answer: To enable standards rendering mode instead of quirks mode

    DOCTYPE is neither a tag nor a resource link. It tells the browser the page follows modern standards and switches on standards mode. Without it the browser falls back to quirks mode and emulates old browser bugs (for example, a different box model). The encoding is set by <meta charset="utf-8">, not by DOCTYPE.

  2. Which set contains only HTML5 semantic elements?

    Correct answer: <header>, <nav>, <main>, <article>, <footer>

    Semantic elements describe the meaning of content: header, navigation, main content, a standalone article, footer. <div> and <span> are neutral containers with no meaning, while <b> and <i> are presentational (highlighting without importance). Semantics helps screen readers, search engines and code readability.

  3. How many visible <main> elements can a page have, and what is it for?

    Correct answer: One - it holds the main unique content of the page

    <main> marks the main content of the document that is unique to the page (without header, menu and footer). Only one may be visible (others need the hidden attribute). It is a landmark for screen readers: users can jump straight to the content. <section> is a thematic section, not a replacement for <main>.

  4. How does <div> differ from <span> by default?

    Correct answer: <div> is a block element, <span> is an inline element

    <div> has display: block by default: it stretches to the full width of its parent and starts on a new line. <span> has display: inline: it flows within text and is as wide as its content. Neither carries semantics - both are containers for grouping and styling.

All 75 questions with answers →

HTML & CSS · Middle

  1. What is the specificity of the selector nav#main .item:hover > a::before?

    Correct answer: (1, 2, 3) - an ID, class + pseudo-class, two types + pseudo-element

    Count by column: IDs - #main (1); classes, attributes and pseudo-classes - .item and :hover (2); types and pseudo-elements - nav, a, ::before (3). Combinators (>, space) add no specificity. A pseudo-class weighs like a class, and a pseudo-element like a type selector.

  2. How do you override a third-party library's !important rule without touching its code?

    Correct answer: Write your own rule also with !important and a more specific selector

    A normal rule never beats !important, however specific it is. Among several !important declarations, specificity and order apply again. Other options: an inline style with !important, or cascade layers - for !important the layer order is reversed. The best path is avoiding !important in your own code.

  3. What does the shorthand flex: 1 expand to?

    Correct answer: flex-grow: 1; flex-shrink: 1; flex-basis: 0%

    flex: 1 = 1 1 0%: the base size is zero, so all space is split strictly in proportion to flex-grow - columns end up equal regardless of content. flex: auto = 1 1 auto - only the free space beyond content size is shared. flex: none = 0 0 auto.

  4. How does flex-basis differ from width on a flex item in a row (flex-direction: row)?

    Correct answer: flex-basis is the initial main-axis size; if it isn't auto, it takes precedence over width

    flex-basis sets the item's initial size along the main axis, from which grow and shrink are computed. With flex-basis: auto, width is used (or height in a column). With flex-direction: column, flex-basis applies to height rather than width - that's the key difference from width.

All 75 questions with answers →

HTML & CSS · Senior

  1. How do @layer cascade layers affect style priority?

    Correct answer: Layer order beats specificity: the later layer wins

    The cascade compares layers first and only then specificity within a layer. So .btn in the components layer beats #app .btn in an earlier base layer. Unlayered styles are stronger than any layer. For !important the order is reversed: important declarations in an earlier layer win. Tailwind v4 builds its styles on the theme, base, components and utilities layers.

  2. How do normal (non-!important) layered and unlayered styles rank against each other?

    Correct answer: Unlayered styles are stronger than any layer

    Unlayered styles implicitly go into a "last" layer and beat all named layers. That lets you wrap third-party CSS in @layer vendor and easily override it with your own styles. With !important the logic flips: important layered styles beat important unlayered ones.

  3. What does @scope (.card) to (.card__content) { img { ... } } do?

    Correct answer: Styles img inside .card, but not inside .card__content

    @scope defines a scope root and an optional "lower boundary" (donut scope): styles apply inside .card but don't reach into .card__content and its descendants. In addition, with equal specificity the rule with the closer root wins (scoping proximity). @scope doesn't create a Shadow DOM.

  4. What problem does subgrid solve?

    Correct answer: It gives a nested grid its parent's tracks, aligning parts across cards

    With grid-template-rows: subgrid a child grid inherits the parent's lines. The classic example is a row of cards whose titles, text and buttons should line up even when one card's title wraps to two lines. Without subgrid, each card aligns independently.

All 75 questions with answers →

Combined quizzes with this topic

Questions from several topics at once - just like an interview for a specific role.

Coding tasks

Write your solution right in the browser, and tests check it instantly. Interview classics: debounce, throttle, deepClone, Promise.all, EventEmitter, an LRU cache and more.

Open tasks →