0 Replies - 1313 Views - Last Post: 01 December 2011 - 01:34 AM

#1 e_i_pi  Icon User is offline

  • = -1
  • member icon

Reputation: 879
  • View blog
  • Posts: 1,893
  • Joined: 30-January 09

Opaque foreground, semi-transparent background

Posted 01 December 2011 - 01:34 AM

Description: Copy and paste the snippet into a text file, and open in a browser as HTML. The instructions and explanation are contained within the snippet.A solution for the difficult HTML/CSS problem of having a semi-transparent background beneath an opaque foreground. (e.g. - Solid text on a 50% transparent background, which can then be imposed over a further background)
<html>
	<head>
	</head>
	<body>
		<style>
			body{
				background-image: url("https://www.google.com/intl/en_com/images/srpr/logo3w.png");
			}
			.FillContainer
			{
				position: absolute;
				width: 100%;
				left: 0px;
				right: 0px;
				bottom: 0px;
				height: 100%;
				top: 0px;
			}
			.Margin10px
			{
				margin: 10px;
			}
			.PositionAbsolute{
				position: absolute;
			}
			.PositionRelative{
				position: relative;
			}
			.SemiTransparentBackground{
				background-color: #ffcfff;
				filter: alpha(opacity=90);
				opacity: 0.9;
				z-index: -1;
			}
			.TextAlignJustify
			{
				text-align: justify;
			}
			.TextAlignCentre
			{
				text-align: center;
			}
		</style>

		<div id="OuterWrapper" class="PositionRelative" style="left: 50px; top: 20px; width: 800px;">
			<div id="InnerWrapper" class="PositionAbsolute">
				<div id="Contents" class="TextAlignJustify Margin10px">
					<h2 class="TextAlignCentre"><u>Opaque foreground on a semi-transparent background</u></h2>
					<span>
						One of the harder styling effects to achieve in HTML is having opaque foreground text on semi-transparent background.
						This is because, when you set the opacity of an element, such as <div> or <span>, then the entire contents of that element inherit that opacity setting multiplicatively.
						Eh, that's a big word, let me explain...
						

						

						Take for example the scenario where you have one <div> nested inside another <div>.
						You set the opacity of the outer <div> to 50% and the opacity of the inner <div> to 90%.
						You'd expect the inner div to now have opacity 90%, right?
						

						

						<b>WRONG!</b>
						

						The reason for this is that big word I chucked in before - multiplicatively.
						The opacity of the inner <div> is <i>multiplied</i> with the opacity of the first <div>.
						Therefore, the inner <div> ends up with an opacity of 50% x 90% = 45%.  Weird huh?
						

						

						What makes matters worse is that certain intuitive solutions don't actually fix the problem.
						The first solution that springs to mind is setting the opcaity of the inner <div> to "<b>90% !important</b>".
						If you think that will work, think again.
						This is one of the few cases where the CSS keyword <b>!important</b> has no effect
						Another potential fix is creating a background <div> and a foreground <div> and positioning the foreground <div> higher than the background <div> on the z-index.
						Again we run into the problem of multiplicativity.
						

						

						Luckily there is a solution, and it's contained right here in this HTML code.
						The solution has several key points that you should take note of, especially within the CSS and which classes have been applied to the particular DOM elements.
						There are a total of four DOM elements required to achieve this:
						<ol>
							<li>The first DOM element is the outermost wrapper, which I've given the id "OuterWrapper".  We can apply any and all styling attributes we want to this element, such as those I have declare inline and by class.</li>
							<li>The second DOM element is the next wrapper, which I've given the id "InnerWrapper".  This element acts as a wrapper only, and needs to have it's position set to "absolute".</li>
							<li>The third DOM element is the first inside element, which I've given the id "Contents", and contains the actual contents.  We can add any type of content here, and apply any styling attributes to this element.</li>
							<li>The fourth DOM element is the second inside element, which I've given the id "TransparentBackground", and contains the semi-transparent lilac background you see.  Note well the two classes I have assigned to it - "FillContainer" and "SemiTransparentBackground".  The "FillContainer" class ensures that this element takes up all the room that it's <i>immediate previous sibling</i> is occupying.  The "SemiTransparentBackground" class contains the background attributes, including the opacity and the colour.</li>
						</ol>
						By applying this double-nesting technique, we achieve a semi-transparent background against opaque contents, and can apply any positioning or styling to the object as a whole.  Enjoy.
						

						

						The big things to note here are the following:
						<ol>
							<li>The value of the <b>position</b> attributes on each <div> are key.</li>
							<li>The order and nesting of the <div> elements is crucial to get cross-browser compatibility.  (IMPORTANT: The TransparentBackground <div> <i>must come after</i> the Contents <div> in order to pick up it's dimensions, and size itself appropriately!)</li>
							<li>The z-index of the SemiTransparentBackground CSS class must be negative.  If this is set to any value greater than -1, the opacity of <div> will apply to any other DOM element occupying the same space, no matter what the other elements z-indices are!</li>
						</ol>
						

						

						

						

						Tested in Firefox 8, Internet Explorer 9, and Safari 5
					</span>
				</div>
				<div id="TransparentBackground" class="SemiTransparentBackground FillContainer"> </div>
			</div>
		</div>
	</body>
</html>


Is This A Good Question/Topic? 0
  • +

Page 1 of 1