Sass mixin for background transparency back to IE8

14,118

Solution 1

@mixin transparent($color, $alpha) {
  $rgba: rgba($color, $alpha);
  $ie-hex-str: ie-hex-str($rgba);
  background-color: transparent;
  background-color: $rgba;
  filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#{$ie-hex-str},endColorstr=#{$ie-hex-str});
  zoom: 1;
}

NOTE: The ie-hex-str is only available in recent versions, not sure when it was introduced though

Solution 2

I think I encountered a similar problem when I wanted to pass a url to the mixin. Instead of sending only the url I had the send the whole url parameter as a parameter to the mixin. If you understand what I mean?

example:

@mixin bg($url)
  background: #000 $url repeat-x

insted of:

@mixin bg($url)
  background: #000 url($url) repeat-x

Also, this might not the suited for your application, but I usually work around that problem using opacity:

@mixin transparent_bg($hex, $a){
  /* for IEGR8 */
  filter:alpha(opacity=$a)
  zoom: 1;

  /* for modern browsers */
  background-color: $hex;
  opacity: ($a*10)
}

Solution 3

This probably is as bulletproof as you'll get without a proper shim.

To build on seutje's answer, this lets you use ms-filter transparency if you're doing background-color on IE, but if you if you know the colour of the element behind the element you want to make transparent, you can use Sass's "mix" function to mix the two colours and get fake transparency - for any kind of colour. That means borders and text and all that jive. It's still a manual fallback but it'll give you the exact colour you're trying to simulate with a solid hex.

SCSS:

@mixin alpha-color($foreground-color, $property: 'background-color', $background-context-color: #fff) {
    #{$property}: mix( 
        fade-in($foreground-color, 1), 
        $background-context-color, 
        percentage(opacity($foreground-color)) 
    ); // Browsers without color opacity
    #{$property}: $foreground-color; // Decent browsers
    @if $property == 'background-color' {
        .lt-ie9 & { // IE8 has background filters; use them instead
            #{$property}: transparent;
            $ie-hex: ie-hex-str($foreground-color);
            filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#{$ie-hex},endColorstr=#{$ie-hex});
            zoom: 1;
        }
    }
}

To get border-color: rgba(255, 0, 0, 0.5) on a blue background, you'd use it like:

.blue-container {
    $color-bg: rgb(0,0,255);
    background-color: $color-bg;
    .transparent-red-element {
        @include alpha-color(rgba(255, 0, 0, .65), border-color, $color-bg);
    }
}

Sass automatically turns 100% opacity colors back into a hex code, hence the fade-in of 100%.

The only browsers without colour opacity are IE8 <=8 and Opera <=9.6, and IE 8 has filters so this only helps for colors other than background-color. The principle is that you mix the background and foreground colours together into a flat hex.

ie-hex-str is like a year old now so you'll definitely have it.

Share:
14,118
RSG
Author by

RSG

The sheriff of tumbleweed town.

Updated on July 10, 2022

Comments

  • RSG
    RSG almost 2 years

    I'm new to Sass and struggling with this. I can't get the color to render in both hex (for IE) and rgba. Every little piece is frustrating me because I haven't mastered the syntax yet, and Google results for Sass are still sparse.

    Here's the mixin:

    @mixin transparent($hex, $a){
        /* for IEGR8 */
        background: transparent;
        filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#{$a}#{$hex},endColorstr=#{$a}#{$hex});
        zoom: 1;
        /* for modern browsers */
        background-color: rgba(#{$hex},.#{$a});
    }
    

    Such that @include transparent(#FFF,.4) should produce the nice, browser compatible transparent code below:

    background: transparent;         
    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#40FFFFFF,endColorstr=#40FFFFFF);
    zoom: 1;
    background-color: rgba(100,100,100,.40);
    

    I've been noobing on the following for a couple hours:

    • The # required for #RGB format.
    • The . required for rgba alpha.

    Both need to be included for the call to rgba(), however the # can't be included for the IE #AARRGGBB or it will look like #AA#RRGGBB, and the . can't be included for IE or it rejects #.AARRGGBB.

    Am I missing a much simpler way to do this? Can this be done with Sass string manipulation or any slightly clever color cast function in Sass which handles this for me already?

  • RSG
    RSG almost 13 years
    Thanks- this is helpful. Am I right that changing opacity on a block level element actually fades the content of the whole DOM element and its children? I'm just trying to adjust the background opacity.
  • zeeraw
    zeeraw almost 13 years
    This is dirty, but you could add a div with the sole purpose of acting BG :p
  • Shawn
    Shawn over 12 years
    This works in chromium-browser 14.0.835.202 and Firefox 8 under ubuntu 11.10. Can anyone confirm for other browsers?
  • Capi Etheriel
    Capi Etheriel about 12 years
    @Shawn rgba has pretty good support since it was first proposed. IE is the dumb browser holding the web back, as always: caniuse.com/#feat=css3-colors
  • Andrew Swihart
    Andrew Swihart almost 12 years
    This is great, thanks! Just one thing - I had to add a space after "filter: " on the next to last line for SASS to be able to compile it.
  • napster
    napster almost 12 years
    What version is ie-hex-str in? Does seem to work in 3.1.20.