[Sass] Mixin for inside borders
A way to add a border/outline to an element without affecting its final dimensions.
After many times deciding to add an outline to different elements to improve their usability, I found out that doing it via the border property was making the element ‘expand’ on :hover.
The reason for this is that the border of an element is added to the width & height of its box model. So if you have a square that’s 50x50px with a border of 2px, the box is really 54x54px.
So I needed to come up with a solution to this problem: A way to add an border/outline to an element without affecting its final dimensions.
Enter box-shadow’s inset value.
Here’s how you create a 1px black border with box-shadow and the inset value:
.element { box-shadow:inset 0 0 0 1px black; }
Now, I needed a Sass mixin that would allow me to create borders of any thickness, any color and any opacity.
So if I would write:
.element { @include ib(2em, orange, .5); }
This would compile to:
.element { box-shadow: inset 0 0 0 2em rgba(255, 165, 0, 0.5); }
So, here’s that Sass mixin:
//Default values:
$ibThickness: 2px !default;
$ibColor: black !default;
$ibAlpha: .1 !default;//Use a "variable argument" to accept any number of values.
@mixin ib($values...) {
$borderThickness: $ibThickness;
$borderColor: $ibColor;
$borderAlpha: $ibAlpha;
@each $value in $values {
@if type_of($value) == number {
@if unit($value) == "" {
$borderAlpha: $value;
} @else {
//No need to limit this length to just "px"
$borderThickness: $value;
}
} @else if type_of($value) == color {
$borderColor: $value;
}
}
box-shadow: inset 0 0 0 $borderThickness rgba($borderColor, $borderAlpha);
As you can see at the top there’s a list with default values, so if you don’t specify any values in the mixin, those default values will be used.
I other words, the default values would create a: 2px black border with .2 opacity:
.element { box-shadow:inset 0 0 0 2px 0, 0, 0, 0.2; }
Here are the ways you use can use the above mixin:
.element { @include ib(); }
.element { @include ib(20px); }
.element { @include ib(blue); }
.element { @include ib(.6); }
.element { @include ib(20px, blue, .6); }
Here’s my demo in CodePen: http://codepen.io/ricardozea/full/Fakih
Hope this is helpful!
Thanks for reading.