2

I've been using the great REM to PX mixin function from David Walsh's blog - http://davidwalsh.name/rem-px-browser-function-sass - see below:

$px-only:false;  

$pixelBase : 16; /* 1 */

@function parseInt($n) {
    @return $n / ($n * 0 + 1); /* 2 */
}

@function u($values){ /* 3 */

      $list: (); /* 4 */

      @each $value in $values { /* 5 */

            $unit : unit($value); /* 6 */
            $val  : parseInt($value); /* 2 */

            @if ($px-only) and ($unit == 'rem') { /* 7 */
                  $list: append($list, ($val * $pixelBase) + px); /* 7 */
            }

            @else if($unit == 'px') or ($unit == 'rem'){ /* 8 */
                  $list: append($list, $value); /* 8 */
            }

            @else {
                  @warn 'There is no unit conversion for #{$unit}'; /* 9 */
            }

      }

      @return $list(); /* 10 */

}

This allows you to write the following:

.style {
    margin:u(1rem 2rem 20px 3rem);
    padding-bottom:u(0.25rem);
    font-size:u(0.875rem);
}

Which outputs the following if $px-only = false:

.style {
    margin: 1rem 2rem 20px 3rem;
    padding-bottom: 0.25rem;
    font-size: 0.875rem;
}

And the following in your IE stylesheet if $px-only = true:

.style {
    margin: 16px 32px 20px 48px;
    padding-bottom: 4px;
    font-size: 14px;
}

I'd like to avoid having to create a separate stylesheet to output the IE specific pixel fallback and target the body class, like below:

<!--[if lt IE 7 ]> <body class="ie6 "> <![endif]-->
<!--[if IE 7 ]>    <body class="ie7 "> <![endif]-->
<!--[if IE 8 ]>    <body class="ie8 "> <![endif]--> 
<!--[if !IE]><!--> <body> <!--<![endif]-->

Would anybody have any ideas on how this could be achieved so something similar to the below code is outputted in the same stylesheet?

.style {
    margin: 1rem 2rem 20px 3rem;
    padding-bottom: 0.25rem;
    font-size: 0.875rem;
}

.ie8 .style {
    margin: 16px 32px 20px 48px;
    padding-bottom: 4px;
    font-size: 14px;
}

Any help would be great!

abbas_arezoo
  • 1,038
  • 3
  • 20
  • 38

1 Answers1

1

You can't do what you're asking for with just functions. Functions are for returning a single value. You have to use mixins to get the desired effect. Also, there is absolutely zero benefit to having a separate selector like that when you can take advantage of how browsers parse CSS (also, the effort involved in doing what you're asking for is simply not worth it).

Your desired output should look like this:

.style {
    margin: 16px 32px 20px 48px;
    margin: 1rem 2rem 20px 3rem;
    padding-bottom: 4px;
    padding-bottom: 0.25rem;
    font-size: 14px;
    font-size: 0.875rem;
}

Which means you need a mixin like this:

@mixin rem($propertie, $value) {
  #{$propertie}: $value;
  #{$propertie}: calculateRem($value);
}
// To convert px to rem
@mixin toRem($property, $value) {
  #{$property}: ($value / 16) + rem;
}

See: Automate pixel fallback using REM units throughout a project

Community
  • 1
  • 1
cimmanon
  • 67,211
  • 17
  • 165
  • 171