skip to content

In Flutter, what does FractionallySizedBox's widthFactor multiply, and why does it throw as a plain child of a Row?

level: juniorimportance: should knowfreq 30%

answer

  1. factor times max incoming constraint
  2. child gets a tight size
  3. null factor passes through
  4. infinity times factor
  5. alignment needs spare room

basics

~20 s

widthFactor multiplies the maximum incoming width and gives the child that exact width. As a plain Row child the maximum width is infinite, so the child gets an infinite tight width and layout throws 'BoxConstraints forces an infinite width'.

solid answer

~40 s

`FractionallySizedBox` sizes its child to a fraction of the **maximum** incoming constraint: with `widthFactor: 0.6`, the child gets a **tight** width of `maxWidth * 0.6`. A `null` factor passes that axis's constraints through unchanged. The box itself takes the child's size, clamped to its own constraints, so `alignment` (default `Alignment.center`) only matters when the parent forces the box to be larger than the child. As a non-flex child of a `Row`, it receives an unbounded `maxWidth`; infinity times 0.6 is still infinity, and the framework reports `BoxConstraints forces an infinite width`. Give it a bounded slot, such as wrapping it in `Expanded`. Factors must be non-negative; a factor above 1.0 makes the child larger than the box, which paints outside it.

code

dart · 24 lines
dart
import 'package:flutter/material.dart';

class WatchedBar extends StatelessWidget {
  const WatchedBar({super.key, required this.watched});

  final double watched;

  @override
  Widget build(BuildContext context) {
    final ColorScheme colors = Theme.of(context).colorScheme;
    return SizedBox(
      height: 4,
      width: double.infinity,
      child: ColoredBox(
        color: colors.surfaceContainerHighest,
        child: FractionallySizedBox(
          alignment: Alignment.centerLeft,
          widthFactor: watched.clamp(0.0, 1.0),
          child: ColoredBox(color: colors.primary),
        ),
      ),
    );
  }
}

go deeper

for a junior

Know that widthFactor and heightFactor size a child to a fraction of the available space, and that it needs bounded space to work.

for a middle

Explain the tight child constraint from max times factor, the pass-through for null, and the infinite-width error in a Row.

for a senior

Reason about the box's own size, when alignment is visible, overflow with factors above 1.0, and when flex factors fit better.

for a principal

Prefer proportional sizing rules in shared components over hard-coded pixel widths, while keeping fractions relative to bounded containers.

## What it does `FractionallySizedBox` answers "make this child **60% as wide** as the space I have". Its parameters: | Parameter | Default | Meaning | |---|---|---| | `widthFactor` | `null` | fraction of the max incoming width | | `heightFactor` | `null` | fraction of the max incoming height | | `alignment` | `Alignment.center` | where the child sits inside the box | | `child` | none | the widget being sized | ## The algorithm The render object is `RenderFractionallySizedOverflowBox`. For each axis: 1. If the factor is non-null, compute `max * factor` and give the child that value as **both** min and max: a tight constraint. 2. If the factor is null, pass the incoming min and max through unchanged. 3. Lay the child out with those constraints. 4. Set its own size to `constraints.constrain(child.size)`. 5. Position the child using `alignment`. Step 4 is easy to miss. The box is not automatically as big as its parent's maximum; it takes the child's size, clamped to what the parent allows. So in a loose context, such as inside a `Center`, the box is exactly the child's size and `alignment` has no visible effect. It becomes visible when the box is forced larger — for example, when the parent gives it tight constraints. ## Why it throws in a Row A `Row` lays out a non-flex child with no maximum width. In step 1, `double.infinity * 0.6` is still infinity, so the child is told to be exactly infinitely wide. The constraints check fails with **`BoxConstraints forces an infinite width.`** The same happens vertically in a `Column` with `heightFactor`, or inside a vertically scrolling list. Fixes: - wrap it in `Expanded` or `Flexible`, so the `Row` gives it a finite slot and the factor applies to that slot; - or, for proportions between siblings, drop it and use flex factors directly. ## Typical uses - **Progress fills.** A watched-progress bar on a lecture thumbnail: a full-width track with a `FractionallySizedBox(widthFactor: watched, alignment: Alignment.centerLeft)` fill. - **Proportional buttons or cards**, such as a sign-in button at 80% of the screen width on phones. - **Centred content with margins**, such as a dialog body at 90% of available width. ## Edge cases - A factor of **0** gives the child zero size on that axis. - A factor **above 1.0** is allowed. The child becomes larger than the box and paints outside it — the "overflow" in the render object's name. - Negative factors fail an assertion. - It fractions the **parent's constraints**, not the screen. Inside a 320-wide card, `widthFactor: 0.5` means 160. ## Compared with neighbours - `SizedBox` sets an absolute size; `FractionallySizedBox` a relative one. - `Expanded` and `Flexible` divide a `Row` or `Column` among siblings; `FractionallySizedBox` fractions one child against its own parent. - `LayoutBuilder` can compute any function of the constraints; `FractionallySizedBox` is the direct, declarative version of "a fixed fraction".

  • Inside a Center, why does changing FractionallySizedBox's alignment have no visible effect?
    `Center` gives loose constraints, so the box sizes itself to its child. With no spare room inside the box, there is nowhere for `alignment` to move the child. Alignment shows only when the box's own constraints force it to be larger than the child.
  • What does FractionallySizedBox(widthFactor: 1.2) do?
    The child gets a tight width of 120% of the maximum incoming width, while the box itself is clamped to its constraints. The child therefore overflows the box and paints outside it, positioned by `alignment`.

It is a tailor told to cut a sleeve at 60% of the bolt's width: fine with a real bolt, impossible when the bolt is infinitely long.

saying these in an interview costs you the question

  • widthFactor is a fraction of the screen width.
  • widthFactor multiplies the minimum incoming width.
  • A null widthFactor makes the child zero wide.
  • The box always fills its parent's maximum size.
  • It works as a plain Row child because Row gives it the row's width.