Dimension — A CSS inspired distance calculating package for Flutter

Wenkai Fan
ITNEXT
Published in
2 min readFeb 27, 2021

--

CSS offers the <length>/<percentage> data type for easier responsive design of websites. It also allows some handy functions like:

max(10px, 10%)
calc(10px + 10%)
clamp(10px, 50%, 20px)

Flutter’s layout system differs from the web and Flutter does not use CSS. But in my opinion, it would still be beneficial to be able to do something like what CSS offers for easier responsive design purposes.

This is why I created the dimension package (formally called length_unit). The base class is simply called Dimension and below are the interface of this class (implementation omitted):

abstract class Dimension {
const Dimension();

double toPX({double? constraint, Size? screenSize});

@protected
Dimension? add(Dimension other) => null;

Dimension operator +(Dimension other);

Dimension operator -();

Dimension operator -(Dimension other);

Dimension scale(double t);

static Dimension max(Dimension value1, Dimension value2);

static Dimension min(Dimension value1, Dimension value2);

static Dimension clamp(Dimension min, Dimension value, Dimension max);
Dimension? lerpFrom(Dimension? a, double t);

Dimension? lerpTo(Dimension? b, double t);

static Dimension? lerp(Dimension? a, Dimension? b, double t);
}

You can see it supports addition and subtraction. Lerp(tweening) is also supported. Functions like min, max, and clamp should behave just like what CSS provides and can be nested. And one just needs to call the toPX() method to convert a Dimension instance to a px value that Flutter uses.

Dimension is abstract. What you actually use is the Length class:

class Length extends Dimension {
final double value;
final LengthUnit unit;

const Length(this.value, {this.unit = LengthUnit.px});
...}

It has a value and a unit. Supported units are:

enum LengthUnit {
///logic pixel
px,
///percent of the parent size
percent,
///percent of the screen width
vw,
///percent of the screen height
vh,
}

To create a Length instance, write:

var length=Length(10.0, unit: LengthUnit.percent);

Or use those handy extension methods:

length=10.toPXLength; //10 px
length=10.toPercentLength; // 10% of the parent constraint
length=10.toVWLength; //10% of the screen width
length=10.toVHLength; //10% of the screen height

Then convert the Length to px value:

double px=length.toPX(constraint: 100, screenSize: MediaQuery.of(context).size);

The constraint value is for percentage units and should be provided by the user. You can get the parent constraint size by calling LayoutBuilder.

Here’s a snippet for creating a responsive container:

The Dimension class supports serialization/deserialization (as for every other package that I developed), including combinations of function calls and multiple Length instances.

Dimension length=Dimension.clamp(10.toPXLength+10.toVWLength, 100.toPXLength+20.toPercentLength, Dimension.max(500.toPXLength, 50.toVWLength));
String jsonStr=json.encode(length.toJson());
Dimension newLength=parseDimension(jsonStr);

The dimension package is more like a helper class for you to quickly calculating some distances based on the parent constraint and screen size. If you have use cases for this package, feel free to comment down below. Thank you!

Animate between two responsive sizes

--

--

Ph.D. in Nuclear Physics, M.S. in Computer Science at Duke University, Flutter lover