Skip to content

Instantly share code, notes, and snippets.

@twome
Last active September 23, 2018 07:35
Show Gist options
  • Save twome/5605043 to your computer and use it in GitHub Desktop.
Save twome/5605043 to your computer and use it in GitHub Desktop.
Sass colour helpers, for the frontend folk on the go.
// This lets you specify the colour of the backdrop behind your transparent
// foreground colour - ideally with a variable - so that Sass can use its
// `mix` function to get fake transparency. It looks identical to real
// transparency (for solid-on-solid colour). IE8 can use `filter` to get real
// *background* transparency, but if you use this you can also get
// "transparency" on border-color, font color, and everything else. It
// defaults to the most legitimate transparency available.
// It doesn't expect Modernizr, but it does expect some kind of similar 'IE8'
// class in the `<html>` element, like H5BP's. Can Modernizr detect the old MS
// filters? It would be preferable to an IE8 class, but I don't think it can.
// I took the filter idea taken from StackOverflow user "seutje"
// http://stackoverflow.com/a/8009864/1129420
// Browser support: http://caniuse.com/css3-colors - it's just IE <=8 and Opera
// <=9.6 that lack it.
// (Unfinished) test:
// http://codepen.io/twome/pen/wqvbg
// Requirements:
// $backdrop must be a fully opaque colour, and must be completely untextured;
// otherwise the jig will be up and the ruse: exposed.
// Example:
// @include alpha-color(hsla(230, 80%, 60%, 0.4), #dd3333, 'border-color');
@mixin alpha-color($foreground, $backdrop: false, $property: 'background-color') {
// For browsers without color opacity
@if $backdrop {
@if opacity($backdrop) != 1 {
@warn 'Used a transparent backdrop in alpha-color mixin; this will
give an innacurate result.'
};
// Mix the the foreground into the backdrop proportionally to its alpha
#{$property}: mix(
fade-in($foreground, 1),
$backdrop,
percentage( abs( 0 - opacity($foreground) ) ) // Flip the weighting
);
} @else {
// If you don't know or care what the background is, just turn the
// foreground opaque
#{$property}: fade-in($foreground, 1)
}
// For browsers worthy of the title
#{$property}: $foreground;
// IE8 has background filters; smoke 'em if you got 'em
@if $property == 'background-color' {
.lt-ie9 & {
#{$property}: transparent;
$ie-hex: ie-hex-str($foreground);
filter:progid:DXImageTransform.Microsoft.gradient(
startColorstr=#{$ie-hex},
endColorstr=#{$ie-hex}
);
zoom: 1;
}
}
}
// Function format of alpha-color mixin - more obvious and readable; no IE
// filters; must hand-write two property declarations.
// Example:
// border-color: make-opaque(hsla(230, 80%, 60%, 0.4), #dd3333);
@function to-opaque($foreground, $backdrop: false) {
@if $backdrop {
@if opacity($backdrop) != 1 {
@warn 'Used a transparent backdrop in alpha-color mixin; this will
give an innacurate result.';
}
// Mix the the foreground into the backdrop proportionally to its alpha
@return mix(
fade-in($foreground, 1),
$backdrop,
percentage( abs( 0 - opacity($foreground) ) ) // Flip the weighting
);
} @else {
// If you don't know or care what the background is, just turn the
// foreground opaque
@return fade-in($foreground, 1);
}
}
// HSLA extended
// Params: (hex|hsl)[a]
// This allows you to specify a hex/alpha pair without having to swap back to
// RGBA. I never work in RGBA anymore; it makes less semantic sense than HSLA
// and colour conversions are harder. This also makes quickly swapping colours
// a bit faster, now that you don't have to change the colour type.
// Examples:
// Hex:
// hslx(#b4d455) -> hex output
// Hex with alpha:
// hslx(#b4d455, 0.5) -> hsla output
// HSL:
// hslx(75, 60%, 58%) -> hsl output
// HSL with alpha:
// hslx(75, 60%, 58%, 0.5) -> hsla output
@function hslx ($channels...) {
@if length($channels) == 4 {
// Hue, Saturation, Lightness, Alpha
@return hsla($channels);
} @elseif length($channels) == 3 {
// HSL
@return hsl($channels);
} @elseif length($channels) == 2 {
// Hex, Alpha
// Sass' native functions don't yet allow you to input a hex/alpha
// into an HSLA
$col: change-color(nth($channels, 1), $alpha: nth($channels, 2));
@return hsla(hue($col), saturation($col), lightness($col), alpha($col) );
} @elseif length($channels) == 1 {
// Hex
@return $channels;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment