Substance Labs » HTML http://labs.findsubstance.com Create. Constantly. Wed, 27 Jul 2011 18:18:57 +0000 en-US hourly 1 http://wordpress.org/?v=3.5 Fixing the IE8 Form Button with Background Image On Click CSS Bug http://labs.findsubstance.com/2009/05/21/ie8-form-button-with-background-image-on-click-css-bug/ http://labs.findsubstance.com/2009/05/21/ie8-form-button-with-background-image-on-click-css-bug/#comments Thu, 21 May 2009 20:36:06 +0000 Cory Duncan http://labs.findsubstance.com/?p=107 That’s really the best title I could come up with to describe this head-banger of a bug I’ve encountered. I searched and scoured the tubes of the Internet, but couldn’t find anyone talking about it, so I thought I’d share my experience so far.

From my testing, I’ve found this is only an issue in Internet Explorer 8 (hats off to Microsoft for a brand new CSS bug).

The Setup

The setup for this bug is fairly straightforward. It requires a <button> or submit <input> that has a background image. For this example, I’ll use the <button> element. I’ll also be using image replacement to hide the button’s HTML text. I believe this makes the bug more apparent, though it has nothing to do with the actual bug.

The markup:

<button type="submit">Submit</button>

The CSS:

button {
	background: url(button.png) no-repeat 0 0;
	border: 0;
	display: block;
	height: 30px;
	margin: 0;
	padding: 0;
	text-indent: -9999px;
	width: 81px;
	}
button:hover {
	background-position: 0 -30px;
	}

Experiencing the Bug

On first glance, it appears that everything is fine in IE8. The problem occurs when the button is in its active state. Upon clicking the button, the background image shifts -1px to the top and left, though the container of the button stays in the same position. Here’s a demo (view this in IE8) of the bug in action, and here’s a screenshot (I’ve added a red outline to help illustrate the background shift):

So how do you fix this?

I was able to find some workarounds for this bug, and though none are completely bulletproof, all are better than the alternative (doing nothing).

Solution 1: Mo’ Markup + Mo’ CSS (demo)

One option is to add an extra element within the <button> and target that element for the background-image. We can use the same base CSS from The Setup with some additional IE-specific CSS.

The markup:

<button type="submit"><span>Submit</span></button>

The IE-specific (version 8 and below) CSS:

button {
	position: relative;
	}
button span {
	background: url(button.png) no-repeat 0 0;
	height: 30px;
	left: 0;
	position: absolute;
	top: 0;
	width: 100%;
	}
button:hover span {
	background-position: 0 -30px;
	}

There are a number of problems with this solution.

  1. Requires extraneous markup.
  2. Will not work for a submit <input> element, as it does not allow for any child elements.
  3. Requires IE specific CSS to absolutely position the extra element – neglecting to do so will result in an opposite 1px shift to the right and bottom in IE (version 8 and below). If this CSS is not targeted for IE, Mozilla browsers (at least Firefox 2 and 3) exhibit a different bug altogether (a topic for a future post).

Because of the problems associated with this solution, I don’t recommend this approach.

Solution 2: JavaScript-only

I’m sure this could be fixed using IE8-targeted JavaScript, but I’d rather not rely on it, as it would break down if the browsing device has JavaScript disabled or lacks JavaScript support. Let’s try a CSS-only method (my preference)…

Solution 3: CSS-only (demo)

With the release of IE8, Microsoft has added several proprietary CSS extensions. Each of these extensions work in IE8, but not in previous IE versions, or any non-IE browsers. Because this bug is isolated to IE8, we can take advantage of these extensions.

The CSS:

button:active {
	-ms-background-position-x: 1px;
	-ms-background-position-y: -29px;
	}

This CSS counters the bug, by positioning the background top and left 1px. This offset is relative to the button’s hover state, using the height dimension to offset the y-axis (in this case 30px height -1px offset results in -29px for the y-axis offset). If your button has no hover state, the offset would be relative to the button’s default background position. This can be safely included in your main stylesheet without affecting other modern browsers, but as a best practice I’d recommend including this in a separate IE stylesheet along with any other IE-specific CSS (using CSS conditional comments to target IE).

As I mentioned, none of the solutions are bulletproof and that includes this one. If you click the button and drag your cursor off the button’s boundaries, the background shift is visible. I feel that this type of interaction is atypical and most users will click the button without much movement, so this is my recommended approach for the time being.

In Conclusion

I’d love to hear any alternative solutions for this issue. Track and vote for this bug on Microsoft Connect.

]]>
http://labs.findsubstance.com/2009/05/21/ie8-form-button-with-background-image-on-click-css-bug/feed/ 27
Layering Transparent Flash Content over HTML with Scripted Masking http://labs.findsubstance.com/2008/06/30/transparent-flash-over-html/ http://labs.findsubstance.com/2008/06/30/transparent-flash-over-html/#comments Mon, 30 Jun 2008 14:59:15 +0000 Shaun Tinney http://labs.findsubstance.com/2008/06/30/transparent-flash-over-html/ Anyone who has ever tried to display transparent Flash content over HTML knows that getting things to sort properly on the z-index can be frustrating. Flash has an annoying tendency to force itself to render above of all other content Some browsers have trouble rendering plugin content consistently, which can make HTML stacked below Flash content inaccessible to the user. The technique described below is meant to ensure a consistent cross-browser user experience when it comes to issues with flickering or unwanted re-sorting of transparent Flash content.

We at Substance have come across this a number of times, and the best solution we have found is to knock out the areas of the Flash movie that require accessible content displayed below. This can be accomplished rather easily with the use of layer blend modes.

The first step to making this work is to set wmode in your HTML Flash embed code to transparent. After that is done, you can immediately take advantage of this trick:

  1. Set the blendMode property in your Document Class to BlendMode.LAYER
  2. Set the blendMode property of your knockout area to BlendMode.ERASE

This approach differs from creating a true mask, which acts as a window to the clip being masked, by doing the reverse – creating a window through the clip being masked, which in this case is the entire SWF.

Here is a quick example ( assuming “this” is your document class ):

// set blendMode for Document Class;
this.blendMode = BlendMode.LAYER;

// create knockout area;
var knockout : Sprite = new Sprite();
			
// draw 50 x 100 px box;
with ( knockout.graphics )
{
	beginFill( 0x000000 );
	drawRect( 0, 0, 50, 100 );
}

// give mask knockout powers;
knockout.blendMode = BlendMode.ERASE;

// add knockout mask to stage;
this.addChild( knockout );

On the Arakawa home page, the Flash area is set to fill the browser window completely. The logo, navigation, and footer are all knocked out, with a listener attached to the stage for Event.RESIZE so that the footer window always remains at the bottom of the file. This is pretty simple, but here’s a snippet of to show how to keep an item positioned at the bottom of the stage:

// add listener to stage in constructor;
stage.addEventListener( Event.RESIZE, onResize );

// resize listener in class body;
private function onResize () : void
{
	knockout.y = stage.stageHeight - knockout.height;
}
]]>
http://labs.findsubstance.com/2008/06/30/transparent-flash-over-html/feed/ 13