Centering sprites with SASS/Compass - css

I'm having an issue with horizontally centering sprites using Compass Sprites.
I have a bunch of sprites that are of different sizes for icons and I want them to be centered on the container they're in so they're a left hand side icon for instance.
If I do this:
$sprite-position: 50%;
#import "sprite/*.png";
then the images are centered on the generated sprite.png but the CSS is actually something like:
background-position: -9px -223px;
rather than the expected:
background-position: 50% -223px;
What's the point of centering it on the sprite if its going to have the location specifically declared like that? Right now I'm hardcoding it as 50% and the Y-axis which sucks because when I add a new sprite then I have to change them all which completely defeats the purpose.
Am I doing this wrong in Compass, CSS or does it just not work as its supposed to?
The only way I can see this being done is by having it specify the dimensions then contain the icon and center it within there. The 50% left value is there though so you don't need to do this... right?
Just a note... it sucks that Compass doesn't support JPEG sprites as well -.- Got about 6 promotion images on the front page and it would be nice to have them sprited up where you can just replace the images in the folder and its sorted!
Thanks, Dom

Just stubmled upon your question. I get your point and had the same problem. I also tried to find a general solution. But it doesn't seem to be possible atm.
For me the position offset option works, but it's not perfect cause you have to apply it to each sprite:
#import "socialmedia/*.png";
a.twitter {
#include socialmedia-sprite("twitter");
#include socialmedia-sprite-position("twitter", 50%);
}
a.facebook {
#include socialmedia-sprite("facebook");
#include socialmedia-sprite-position("facebook", 50%);
}
This is overwriting the horizontal value but keeps the vertical value.
As I said, not perfect but works if you don't need to adjust a huge amount of spites. You could write a mixin though. But still... would be great if Compass itself would provide such an option.

Just to check if I'm getting you right: You created a sprite for all the icons you want to center. Within the sprite all icons are centered, so you can use x:50% and the according y-value, right?
Since compass set's the wrong background-position you could use other method. At least, thats what I did. If you don't need to support IE6/7 you could use compasses inline-data-feature: http://compass-style.org/reference/compass/helpers/inline-data/
This way you reduce the HTTP-Requests which is the main purpose of a sprite but at the same time you get all the benefits a normal image would give you.
If you build a smart mixin this is very, very handy. And even smarter than sprites.

I had the same issue. I wanted to center a horizontal sprite vertically (e.g. creating icon using :after on an inline element).
Unfortunately Compass converted my 50% to 50px so I created these functions:
#function _sprite-position-nth($map, $sprite, $n) {
$positions: sprite-position($map, $sprite);
#return nth($positions, $n);
}
#function sprite-position-x($map, $sprite) {
#return _sprite-position-nth($map, $sprite, 1);
}
#function sprite-position-y($map, $sprite) {
#return _sprite-position-nth($map, $sprite, 2);
}
Example usage:
$icons: sprite-map("icons/*.png", $layout: horizontal);
a.arrow:after {
background: $icons sprite-position-x($icons, arrow-right) 50%;
//...
}
I hope I could help.

Related

Background Texture Not Showing In Twitter Bootstrap

I am designing a website using the Flat UI Twitter Bootstrap mod. While trying to set a background texture, I have found that it is not visible. Here is my CSS:
body
{
background-color: transparent;
background-image: url(img/texture.png);
}
Can someone help me to get my background texture to work?
Without more details, the first thing I would check is the path to the texture.png image. Since its a background image, the url is relative to your stylesheet.
So say your your CSS is in the website/css folder and the texture is in the website/images folder, your CSS would be more like:
body
{
background-color: transparent;
background-image: url(../images/img/texture.png);
}
If you know how to use the web inspector or something similar on most browsers, it will help to pinpoint the source of the problem.
Good luck!

PHP: Add hover effect to image

I am working on a PHP file. I'm working on the menu bar, the menu bar contains all the image buttons, if someone hovers on one of the buttons I want them to change image(color). Could someone help me out with this?
$globalsettings = array(
'src' => $sImageURL.'global1.png',
'alt' => $clang->gT("Global participant settings"),
'title' => $clang->gT("Global participant settings"),
'style' => 'margin-left:5px',
'style' => 'margin-right:1px'
);
You can create hover effects using CSS (cascading stylesheets). Your CSS must be in an external stylesheet or embedded style element.
I'm using BUTTON that will style all <button> elements, but you can replace it with whatever element you want to style, such as an <img> with IMG (lowercase or uppercase).
BUTTON {
background: url(my_bg.png);
}
BUTTON:hover {
background: url(my_hover_bg.png);
}
If you don't know how to use stylesheets, just insert embedded styling into the <head> of your HTML document.
<style type="text/css">
/* Place CSS here */
</style>
If you want you can take it a step further and use CSS sprites (like old videos games used to do it). CSS sprites are a collection of images in one single image, and you simply change the position of the location of the background, and it creates the effect. You can achieve this like this:
#myelement {
background: url(my_bg.png) -0 -0;
}
#myelement:hover {
background: url(my_bg.png) -0 -100px;
}
There are also old school ways of hover effects but they're like Frontpage-era, so I don't recommend using them. CSS hover effects is the standard of today.
You're trying to solve 2 problems in one step. You need to get the images to display and then swap between them on hover.
You can't dynamically edit a button in JS (ok, you could with canvases and html 5 but it's non-trivial). So, you need to use CSS (or possibly JS) to to swap between 2 images.
Where those images come from is up to you - you can either pre-generate them which is a little work up front but easy to implement and no PHP required. This would be the preferred option if there's only one or two variations in colour.
Alternatively, you can have a PHP script which generates the images on-the-fly (and ideally caches them to save recomputing them later). This allows for infinite variation but requires more overhead on the server. This approach is commonly used to generate thumbnails as the source image isn't known in advance
Note that PHP has no control over when each image is displayed - it simply provides images to your CSS/JS in exactly the same way as a webserver would serve a static image.
If you want to edit an image in PHP, you need to look at the GD+ library
You can use css to do this quite easily by using the content: selector.
for example, your markup might look like this:
<div class="link" id="link1">
<img />
</div>
and the css would be something like:
#link1 a img{
content:url("http://www.maxxpotential.com/stephen2/wp-content/uploads/2013/03/Images-from-Deep-in-the-Woods-by-Astrid-Yskout-4.jpg");
}
#link1:hover a img{
content:url("http://blogs.mathworks.com/pick/files/zebrainpastelfield.png");
}
by using the selectors you assign in your script, you should find it pretty easy to amend this to suit your needs.
here is a working fiddle demonstrating this http://jsfiddle.net/pWYtu/1
You can use sprite image and onhover change position.
also you will get benefit of performance.

Scaling a sprite with css/sass

I'm using sass image sprites and span tags to create images. I'm now having a problem resizing these images. It appears that using background-size somehow applies to the whole sprite atlas and not just the chosen sprite.
How can I resize the sprite images?
Example code, I setup sprites like this:
#import "compass/utilities/sprites/sprite-img";
#import "icons/*.png";
#include all-icons-sprites;
And then I use them with a class tag, or I create new classes which directly mention them in the scss file:
.more span.right-icon {
#include icons-sprite('item-more');
}
There's no way around it - the image is considered as a whole and the sprites are just logic inner guides.
You could, however, recalculate the image-position according to any changes you apply to the background-size respectively.

Site loads Sprite Image twice

I have been trying to speed up my website, and in doing so I combined a number of my images into a sprite file. Everything works great now, however, when I run the site, either locally or on the test site it loads the sprite file twice, and I can't for the life of me figure out why. I am using masterpages with asp.net, and I only have one css file, not including the css files that some of my telerik controls use, and I have not tampered with any of the telerik css files or sprites. You can venture to our test site at: http://www.myheadpiece.com/test and take a look. The name of the sprite file is ms1.png. I can also provide other code/answers where necessary, I am just not sure what/where to look. If anyone has any ideas please let me know. Thanks.
Check the case of the paths to the sprite, you have
http://www.myheadpiece.com/test/Images/Structure/ms1.png
and
http://www.myheadpiece.com/test/images/Structure/ms1.png
One is with a capital "I" the other one with a small "i". So in you CSS you should refer to the sprite either with "Images" or with "images".
Your css should look like this:
.Sprite { background-image: url("../Images/Structure/ms1.png"); background-color: transparent; background-repeat: no-repeat; }
.HeaderLogo { background-position: 0 -768px; ... other styles ... }
.CartButton { background-position: -818px -754px; ... other styles ...}
And both HeaderLogo and CartButton should have second css class assigned ('Sprite') so you load an image only once for Sprite class and all the elements that are going to use it change it position only.

jquery cycle IE7 transparent png problem

I'm having trouble getting jquery cycle to work when I have transparent png files in IE7
It's fine in Firefox and Chrome but in IE (version 7) I get a black colour where
the png transparency is during the fade.
Can this be made to work right?
unfortunately, though IE7 supports transparent PNG's, only one filter can be applied to an element at a time.
What is happening in your application is that IE7 is applying the alpha filter to your PNG, and is then asked by jQuery to apply another alpha filter for the fade. This has visible results like you said.
The way to get around this is to nest your png inside a container and then fade the container. Sort of like this:
<div id="fadeMe">
<img src="transparent.png" alt="" />
</div>
Another way to get around this is this simple jQuery plugin that i used because i couldn't change the structure. I would give attribution but I honestly cant remember where i found it.
/* IE PNG fix multiple filters */
(function ($) {
if (!$) return;
$.fn.extend({
fixPNG: function(sizingMethod, forceBG) {
if (!($.browser.msie)) return this;
var emptyimg = "empty.gif"; //Path to empty 1x1px GIF goes here
sizingMethod = sizingMethod || "scale"; //sizingMethod, defaults to scale (matches image dimensions)
this.each(function() {
var isImg = (forceBG) ? false : jQuery.nodeName(this, "img"),
imgname = (isImg) ? this.src : this.currentStyle.backgroundImage,
src = (isImg) ? imgname : imgname.substring(5,imgname.length-2);
this.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + src + "', sizingMethod='" + sizingMethod + "')";
if (isImg) this.src = emptyimg;
else this.style.backgroundImage = "url(" + emptyimg + ")";
});
return this;
}
});
})(jQuery);
NOTE Originally the plugin was written to fix PNG transparency in IE6 but I modified it to work with your problem in IE6+.
Sidenote: I cant remember off the top of my head but i think that IE8 may have the same problem. Correct me if i'm wrong :)
This has been driving me mad for the last few days! Finally found a decent solution that works pretty well.
Add this to your CSS:
img {
background: transparent;
-ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#00FFFFFF,endColorstr=#00FFFFFF)"; /* IE8 */
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#00FFFFFF,endColorstr=#00FFFFFF); /* IE6 & 7 */
zoom: 1;
}
Credit: Dan Tello
Try adding
cleartype: true,
cleartypeNoBg: true
to your cycle jquery arugments.
It should be fine now :)
Coupled with the "wrap the image in a div / fade the div" tactic previously mentioned, using this line of CSS will fix the IE issue:
#div img {
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader (src='../images/bubble_intro_ph1.png');
}
For me it worked to just include the filter property with blank value in jQuery's .animate()function
Maybe this will work for you, too.
$("#btn").animate({opacity:1,"margin-left":"-25px", filter:''});
Internet Explorer 7 has some issues
with fading transparent PNGs. If
you've gotten to the this page because
you're seeing a black border where the
transparent edges in your PNG are,
then here are some tips for fixing the
problem:
Do not fade the element directly, but fade a parent container
holding the PNG. This may mean you
need to add a wrapper element to your
code.
Give the parent element a background color.
Lastly, if you're still having problems, try giving your parent element
the old zoom: 1 trick. Give the
parent element a style declaration of
zoom: 1 (either via CSS or an inline
style.) This will force IE to give the
element hasLayout—which tends to fix
all sorts of weird display issues in
IE.
Source: Fading a 24-bit transparent PNG in IE7+
Unfortunately, this means that it’s impossible to have transparent PNGs fading in over a transparent background, since you have to apply a background color to the parent element in order for the transition to go smoothly, i.e. without the black pixels. background: transparent won’t work (since transparent isn’t really a color). :(
I'm loading some png's dynamically into the DOM... this worked for me: http://www.twinhelix.com/css/iepngfix/
I had this problem with Drupal Views Slideshow using the Fade transition on transparent PNGs.
I stumbled across the following quasi-solution totally by chance. I don't know why it works, but the drawback is it essentially removes the cross-fade envelope in IE (it doesn't appear to visibly affect FF or Safari):
Views Slideshow will print something like the following as part of its output:
<div class="views-field-field-photo-fid">
<span class="field-content"><img height="433" width="834" src="http://devel.acupuncture2.polishyourimage.com/sites/acupuncture2.polishyourimage.com/files/pain_splash.png?1292552784" alt="" class="imagefield imagefield-field_photo"></span>
</div>
I hid views-field-field-photo-fid:
.views-field-field-photo-fid { width: 0px; }
Not perfect but maybe good enough till I find a better solution. You can take a look at the development site: http://acupuncture2.polishyourimage.com/
I'm also using Weezy's solution but doesn't play nice with IE7. The effects is even worse.
When assigning jQuery opacity-property to animate-function instead of Black-Border-Bug it generates a Black&White-Border-Bug :-P So I did the following for IE8;
In the head IE8 conditional comment with the HTC behavior on class .fixpng especially for htc.
<!--[if IE 8]>
<style type="text/css">
.fixpng {
/* this fixes transparency in IE8 ONLY! */
behavior: url(css/IE8pngfix.htc);
}
</style>
<![endif]-->
changed HTC-file to IE8pngfix.htc. Changed line 75 in the .htc to
!/MSIE
(8)/.test(navigator.userAgent
It's actually double-filtered, first IE conditional and then in htc, but what the hell!
I found that because htc could interfere with jQuery. Example;
[div id="tooltip" class="fixpng"]
Had to change $(div#tooltip).css({opacity: 0}) to display:none in CSS and set display: 'block' in hover-event.
So if anybody has found a working solution for IE7 I would be really happy. All the workarounds /hacks above don't work for me. About IE6 I don't care any second.
Ok so I took Darko Z suggestion about the div. In the end this is what I had to do to be able to get jQuery Cycler fadeing FX to work on IE with drupal 7. Instead of placing an tag I used divs and applied the.png to the background of the image along with
So I changed this:
<div class="fademe">
<a href="http://mysite/node/1">
<img class="firstTAB-phase2" src="http://mysite/IMG/bio_640x330.png" height="330px" width="640px" />
</a>
to this:
<a href="http://mysite/node/1">
<div class="fademe" id="TAB1"></div>
</a>
then in the css I did:
.fademe{ width:640px; height:330px;}
#TAB1{ background: #999 url(http://mysite/IMG/bio_640x330.png) no-repeat;}
and it works for now =D.
Hope it helps,
Defigo
I've got the ultimate solution for this damn IE-PNG-BlackBorderProblem when using fading or other jQuery effects. It is working in every IE > 6 even in IE8!:
Download jQuery's pngFix at: http://jquery.andreaseberhard.de/pngFix/
Modify this script by searching:
if (jQuery.browser.msie && (ie55 || ie6)) {
and replace it with:
if (jQuery.browser.msie) {
create a blank.gif (1x1 transparent gif)
put a:
.pngFix( {blankgif: '< relative location to the blank.gif >'} );
at the end of the line where you perform jQuery effects eg.
$('#LOGO').animate( {'top': '40%', 'opacity': '1.0'}, 2500 ).pngFix( {blankgif: './library/img/blank.gif'} );
make sure that all pictures have been loaded before you use jQuery effects within your document ready function by using the .load event on the window DOM-Element:
$(document).ready( function() {
$(window).load( function() {
$('#LOGO').animate( {'top': '40%', 'opacity': '1.0'}, 2500).pngFix( {blankgif: './library/img/blank.gif'} );
});
});
Load page in IE8 and feel happy ;-)
You can see it in action on http://www.claudworks.net
No ugly dark borders anymore around some animated PNGs in IE.
I found the fix to this bug, simply add the following to the wrapping div and to the img and other elements (e.g. h1,h2,p)
#div, #div img {
background:none !important;
filter:none !important;
}
This will fix it
This drove me mad for a couple of days and I finally stumbled across Unit's PNG fix. http://labs.unitinteractive.com/unitpngfix.php - works with Cycle and stopped me from switching to a JPEG solution!
It needs a bit of tinkering to target specific PNGs in the cycle div, but she works!
Hoping to help somebody else who encounters this problem:
I had transparent .png backgrounds (tiled) on a few divs on my page and when I activated the jquery cycle plugin, those transparent areas became screwy. They lost some of their transparency.
My solution was to simply make the tiles much bigger, so there really is no tiling at all. There is a small trade off for file size, but it fixed the problem.
I rewrited the fadeIn and fadeOut methods. It seems I don't get the black color on PNG image. No parent div is needed. Still you use as jQuery.
http://www.pagecolumn.com/javascript/fade.htm
If you can afford to sacrifice a bit of image quality, you can save the images as PNG-8 instead of PNG-24, then apply the fix mentioned by Prosini, i.e.
cleartype: true, cleartypeNoBg: true
and that should work. With PNG-24, I was still getting a bit of black border during the transitions.
While not specifically limited to the cycle plugin, this may help others. I came across this stream in my attempt to find a solution to .animate() transparent/translucent png files. I had the issue of a black border occurring in both IE7 and IE8. The images appear fine until I attempted to use JQuery to animate the opacity...
$('#my-png-img').stop().animate({opacity:0.0},3000);
I went thru a number of the solutions and unfortunately, none of them were ideal. While this stream is a bit dated, it may help someone else still searching to piece together a solution. I ended up using the Twin Helix solution (http://www.twinhelix.com/css/iepngfix/) with a bit of a tweak. I'm not a huge fan of .htc files but that's beside the point. I edited the iepngfix.htc file (~line 75) to trap for IE7 and IE8. I changed...
!/MSIE (5\.5|6)/.test(navigator.userAgent) ||
to
!/MSIE (5\.5|6|7|8)/.test(navigator.userAgent) ||
From there I followed the general instructions (see demo) including adding this bit to my CSS
/* IE PNG Fix */
img, div, a, input {
behavior: url(/_css/iepngfix.htc)
}
In addition and as others have mentioned, I had to nest my image in a container...
<div id="img-container"><img src="/images/my_semi_trans_png24.png" /></div>
Then I applied .animate() effect to the containing div. A bit constraining however, this was the only way I was able to get fading to work consistently. In one case, I even found that the transparency issue affected animating the opacity on a transparent .gif file. Oh and, whether I used .fadeIn()/.fadeOut rather than .animate() made no difference.
This is all pretty hectic stuff you're being asked to do. All very coding codingsky.
Here's my suggestion. IE will not allow a png background above a colored background to live in peace, like so...
<div style="background:url('something.png') no-repeat 0 0 scroll; position:absolute; z-index:2;"> </div>
<div style="background-color:#fa0237; position:absolute; z-index:1;"> </div>
Notice the first div is z-index 2(on top of 2nd div).
This can be simplified by putting your bgColor in the background css in the 1st Div and doing away with the second div. This solves the problem of the black areas. I had this problem myself.
The only way I can see you having a problem where you can't use this method is where you have the need to overlay two png background images over one another and fade simultaneously. Don't do that. You'll need to animate each one after one another.
Define a solid background color to your image:
.container img {
background-color: white;
}
Define the background-image css property of your image to its src attribute:
$('.container img').each(function() {
$(this).css('background-image', $(this).attr('src'));
});
Advantage: you don't need to change your markup
Disadvantage: sometimes applying a solid background color is not an acceptable solution. It normally is for me.
To solve this issue simply add:
"filter" : ""
to your .css() or .animate() and it'll fix a number of IE related issues.
The most reliable solution is to not use pngs in fading style animations in <IE9 browsers.
I tried nearly every "fix" and variation of a fix available that I could find for this issue and had no success. The solution I used was to export pngs that were going to have fading-style animations applied to them (ie, fadeIn/fadeOut) to gifs and do a conditional replacement for <IE9. Although the gifs don't look as good as pngs in a modern browser, they look a hell of a lot better than the way IE8 and earlier render pngs, and this method works reliably. You still get to display nice pngs for capable browsers and when the fix is applied nothing else gets broken; most of the png hacks are known to break other css properties. Your code might look something like this:
$(document).ready(function ()
{
if ($.browser.msie && parseInt($.browser.version, 10) < 9)
{
$(".myClass, .myOtherClass").each(function (val)
{
var backgroundValue = val.css("background-image");
backgroundValue.replace('.png', '.gif');
$(this).css("background-image", backgroundValue);
//you could just as easily do this with 'img' tags
});
}
}
Weezy's solution worked for me!
I tweaked the .htc file further, and changed this line:
var bgPNG = bgSrc.match(/url[("']+(.*\.png[^\)"']*)[\)"']/i);
to:
var bgPNG = bgSrc.match(/url[("']+(.*\.fixme.png[^\)"']*)[\)"']/i);
By doing this, the .htc script will ignore all .png files unless they end with .fixme.png (for example "transparant.fixme.png"). I intended this to speed up the script a little and ensure that only problem .pngs are fixed (the ones you must have transparant).
I use other .pngs which are not transparant, and therefore don't need this script to run against them.
The best fix is unitpngfix.
Include it in your script and be sure to provide the path to your 1px by 1px transparent gif. Voila!

Resources