toRem function
Converts a pixel (px
) value
to its rem
equivalent using the current font size
found on the HtmlDocument.
- If
value
is a String or CssValue:- And
value
already has the correct unit, it will not be converted. - And CssValue.unit is not
'px'
or'rem'
, an error will be thrown unlesspassThroughUnsupportedUnits
istrue
, in which case no conversion will take place.
- And
- If
value
is a num, it will be treated as apx
and converted, unlesstreatNumAsRem
istrue
. - If
value
isnull
,null
will be returned.
Examples (all will output 1.5rem
assuming 1rem == 10px
):
toRem('15px');
toRem(new CssValue(15, 'px'));
toRem(15);
toRem(1.5, treatNumAsRem: true);
toRem('1.5rem');
new CssValue(1.5, 'rem');
Related: toPx
Implementation
CssValue? toRem(dynamic value, {bool treatNumAsRem = false, bool passThroughUnsupportedUnits = false}) {
// Because Chrome changes the value of its root font size when zoomed out lower than 90%, we need
// to automatically wire up the rem change sensor so that any calls to `toRem` when the viewport is
// zoomed return an accurate value.
//
// Only run them when `testMode` is false as a workaround to not break all the individual `toRem` tests
// that rely on `onRemChange.first`, and so that the dom node that is mounted via `_initRemChangeSensor`
// is not suddenly present in the dom of all consumer tests - which could break their assertions about
// a "clean" / empty `document.body`.
//
// See: https://jira.atl.workiva.net/browse/AF-1048 / https://bugs.chromium.org/p/chromium/issues/detail?id=429140
if (browser.isChrome && !component_base.UiProps.testMode) {
// TODO: Why does Zone.ROOT.run not work in unit tests? Passing in Zone.current from the call to toRem() within the test also does not work.
// Zone.ROOT.run(_initRemChangeSensor);
initRemChangeSensor();
}
if (value == null) return null;
num remValueNum;
if (value is num) {
remValueNum = treatNumAsRem ? value : value / rootFontSize;
} else {
var parsedValue = value is CssValue ? value : CssValue.parse(value);
if (parsedValue?.unit == 'rem') {
remValueNum = parsedValue!.number;
} else if (parsedValue?.unit == 'px') {
remValueNum = parsedValue!.number / rootFontSize;
} else {
if (passThroughUnsupportedUnits) return parsedValue;
throw ArgumentError.value(value, 'value', 'must be a px num or a String px/rem value');
}
}
return CssValue(remValueNum, 'rem');
}