Quantcast
Channel: internet mix » css
Viewing all articles
Browse latest Browse all 3

CSS transparency inheritance workaround (PHP & CSS3)

$
0
0

Transparency Comparison
After many hours reading up on the caveats of transparency; after tabbing through many suggestions found on many websites, blogs and forums; after trying to create visible containers on top of invisible containers, changing positions from relative to absolute and back only to see layout go totally awry, I finally decided to create my own approach to display child elements that do not inherit the parent’s transparency setting.

This is not a fix for every single browser out there and for every possible scenario, but it’s working in IE > 6, Firefox 3+ and our current versions of Safari (4.0.3) and Opera (10.51).
(If you come up with a variation to make it work in additional browsers, please share your findings!)

First, the situation:

We have a background image and we want to make to container on top it semi-transparent (so the background image is still visible), but inside this nested container we have another item (an image, a div, etc) which we DO NOT WANT to be transparent.

The two images side-by-side show the desired result (left, image in nested container NOT transparent) and the actual result (right, image in nested container is transparent):

The code is as follows (simplified):
HTML:


Lorem Ipsum

<p>In id nulla vitae nisi aliquet blandit in facilisis tellus. Duis et mauris eget enim posuere commodo. Aliquam et leo augue. Sed ut diam lacus.</p>
read more &raquo;

CSS:

.bgdiv {
	font-family:Arial, Helvetica, sans-serif;
	height:400px;
	width:400px;
	background:#ffffff url('[path-to-image]') top left no-repeat;
	padding:15px 0 0 0;
}

#content {
	min-height:340px;
	width:300px;
  	background-color:#ffffff;
	/* for IE 8 - always needs to come first */
	-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=85)";
  	/* for IE */
  	filter:alpha(opacity=85);
  	/* for FF etc */
  	opacity:0.85;
  	-moz-opacity:0.85
}

.servicebox {
	width:200px;
	margin:20px auto;
	color:#666666;
}

.servicebox h1 {
	font-family: Century Gothic,Myriad Pro,Arial,Helvetica,sans-serif;
	font-size:16px;
	color:#bf31ad;
	margin:0 0 12px 0;
	width:200px;
	line-height:12px;
	padding:10px 0;
	border-bottom:1px solid #bf31ad;
}

.serviceimg {
	border:1px solid #bfbfbf;
	width:200px;
	overflow:hidden;
	margin:0;
}

.servicebox p {
	font-size:12px;
	margin:0;
	padding: 15px 5px 5px 5px;
	color:#222222;
}

.servicebox div.more {
	text-align:center;
	color:#ffffff;
	height:20px;
	width:100px;
	margin:5px 0 0 100px;
	font-size:11px;
	line-height:18px;
	background:url('[path-to-sprite]') 0 0 no-repeat;
}

.servicebox div.more:hover {
	background:url('[path-to-sprite]') 0 -20px no-repeat;
	color:#2c8819;
}

Lines 12-14 are responsible for the transparency, we used -moz-opacity and opacity for Firefox, Safari, Opera, etc, and a filter for IE.

You can see everything that sits on top of (or inside) the "content" div automatically becomes transparent as well, no matter what you do. As mentioned above, we tried all suggestions we could find – to no avail.

Except for these:
IE 7: To make the images contained in the "servicebox"div opaque, simply add

.servicebox {position:relative;}

to the "servicebox"div. This won’t work in Firefox, etc, but it doesn’t hurt the layout either.

To make it work in Firefox, Opera & Safari, we had to make use of the color model in CSS3:
Instead of setting -moz-opacity and opacity for non-IE browsers, we added

#content {background-color: rgba(255, 255, 255, 0.85);}

to the "content" div, where the last part (0.85) sets the transparency/opacity level for that object only.

Although browsers that don’t understand CSS3 should ignore it and simple move on to the next step, we experienced weird behavior when simply adding to the style sheet.

So we tried conditional statements, but then the code didn’t validate and we had trouble with the explicit non-IE condition {sigh}.

The final result was probably the easiest one (naturally rgba only validates against CSS3, see below):
Detect the browser with PHP (very basic) and display the required declarations (or load a browser-specific stylesheet) based on the browser detection result.

<?
$isIE6 = 0;
$isIE7 = 0;
$isIE8 = 0;
$ie6 = "MSIE 6.0";
$ie7 = "MSIE 7.0";
$ie8 = "MSIE 8.0";

$browser = $_SERVER['HTTP_USER_AGENT'];

if(stristr($browser, $ie6) !== false ) {
	$isIE6 = 1;
	// add any styles for IE 6 here
	// not really necessary
	// $style = "";
	/* to add a browser-specific stylesheet for IE6, simply add this:
	$style = "
";
	*/
} elseif(stristr($browser, $ie7) !== false ) {
	$isIE7 = 1;
	// add any styles for IE 7 here
	$style = "


";
	/* to add a browser-specific stylesheet for IE7, simply add this:
	$style = "
";
	*/
} elseif(stristr($browser, $ie8) !== false ) {
	$isIE8 = 1;
	// add any styles for IE 8 here
	$style = "


";
	// to add a browser-specific stylesheet for IE8, simple add this:
	// $style = "
";

} else {
	$isIE6 = 0; $isIE7 = 0; $isIE8 = 0;
	$style= "


";
	/* to add a browser-specific stylesheet for non IE6/IE7, simply add this:
	$style = "
";
	*/
}
?>

Super-short version (active version on Demo page):

<?
$browser = $_SERVER['HTTP_USER_AGENT'];
$browsers = array("MSIE 6.0","MSIE 7.0","MSIE 8.0");
$styles = array("",".serviceimg2 {position:relative;}",".serviceimg2 {position:relative;}");
$msie= 0;

for($x = 0; $x 
	$sstyle


";
?>

Insert $style (or its output) via shorthand PHP into your HTML code:

<head>
	[other important things go here]
	<?=$style;?>
</head>
CSS validated

Viewing all articles
Browse latest Browse all 3

Latest Images

Trending Articles





Latest Images