Sass Modular Scale Mixin / Function

Hello Experts,

Can anyone help me with a SASS mixin and or a SASS function that takes the value from a modular scale such as (major-third, perfect-fourth, golden-section) values against my base-font-size of 16px and provide me the "em" value from that for all of my heading styles of h1,h2,h3,h4,h5,h6?

Everytime I change the modular scale value to see what I like better I have to compute them all into "ems" and then add them to my css file for all of my h1,h2,h3,h4,h5,h6 font-size values. I'm looking for a way to just plug in the modular scales value that I plan on using and use some type of equation with my base font size to have it compute all my individual h1,h2,h3,h4,h5,h6 headings for me.
LVL 4
asp_net2Asked:
Who is Participating?
 
Kyle HamiltonData ScientistCommented:
putting it all together :

body{
	font-size: 100%; // 16 px = 1em
}
// stolen from modular-scale:
$phi              : 1.618             ;
$golden           : $phi              ;
$double-octave    : 4                 ;
$major-twelfth    : 3                 ;
$major-eleventh   : 2.666666667       ;
$major-tenth      : 2.5               ;
$octave           : 2                 ;
$major-seventh    : 1.875             ;
$minor-seventh    : 1.777777778       ;
$major-sixth      : 1.666666667       ;
$minor-sixth      : 1.6               ;
$fifth            : 1.5               ;
$augmented-fourth : 1.41421           ;
$fourth           : 1.333333333       ;
$major-third      : 1.25              ;
$minor-third      : 1.2               ;
$major-second     : 1.125             ;
$minor-second     : 1.066666667       ;

$font-size-base   : 1rem;  // ex: 14px = 14/16 em
// If a native exponent function doesnt exist
// this one is needed.
@function pow($Base, $Exponent) {

  // Find and remove unit.
  // Avoids messyness with unit calculations
  $Unit: $Base * 0 + 1;
  $Base: $Base/$Unit;

  // This function doesnt support non-interger exponents.
  // Warn the user about why this is breaking.
	@if round($Exponent) != $Exponent {
		@warn "Unfortunately, you need Compass to use non-integer exponents";
	}

  // Set up the loop, priming the return with the base.
	$Return: $Base;

  // If the number is positive, multiply it.
  @if $Exponent > 0 {
    // Basic feedback loop as exponents
    // are recursivley multiplied numbers.
    @for $i from 1 to $Exponent {
      $Return: $Return * $Base;
    }
  }

  // If the number is 0 or negitive
  // divide instead of multiply.
  @else {
    // Libsass doesnt allow negitive values in loops
    @for $i from (-1 + 1) to (abs($Exponent) + 1) {
      $Return: $Return / $Base;
    }
  }

  // Return is now compounded redy to be returned.
  // Add the unit back onto the number.
	@return $Return * $Unit;
}
@mixin scalar($scalar, $multiplier){
	font-size: $font-size-base * pow($scalar, $multiplier);
}

h1{
	@include scalar($golden, 6)
}
h2{
	@include scalar($golden, 5)
}
h3{
	@include scalar($golden, 4)
}
h4{
	@include scalar($golden, 3)
}
h5{
	@include scalar($golden, 2)
}
h6{
	@include scalar($golden, 1)
}

Open in new window

0
 
Kyle HamiltonData ScientistCommented:
0
 
asp_net2Author Commented:
Hi Kyle,

Yes, I have seen both of those already. I would like to be able to create my own rather than using someone else's so that I can learn from it rather than rely on something that i didn't create. I don't need what I'm trying to create to be very detailed. Basically something that I plug the ration, base-size and how many values I would want. That's it.
0
Ultimate Tool Kit for Technology Solution Provider

Broken down into practical pointers and step-by-step instructions, the IT Service Excellence Tool Kit delivers expert advice for technology solution providers. Get your free copy now.

 
Kyle HamiltonData ScientistCommented:
Ratio, Base size, and:
how many values I would want

not sure what you mean by how many values.

here is one simple suggestion. Since the default browser font size is actually 16px, you can specify the base size as 1em.

If your intention is to learn, build on this, or read through the source of modular-scale. remember that ems are relative to the overall font size - that's what the body class is for. So if you specified your body font size to 50%, 1 em would be 8px

body{
	font-size: 100%; // 16 px = 1em
}
// stolen from modular-scale:
$phi              : 1.618034          ;
$golden           : $phi              ;
$double-octave    : 4                 ;
$major-twelfth    : 3                 ;
$major-eleventh   : 2.666666667       ;
$major-tenth      : 2.5               ;
$octave           : 2                 ;
$major-seventh    : 1.875             ;
$minor-seventh    : 1.777777778       ;
$major-sixth      : 1.666666667       ;
$minor-sixth      : 1.6               ;
$fifth            : 1.5               ;
$augmented-fourth : 1.41421           ;
$fourth           : 1.333333333       ;
$major-third      : 1.25              ;
$minor-third      : 1.2               ;
$major-second     : 1.125             ;
$minor-second     : 1.066666667       ;

$font-size-base   : 1em;  // ex: 14px = 14/16 em

@mixin scalar($scalar, $multiplier){
	font-size: $font-size-base * $scalar * $multiplier;
}

h1{
	@include scalar($golden, 2)
}

Open in new window

0
 
Kyle HamiltonData ScientistCommented:
oh, and I found this converter. very convenient seeing quick results.

http://sasstocss.appspot.com/
0
 
asp_net2Author Commented:
Kyle,

First of all thank you for helping me with this post!!!

>> not sure what you mean by how many values.
I'm sorry, what I meant was I would like a mixin/function that would output the h1-h6 headings for me after proving my font-size-base and ratio that I would like to use. I tried the mixin that you supplied above on http://sassmeister.com and it seems that the output values are off compared to what they are on http://www.modularscale.com

Mixin that you supplied Kyle with me adding the h2-h6 headings. Nothing else what modified.
body{
	font-size: 100%; // 16 px = 1em
}
// stolen from modular-scale:
$phi              : 1.618             ;
$golden           : $phi              ;
$double-octave    : 4                 ;
$major-twelfth    : 3                 ;
$major-eleventh   : 2.666666667       ;
$major-tenth      : 2.5               ;
$octave           : 2                 ;
$major-seventh    : 1.875             ;
$minor-seventh    : 1.777777778       ;
$major-sixth      : 1.666666667       ;
$minor-sixth      : 1.6               ;
$fifth            : 1.5               ;
$augmented-fourth : 1.41421           ;
$fourth           : 1.333333333       ;
$major-third      : 1.25              ;
$minor-third      : 1.2               ;
$major-second     : 1.125             ;
$minor-second     : 1.066666667       ;

$font-size-base   : 1rem;  // ex: 14px = 14/16 em

@mixin scalar($scalar, $multiplier){
	font-size: $font-size-base * $scalar * $multiplier;
}

h1{
	@include scalar($golden, 6)
}
h2{
	@include scalar($golden, 5)
}
h3{
	@include scalar($golden, 4)
}
h4{
	@include scalar($golden, 3)
}
h5{
	@include scalar($golden, 2)
}
h6{
	@include scalar($golden, 1)
}

Open in new window


Results:
body {
  font-size: 100%;
}

h1 {
  font-size: 9.708rem;
}

h2 {
  font-size: 8.09rem;
}

h3 {
  font-size: 6.472rem;
}

h4 {
  font-size: 4.854rem;
}

h5 {
  font-size: 3.236rem;
}

h6 {
  font-size: 1.618rem;
}

Open in new window


Now if you look at the h2-h6 values they are larger than what is on the http://www.modularscale.com website. Why is that?
0
 
Kyle HamiltonData ScientistCommented:
cause I'm an idiot :)

it's not correct to just multiply by the "multiplier". You need to multiply by the scalar "multiplier" number of times.

so in pseudo code, you would do:

font-size: $font-size-base * ( $scalar  to the power of $multiplier);

have a look at :
https://github.com/modularscale/modularscale-sass/blob/2.x/stylesheets/modular-scale/_pow.scss
0
 
asp_net2Author Commented:
Your not an idiot :) I feel like the idiot asking :) I actually got the same results as you did yesterday in my own mixin hence the reason I'm asking for help now ;)

Ok, so how would I implement that into what you supplied me in the original mixin that you did?
0
 
Kyle HamiltonData ScientistCommented:
I stole the power function from modular scale. see above post ID: 40638782. It appears to be working correctly now.

in real life you would move your function to a separate file to get rid of clutter, and to be able to import it where ever else you need

if you are using compass, there is a pow function built in.
0
 
asp_net2Author Commented:
Hi Kyle,

Yes, that seems a lot better :) Is there a way on top of what you did to round those values up to whole numbers or to round them up to the values that modular scale outputs to, rather than having the long decimal values?

Also, is there a way to just implement what you did in your mixin in pseudo code rather than use the "pow" function?

Thank you very much Kyle for your input, patience and hard work on trying to help me with this issue!!!!
0
 
Kyle HamiltonData ScientistCommented:
no prob

to round, you can do:

round up:
font-size: ceil($font-size-base * pow($scalar, $multiplier));

Open in new window


round down:
font-size: floor($font-size-base * pow($scalar, $multiplier));

Open in new window


round
font-size: round($font-size-base * pow($scalar, $multiplier));

Open in new window


the pseudo code just says "use a power function here". So the answer is no, not really. Unless you are using compass, there is no power function out of the box, so you have to write one. but like I said, you should move it out to a separate file so it's not "in the way" so to speak.

Also, have a look here for a SCSS implementation of toFixed() - this will give you a number with the specified number of decimal places - as well as an alternative pow function.

https://css-tricks.com/snippets/sass/fix-number-n-digits/
0
 
asp_net2Author Commented:
Kyle,

You are a God send!! Thank you very much!!! :)

I took your advice and looked at CSS-Tricks and I think I may use that one instead.

Only, one more question, I PROMISE :)

So, the next question is how do I get the values below 1em using the mixin that you provided with the ratio? Just like in Modularscale how they have values starting at 0.0xxxx?
0
 
Kyle HamiltonData ScientistCommented:
you mean to set the font size below 1em?

you would provide a negative exponent:

@include scalar($golden, -2)
0
 
Kyle HamiltonData ScientistCommented:
just fyi.. the only difference between the two pow functions is that the modscale one gives you a warning if you provide a non-integer exponent - but neither function actually allows for non-integer exponents. And it has lots of comments. but the rest is the same. (oh, it's got that weird $Unit thing that doesn't appear to actually do anything. wt..?)

cheers.
0
 
asp_net2Author Commented:
Ok, thank you for letting me know that. Thank you again so much Kyle for helping me out with this. You have been able to answer all the questions I have, thank you so much! for everything. I'm sure you will see me around here again for me questions in regards to CSS,HTML and SASS ;) Take care Kyle...
0
 
Kyle HamiltonData ScientistCommented:
:)
 c u next time
0
 
asp_net2Author Commented:
Thank you again very much Kyle!!!
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.