RamseyInHouse/scut

scut-em function when the $base argument's unit is "em" has wrong output

Closed this issue · 2 comments

scut-em function produces wrong results when the $base argument passed in the scut-em function has a unit of em and we have a differente scut-em-base value.

//let's change first the scut-em-base

$scut-em-base: 20;

//scss
.foo {
     padding: scut-em(25); // should output 1.25em
     margin: scut-em(25, 1em); // 1em in this case is 20 which is the value of $scut-em-base, so the output should also be 1.25em
}

//css
// the supposed margin output should also be 1.25em since we passed 1em as the base argument w/c must be equals to the $scut-em-base variable

.foo {
    padding: 1.25em;
    margin: 1.5625em;
}

Shouldn't this particular line in the scut-em function

$multiplier: if(unit($base) == em, 16, 1);

be replace with this one:

$multiplier: if(unit($base) == em, 16, $scut-em-base);

Interesting problem. Took a while for me to think it through but here's what I think is going on -- (I'm not sure anything's wrong with the function, just with the implementation) --

Using an em-value for the $base argument is much less reliable than using a px-value. The $base argument that you pass to the function can't be aware of its context. If you specify 1em the function has to assume that is the equivalent of 16px because it cannot knwo better. It cannot know that in the context of your function call, because of the nesting of elements, etc., 1em actually equals 20px on the rendered page. The $base argument is manually informing the function of a context it wouldn't otherwise know about.

So when you specify an em-value as $base I think that the function has no choice but to assume that the em-value is relative to a default 16px. So it would still be useful if you are setting your font-sizes in ems and you are not nesting ems. E.g. this will not work

// ANTI-PATTERN
.foo {
  font-size: 20px; // 20px;
  padding: scut-em(25, 1em); // hoping to get 1.25em (25/20) as a result
  // ... but you'll actually get 1.5625em (25/16) because you were
  // assuming that function knows 1em = 20px in this context
  // -- but it cannot know that. 
}

Here's how and why you might pass ems as a $base argument:

.foo {
  font-size: 1.25em; // 20px
  padding: scut-em(25, 1.25em);
}

Does that clear it up at all?

(Also, because $base is just informing the function of a context, you shouldn't within the same ruleset pass different $base arguments, as in your example. Both margin and padding values are relative to the same context, so their $base arguments should be the same.)

My impression is that this isn't a problem after all. If somebody can reproduce and address my comments above, please reopen.