简体   繁体   中英

Sass mixin output css with calc different output than simplified by hand

I have the following HTML:

  <div class="row">
    <div class="col-1-of-3">Col 1 of 3</div>
    <div class="col-2-of-3">Col 2 of 3</div>
  </div>

and the following scss:

$gutter-horizontal: 6rem;

@mixin clearfix {
  &::after {
    content: "";
    display: table;
    clear: both;
  }
}

@mixin colWidth($dim, $sub: 1) {
  width: calc(
    #{$sub} * (100% - (#{$dim}-1) * #{$gutter-horizontal}) / #{$dim} +
      (#{$sub}-1) * #{$gutter-horizontal}
  );
}
.row {
  max-width: $grid-width;
  background: #eee;
  margin: 0 auto;

  &:not(:last-child) {
    margin-bottom: $gutter-vertical;
  }

  @include clearfix;

  [class^="col-"] {
    float: left;
    background: red;
    &:not(:last-child) {
      margin-right: $gutter-horizontal;
    }
  }

  .col-1-of-3 {
    width: calc((100% - 2 * #{$gutter-horizontal}) / 3);
  }

  .col-2-of-3 {
    @include colWidth(3, 2);
  }

I am trying to generalize:

.col-2-of-3 {
  width: calc(
    2 * ((100% - 2 * #{$gutter-horizontal}) / 3) + #{$gutter-horizontal}
  );
}

When rendered, inspect tells me my mixin yields:

width: calc( 2 * (100% - (3-1) * 6rem) / 3 + (2-1) * 6rem);

which simplifies to:

width: calc( 2 * (100% - 2 * 6rem) / 3 + 6rem);

while the direct method inspects to:

width: calc( 2 * ((100% - 2 * 6rem) / 3) + 6rem);

While these are the same up to order of operations, the final widths according to inspect are different.

For me they were 614 and 594 respectively.

Why the difference?

Thank you.

I think the problem here is the space

If your mixin give to you this output:

width: calc( 2 * (100% - (3-1) * 6rem) / 3 + (2-1) * 6rem);

Browsers return you an error because you have to put space between every operator:

width: calc( 2 * (100% - (3 - 1) * 6rem) / 3 + (2 - 1) * 6rem);

I created an example. In the first case I used your mixin result and your direct method:

 .col-1-of-3 { width: calc(2 * (100% - (3-1) * 6rem) / 3 + (2-1) * 6rem); background-color:#ff0000; } .col-2-of-3 { width: calc(2 * ((100% - 2 * 6rem) / 3) + 6rem); background-color:#00ff00; } 
 <div class="row"> <div class="col-1-of-3">Col 1 of 3</div> <div class="col-2-of-3">Col 2 of 3</div> </div> 

The widths are different because, with your mixin result, browsers can't understand your (3-1) & (2-1) operations. But if we put spaces between operators, the mixin result & direct method give us the same result:

 .col-1-of-3 { width: calc(2 * (100% - (3 - 1) * 6rem) / 3 + (2 - 1) * 6rem); background-color:#ff0000; } .col-2-of-3 { width: calc(2 * ((100% - 2 * 6rem) / 3) + 6rem); background-color:#00ff00; } 
 <div class="row"> <div class="col-1-of-3">Col 1 of 3</div> <div class="col-2-of-3">Col 2 of 3</div> </div> 

I think this is the reason for that difference.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM