Skip to content

Instantly share code, notes, and snippets.

@lemnis
Last active December 21, 2015 18:39
Show Gist options
  • Save lemnis/6348439 to your computer and use it in GitHub Desktop.
Save lemnis/6348439 to your computer and use it in GitHub Desktop.
A mixin for making webkit-filters a little bit more useful.

Sassy filters

A polyfill for webkit filters

inspired by: https://github.com/Schepp/CSS-Filters-Polyfill

=======

supported filters

  • blur
  • brightness
  • hue-rotate
  • grayscale
  • invert
  • opacity
  • saturate (only works below 1 or 100%)
  • sepia

supported filters within IE

  • blur
  • grayscale with a value of 100% or 1
  • invert with a value of 100% or 1

unsupported filters

  • contrast

Supported browsers

  • IE 6 / 9 (limited)
  • Firefox 3.5+
  • Chrome 18+
  • Safari 6+
  • iOS 6+
  • Opera 15+
  • Blackberry 10+
  • Opera mobile 14+
  • Chrome for android

Usage

@include filter($filter: value)

To enable support in IE you have to set $ieSupport to yes

For example:

div{
  @include transform($grayscale: 100%, $ieSupport: yes);
}
$svg-filters: no;
// add different output if it is used within the mixin filter
@function grayscale($value){
@if $svg-filters == yes{
@return $value
} @else {
@return desaturate($color, 100%)
}
}
@function invert($value){
@if $svg-filters == yes{
@return $value
} @else {
$red: 255 - red($value);
$green: 255 - green($value);
$blue: 255 - blue($value);
$value: rgba($red, $green, $blue, opacity($value));
@return $value;
}
}
@function opacity($value){
@if $svg-filters == yes{
@return $value
} @else {
@return alpha($value)
}
}
// the actual mixin
@mixin filter($blur: 0cm, $brightness: 0cm, $hue-rotate: 0cm, $grayscale: 0cm, $invert: 0cm, $opacity: 0cm, $sepia: 0cm, $drop-shadow: 0cm, $saturate: 0cm, $ieSupport: no){
$ieFilter: (); $includeSVG: (); $cssFilter: ();
$shadowX: null; $shadowY: null; $shadowBlur: null; $shadowColor: null;
$svg-filters: yes;
@if length($drop-shadow) >= 3{
@if type-of(nth($drop-shadow, 1)) == color{
$shadowX: nth($drop-shadow, 2);
$shadowY: nth($drop-shadow, 3);
$shadowColor: nth($drop-shadow, 1);
@if length($drop-shadow) == 4{
$shadowBlur: nth($drop-shadow, 4);
}
} @else {
$shadowX: nth($drop-shadow, 1);
$shadowY: nth($drop-shadow, 2);
$shadowColor: nth($drop-shadow, 3);
@if length($drop-shadow) == 4{
$shadowBlur: nth($drop-shadow, 3);
$shadowColor: nth($drop-shadow, 4);
}
}
}
@if $blur != 0cm{
$cssFilter: append($cssFilter, unquote("blur(#{$blur})"));
$blur: $blur / ($blur * 0 + 1);
}
@if $brightness != 0cm{
$cssFilter: append($cssFilter, unquote("brightness(#{$brightness})"));
@if unit($brightness) == '%'{ $brightness: $brightness / ($brightness * 0 + 1) / 100; }
}
@if $grayscale != 0cm{
$cssFilter: append($cssFilter, unquote("grayscale(#{$grayscale})"));
@if unit($grayscale) == '%'{ $grayscale: $grayscale / ($grayscale * 0 + 1) / 100; }
}
@if $hue-rotate != 0cm{
$cssFilter: append($cssFilter, unquote("hue-rotate(#{$hue-rotate})"));
$hue-rotate: $hue-rotate / ($hue-rotate * 0 + 1);
}
@if $invert != 0cm{
$cssFilter: append($cssFilter, unquote("invert(#{$invert})"));
@if unit($invert) == '%'{ $invert: $invert / ($invert * 0 + 1) / 100; }
}
@if $opacity != 0cm{
$cssFilter: append($cssFilter, unquote("opacity(#{$opacity})"));
@if unit($opacity) == '%'{ $opacity: $opacity / ($opacity * 0 + 1) / 100; }
}
@if $saturate != 0cm{
$cssFilter: append($cssFilter, unquote("saturate(#{$saturate})"));
@if unit($saturate) == '%'{ $saturate: $saturate / ($saturate * 0 + 1) / 100; }
}
@if $sepia != 0cm{
$cssFilter: append($cssFilter, unquote("sepia(#{$sepia})"));
@if unit($sepia) == '%'{ $sepia: $sepia / ($sepia * 0 + 1) / 100; }
}
@if $drop-shadow != 0cm{
$cssFilter: append($cssFilter, unquote("drop-shadow(#{$drop-shadow})"));
$shadowX: $shadowX / ($shadowX * 0 + 1);
$shadowY: $shadowY / ($shadowY * 0 + 1);
$shadowBlur: $shadowBlur / ($shadowBlur * 0 + 1);
}
$sepia: 1 - $sepia; $saturate: 1 - $saturate; $grayscale: 1 - $grayscale; $zeroSeven: 0.0722 - 0.0722 * $grayscale; $twoOne: 0.2126 - 0.2126 * $grayscale; $sevenOne: 0.7152 - 0.7152 * $grayscale;
@if $blur != 0cm{
$includeSVG: append($includeSVG, unquote("<feGaussianBlur stdDeviation='#{$blur}' />")); }
@if $brightness != 0cm{
$includeSVG: append($includeSVG, unquote("<feComponentTransfer><feFuncR type='linear' slope='#{$brightness}'/><feFuncG type='linear' slope='#{$brightness}'/><feFuncB type='linear' slope='#{$brightness}'/></feComponentTransfer>")); }
@if $grayscale != 1cm{
$includeSVG: append($includeSVG, unquote("<feColorMatrix type='matrix' values='#{(0.2126 + 0.7874 * $grayscale) $sevenOne $zeroSeven} 0 0 #{$twoOne (0.7152 + 0.2848 * $grayscale) $zeroSeven} 0 0 #{$twoOne $sevenOne (0.0722 + 0.9278 * $grayscale)} 0 0 0 0 0 1 0'/>")); }
@if $hue-rotate != 0cm{
$includeSVG: append($includeSVG, unquote("<feColorMatrix type='hueRotate' values='#{$hue-rotate}'/>")); }
@if $invert != 0cm{
$includeSVG: append($includeSVG, unquote("<feComponentTransfer><feFuncR type='table' tableValues='#{$invert (1 - $invert)}'/><feFuncG type='table' tableValues='#{$invert (1 - $invert)}'/><feFuncB type='table' tableValues='#{$invert (1 - $invert)}'/></feComponentTransfer>")); }
@if $opacity != 0cm{
$includeSVG: append($includeSVG, unquote("<feComponentTransfer><feFuncA type='table' tableValues='0 #{$opacity}'/></feComponentTransfer>")); }
@if $sepia != 1cm{
$includeSVG: append($includeSVG, unquote("<feColorMatrix type='matrix' values='#{(0.393 + 0.607 * $sepia) (0.769 - 0.769 * $sepia) (0.189 - 0.189 * $sepia) 0 0 (0.349 - 0.349 * $sepia) (0.686 + 0.314 * $sepia) (0.168 - 0.168 * $sepia) 0 0 (0.272 - 0.272 * $sepia) (0.534 - 0.534 * $sepia) (0.131 + 0.869 * $sepia) 0 0 0 0 0 1 0}'/>")); }
@if $drop-shadow != 0cm{
$includeSVG: append($includeSVG, unquote("<feGaussianBlur in='SourceGraphic' stdDeviation='#{$shadowBlur}'/><feOffset dx='#{$shadowX + 1}' dy='#{$shadowY + 1}' result='offsetblur'/><feFlood flood-color='#{$shadowColor}'/><feComposite in2='offsetblur' operator='in'/><feMerge><feMergeNode/><feMergeNode in='SourceGraphic'/></feMerge>")); }
@if $saturate != 1cm{
$includeSVG: append($includeSVG, unquote("<feColorMatrix type='saturate' values='#{$saturate}'/>")); }
@if $ieSupport == yes{
@if $grayscale == 0 {
$ieFilter: append($ieFilter, unquote("progid:DXImageTransform.Microsoft.BasicImage(grayScale=0.5)"), comma); }
@if $invert == 1 {
$ieFilter: append($ieFilter, unquote("progid:DXImageTransform.Microsoft.BasicImage(invert=1)"), comma); }
@if $blur != 0cm{
$ieFilter: append($ieFilter, unquote("progid:DXImageTransform.Microsoft.Blur(pixelradius=#{$blur}) "), comma); }
}
filter: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg'><filter id='filter'>#{$includeSVG}</filter></svg>#filter");
-webkit-filter: $cssFilter;
@if $ieFilter != (){
filter: $ieFilter;
zoom: 1; }
}
$svg-filters: no;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment