Sliding window button - changing background possible?

Hello,

I’m trying to change all the buttons on a website into sliding window buttons so to radically reduce CSS file overload.

I’m displaying the button image as a background. On :hover I want both the left and right part of the button to show it’s second (lower) state. Each button is 33px high whereas each image file (i.e. button_gray_right.png and button_gray_left.png is 66px). The top 33px is the non-hover state, the lower 33px is the hover state. I’ve attached a sample to help clarify this further.

Currently, when I hover the mouse over a test button, it will hover correctly in as far as displaying button_gray_left.png but I can’t get it to also show the lower part of button_gray_right.png.

Is this possible and if so how? I guess another way would be just to have one button image and stretch it within a span class?

a.button-gray {
	/* Sliding right image */
	background: transparent url("../images/button_gray_right.png") no-repeat scroll top right; 
	display: block;
	float: left;
	height: 33px; /* CHANGE THIS VALUE ACCORDING TO IMAGE HEIGHT */
	padding-right: 15px; /* CHANGE THIS VALUE ACCORDING TO RIGHT IMAGE WIDTH */
	margin: 10px 0px 10px 0px;

	/* FONT PROPERTIES */
	text-decoration: none;
	color: #000000;
	font-family: Arial, Helvetica, sans-serif;
	font-size: 14px;
	font-weight: bold;
	text-transform: uppercase;
}

a.button-gray span {
	/* Background left image */ 
	background: transparent url("../images/button_gray_left.png") no-repeat; 
	display: block;
	line-height: 33px; /* CHANGE THIS VALUE ACCORDING TO IMAGE HEIGHT */
	padding: 0px 0px 0px 15px;		
} 

a.button-gray:hover {
	background: url("../images/button_gray_right.png") bottom left no-repeat;	
}
a.button-gray:hover span{
	background: url("../images/button_gray_left.png") bottom left no-repeat;	
}

Thanks many,

Thanks for the above. I’ve looked at your code and it seems to work nicely in Opera, even in IE without the additional IE code path.

Perhaps an explanation. I was hoping to kill two birds with one stone. I would have buttons with rounded corners regardless of browser (new or old). The only reliable way of doing this until CSS3 is widely supported is via images.

Of course the above would work via the sliding window technique.

On top of that, I was hoping to be able to programatically add a button border if desired so to differentiate buttons if and when need be (say red borders, green borders, blue borders etc.). This would be very quick and efficient and void the need to re-design (graphically) the button images each time (thus speed up loading the page too, save bandwidth and so forth). The current button image I provided does have a border but it’s only 1px and light gray. Adding a border programtically causes this faint border to disappear (become hidden enough for it to take let the new foreground border take priority).

Like I say, maybe you think I’m crazy but you solved the problem it seems :slight_smile: I’m going to study your code and compare changes, so far I see you’re applying the border twice (as you say above) but also some changes in padding and what not.

You wrote the a.sample-button {} class twice, I’ve condensed into just one instance of the same class.

Anyway, great food for thought. Thanks again for taking time out on this.

I’ve already overridden the button image as I keep experimenting. The ones attached at the top should work even though that image is 66px and not 90px tall (i.e. 2x 33px buttons non-hover + hover and not 2x 45px buttons).

I’m in the process or re-designing all the button images.

I think the problem was that the lower hover button had a different corner radius than the non-hover state image. This caused problems on the left hand side corners but oddly never on the right hand side corners. You can make this out from the images attached above, though it’s more visible on a taller button (either way best to zoom in).

I’m redesigning buttons to always have the same corner radius which according to initial testing fixes the problem.

Can you attach the images you are using and then post the full html and css as there must be something we are missing :). We need to build a working copy of exactly what you have to test properly.

I’m still trying to disect it one way or another but somehow it doesn’t seem to be the image. I’ve even re-sampled the button to make sure it’s pixel perfect on both ends but to no avail.

If I cut a 15px wide section from its left side (thus with its rounded corners) and then horizontally flip that to then save it as button_gray_double_right.png then you still get the programtically applied erroneous border on the left side.

Unfortunately I don’t have an online version to show, but the above code and graphics is all I’m working on at present.

It’s either CSS or image.

Glad you got it working.:slight_smile:

If you have time it would be worth putting up a demo so we can see the bugs in action.:slight_smile:

IE was always pretty slow with hover effects and buggy anyway but I assume you haven’t turned off caching of images. In the beta version of IE8 position:relative was needed on hovered elements to make them work and indeed does speed up hovered elements in IE7 in some cases.

There is also no need for two images as you could have used one image and just shown the right side of it when needed.

Do you have a link or a working demo as these types of bugs are easier to solve when you have something to look at :). Make sure you have the height set for both images and don’t rely on line-height alone to give you the height.

Are you sure it’s not the image causing that? What happens if you disable the image?

Firstly, your button_gray_left.png image is too small. It need to be 66px high.

So change that, and then change this

a.button-gray:hover {
	background: url("button_gray_right.png") bottom left no-repeat;	
}

to

a.button-gray:hover {
	background: url("button_gray_right.png") bottom [COLOR="Red"]right[/COLOR] no-repeat;	
}

Also, there’s an error in your HTML. Change

<a class="button-gray" [COLOR="Red"]href="/test/test.php<span>[/COLOR]testing new button</span></a>

to

<a class="button-gray" [COLOR="Red"]href="/test/test.php"><span>[/COLOR]testing new button</span></a>

So, making those changes, this code worked for me:


<!DOCTYPE html>
<html lang="en">

<head>

<meta charset="utf-8">

<title>Experiment</title>
	
<style type="text/css" media="all">
a.button-gray {
	/* Sliding right image */
	background: transparent url("button_gray_right.png") no-repeat scroll top right; 
	display: block;
	float: left;
	height: 33px; /* CHANGE THIS VALUE ACCORDING TO IMAGE HEIGHT */
	padding-right: 15px; /* CHANGE THIS VALUE ACCORDING TO RIGHT IMAGE WIDTH */
	margin: 10px 0px 10px 0px;

	/* FONT PROPERTIES */
	text-decoration: none;
	color: #000000;
	font-family: Arial, Helvetica, sans-serif;
	font-size: 14px;
	font-weight: bold;
	text-transform: uppercase;
}

a.button-gray span {
	/* Background left image */ 
	background: transparent url("button_gray_left.png") no-repeat; 
	display: block;
	line-height: 33px; /* CHANGE THIS VALUE ACCORDING TO IMAGE HEIGHT */
	padding: 0px 0px 0px 15px;		
} 

a.button-gray:hover {
	background: url("button_gray_right.png") bottom right no-repeat;	
}
a.button-gray:hover span{
	background: url("button_gray_left.png") bottom left no-repeat;	
}
</style>
	
</head>

<body>
<a class="button-gray" href="/test/test.php"><span>testing new button</span></a>

</body>

</html>

I spoke too soon in as far as IE7 and IE8. Indeed, they seem to insert what seems to be part of the button image’s left side causing those fine gray areas.

I know you provided a solution but I’ve also managed to fix it via doing this:
a.button-gray3 span {background: url(“…/images/button_gray.png”) no-repeat -4px -1px;}

It has to be -4px, could be more but then the button gets shorter for no valid reason.

The above saves using the conditional statements.

I’ve tested it in all major browsers…so touch on wood…it should work fine.

Thanks for pointing me in the right direction.

I’ve fixed the bug above via re-designing the buttom images.

Just some other observations I found:

a) Works fine in all browsers except IE6, no biggie.

b) IE8 gets very slow if there’s too many buttons on screen using the sliding window technique, much slower than IE7. Strange.

c) Opera 10 will corrupt a button image if I apply a border to the <a> element. Other browsers (including IE7/IE8 surprisingly work fine). Seems to be a genuine Opera bug. Image attached, zoom in to see the white marks.

(C) is interesting since Opera and Opera only thinks the button (link) ends where the left button image ends and not after the right button image.

I’ve changed the code to a sliding window as below but unfortunately the border problem now exists, not just in Opera but all major browsers.

The right part of the border now always ends where the link text ends. A button now looks like the one attached.

So, all in all, regardless whether the sliding window technique is implemented in the left/right image (2 image) variant or the single image variant, problems with prommatically applying a border at runtime exist. Most browsers don’t reveal the problem when using the left/right (thus 2 image) variant, except for Opera. Either this is a bug in Opera 10 (latest release) or some very smart CSS changes are needed.

HTML:
<ul class=“sample-button”>
<a class=“btn-border” href=“#”>Sample button<span></span></a>

CSS:
.sample-button a {
float: left;
position:relative;
line-height: 34px;
padding: 0px 0px 0px 15px;
margin: 0px 20px 0px 20px;
background: url(…/images/menu.png) 0px 0px no-repeat;

/* FONT PROPERTIES */
text-decoration: none;
color: #191919;
font-family: Arial, Helvetica, sans-serif;
font-size: 16px;
font-weight: bold;
text-transform: capitalize;

}

.sample-button a span {
position:absolute;
top: 0;
left: 100%;
width: 15px;
height: 34px;
background:url(…/images/menu.png) -497px 0px no-repeat;
}

.sample-button a:hover {background-position:0 -34px;}
.sample-button a:hover span {background-position: -497px -34px;}

.btn-border {
border: 2px solid #B3B3B3;
-webkit-border-radius: 9px;
-moz-border-radius: 9px;
border-radius: 9px;
}

Hmmm

Thanks for your suggestion.

If I apply the above it will yield something as in the attached image. Effectively it cuts the button at where the span ends, even though there’s still a 15px right button section to include.

Hi,

I’m a little confused as to exactly what you are trying to do :slight_smile:

You have a rounded image button but then you have decided to use border radius instead. You should really just remove the border from your image and everything would be ok. (Or if you just want css3 you can do the whole thing with border radius and css gradients).

Anyway back to the problem.

The problem is that images are drawn inside the borders of an element so your button border will start inside the border that you placed on the element thus in effect giving you three borders. The border-radius has transparent areas and lets the background shine through and thus you get this clipped effect with the image and border underneath the radius (although this does depend on browser).

As I mentioned earlier you should apply the border radius to both the anchor and the span to clear up some of the noise but you also need to move the image borders out of the equation also.

Here is an example using your image but changing the image position so that the borders are not an issue.

http://www.pmob.co.uk/temp/sliding-door-button.htm

That looks much the same to me in all but IE. IE gets a whole different routine using the image only.

You’ll probably need to apply the border radius to the span as well.


a.button-gray span {
    -webkit-border-radius: 9px;
    -moz-border-radius: 9px;
    border-radius: 9px;
}


That should stop the border from being clipped.

I’ve stumbled across this side-issue which is a real eye opener it seems.

I’m applying a border programtically to buttons so I don’t need to draw the button on the image but rather can adjust it at will at runtime.

I’m applying the border via:

.btn-border {
border: 3px solid #4D4D4D;
-webkit-border-radius: 9px;
-moz-border-radius: 9px;
border-radius: 9px;
}

and

<a class=“button-gray-double btn-border” href=“\ est\ est.php” title=“sample title”><span>Sample button</span></a>

…and it works 90% great, except:

a) for some very odd reason in non-hover state the bottom left corner of such button has a thinner border. I’ve attached a sample showing this defect for further clarification.
b) for some very odd reason in hover state the top left corner of such button has a thinner border. I’ve attached a sample showing this defect for further clarification.

Is this a CSS bug (though other browsers seem to behave exactly the same) or what? I’ve examined the image and it’s corners are symmetrical.

So far no amount of margin/padding tweaking seems to remedy it. Very oddly the right top and bottom corners always have a pixel perfect border.

Thank you, works wonderfully, as proven again two brains better than one (especially if one’s tired).

I was hesitant this could be made to work (changing the background on a sliding window approach) but it does. Looks so much better than resorting to text-transform or text-decoration for the a:hover effect.

Thanks again, and for taking the time out to test it locally too.

Thanks for your response.

At the moment I’ve only got one call to a test button. It goes like this:

<a class=“button-gray” href="/test/test.php<span>testing new button</span></a>

It will hover the left part of the button image nicely, just not react to the right part of the button image (the right-most 15px in my case).

Could you post the HTML for those buttons? That would help to interpret the CSS.