In Flutter, what does FractionallySizedBox's widthFactor multiply, and why does it throw as a plain child of a Row?
answer
- factor times max incoming constraint
- child gets a tight size
- null factor passes through
- infinity times factor
- alignment needs spare room
basics
~20 swidthFactor 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 linesimport '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
Know that widthFactor and heightFactor size a child to a fraction of the available space, and that it needs bounded space to work.
Explain the tight child constraint from max times factor, the pass-through for null, and the infinite-width error in a Row.
Reason about the box's own size, when alignment is visible, overflow with factors above 1.0, and when flex factors fit better.
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.