Responsive Web Design

Chapter 3
CSS Foundations for Responsive Interfaces

Bachelors Program in Full Stack Development
Responsive Web Design   •   Bachelor

CSS Foundations for Responsive Interfaces

Introduction

Responsive interfaces depend less on isolated media queries than on a correct understanding of how CSS resolves conflicts, computes dimensions and adapts values to available space. A layout may fail because a selector unexpectedly wins the cascade, a percentage has an unsuitable reference, padding enlarges a content-box, or a viewport unit responds poorly to mobile browser controls.

This chapter develops the CSS foundations required to reason about such behavior. It connects the cascade and value-processing model to inheritance, specificity, box generation, sizing constraints, logical properties, custom properties and relative units. These concepts support interfaces that remain usable across viewport sizes, writing systems, zoom levels and device configurations.

Learning Objectives

After completing this chapter, you should be able to:

  1. Explain all six stages of CSS value processing.
  2. Resolve conflicts using cascade origin, importance, layers, specificity and source order.
  3. Distinguish inherited properties from non-inherited properties.
  4. Calculate content-box and border-box dimensions.
  5. Select appropriate block, inline, flex, grid and none display behavior.
  6. Apply logical properties for writing-mode-independent layouts.
  7. Define reusable design values with custom properties and fallbacks.
  8. Apply minimum, preferred and maximum sizing constraints.
  9. choose appropriately among %, em, rem and viewport-relative units.
  10. Diagnose responsive layout failures systematically.

1. CSS as a Constraint and Resolution System

A browser does not simply read the last declaration and place its value on the screen. It must determine which declarations apply, resolve conflicts, interpret relative values and account for layout constraints. CSS is therefore best understood as a declarative constraint system.

Consider:

.notice {
  color: navy;
}

main .notice {
  color: darkred;
}

Both declarations are eligible for a .notice inside main. Assuming the same origin, importance and layer, the second selector wins because it has greater specificity.

The winning source text is still not necessarily the final rendered value. A declaration such as width: 50% must be converted into a computed representation and then resolved against the element's containing block during layout.

2. CSS Value Processing

The CSS value-processing model contains six stages:

  1. Declared values: All property declarations that apply to an element.
  2. Cascaded value: The declaration that wins the cascade.
  3. Specified value: The cascaded value after CSS defaulting and inheritance rules are applied.
  4. Computed value: The specified value resolved as far as possible before layout.
  5. Used value: The value selected after layout-dependent quantities are known.
  6. Actual value: The used value after implementation constraints or physical rendering adjustments.

For example, suppose a child has width: 50%. The percentage can remain unresolved in its computed value. If the containing block's content width becomes 720 px during layout, the used width is 360 px. Device-pixel rounding may then influence the actual painted result.

The six stages of CSS value processing 1. Declared valuesAll applicable declarations 2. Cascaded valueWinning declaration 3. Specified valueAfter defaulting/inheritance 4. Computed valueResolved before layout 5. Used valueResolved during layout 6. Actual valueRendered result
The six stages of CSS value processing from declared values to actual value
Figure: The six stages of CSS value processing from declared values to actual value

Figure: The complete six-stage CSS value-processing sequence, including the specified-value stage between cascading and computation.

This sequence is useful for debugging. If color is wrong, inspect cascade and inheritance. If width is wrong despite the expected rule winning, inspect containing-block dimensions and sizing constraints.

3. The Cascade

The cascade chooses one value when multiple declarations target the same property on the same element. Its principal criteria are evaluated in a defined order.

3.1 Relevance

Declarations that do not match the element or whose conditional rules are false are excluded. A declaration inside an unmatched media query, for example, is not relevant.

3.2 Origin and importance

CSS declarations may originate from the user agent, user or author. Animations and transitions also participate in cascade ordering. The !important annotation changes the precedence category; it is not merely an increase in selector specificity.

User important declarations can override author important declarations. This behavior supports accessibility—for example, a user stylesheet may enforce readable colors or font sizes.

Authors should avoid using !important as a routine repair mechanism because it makes later overrides more difficult. It may be justified for narrowly defined utility rules or controlled overrides.

3.3 Cascade layers

Cascade layers provide explicit precedence groups:

@layer reset, base, components, utilities;

@layer base {
  button { font: inherit; }
}

@layer utilities {
  .text-center { text-align: center; }
}

For normal author declarations, later layers have higher priority than earlier layers. Unlayered normal author rules outrank layered normal author rules. For important declarations, layer order is reversed, protecting foundational important rules from later layers.

3.4 Specificity

Selector specificity can be represented as a three-component tuple:

S = (a, b, c)

Here:

  • a is the number of ID selectors.
  • b is the number of class selectors, attribute selectors and pseudo-classes.
  • c is the number of type selectors and pseudo-elements.

Tuples are compared lexicographically: first a, then b, then c. This is not ordinary base-ten arithmetic.

SelectorSpecificity
article(0, 0, 1)
.card(0, 1, 0)
article.card(0, 1, 1)
#checkout .card(1, 1, 0)

Inline style declarations conceptually outrank ordinary selector-based author declarations within their cascade category, but they should not be treated as a fourth selector tuple component.

The pseudo-class :where() always contributes zero specificity. By contrast, :is(), :not() and :has() adopt the specificity of their most specific selector argument.

:where(nav, aside) a { color: inherit; } /* low specificity */
.card:is(.featured, #priority) { /* adopts the highest argument specificity */ }

3.5 Scoping proximity and source order

If competing declarations remain tied, rules closer to the scoped element can win when CSS scoping is in use. If all earlier criteria are tied, the declaration appearing later in source order wins.

A maintainable strategy is to use low-specificity component selectors, deliberate cascade layers and limited nesting rather than escalating selector complexity.

4. Inheritance and Defaulting

Inheritance passes the computed value of selected properties from parent to child. Text-oriented properties such as color, font-family and line-height commonly inherit. Box properties such as margin, padding, border and width normally do not.

body {
  color: #1f2937;
  font-family: system-ui, sans-serif;
}

Descendants inherit these text properties unless another declaration overrides them.

CSS-wide keywords provide explicit control:

KeywordEffect
inheritUses the parent's computed value.
initialUses the property's specification-defined initial value.
unsetActs as inherit for inherited properties and initial otherwise.
revertRolls back to a lower-priority origin or earlier cascade state.
revert-layerRolls back within the cascade-layer structure.

The initial value is not necessarily the browser's familiar presentation. For example, headings appear bold largely because of user-agent stylesheet rules, not because every relevant property has that appearance as its formal initial value.

5. The Box Model

Most CSS layout boxes contain four nested regions:

  1. content,
  2. padding,
  3. border,
  4. margin.

For a non-fragmented rectangular box using box-sizing: content-box, its outer border-box width is:

Wborder = Wcontent + Pis + Pie + Bis + Bie

where Wcontent is content width, Pis and Pie are inline-start and inline-end padding, and Bis and Bie are corresponding border widths. All quantities must use compatible length units. Margins lie outside the border box and are excluded from this equation.

Worked Example: Content-box versus Border-box

Assume an element has:

.panel {
  width: 360px;
  padding: 24px;
  border: 2px solid;
}

With content-box, the horizontal border-box width is:

360 px + 24 px + 24 px + 2 px + 2 px = 412 px

With box-sizing: border-box, the declared 360 px includes padding and borders. The content width becomes:

360 px - 48 px - 4 px = 308 px

A common baseline is:

*,
*::before,
*::after {
  box-sizing: border-box;
}

This makes declared dimensions easier to compare with visible dimensions. It does not guarantee that an element can never overflow; long unbreakable content, intrinsic minimum sizes or transforms may still do so.

Margin behavior

Adjacent vertical margins of block boxes in normal flow can collapse under defined conditions. Flex and grid item margins do not collapse with one another. Because margin collapsing is conditional, developers should not assume that two adjoining vertical margins will always be added.

6. Display Modes and Formatting Contexts

The display property influences both the element's outer participation in layout and the layout model used for its children.

Display valuePrincipal behavior
blockGenerates a block-level box that normally occupies an available line in normal flow.
inlineParticipates within line boxes; ordinary width and height do not size it like a block box.
inline-blockFlows inline while accepting box dimensions.
flexCreates a block-level flex container for one-dimensional layout.
inline-flexCreates an inline-level flex container.
gridCreates a block-level grid container for two-dimensional layout.
inline-gridCreates an inline-level grid container.
flow-rootCreates a block formatting context, useful for containing floats.
noneRemoves the element's generated box and descendants from layout.

Flexbox is suited to distributing items primarily along one axis. Grid explicitly coordinates rows and columns. Either may wrap responsively, but their conceptual models differ.

.toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
}

.gallery {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr));
  gap: 1rem;
}

The min(100%, 16rem) construction prevents the minimum track size from exceeding a narrow grid container.

In flex and grid layouts, intrinsic minimum sizing can cause unexpected overflow. Applying min-inline-size: 0 to a flexible item allows it to shrink below its content-based automatic minimum when that behavior is appropriate.

display: none normally removes content from both visual layout and the accessibility tree. It should not be used when information must remain available to assistive technology.

7. Logical Properties

Physical properties such as margin-left and width assume physical directions. Logical properties instead express layout relative to writing mode and text direction.

Physical conceptLogical form
widthinline-size
heightblock-size
min-widthmin-inline-size
margin-left/rightmargin-inline-start/end
padding-top/bottompadding-block-start/end
left borderborder-inline-start

In horizontal English text, the inline axis runs left to right and the block axis generally runs top to bottom. In right-to-left text, inline start is on the right. In vertical writing modes, the axes change more substantially.

.callout {
  border-inline-start: 0.3rem solid var(--accent);
  padding-inline-start: 1rem;
  margin-block: 1.5rem;
  max-inline-size: 65ch;
}

This component adapts more naturally to localization than one based on border-left, padding-left and fixed physical dimensions.

8. Custom Properties

Custom properties store reusable CSS token sequences:

:root {
  --space-1: 0.5rem;
  --space-2: 1rem;
  --surface: #ffffff;
  --text: #172033;
}

.card {
  padding: var(--space-2);
  color: var(--text);
  background: var(--surface);
}

Names are case-sensitive. Standard custom properties beginning with -- inherit by default. They participate in the cascade and can be overridden contextually:

[data-theme="dark"] {
  --surface: #172033;
  --text: #f8fafc;
}

A fallback is used when the referenced custom property is missing or invalid for substitution:

.card {
  gap: var(--card-gap, 1rem);
}

The fallback is the second argument to var(), not a general error handler for every invalid final declaration. A substituted custom-property value can make a declaration invalid at computed-value time, causing the declaration to resolve according to CSS invalid-value rules.

Custom-property cycles are invalid:

:root {
  --a: var(--b);
  --b: var(--a);
}

The @property rule can register a type, inheritance behavior and initial value:

@property --panel-opacity {
  syntax: "<number>";
  inherits: false;
  initial-value: 1;
}

Registration can improve validation and make some custom properties safely animatable. Browser support and project requirements should be checked before relying on it as a critical dependency.

9. Sizing Constraints and Intrinsic Responsiveness

Responsive sizing is often better expressed as a range than as a single fixed value.

article {
  inline-size: 100%;
  max-inline-size: 70rem;
  margin-inline: auto;
}

The preferred inline size is 100% of the relevant containing block, but it cannot exceed 70 rem.

When compatible minimum, preferred and maximum values are available, the effective size can be conceptualized as:

Sused = min(max(Spreferred, Smin), Smax)

Here Sused is the constrained used size, Spreferred is the preferred size, and Smin and Smax are lower and upper bounds. This simplified relationship assumes a consistent ordering where Smin ≤ Smax and omits intrinsic sizing and formatting-context effects. In CSS conflict resolution, a minimum constraint can take precedence when minimum and maximum constraints are inconsistent.

The clamp() function expresses a bounded preferred value:

h1 {
  font-size: clamp(2rem, 1.4rem + 2vw, 3.5rem);
}

Conceptually:

clamp(MIN, PREFERRED, MAX) = max(MIN, min(PREFERRED, MAX))

This expression assumes comparable values. CSS performs the precise type and value resolution defined for math functions.

Fixed width is not inherently wrong, but fixed widths should be used only when the content and context justify them. Controls, cards and text columns usually benefit from maximum constraints and flexible preferred sizes.

10. Relative Units

10.1 Percentages

A percentage's reference depends on the property. A percentage inline-size or width is generally resolved against the containing block's corresponding size. Percentage heights often require a definite containing-block height; otherwise they may behave as auto.

An important historical rule is that percentage padding and margin values resolve against the containing block's inline size, including values used on block-axis sides.

Worked Example: Percentage Width

If a containing block has a 720 px content width, a child with width: 50% receives a 360 px content width under content-box:

0.50 × 720 px = 360 px

If the child also has 24 px padding on each side and 2 px borders, its border-box width is 412 px. Under border-box, a declared width: 50% produces a 360 px border box instead.

10.2 em

For font-size, an em value is relative to the inherited font size used to calculate that element's font size. For most other properties, em is relative to the element's own computed font size.

Suppose the root font size is 16 px:

.card {
  font-size: 1.25rem;
  padding: 1.5em;
}

.card small {
  font-size: 0.8em;
}

The card font size is 1.25 × 16 px = 20 px. Its padding is 1.5 × 20 px = 30 px. The small element's font size is 0.8 × 20 px = 16 px.

em is useful when a component's spacing should scale with its own typography. Deeply nested font sizing in em can compound, so it should be applied intentionally.

10.3 rem

The rem unit is relative to the root element's font size. It provides a stable document-level scale and is commonly used for spacing, typography and sizing constraints.

Do not disable user text scaling by forcing inaccessible root sizing. A default root size controlled by browser and user preferences generally provides a sound baseline.

10.4 Viewport units

Classic viewport units include:

  • vw: 1% of viewport width,
  • vh: 1% of viewport height,
  • vmin: 1% of the smaller viewport dimension,
  • vmax: 1% of the larger viewport dimension.

On mobile devices, browser interface elements expand and retract, making viewport height ambiguous. Modern CSS therefore defines:

  • svh: 1% of the small viewport height,
  • lvh: 1% of the large viewport height,
  • dvh: 1% of the dynamic viewport height.

Corresponding width and logical-axis families also exist, including svw, lvw, dvw, svi, lvi, dvi, svb, lvb and dvb.

.hero {
  min-block-size: 100svh;
}

.live-panel {
  min-block-size: 100dvh;
}

100svh provides a stable height based on the viewport with browser controls present. 100dvh follows the changing viewport and can therefore resize as controls move. Neither is universally superior: the correct choice depends on whether stability or current visible-area fit is more important.

Using 100vw for ordinary page-width content may create horizontal overflow where the unit includes space associated with a vertical scrollbar. width: 100% is often safer for content intended to match its containing block.

10.5 Character-based units

Although not viewport units, ch and lh are valuable for responsive systems. 1ch is based on the advance measure of the 0 glyph, while 1lh represents the element's computed line height. A readable text column might use max-inline-size: 65ch, although ch is only an approximation of character count and varies by font.

11. Applied Case: Responsive Public-Service Portal

Background

This illustrative case concerns a municipal portal used to apply for permits. Residents access it on mobile phones, desktop computers and zoomed browser windows. The service must also support right-to-left localization.

Problem

The original interface used fixed 960 px panels, left-specific spacing and a 100vh form screen. On narrow phones, form fields overflowed. Mobile browser controls obscured the submit area, and Arabic localization required numerous overrides. Highly specific selectors and repeated !important declarations made maintenance difficult.

Analysis

Inspection identified five underlying causes:

  1. content-box caused padding to enlarge declared field widths.
  2. Fixed dimensions did not adapt to the containing block.
  3. margin-left and border-left encoded one writing direction.
  4. 100vh did not represent the stable visible height reliably on mobile.
  5. High selector specificity prevented predictable component overrides.

Approach

The team introduced a layered architecture and design tokens:

@layer reset, base, components, utilities;

:root {
  --space: 1rem;
  --measure: 68rem;
  --field-border: #64748b;
  --focus: #075985;
}

*, *::before, *::after {
  box-sizing: border-box;
}

.portal {
  inline-size: min(100% - 2rem, var(--measure));
  margin-inline: auto;
  min-block-size: 100svh;
}

.form-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 18rem), 1fr));
  gap: var(--space);
}

.field {
  min-inline-size: 0;
}

.field input,
.field select {
  inline-size: 100%;
  min-block-size: 2.75rem;
  border: 1px solid var(--field-border);
}

.field input:focus-visible,
.field select:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 2px;
}

.alert {
  border-inline-start: 0.3rem solid #b91c1c;
  padding-inline: 1rem;
}

At a viewport width of 390 px, the portal expression 100% - 2rem, assuming a 16 px root font size and a containing block matching the viewport, yields:

390 px - (2 × 16 px) = 358 px

The grid's min(100%, 18rem) track minimum cannot exceed the narrow container, so the form collapses to a single column without forcing horizontal overflow.

Outcome

The interface became usable at narrow widths and high zoom. Logical properties reduced localization-specific CSS, while low-specificity layered rules made overrides predictable. Stable viewport sizing kept essential controls within the mobile layout more reliably.

Learning Points

Responsive success resulted from interacting foundations rather than from adding many breakpoints. Box sizing prevented accidental enlargement; constraints allowed flexible dimensions; logical properties supported internationalization; and cascade management improved maintainability.

12. Debugging and Professional Practice

A systematic debugging process should ask:

  1. Does the selector match, and is the declaration relevant?
  2. Which declaration wins the cascade?
  3. Is the property inherited or defaulted?
  4. What is the computed value?
  5. What containing block or font size resolves the relative unit?
  6. Do minimum, maximum or intrinsic sizes modify the result?
  7. Does the box model add padding or borders?
  8. Is overflow caused by content, transforms or formatting-context rules?

Browser developer tools expose matched declarations, crossed-out rules, computed styles and box-model dimensions. Responsive-mode emulation is useful, but real-device testing remains important because browser controls, font availability, safe areas and input methods differ.

Accessibility and governance

Responsive design is an accessibility concern. Interfaces should support text enlargement and reflow without loss of information or functionality. Avoid using tiny viewport-dependent text without minimum bounds. Touch targets should remain operable, focus indicators visible and source order meaningful when layouts rearrange visually.

Custom properties should use semantic names such as --color-danger rather than names tied only to appearance such as --red. Semantic tokens enable theme governance, contrast review and controlled system-wide changes.

User important rules must not be casually defeated; they may represent accessibility requirements. Teams should document cascade layers, supported writing modes, browser targets and token ownership as part of frontend governance.

Contemporary direction

Modern responsive CSS increasingly favors intrinsic layouts: min(), max(), clamp(), flexible grid tracks, logical properties and container queries. Container queries allow components to respond to the size of their containing context rather than only the viewport. Nevertheless, these newer capabilities still depend on the cascade, box model and value-resolution principles developed in this chapter.

Chapter Summary

CSS responsive behavior emerges through a six-stage value process: declared, cascaded, specified, computed, used and actual values. The cascade resolves competing declarations through relevance, origin and importance, layers, specificity, scoping proximity and source order. Inheritance then supplies values for selected properties where appropriate.

The box model explains how content, padding, borders and margins contribute to layout. border-box often makes declared dimensions easier to manage, while display modes establish normal-flow, flex, grid and other formatting behaviors. Logical properties provide writing-mode independence, and custom properties support reusable, context-sensitive design tokens.

Responsive sizing should usually express constraints rather than rigid dimensions. Percentages respond to containing blocks; em responds to local typography; rem provides a root-relative scale; and viewport units respond to viewport dimensions. Small, large and dynamic viewport units address the variable browser interface on mobile devices. Effective professional practice combines these tools with accessibility testing, predictable cascade architecture and systematic debugging.

Key Terms

Actual value: The final rendered value after device and implementation adjustments.

Border box: The region containing content, padding and borders.

Box model: The CSS model comprising content, padding, border and margin regions.

Cascade: The algorithm that selects among competing declarations.

Cascade layer: A named precedence group created with @layer.

Computed value: A specified value resolved as far as possible before layout.

Containing block: The reference rectangle used to resolve an element's position or dimensions.

Custom property: A cascading author-defined property whose name begins with --.

Declared value: A value from a declaration applicable to an element and property.

Dynamic viewport: The viewport size that changes as browser interface elements expand or retract.

Inheritance: The transfer of selected computed property values from parent to child.

Intrinsic sizing: Sizing influenced by an element's content and natural dimensions.

Logical property: A property expressed relative to inline and block axes rather than physical directions.

Relative unit: A unit whose magnitude depends on another measurement, such as font or viewport size.

Specified value: The value resulting after cascading and defaulting, including inheritance.

Specificity: Selector weight used to resolve otherwise competing declarations.

Used value: The value determined after layout-dependent measurements are available.

Viewport unit: A unit based on a percentage of a viewport dimension.

Review Questions

Short Answer Questions

  1. List the six stages of CSS value processing in order.
  2. How does border-box change the interpretation of a declared width?
  3. What is the difference between em and rem?
  4. Why are logical properties useful for localization?
  5. What does min-inline-size: 0 commonly achieve in flex or grid layouts?

Long Answer Questions

  1. Explain how origin, importance, layers, specificity and source order interact in the cascade.
  2. Compare block, inline, flex and grid formatting behavior, giving an appropriate use case for each.
  3. Explain inheritance and the effects of initial, inherit, unset, revert and revert-layer.
  4. Evaluate the benefits and risks of custom properties in a large design system.
  5. Compare vh, svh, lvh and dvh for mobile interface design.

Analytical / Application Questions

  1. A content-box element has width: 60%, 20 px padding on each side and 2 px borders. Its containing block is 800 px wide. Calculate its content width and border-box width. Then calculate its content width if border-box is applied.
  2. Refactor a component that uses margin-left, padding-right, width and height into logical properties, and explain how the change supports vertical or right-to-left writing.
  3. Diagnose a grid card that overflows despite having width: 100%. Consider intrinsic minimum sizing, unbreakable text, box sizing and percentage resolution in your analysis.

Multiple Choice Questions with Answers

Question 1

Which sequence correctly represents the six stages of CSS value processing?

A. Declared → specified → cascaded → computed → actual → used

B. Declared → cascaded → specified → computed → used → actual

C. Cascaded → declared → inherited → computed → actual → used

D. Declared → cascaded → computed → specified → actual → used

Correct Answer: B. Declared → cascaded → specified → computed → used → actual

Question 2

A content-box element has width: 300px, 20 px padding on each side and 2 px borders on each side. What is its border-box width?

A. 300 px

B. 324 px

C. 340 px

D. 344 px

Correct Answer: D. 344 px

Question 3

Which selector has specificity (1, 1, 0)?

A. article.notice

B. #main .notice

C. .notice:hover

D. #main article

Correct Answer: B. #main .notice

Question 4

Which statement about cascade layers is correct for normal author declarations?

A. Earlier layers always outrank later layers.

B. Specificity is compared before layer order.

C. Later layers outrank earlier layers.

D. Layered normal declarations always outrank unlayered normal declarations.

Correct Answer: C. Later layers outrank earlier layers.

Question 5

If the root font size is 16 px, what is the computed font size of an element declared with font-size: 1.25rem?

A. 12.8 px

B. 16 px

C. 20 px

D. 25 px

Correct Answer: C. 20 px

Question 6

Which declaration is most appropriate for a border that should appear at the start of the inline axis in both left-to-right and right-to-left layouts?

A. border-left: 1px solid

B. border-inline-start: 1px solid

C. border-block-start: 1px solid

D. border-right: 1px solid

Correct Answer: B. border-inline-start: 1px solid

Question 7

Which viewport unit follows changes in the visible viewport as mobile browser controls expand or retract?

A. svh

B. lvh

C. dvh

D. rem

Correct Answer: C. dvh

Question 8

What is the default inheritance behavior of an unregistered custom property such as --theme-color?

A. It inherits from the parent.

B. It never inherits.

C. It inherits only inside flex containers.

D. It inherits only when used by color.

Correct Answer: A. It inherits from the parent.

Question 9

A containing block is 720 px wide. A content-box child has width: 50%, 24 px padding on each side and 2 px borders on each side. What is the child's border-box width?

A. 360 px

B. 364 px

C. 408 px

D. 412 px

Correct Answer: D. 412 px

Question 10

Which declaration most directly allows a flex item to shrink below its automatic content-based minimum size along the inline axis?

A. max-inline-size: 0

B. min-inline-size: 0

C. inline-size: auto

D. overflow: visible

Correct Answer: B. min-inline-size: 0

Responsive Web Design
Chapter 3 of 15