Vertical Rhythm and multiple $Base-Line-Height's (responsive)

901 views
Skip to first unread message

Andrew Jones

unread,
Jun 25, 2013, 12:22:15 PM6/25/13
to compas...@googlegroups.com
I'm trying to get my SASS project up and running with Compass' vertical rhythm libraries. It's mostly been a god experience, but now I'm really stuck using $base-line-height, on a responsive project where the line height changes based on screen width. 

This variable is annoyingly hardcoded in many of the functions/mixins, so using more than one for each media query is a no. I have three approaches but I was wondering if there's a better solution - I couldn't find any mention in the documentation.

1) Set base-line-height to something incredibly small e.g. 2px, adjust-leading to the line-height i need on html {} for each media query

2) Set base-line-height to the mobile baseline, and any other media queries multiply margins, font-sizes etc. from that

My project is kind of strange in that the mobile size is 16px/22px, but the desktop is font size 11px/13px.

3 ) override all of the compass functions - please no!

Both those options are a bit of a pain to implement (constantly multiplying/dividing) and I think mixins like margin-leader() should be margin-leader(number of lines) and NOT margin-leader(line-height * 10).

Looking at the source it looks like the issue is how $base-line-height is hardcoded into the functions, whereas I think it would be better if we could pass in a line-height as a parameter into those mixins.


I'm hoping I'm just doing this all wrong and there's an easy solution to my problems...?

gabriel nau

unread,
Jun 25, 2013, 3:59:10 PM6/25/13
to compas...@googlegroups.com
I had the same issue, but I didn't implement a solution since the design changed to one baseline for all devices.
Here is what I did consider though : 

1) a custom media query mixin which set the right $base-line-height in the scope of your targeted viewport, in order to use Compass mixins normally.
2) Multiply everything, if you set all your font sizes in one variables file it's fine.
3) Fork Compass vertical rhythm lib and add your optionnal argument $base-line-height, $base-font-size at the end of each mixin/function. The issue with that approach is you cannot upgrade easily this module in the future.

Andrew Jones

unread,
Jun 25, 2013, 5:47:34 PM6/25/13
to compas...@googlegroups.com
Thanks. Yeah all options I had considered but none are as elegant as using multiple base-line-heights.

Eric Meyer

unread,
Jun 26, 2013, 4:04:35 AM6/26/13
to compas...@googlegroups.com
I think it's worth considering changes to the module. I'd like to see a proposal, or a patch.

-e

Andrew Jones

unread,
Jun 26, 2013, 4:23:15 AM6/26/13
to compas...@googlegroups.com
Agreed Eric.

For reference to anyone with the same issue, what I've decided for now (until the module somehow addresses these issues) that overriding the module functions in my own file is probably the best option in the long run.

It's initially quite painful, but switching between my override and a patched version of the compass modules is as easy as removing the override file.

The other options has me going back and moving css around and changing variables, which I don't want to be doing when I have 5,10, or 15+ sites built this way.

gabriel nau

unread,
Jun 26, 2013, 1:34:47 PM6/26/13
to compas...@googlegroups.com
I'm glad to hear that Eric, I will try something.

gabriel nau

unread,
Jun 27, 2013, 6:16:30 PM6/27/13
to compas...@googlegroups.com
I tried something, here is the commit on branch stable : https://github.com/gabrielnau/compass/commit/eb1f9e7a6a2113a7e9c21d498cd9105cabde8dcb

Proposal :
  • introduce 2 optional arguments in mixins : $font-size-context and $line-height-context
  • change $font-unit, $base-rhythm-unit, $base-leader, $base-half-leader to functions
Caveats :
  • I still don't understand everything, for example I'm not sure at all about base-rhythm-unit or font-unit
  • In adjust-font-size-to, I had to set an absurd default value to $lines in order to catch it later
  • I didn't want change the order of arguments, so I only did append optional args, but in mixins like apply-side-rhythm-border, it's not "natural" to have $font-size then $border-style then $line-height-context

gabriel nau

unread,
Jun 28, 2013, 5:37:06 AM6/28/13
to compas...@googlegroups.com
I see I did rush a bit and there is some mistakes, but what do you think of the overall idea ?

Andrew Jones

unread,
Jun 28, 2013, 12:03:24 PM6/28/13
to compas...@googlegroups.com
It's similar to how I've hacked together my override file and I found the same caveats with mine, specifically how unnatural it is for example to write parameters as font-size, offset, and THEN line-height.



--

Andrew



--
You received this message because you are subscribed to a topic in the Google Groups "Compass" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/compass-users/NecGNw31Rzc/unsubscribe.
To unsubscribe from this group and all its topics, send an email to compass-user...@googlegroups.com.
To post to this group, send email to compas...@googlegroups.com.
Visit this group at http://groups.google.com/group/compass-users.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Eric Meyer

unread,
Jun 28, 2013, 5:04:22 PM6/28/13
to compas...@googlegroups.com
Any work on this should really be based off the master branch. I think there have already been major changes there, worth integrating with.

This proposal is interesting, but it looks daunting to use. Ideally, this should be as easy as changing a setting - without changing the main mixin interfaces at all. Something like this?

@include establish-baseline;

// our main baseline settings

@include use-baseline($new-base-size, $new-line-height) {
  // our alternative baseline
}

That could be combined with media-queries:

$base-font-size: 14px;
$base-line-height: 18px;

// mobile baseline
.rhythm { @include leader; }

@media (min-width: 40em) {
  @include use-baseline(16px, 21px) {
    // desktop baseline
    .rhythm { @include leader; }
  }
}

or different parts of a layout:

$base-font-size: 14px;
$base-line-height: 18px;

// main baseline
.rhythm { @include leader; }

#alternative {
  @include use-baseline(16px, 21px) {
    // alternative baseline
    .rhythm { @include leader; }
  }
}

No change to how we use "leader" in the example, we've just changed the variables underneath. Does that make sense?

Cheers,
-e

gabriel nau

unread,
Jul 1, 2013, 4:35:56 AM7/1/13
to compas...@googlegroups.com
Yes, that seems far more lighter to use. I will do something on master, thanks.

rober...@gmail.com

unread,
Jul 3, 2013, 12:58:49 PM7/3/13
to compas...@googlegroups.com
Both those options are a bit of a pain to implement (constantly multiplying/dividing) and I think mixins like margin-leader() should be margin-leader(number of lines) and NOT margin-leader(line-height * 10).
Looking at the source it looks like the issue is how $base-line-height is hardcoded into the functions, whereas I think it would be better if we could pass in a line-height as a parameter into those mixins.

Why override the module functions, if you can wrap your own function around them?
Write your wrapper function/mixin to accept the parameters in a format that **you** find logical. Then in your wrapper, first convert from **your** parameter format to what Compass expects, and then call the Compass function, or include the Compass mixin.

1) Set base-line-height to something incredibly small e.g. 2px, adjust-leading to the line-height i need on html {} for each media query

BTW, I'm using wrapping together with what you suggested at 1) but with a 6px $base-line-height (instead of 24px) combined with the occasional manual adjustment of the line-height (with the adjust-leading-to mixin).


On Tuesday, June 25, 2013 6:22:15 PM UTC+2, Andrew Jones wrote:

Andrew Jones

unread,
Jul 3, 2013, 2:20:43 PM7/3/13
to compas...@googlegroups.com
Yeah my problem with doing that is that the functions themselves don't let you set the line height or pass it in as a parameter, so you'd have to do something like below. It might be a decent solution, but I'm not sure if it would work or recommended:

@function margin-trailer-wrapper($lines, $font-size, $line-height) {

$base-font-size : $font-size
$base-line-height : $line-height

@return margin-trailer(1)

}


Apologies if that doesn't compile! :) but I imagine it would have to work like that.

You're then writing a wrapper for each mixin in the compass library - would you might as well just override the compass module? 

Your main SASS file will also be full of @include margin-trailer-wrapper; which means in future if this gets resolved you might have to find-replace the @includes. Maybe not a big deal - depends on the scale of the project.

I have my own override about 50% done and working on responsive, I'll carry on playing with it tomorrow and see if the idea works.


--

Andrew



--

rober...@gmail.com

unread,
Jul 3, 2013, 9:23:13 PM7/3/13
to compas...@googlegroups.com
Well nothing comes for free. There's always some work involved when bending something to get it (close to) exactly what you want.

Why use the word wrapper in your wrapper name? Another **short** unique prefix/suffix will do.

And why replace wrappers? Permanently bending what you get (from Compass) to an in-house solution is not as bad as you think.
You can fix removal and addition of parameters in your wrapper. Leaving the calls to, and includes of your own wrappers the same across Compass parameter changes. The wrappers are the way you want to see and do things. Remember?
If new parameters are added, you can provide the defaults (or your own defaults) in the wrapper. Therefore the call/include to your wrapper function/mixin remains unchanged.
If old parameters are removed, you can temporarily "lose" them in the wrapper (by not passing them on to Compass anymore). And/Or convert them to their new equivalent(s).

But it's up to you. Good luck with it. ;)

Andrew Jones

unread,
Jul 4, 2013, 9:51:01 AM7/4/13
to compas...@googlegroups.com
Yeah I agree, maybe some of the issues wouldn't affect most people anyway and things like writing wrappers / find replace in the future will be dependent on the project.

I'm almost done with my take on the vertical rhythm module while working on a site - Now obviously I think it makes sense and moderately easy to work with - that said I've done nothing but look at this for the past few days so I would say that! :) I'm interested to see what others think of my suggestion, the general idea is as follows:

1. Replace the $base-font-size / $base-line-height variables with a sass list like:

      $font-sizes   : (min 14px 22px), (max 16px 24px);

Where 1. Key, 2. Font-size and 3. Line-height

2. Modify the functions and parameters to accept $font-size as a string as well as a number like 16px

3. Inside the function - check the type of $font-size, if it's a number, carry on as normal, if it's a string, loop through the $font-sizes list looking for the key given.

This way you aren't changing the order of the parameters and any legacy compass projects work as normal. You can then write things like

div {
  @include margin-trailer(1); // 'min' is the default 14px/22px

  @include media-query-mixin(768px) {
     @include margin-trailer(2,max); //max refers to 16px/24px
  }
}


I had this idea from how I write my media queries ( see this on github )

gabriel nau

unread,
Jul 4, 2013, 3:26:09 PM7/4/13
to compas...@googlegroups.com
Your idea Andrew is clever but I think Eric will have the same problems as the previous solutions : it's too complicated, especially for developers new with the vertical rhythm module. Moreover it adds complexity in an already complex codebase.

I stick on Eric's proposal for a 'use-baseline' mixin : it's just an additional layer on top of the existing API that doesn't change anything else. Plus it's pretty easy to understand for newcomers.

gabriel nau

unread,
Jul 4, 2013, 4:23:06 PM7/4/13
to compas...@googlegroups.com
Here is something based on Eric's proposal : http://codepen.io/anon/pen/wvtcG

Andrew Jones

unread,
Jul 5, 2013, 5:33:38 AM7/5/13
to compas...@googlegroups.com
Nice! I've just added it as my own mixin and reverted back to the original vertical rhythm module and it works pretty well. It's especially nice that there's no modification of compass' mixins. I also took it a step further and integrated it with my media query mixin, so I can write my sass as I've always done and not have to worry about setting the right baseline each time:

.header {
  height: rhythm(5);

  // 'max' here refers to a sass list of variables I have e.g.
  // $font-sizes : (min, 14px, 22px), (max, 16px, 24px);
  @include respond-to (max) {
    height: rhythm(7);
  }
}

Now the above lets me change the variables in $font-sizes and apply it site wide, with the added bonus of being able to change what the sizes are e.g. change max to large without having to change any of the sass.

As long as there isn't some fundamental problem in SASS/Compass with changing the $base-font-size variables constantly, I think this works pretty well.

gabriel nau

unread,
Jul 5, 2013, 8:34:31 AM7/5/13
to compas...@googlegroups.com
Yes, the simpler the better !
Just a notice : debug-vertical-alignment will not take into account the alternative baseline, it don't know how to explain it here but the fix is really simple : https://github.com/gabrielnau/compass/commit/5d0ac0f16224f8391f78b7fe464fc8d513d1ccfd#L0R139

I will make a pull request to Compass, in the meantime is it totally useless to make a compass plugin ? Even if it's 5 lines of code, I really dislike the copy paste of several gists for custom cooking.

Andrew Jones

unread,
Jul 5, 2013, 10:10:38 AM7/5/13
to compas...@googlegroups.com
Yeah I guess it's up to the compass gods if it's necessary. Personally I think it would be quite useful to have a mixin that sets the baseline to whatver you want.

Either way it's integrated with my own mixin library now.


--

Andrew



Eric Meyer

unread,
Jul 7, 2013, 10:05:16 PM7/7/13
to compas...@googlegroups.com
I'm intrigued by the naming option, but I think in many cases names are better handled as as variable names, rather than keys to an array. In this case, Gabriel's mixin would handle that great, with less change to the way things work:

$min: 14px 22px;
$max: 16px 24px;

@include use-baseline($min...) {
  // min baseline
}

That should be easy to combine with media-queries.

I have a feeling there may be several vertical-rhythm mixins that use initial settings rather than current settings. I'd love to see a patch for that - especially in the master branch. If you update the tests/docs to match, I can pull that in pretty quick.

cheers,
-e

gabriel nau

unread,
Jul 8, 2013, 4:47:09 PM7/8/13
to compas...@googlegroups.com
Great, I will do that.
Reply all
Reply to author
Forward
0 new messages