box-sizing: border-box Sass Mixin

box-sizing: border-box is a great way to handle the pesky box model issue that comes with setting padding to your layouts. It works from IE8+, but sometimes you need to support older browsers.

There are some solutions for the older browsers, but they involve Poly Fills so are not ideal because if a user has javascript disabled or the script fails for whatever reason then all the dimensions will be too wide and your layout will break.

Fortunately for all of us the very clever Stu Robson has developed a Sass mixin that will allow you to target IE7 without having to use a PolyFill.  Yay for Stu.

The full Mixin is available below, and you can demo it using the CodePen that Stu made below as well.  He also has made it avaiable as part of Stu’s Sassification GitHub.

If you are wondering how this all works then read on a little further.


@mixin IE7Padding($width: null, $unit: 1px, $paddingLeft: 0, $paddingRight: 0) {
@if $paddingLeft == 0 and $paddingRight != 0 {
      padding-right: $paddingRight * $unit;
      width: $width * $unit;
      .lt-ie8 & {
        padding-right: $paddingRight * $unit;
        width: ($width - $paddingRight) * $unit;
      }
    }
    @else if $paddingRight == 0 and $paddingLeft != 0{
      padding-left: $paddingLeft * $unit;
      width: $width * $unit;
      .lt-ie8 & {
        padding-left: $paddingLeft * $unit;
        width: ($width - $paddingLeft) * $unit;
      }
    }
  @else if $paddingRight !=0 and $paddingLeft != 0 {
    padding-right: $paddingRight * $unit;
    padding-left: $paddingLeft * $unit;
    width: $width * $unit;
    .lt-ie8 & {
      padding-right: $paddingRight * $unit;
      padding-left: $paddingLeft * $unit;
      width: ($width - $paddingLeft - $paddingRight) * $unit;
    }
  }
}

section {
  @include IE7Padding(100, 1%, 20); 
}
nav {
  @include IE7Padding(100, 1px, 0, 30);  
}
aside {
  @include IE7Padding(100, 1%, 2, 30); 
}
footer {
  @include IE7Padding(970, 1px, 20, 80); 
}
header {
  @include IE7Padding(970, 1px, 20, 10);   
}

How it works

The mixin is divided into four main sections.

  1. The definition of the mixin values
  2. A series of IF statements that cover all possibilities
  3. Rules based on the IF statements
  4. Application of the Mixin

Lets go through each of them one by one so it’s clearer.

Defining Mixin Values

The first line sets the scene and provides us with a structure, some variable names and some default values.

 @mixin IE7Padding($width: null, $unit: 1px, $paddingLeft: 0, $paddingRight: 0) 

Here Stu is declaring the mixin and its name with the @mixin IE7Padding . Then each of the values within the brackets that start with a $ are variables (it’s the $ that denotes a variable).

Each of the values require a value to be assigned. In this case the $width variable gets a null values, the $unit is given 1px, and the two padding variables are set to 0.

Covering bases with IF

The next part of the mixin adds some intelligence. The first @if statement says

> @if $paddingLeft == 0 and $paddingRight != 0 

If the value for the variable $paddingLeft is equal to 0 and if the value for variable @paddingRight does not equal 0 then the statement is true and it will execute the instructions immediately following. If both of those conditions are not met, then it moves onto to the next condition.

The next condition is an @else if statement.  These follow if statements and allow another comparison to be made. The second condition is the exact opposite of the first condition, this time checking to see if the $paddingRight is equal to zero and if the $paddingLeft does not equal zero.

The final condition, another @else if statement, checks the final possibility that neither the left or right padding variables have padding.

This covers all four possibilities 

  1. There is no left padding but there is right padding;
  2. There is no right padding but there is left padding;
  3. There is both left and right padding;
  4. There is no padding (in which case you don’t need the mixin to do anything so we don’t test for this)

Defining the Rules

We’re going to assume that the first rule is met and there is no left padding but there is padding on the right of an element.

 @if $paddingLeft == 0 and $paddingRight != 0 { padding-right: $paddingRight * $unit; width: $width * $unit; .lt-ie8 & { padding-right: $paddingRight * $unit; width: ($width - $paddingRight) * $unit; } } 

When the @if statement is true, it executes the code within the {parentheses}, and in this case it starts off with

  • setting the padding-right to the value $paddingRight * $unit
  • setting the width to the value of $width * $unit

The next part of the rule it nests a .lt-ie8 class within the declaration and is the followed by an & . This means that when it compiles it will prefix .lt-ie8 to the class you apply the mixin against. It’s okay if you get a little confused at this point, that part should appear more clear when we put all the bits together.

Within the .lt-ie8 declaration is where the trickiness happens. This does the following

  • sets padding-right to the value $paddingRight * $unit (as before)
  • sets the width to the $width value MINUS and $paddingRight value (therefore allowing for the box model issue)

Each of the rules within each IF statement does a similar thing. This one subtracts the $paddingRight whereas the next will subtract the $paddingLeft and the final statement subtracts both left and right padding values.

Applying the Mixin

Now you have a clear idea about what the Mixin is doing it’s time to apply it to our class.

Lets take a look at the section element.

 section { @include IE7Padding(100, 1%, 20); } 

Here we have defined the element within the CSS. Then instead of setting the width and padding in the usual way you call your mixin using the @include nameofmixin.  When you call the Mixin you also need to pass in the variable values we defined back in step one.

For the section  element we are passing

  • $width = 100
  • $unit = 1%
  • $paddingLeft = 20
  • $paddingRight = 0 (by not passing any value it defaults to the original value of 0)

That means that $paddingLeft does not equal 0, but $paddingRight does equal 0 and subsequently activates the second IF statement. Lets have a look at that

 padding-left: $paddingLeft * $unit; width: $width * $unit; .lt-ie8 & { padding-left: $paddingLeft * $unit; width: ($width - $paddingLeft) * $unit; } 

translates to 

 padding-left: 20 * 1%; width: 100 * 1%; .lt-ie8 & { padding-left: 20 * 1%; width: (100 - 20) * 1%; } 

which then translates to

 section { padding-left: 20%; width: 100%; } .lt-ie8 section { padding-left: 20%; width: 80%; } 

It works the same way with pixels and right padding where you have

 nav { @include IE7Padding(100, 1px, 0, 30); } 

translate to

 nav { padding-right: 30px; width: 100px; } .lt-ie8 nav { padding-right: 30px; width: 70px; } 

Final Result

This is the final processed CSS file, with all the pre IE8 fallbacks that you need. The final thing that you will need to do is include a conditional comment in your HTML to include the .lt-ie8 class for the CSS to work.

This can be done by using the following code:


<!-- [if lt IE 8]><html class="lt-ie8"> <![endif]-->
<!-- [if gt IE 8]><!--> <html lang="en"> <!-- <![endif]-->

Final processed CSS


section {
  padding-left: 20%;
  width: 100%;
}
.lt-ie8 section {
  padding-left: 20%;
  width: 80%;
}

nav {
  padding-right: 30px;
  width: 100px;
}
.lt-ie8 nav {
  padding-right: 30px;
  width: 70px;
}

aside {
  padding-right: 30%;
  padding-left: 2%;
  width: 100%;
}
.lt-ie8 aside {
  padding-right: 30%;
  padding-left: 2%;
  width: 68%;
}

footer {
  padding-right: 80px;
  padding-left: 20px;
  width: 970px;
}
.lt-ie8 footer {
  padding-right: 80px;
  padding-left: 20px;
  width: 870px;
}

header {
  padding-right: 10px;
  padding-left: 20px;
  width: 970px;
}
.lt-ie8 header {
  padding-right: 10px;
  padding-left: 20px;
  width: 940px;
}

CodePen FTW

Stu set this up as a code pen for everyone to enjoy, make sure you like it

@mixin IE7Padding($width: null, $unit: 1px, $paddingLeft: 0, $paddingRight: 0) {
@if $paddingLeft == 0 and $paddingRight != 0 {
      padding-right: $paddingRight * $unit;
      width: $width * $unit;
      .lt-ie8 & {
        padding-right: $paddingRight * $unit;
        width: ($width - $paddingRight) * $unit;
      }
    }
    @else if $paddingRight == 0 and $paddingLeft != 0{
      padding-left: $paddingLeft * $unit;
      width: $width * $unit;
      .lt-ie8 & {
        padding-left: $paddingLeft * $unit;
        width: ($width - $paddingLeft) * $unit;
      }
    }
  @else if $paddingRight !=0 and $paddingLeft != 0 {
    padding-right: $paddingRight * $unit;
    padding-left: $paddingLeft * $unit;
    width: $width * $unit;
    .lt-ie8 & {
      padding-right: $paddingRight * $unit;
      padding-left: $paddingLeft * $unit;
      width: ($width - $paddingLeft - $paddingRight) * $unit;
    }
  }
}

section {
  @include IE7Padding(100, 1%, 20); 
}
nav {
  @include IE7Padding(100, 1px, 0, 30);  
}
aside {
  @include IE7Padding(100, 1%, 2, 30); 
}
footer {
  @include IE7Padding(970, 1px, 20, 80); 
}
header {
  @include IE7Padding(970, 1px, 20, 10);   
}

See the Pen A Sass-y box-sizing fallback by Stuart Robson (@sturobson) on CodePen.

Subscribe to our Newsletter

Add your email address and receive an email every Friday covering off everything worth knowing about building your websites responsively.