Closed rafegoldberg closed 5 years ago
Hi @rafegoldberg.
Glad your enjoying vertical-rhythm-reset!
I'd love to offer public ms()
and vr()
functions that return modular-scale and vertical-rhythm unit values. The challenge is that functions do not have access to the context necessary to support auto-generating rulesets for various breakpoints.
Consider the @vr()
mixin (source). It can access the current CSS selector (via &), the selector content (via @content directive), and the vertical-rhythm properties and values you want to calculate (via the mixin arguments). This means the @vr
mixin has everything it needs to generate a complete ruleset:
$vr-modular-scale: 1.33;
.foo {
@include vr(
$font-size: 1,
$height: 2
);
}
Output:
.foo {
font-size: 1.33rem;
line-height: 1.50001rem;
height: 3.00002rem;
}
The @vr()
mixin then looks at the $vr-breakpoints
map and generates variations of the same ruleset for each breakpoint when needed. For example, if a 1280px
breakpoint is specified with a modular scale of 1.25
, the following media query and ruleset will be auto-generated:
@media (min-width: 80em) {
.foo {
font-size: 1.25rem;
line-height: 1.7894836842rem;
height: 3.5789673684rem;
}
}
Now consider an ms()
or vr()
function:
$vr-font-size: 14px;
$vr-line-height: 1.5;
$vr-modular-scale: 1.33;
.ms-example {
top: -1 * ms(2);
}
.vr-example {
top: -1 * vr(2);
}
It's easy enough to return a value based on the $vr-*
variables:
:root {
font-size: 14px;
}
.ms-example {
top: -1.769rem; // -1 * (((14*1.33)*1.33) / 14)
}
.vr-example {
top: -3rem; // -1 * (1.5*2)
}
But these functions cannot generate ruleset variations for other breakpoints because they have no knowledge of the properties (top
) and values (-1 * ms(2)
and -1 * vr(2)
) in which they are being used.
All that being said, not all configurations require generating ruleset variations for different breakpoints. From the README:
Font-size and line-height values can have a significant impact on the generated CSS output. To keep the CSS output as lightweight as possible, maintain a consistent line-height across breakpoints and use font-size values that equal whole numbers when multiplied by the line-height. This will allow the rem-based values generated for the root breakpoint to work across all breakpoints which removes the need to generate recalculated values for every media query.
If your vertical-rhythm-reset setup aligns with the statement above, then ruleset variations won't need to be generated for your breakpoints. This means you can use the private _modular-scale()
function to accomplish your goal since you don't have to worry about the return value changing across breakpoints.
@import "vertical-rhythm-reset";
$vr-modular-scale: 1.33;
.example {
@include vr($padding-top: 1);
position: relative;
top: -1 * _modular-scale(1);
}
If you are concerned about using a private function, you can always create your own wrapper around _module-scale()
that tests for its existence and provides a safe fallback if it doesn't exist.
@function ms($multiple) {
@if function-exists(_modular-scale) {
@return _modular-scale($multiple);
}
@else {
@warn "ms(): _modular-scale() function not available";
@return 1rem * $multiple;
}
}
Hope this helps, @rafegoldberg.
This is fantastic. Will have to give it another read, alongside the source code. But I think I get the gist of the problem.
Excellent. Let me know if there is anything else I can do to help.
I really love the sparse simplicity of the core
vr()
method. That said, I do occasionally find need to reference scale values outside of the mixin's parameters. Skimming thru your source code, I found the internal_modular_scale
method, which I assume is being used to calculate each step value.I was wondering if it'd be possible to update this internal function so it can be used as a public utility? (Maybe even alias it to an
ms
shorthand, consistent with thevr
naming convention!) That way one could write:And that
ms
function would automatically pull in the$vr-modular-scale
global and output the same step value as the abovevr
calculation.Let me know if that makes sense. Happy to clarify if/where I can!