Skip to content

Instantly share code, notes, and snippets.

@sgregson
Last active August 29, 2015 14:20
Show Gist options
  • Save sgregson/6160a6579fbda9371f46 to your computer and use it in GitHub Desktop.
Save sgregson/6160a6579fbda9371f46 to your computer and use it in GitHub Desktop.
Negative Border Radius Mixin
<h1>Negative Border Radius Mixin</h1>
<h2>Parameters</h2>
<div class="all"><code>$corners: 1 1 1 1</code></div>
<div class="top"><code>$corners: 1 1 0 0</code></div>
<div class="bottom"><code>$corners: 0 0 1 1</code></div>
<div class="top-left"><code>$corners: 1 0 0 0</code></div>
<div class="top-right"><code>$corners: 0 1 0 0</code></div>
<div class="bottom-right"><code>$corners: 0 0 1 0</code></div>
<div class="bottom-left"><code>$corners: 0 0 0 1</code></div>
<div class="double">double border</div>
<div class="triple">triple border</div>
<hr noshade/>
<h2>Error States</h2>
<div class="bug" style="width: 201px; height:81px">rgba+odd dims = BAD</div>
<div class="bug">rgba+ content-determined dims = NOT GOOD</div>
<hr noshade/>
<h2>Good States</h2>
<div class="bugfix transparent">rgba+even dims = ALWAYS OK (zoom issues)</div>
<div class="bugfix opaque">opaque = ALWAYS OK</div>
// ----
// libsass (v3.1.0)
// ----
//example code
body { background: url(http://lorempixel.com/1380/1300/abstract/placeholder/); background-size: cover;}
div { font-weight: bold; float: left; min-width: 130px; min-height: 80px; margin: 10px; padding: 0 40px 0;}
hr { clear: both; border: 0; background: transparent; border-top: 1px dashed #fff; }
h1, h2 {color: #fff;}
.bug {min-width: 0; min-height: 0; padding: 20px;}
//////////////////////////////////////////////
//////////////////////////////////////////////
/** MIXIN **/
@mixin negative_border_radius($color, $opacity, $radius:10px, $corners: 1 1 1 1) {
$radius2: $radius + 1px;
// solid color rectangle fallback
background: $color;
// rgba rectangle fallback
@if $opacity != 1 {
background: rgba($color, $opacity);
}
// older browser-specific fallbacks
background: -moz-radial-gradient(circle at 0 100%, rgba($color, 0) if(nth($corners, 4) != 0, $radius, 0), rgba($color, $opacity) if(nth($corners, 4) != 0, $radius2, 0)),
-moz-radial-gradient(circle at 100% 100%, rgba($color, 0) if(nth($corners, 3) != 0, $radius, 0), rgba($color, $opacity) if(nth($corners, 3) != 0, $radius2, 0)),
-moz-radial-gradient(circle at 100% 0, rgba($color, 0) if(nth($corners, 2) != 0, $radius, 0), rgba($color, $opacity) if(nth($corners, 2) != 0, $radius2, 0)),
-moz-radial-gradient(circle at 0 0, rgba($color, 0) if(nth($corners, 1) != 0, $radius, 0), rgba($color, $opacity) if(nth($corners, 1) != 0, $radius2, 0));
background: -webkit-radial-gradient(circle at 0 100%, rgba($color, 0) if(nth($corners, 4) != 0, $radius, 0), rgba($color, $opacity) if(nth($corners, 4) != 0, $radius2, 0)),
-webkit-radial-gradient(circle at 100% 100%, rgba($color, 0) if(nth($corners, 3) != 0, $radius, 0), rgba($color, $opacity) if(nth($corners, 3) != 0, $radius2, 0)),
-webkit-radial-gradient(circle at 100% 0, rgba($color, 0) if(nth($corners, 2) != 0, $radius, 0), rgba($color, $opacity) if(nth($corners, 2) != 0, $radius2, 0)),
-webkit-radial-gradient(circle at 0 0, rgba($color, 0) if(nth($corners, 1) != 0, $radius, 0), rgba($color, $opacity) if(nth($corners, 1) != 0, $radius2, 0));
// standard documentation
background: radial-gradient(circle at 0 100%, rgba($color, 0) if(nth($corners, 4) != 0, $radius, 0), rgba($color, $opacity) if(nth($corners, 4) != 0, $radius2, 0)),
radial-gradient(circle at 100% 100%, rgba($color, 0) if(nth($corners, 3) != 0, $radius, 0), rgba($color, $opacity) if(nth($corners, 3) != 0, $radius2, 0)),
radial-gradient(circle at 100% 0, rgba($color, 0) if(nth($corners, 2) != 0, $radius, 0), rgba($color, $opacity) if(nth($corners, 2) != 0, $radius2, 0)),
radial-gradient(circle at 0 0, rgba($color, 0) if(nth($corners, 1) != 0, $radius, 0), rgba($color, $opacity) if(nth($corners, 1) != 0, $radius2, 0));
// layout requirements
background-position: bottom left, bottom right, top right, top left;
background-repeat: no-repeat;
// Opaque BG's can be odd-px values.
@if $opacity == 1 {
-moz-background-size: 51% 51%;
-webkit-background-size: 51% 51%;
background-size: 51% 51%;
} @else {
-moz-background-size: 50% 50%;
-webkit-background-size: 50% 50%;
background-size: 50% 50%;
}
}
////////
.all {
@include negative_border_radius(#e4ded1, 1, 10px, 1 1 1 1);
}
.top {
@include negative_border_radius(#e4ded1, .9, 20px, 1 1 0 0);
}
.bottom {
@include negative_border_radius(#e4ded1, .8, 20px, 0 0 1 1);
}
.top-left {
@include negative_border_radius(#e4ded1, .7, 30px, 1 0 0 0);
}
.top-right {
@include negative_border_radius(#e4ded1, .5, 30px, 0 1 0 0);
}
.bottom-right {
@include negative_border_radius(#e4ded1, .5, 30px, 0 0 1 0);
}
.bottom-left {
@include negative_border_radius(#e4ded1, .5, 30px, 0 0 0 1);
}
.bug {
// THE PROBLEM IS USING AN ODD VALUE WITH RGBA
@include negative_border_radius(#e4ded1, .8, 10px, 1 1 1 1);
}
.double {
position: relative;
@include negative_border_radius(#e4ded1, 1, 20px, 1 1 1 1);
&:before {
@include negative_border_radius(#000, 1, 20px, 1 1 1 1);
content: '';
position: absolute;
top: -2px;
bottom: -2px;
left: -2px;
right: -2px;
z-index: -1;
}
}
.triple {
position: relative;
@include negative_border_radius(#fff, 1, 20px, 1 1 1 1);
&:before {
@include negative_border_radius(rebeccapurple, 1, 16px, 1 1 1 1);
content: '';
position: absolute;
top: -3px;
bottom: -3px;
left: -3px;
right: -3px;
z-index: -1;
}
&:after {
@include negative_border_radius(#fff, 1, -1px, 1 1 1 1);
content: '';
position: absolute;
top: -4px;
bottom: -4px;
left: -4px;
right: -4px;
z-index: -2;
}
}
.bugfix.transparent {
// IF YOU CAN GUARANTEE THE PIXEL DIMENSION, RGBA IS OK
// no content-determined dimensions
@include negative_border_radius(#e4ded1, .8, 10px, 1 1 1 1);
width: 200px;
height: 80px;
}
.bugfix.opaque {
// OPAQUE BG's are OK for any width
@include negative_border_radius(#e4ded1, 1, 10px, 1 1 1 1);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment