chriseppstein/compass — pull request #896 by ry5n (2012-05-20 05:05:54+00:00)
Title: Add rem output with pixel fallbacks and other improvements to vertical rhythm partial

I've implemented support for feature #775 in this branch. However, there are other changes I'm proposing here, one of which is not backwards compatible. @JohnAlbin and @ericam, I'd love to get your feedback in particular.

Full explanation of changes is below and the diff with master is [here](https://github.com/ry5n/compass/compare/chriseppstein:master...ry5n:improve_vertical_rhythm#L0R1). Oh, test fixtures are included too and run as expected.

---

## Architectural changes ##

`$font-unit` is replaced with a new `$rhythm-unit` variable which accepts a string representing the desired unit for rhythm output: 'em', 'rem' or 'px' (default remains 'em'). Percentage units are no longer allowed because they make calculating margins and padding impractically complex and actually break the rhythm-border mixins completely ([percentage borders are invalid css](http://lists.w3.org/Archives/Public/www-style/2012Jan/0084.html)).

When the output unit is 'rem', by default a fallback declaration in pixels is output for older browsers. This naturally increases output file size, and can be turned off by setting a new `$rem-with-px-fallback` flag to false.

`$relative-font-sizing` is now derived from `$rhythm-unit` and marked private. Previously both `$font-unit` and `$relative-font-sizing` were configurable, with the value of `$font-unit` depending by default on the value of `$relative-font-sizing`. This branch inverts that dependency and removes `$relative-font-sizing` as a concern for authors. Now there is only one thing to set and it directly and accurately expresses what it is.

Internally, almost all unit conversions are now handled by a `convert-length` function. The function is fully abstracted and handles converting between any css lengths/percentages. There is also a new `rem` mixin that handles the logic and output of pixel fallback declarations for rems. Both of these live in a new `units` partial, which vertical-rhythm now imports. `$browser-default-font-size` has been moved here as well.

Convert-length gracefully handles input and has warnings for things that will break, which has allowed me to remove many of the warnings of this type: `@warn "$relative-font-sizing is false but a relative font size was passed to…"`.

Also thanks to convert-length, it's now possible to be more liberal in the units accepted by mixins. The main use case is the `adjust-font-size-to` mixin, which now supports passing the `$to-size` parameter in any valid css length or as a percentage.

However, `$base-font-size` and `$base-line-height` are still assumed to be in pixels. In fact, this is now enforced with a warning, since a few things still break if they aren't. They could be made to support the full range of font units (and represented internally as px), but given they are specified only once, I'm not inclined to do it.

## Other changes ##
I've always had trouble using the rhythm mixin because it handles margins and padding all at once, and has less-than-ideal parameter defaults. Its signature has been optimized for the most common use case (symmetrical rhythm spacing above and below an element):

Old:
```scss
rhythm($leader: 0, $padding-leader: 0, $padding-trailer: 0, $trailer: 0, $font-size: $base-font-size)
```
New:
```scss
rhythm($leader: 1, $padding-leader: 0, $padding-trailer: $padding-leader, $trailer: $leader, $font-size: $base-font-size)
```

I've added two new mixins in the same family: `rhythm-margins` and `rhythm-padding`, which apply symmetrical whitespace as you'd expect.

Mixin `$apply-side-rhythm-border` now supports keyword 'all' for its `$side` parameter, which produces output using the border shorthand rather than four sets of identical declarations.

One more thing: the rhythm-border mixins now support border colors. Authors can set $default-rhythm-border-style to eg. `solid #aaa` instead of the default `solid` and get their desired border color for free. Authors can also pass a similar two-value list individually to any of the rhythm-border mixins.