Skip to content

How it works ​

Every fluid value has a maximum for large layouts and either an explicit or derived minimum for small layouts.

The curve ​

With an explicit minimum, resolution is linear and clamped:

text
progress = clamp(extent / breakpoint, 0, 1)
resolved = minimum + (maximum - minimum) × progress

At or above the breakpoint, the maximum is returned exactly. At an extent of zero, the minimum is returned exactly.

dart
Rfs.value(64, width: 0, min: 36);    // 36
Rfs.value(64, width: 600, min: 36);  // 50
Rfs.value(64, width: 1200, min: 36); // 64

Derived minimums ​

When min is omitted, the configuration derives a minimum magnitude:

text
minimumMagnitude = baseValue + (|max| - baseValue) / factor
minimum = sign(max) × minimumMagnitude

The default configuration uses a base value of 20, a factor of 10, and a breakpoint of 1200.

Small-value cutoff ​

Values whose absolute maximum is at or below baseValue remain fixed. This keeps body text, borders, and fine visual details from shrinking by default.

dart
Rfs.value(18, width: 320); // 18 with the default baseValue

Lower baseValue when smaller design tokens should participate in the curve.

Negative values ​

Negative maxima preserve their sign and mirror the same curve, which makes fluid negative offsets and margins predictable:

dart
Rfs.value(-64, width: 600); // -44.2 with the default configuration

Width or shortest side ​

Width drives resolution by default. For layouts where a short landscape height should constrain scaling, use RfsDimension.shortestSide:

dart
Rfs.valueForSize(
  64,
  size: const Size(800, 500),
  dimension: RfsDimension.shortestSide,
);

Released under the MIT License.