Background-position just vertical - css

I have a ul-menu that exists out of images with different widths for every li. I use a sprite for the mouseovers and bg. The sprite contains all the possible images for the menu. When I hover I want the background image to slide 160px up on every li, and somehow inherit the horizontal background position (I understand that inherit inherits from a parent, not from the element you call :hover on).
How can I slide the background position up, and keep the horizontal position the same. Sample code below. I tried a lot of things, including the inherit option in the example below and I know there is a CSS3 option called background-position-y but thats not crossbrowser...
#menubar ul li.item-101{
width:183px;
background-position: 0 0;
}
#menubar ul li.item-102{
width:163px;
background-position: -183px 0;
}
#menubar ul li.item-103{
width:204px;
background-position: -346px 0;
}
#menubar ul li.item-104{
width:117px;
background-position: -550px 0;
}
#menubar ul li.item-105{
width:173px;
background-position: -667px 0;
}
#menubar ul li:hover{
background-position: inherit -160px;
}

This is currently not possible by just using CSS (In most used browsers). You have to use background-position: YOURVALUE -160px; on every hover.
Maybe we will one day live in a world where this ís possible.
Possible solutions: jQuery can do this for you, but thats probably more work then just brainless copy pasting your individual :hovers , or you can use background-position-y but thats just for a few browsers so not really an option either

I wouldn't hold your breath for background-position-y as it isn't even a part of the CSS3 spec. (The issue is here http://www.w3.org/Style/CSS/Tracker/issues/9). Certain browsers like Chrome have gone ahead and implemented it anyways, but at least Firefox and Opera have yet to follow, if they even will.
Unless you want to resort to javascript, there isn't really any way of doing this in CSS as things currently stand.

Related

Sprite image moves down when hovering over

I am using a sprite to change the color of an image on its hover status, though when I hover over the image it moves down slightly and changes color. I have created a JSFiddle to replicate the problem.
I am probably using the sprite incorrectly? I'm unsure as it is my first time playing with them.
.ratings ul li {
width:18px;
height:18px;
background:url(star.png) 145px 102px;
}
.ratings ul li:hover{
width:18px;
height:18px;
background:url(star.png) 145px 86px;
}
I am using this image:
Can anyone can point out my mistakes?
Cause
The sprite is not configured correctly. At least one of the background-position values should be either zero or negative in your example.
The technique of CSS sprites depends on negative background-position values to change the area within the image used as the element's background. In contrast, positive (i.e. greater than zero) background-position values actually change the position of the background image in the element.
Solution
background:url(star.png) 0 0;
background:url(star.png) 0 -18px;
See jsFiddle demo
Note about the image
Also note that your current sprite is 34px high, while it seems each star is only 16px high. This means there's a 2px gap between the two stars, so the second background-position is -18px and not -16px.
.ratings ul li {
width:16px; /* redefine your image offset */
height:16px;
background:url(http://i.stack.imgur.com/S5T0M.png) no-repeat;
}
.ratings ul li:hover {
background-position: 0 -18px;
}
You do not need to define width and height which you had already on :hover state. You should find informative guidance about css sprires on this site
First: you should use a 16px "box" (width/height) for your star not 18 because your star has a width of 16px.
Then change your offset correctly, you will have less problem.

CSS Sprites limitation

CSS Sprite is useful, helps speed up loading time and performance. But I find they have certain limitations. I like to know whether there are ways around this or whether it is inherent and that they are limited.
For example: If I wanted an arrow icon on my anchor link to be on the right hand side:
a
display:block;
padding:0 15px 0 0;
background:transparent ("/images/arrow.gif") no-repeat scroll right top;
}
a:hover {
background-position:-10px top;
}
This wouldn't actually work because I positioned the arrow icon to be on the right hand side of my anchor tag. But then how would I shift the image -10px when I still want it positioned on the right?
You can use the :after pseudo element to create an additional element after the link text but still inside the anchor tag by CSS, set it to equal size of each picture in your sprite, and then be able to use background position no problem.
Here is an example of doing this with a 4 images sprite, each of the images are sized 18px * 18px (I just found the pic online on google images, so, not even sure how long it'll be available):
To see the example live version: http://jsfiddle.net/Meligy/CLLau/
The important bits of the code:
a:after {
content: " ";
display:inline-block;
width:18px;
height:18px;
overflow:hidden;
vertical-align:middle;
margin-left:0.5em;
background: url(http://www.waterbobble.com/skin/frontend/bobble/default/images/round_arrow_sprite.gif);
background-position: 0 0;
}
a:hover:after {
background-position: 18px 18px;
}
Update:
This is supported in all current browsers, in IE, it's supported starting from IE8.
For a hack to support for IE 6, 7, check this other Stackoverflow reply:
:after and :before css pseudo elements hack for IE 7

Image Rollover, no Javascript, no Link, pure CSS, code validate and Broswer compatible

Image Rollover, no JavaScript, no Link, pure CSS, code validate and Browser compatible.
Hello all, I have been working 24hours strait to come up with this fairly easy solution. I want to know if everything is all right and if there are ways to improve. It's quite elegant, here we go:
I have only one image "Logo" but it will show as 2 different logo each with a rollover effect.
I use a sprite (only 1 image containing my 4 logos) and I just change it's position.
Here I insert my image in a div with
<div id="logo-rollover-1" class="logo-rollover">
<img title="whatever" alt="whatever" src="path-to-your-image">
</div>
Then I insert in another div the same image but with a different id
<div id="logo-rollover-2" class="logo-rollover">
<img title="whatever" alt="whatever" src="path-to-your-image">
</div>
Now my CSS:
.logo-rollover {
background: #ffd42a url('path-to-your-image');
width: 230px;
float: left;
height: 130px;
overflow: hidden;
position: relative;
}
.logo-rollover img { width: 460px; height: 260px; }
.logo-rollover :hover { opacity: 0; filter:alpha(opacity=0); }
#logo-rollover-1 { background-position: 0px -130px; }
#logo-rollover-2 { background-position: -230px -130px; }
#logo-rollover-2 img { right: 230px; position: relative; display: block; }
Explanations: when someone hover an image it becomes transparent and show the background witch is the same image but with a different position. opacity: 0 for Firefox, Google and filter:alpha(opacity=0) for Explorer. position: relative on the .logo-rollover class is for compatibility of hidden overflow with IE6 & IE7. display:block; is added to the id img for the Opera browser.
No Hack: When there is no link, there is no need for href="#" or "javascript:void(0)"
Advantages: instead of requesting 4 (or more) images, there is only 1 image (the total size of 1 image sprite is smaller then the total size of 4). the rollover is instant as the image is already downloaded. No hack, no false link, code validate. Add a title to the image. The only browser not rolling over is IE6 but the site is not broken, the logo show correctly. There is a hack for activating hover for IE6 but I didn't bother as IE6 is dead.
Tip: use the same path for your image everywhere.
I mean the "path-to-your-image" needs to be the same for all call. Because of browser caching.
Is this the best elegant way? Can this code be improve? I hope it will help someone because it was a real pain to develop thank to others user here I found some tricks here and there and came up with this.
Comment appreciated.
Why not completely removing inner <img> and create logo using CSS background?
<a id="logo">Logo</a>
#logo { width:100px; height:60px; background:url(path/to/logo.png) 0 0;
overflow:hidden; text-indent:-1000px; display:block; }
#logo:hover { background-position:0 -60px; }
Explanation:
<a> is the only element that supports :hover pseudo selector on IE6. If you want native solution for hover logo you must use this tag. Some people sometimes wrap other elements ex: <a><div></div></a> to give div hover property by accessing it from CSS using a:hover div { }
overflow:hidden; and text-indent:-1000px; hide text from inside the div. It is a good practise to leave text inside for accessibility reasons.
background sets the background color of your div, initialy alligned to 0, 0
background-position does the actual trick and shifts the image - it is moving it within the 'viewport' div making different part of the image visible.
nice description! I see one small improvement: put the background und no-repeat definition in your .logo-rollover class to have less css code (you have to write it only once instead of twice)

Offset a background image from the right using CSS

Is there a way to position a background image a certain number of pixels from the right of its element?
For example, to position something a certain number of pixels (say, 10) from the left, this is how I'd do it:
#myElement {
background-position: 10px 0;
}
I found this CSS3 feature helpful:
/* to position the element 10px from the right */
background-position: right 10px top;
As far as I know this is not supported in IE8. In latest Chrome/Firefox it works fine.
See Can I use for details on the supported browsers.
Used source: http://tanalin.com/en/blog/2011/09/css3-background-position/
Update:
This feature is now supported in all major browsers, including mobile browsers.
!! Outdated answer, since CSS3 brought this feature
Is there a way to position a background image a certain number of pixels from the right of its element?
Nope.
Popular workarounds include
setting a margin-right on the element instead
adding transparent pixels to the image itself and positioning it top right
or calculating the position using jQuery after the element's width is known.
The easiest solution is to use percentages. This isn't exactly the answer you were looking for since you asked for pixel-precision, but if you just need something to have a little padding between the right edge and the image, giving something a position of 99% usually works well enough.
Code:
/* aligns image to the vertical center and horizontal right of its container with a small amount of padding between the right edge */
div.middleleft {
background: url("/images/source.jpg") 99% center no-repeat;
}
Outdated answer: It is now implemented in major browsers, see the
other answers to this question.
CSS3 has modified the specification of background-position so that it will work with different origin point. Unfortunately, I can't find any evidence that it is implemented yet in any major browsers.
http://www.w3.org/TR/css3-background/#the-background-position
See example 12.
background-position: right 3em bottom 10px;
As proposed here, this is a pretty cross browser solution that works perfectly:
background: url('/img.png') no-repeat right center;
border-right: 10px solid transparent;
I used it since the CSS3 feature of specifying offsets proposed in the answer marked as solving the question is not supported in browsers so well yet. E.g.
The most appropriate answer is the new four-value syntax for background-position, but until all browsers support it your best approach is a combination of earlier responses in the following order:
background: url(image.png) no-repeat 97% center; /* default, Android, Sf < 6 */
background-position: -webkit-calc(100% - 10px) center; /* Sf 6 */
background-position: right 10px center; /* Cr 25+, FF 13+, IE 9+, Op 10.5+ */
A simple but dirty trick is to simply add the offset you want to the image you are using as background. it's not maintainable, but it gets the job done.
This will work on most modern browsers...apart from IE (browser support). Even though that page lists >= IE9 as supported, my tests didn't agree with that.
You can use the calc() css3 property like so;
.class_name {
background-position: calc(100% - 10px) 50%;
}
For me this is the cleanest and most logical way to achieve a margin to the right. I also use a fallback of using border-right: 10px solid transparent; for IE.
Ok If I understand what your asking you would do this;
You have your DIV container called #main-container and .my-element that is within it. Use this to get you started;
#main-container {
position:relative;
}
/*To make the element absolute - floats above all else within the parent container do this.*/
.my-element {
position:absolute;
top:0;
right:10px;
}
/*To make the element apart of elements, something tangible that affects the position of other elements on the same level within the parent then do this;*/
.my-element {
float:right;
margin-right:10px;
}
By the way, it better practice to use classes if you referencing a lower level element within a page (I assume you are hence my name change above.
background-position: calc(100% - 8px);
The CSS3 specification allowing different origins for background-position is now supported in Firefox 14 but still not in Chrome 21 (apparently IE9 partly supports them, but I've not tested it myself)
In addition to the Chrome issue that #MattyF referenced there's a more succinct summary here:
http://code.google.com/p/chromium/issues/detail?id=95085
If you have proportioned elements, you could use:
.valid {
background-position: 98% center;
}
.half .valid {
background-position: 96% center;
}
In this example, .valid would be the class with the picture and .half would be a row with half the size of the standard one.
Dirty, but works as a charm and it's reasonably manageable.
If you would like to use this for adding arrows/other icons to a button for example then you could use css pseudo-elements?
If it's really a background-image for the whole button, I tend to incorporate the spacing into the image, and just use
background-position: right 0;
But if I have to add for example a designed arrow to a button, I tend to have this html:
Read more
And tend to do the following with CSS:
.read-more{
position: relative;
padding: 6px 15px 6px 35px;//to create space on the right
font-size: 13px;
font-family: Arial;
}
.read-more:after{
content: '';
display: block;
width: 10px;
height: 15px;
background-image: url('../images/btn-white-arrow-right.png');
position: absolute;
right: 12px;
top: 10px;
}
By using the :after selector, I add a element using CSS just to contain this small icon. You could do the same by just adding a span or <i> element inside the a-element. But I think this is a cleaner way of adding icons to buttons and it is cross-browser supported.
you can check out the fiddle here:
http://codepen.io/anon/pen/PNzYzZ
use center right as the position then add a transparent border to offset it?
If you have a fixed width element and know the width of your background image, you can simply set the background-position to : the element's width - the image's width - the gap you want on the right.
For example : with a 100px-wide element and a 300px-wide image, to get a gap of 10px on the right, you set it to 100-300-10=-210px :
#myElement {
background:url(my_image.jpg) no-repeat -210px top;
width:100px;
}
And you get the rightmost 80 pixels of your image on the left of your element, and a gap of 20px on the right.
I know it can sound stupid but sometimes it saves the time... I use that much in a vertical manner (gap at bottom) for navigation links with text below image.
Not sure it applies to your case though.
my problem was I needed the background image to stay the same distance from the right border when the window is resized i.e. for tablet / mobile etc
My fix is to use a percenatge like so:
background-position: 98% 6px;
and it sticks in place.
yes! well to position a background image as though 0px from the right-hand side of the browser instead of the left - i use:
background-position: 100% 0px;

Having two backgrounds for an active menu item?

Hi I have a dynamic menu where the ul li items change in width depending on the text set in the CMS (Joomla). They want the menu item, on mouse over, to both have 1. a repeated background image and 2. an image placed at the top (http://screencast.com/t/Zjk4YTJmNGQ).
Now, I'm great with doing the repeated background image on a mouse over and that would be great, but I am not sure how to get both of these images in one css declaration.
Any help would be greatly appreciated, as I haven't learned this technique yet :(
If it's a menu, the relevant markup should probably resemble <li>…</li> — that's two elements, which is plenty for two background images.
Firefox 3 and Webkit browsers support multiple backgrounds.
background: url(image1.png), url(image2.png);
background-repeat: repeat-x, no-repeat;
background-position: top right, 90% 5px;
You could also try to get this working by using the :after pseudoclass.
.menu li {
position: absolute;
background: url(image1.png);
}
.menu li:after {
content: '<img src="image2.png">';
}
You can find a nice example here:
http://s3.amazonaws.com/nettuts/690_textGradients/index.html

Resources