When I have an <a> tag set to a specific image background like this:
HTML:
Click Here
CSS:
a {
background: transparent url(button.png);
}
and I want the background to change whenever a user hovers over the spot, like this:
CSS:
a {
background: transparent url(button_HOVER.png);
}
The hover background image flickers (takes about 1-2 seconds until it fully loads) when a user hovers over the link.
I could save the file as GIF and minify its size and loading time, but that would harm my specific image tremendously (it's big and highly graphical).
That's why I was looking for a better solution, such as perhaps counting on the browsers ability to cache images. Hence would I apply a style to a button like this:
CSS:
a {
background: transparent url(button_HOVER.png);
background: transparent url(button.png);
}
So that the image button_HOVER is first cached. It has seemingly affected the "flickering", but not completely. I thought of maybe creating a hidden tag with the HOVER image, so that maybe the result would be different.
Do you think there's a better way to solve it? (I emphasize I want to keep the file as PNG, it weighs 6-7k). Is my method efficient?
Your solution would be to put both images (hover and active) in the same image file. Positioned on top of each other. Also known as Image Sprites. The browser will load the entire image file. On hover, you just change the background position.
Assuming the active image is at the top, and the hover image is positioned directly below that..your css code would be something like:
a.link {
width:70px;
height:24px;
background: url(image.png) top no-repeat;
}
a.link:hover {
background-position: bottom;
}
Notice background-position. Here I use top and bottom. You can specific exactly in pixels too. The entire image in this example would have a width of 70pixels and height of 48pixels. Some sites put all their small icons into one image. Loads altogether, save on requests too. :)
No need for preload scripts in this case.
The basic options available are to use an html element that's hidden from the viewer, or use javascript.
The html approach is probably the simplest, though:
<div id="preloadedImageContainer">
<img src="img/to/preload_1.png" />
<img src="img/to/preload_2.png" />
</div>
with the css:
#preloadedImageContainer {position: absolute; top: -1000px; left: -1000px; }
or, with javascript:
(function($) {
var cache = [];
// Arguments are image paths relative to the current page.
$.preLoadImages = function() {
var args_len = arguments.length;
for (var i = args_len; i--;) {
var cacheImage = document.createElement('img');
cacheImage.src = arguments[i];
cache.push(cacheImage);
}
}
})(jQuery)
the jQuery approach was lifted in its entirety from this page: http://engineeredweb.com/blog/09/12/preloading-images-jquery-and-javascript.
Though the best approach would probably be, as Lyon suggests, css image sprites.
You should search about this topic "preload images" You will find ways to preload images using css and javascript.
I believe that if you put a hidden image with source equal the src of png images you will use in the css files, this will make the images loaded when the page loads, and CSS work will be just switch preloaded images.
Related
I have a bunch of server-side generated images with the following HTML tags:
<img width="75" height="75" src="/MyController/MyAction/_ac=4d04359f-0d66-45d3-881c-b198e95a8215" data-idx="1">
The problem is that the images show the default "blank document" (or "missing image") icon and a border while they are loading. It looks like this:
After images are loaded, the icon of course disappears, and the broder gets set to the one I specified in my CSS.
I don't want to create fancy preloaders and what not, but I would like to make this "blank document" icon and the default border to go away. Although the user sees it for a less than a second, still that's not good because it creates an impression that something is wrong with my images.
How do I make that icon not to show up while images are being loaded?
One idea was to set background for images, but I cannot do that because images have transparent areas, and then some parts of the background will be visible after the image has been loaded.
UPDATE WITH A WORKAROUND
I noticed that if I do not specify width and height, the default missing icon and border is not shown while the image is loading. As a workaround I did the following:
<div class="imgholder"><img src="/MyController/MyAction/_ac=4d04359f-0d66-45d3-881c-b198e95a8215" data-idx="1"></div>
and style the image holder as follows:
.imgholder {
border: 2px solid #ddd;
margin: 2px;
padding: 2px;
width: 75px; /* fixed dimensions - should match image sizes to avoid cropping */
height: 75px;
overflow: hidden; /* never show scrollbar */
float: left;
}
Still, it would be great to have some way to style the loading image itself and get rid of that image holder <div>.
Does the broken icon show on every browser? Either way, have you tried this jquery plugin: Imagesloaded ? It may help in your case.
You can use alternate text property.
One question how you are loading images? Loading using async calls or loading these images while page loads?
$("img").on({load:function(){},
error:function(){
$(this).attr("src","blank.png")
});
As per the default behavior, alt attribute is rendered first time just before the image rendering. I am displaying 25 images in a grid so it looks bit awkward as all alt attributes are displayed first.
Is it possible to hide alt attributes in Firefox?
Note: alt attributes contain dynamic names in my case.
After trying all the other methods here, I found this method works best which makes the text transparent until the image loads:
.yourClass img {
color: transparent;
}
The way to prevent alt attribute values from being displayed is to remove the attribute.
The meaning of an alt attribute (not tag) is that it specifies an alternative, a substitute for the image, in situations where the image is not displayed. So if you want to hide it when the image has not yet been loaded, you are asking for behavior that contradicts the very meaning of the attribute.
You can however make the alt text invisible (with the usual CSS Caveats) on Firefox by setting e.g.
img { background: white; color: white; }
in CSS. This implies that the alt texts are invisible also in case the browser never gets the image, or the browser has been configured not to display images.
From the reference of all the above answers, I figured out best one is to use
img:-moz-loading {
visibility: hidden;
}
Suppose there is no image and we use color as white or transparent then alt attribute no more use so, we need this attribute if there is no image to show which image here to load and to show alternative text to display.
Old question, but as of 2020, the img:-moz-loading {visibility: hidden;} does not work any longer.
Instead of doing img {background: white; color: white;}, I think it makes a lot more sense to do this:
img {
color: transparent;
}
That way it doesn't mess up images that are supposed to have some transparency. Also, it doesn't affect the rarer cases when you need to set a background color for an img.
For bonus points you could do this:
<img src="src.com/src" onerror="this.style.color='black'"/>
That would revert it to the normal alt color in the event that the browser fails to fetch the image.
Of course this is tedious to add to every image, but easier if you are using a JS framework with a global <Image/> component.
In addition to setting to:
img {
background: white;
color: white;
}
I like to disable Firefox's default image behavoir as well:
img:-moz-loading {
visibility: hidden;
}
Could you place the dynamic names in the title attribute?
You could try a black background or black background image; maybe Firefox still uses a black text color.
Maybe img { color: white; } would do?
If you don't mind adding a little extra, here it is:
<img src = "283414_2114217089554_728204_nn.jpg" onload="this.setAttribute('alt','this is the alt of my image');" />
Hope that helps... :))
Rather than worrying about the alt function, you can give all your images a common class, say image-to-show and create a loading div absolutely positioned over this image. So, when the page loads, you only show the loading div, with a loading gif, something like this:
// show loading image
$('.loader').show();
Once the image is loaded, you can hide the div and show the image.
// main image loaded ?
$('.image-to-show').load(function(){
// hide/remove the loading image
$('.loader').hide();
});
You can further enhance this code by using specific image ID's. Another, cleaner way to do it would be to set data-loading to true for the images that are loading and once the images are loaded, set $('.image-to-show').data('loading', false)
There are multiple ways of tackling this, let me know if you need further clarification.
I'd start by adding this CSS, which will hide all images with alt text (not display: none because we want to undo this and we won't know what to undo to):
img[alt] {
width: 0;
height: 0;
}
And then showing it once it's all loaded (this uses jQuery):
$(document).ready(function() {
$('img[alt]').on('load', function() {
this.style.width = 'auto';
this.style.height = 'auto';
});
});
I have a button that, when hovered over, I would like the background image to display also. (It is an arrow an explanation of the button). There are quite a few questions similar, but I couldn't quite tweak the answers to work for me.
The HTML looks like
<div id="header_feedback">
<a href="#contactForm">
<img title="Add an Event" src="./img/header_feedback.png" alt="Give us your Feedback"/>
</a>
</div>
the CSS then is
#header_feedback
{margin-left:730px;
margin-top:-135px;
position:absolute;}
#header_feedback:hover
{
background: url ('./img/addevent_tip.png');
}
Any ideas hugely welcome!
The main problem here is not with your CSS. Itagi's answer correctly identified the minor issue that you can't have a space between url and the parens/address.
But there are two other bigger issues:
Invalid image url: when applied, background: url('./img/addevent_tip.png'); fails to find a valid image. To fix this, you either need two periods or zero. So either background: url('/img/addevent_tip.png'); or background: url('../img/addevent_tip.png');
Backgrounds applied to opaque images aren't visible: Since the entire content of the div is an image and that image has no transparency, you will not be able to see the on-hover change even when it happens correctly. You can adjust for this by making part of the image transparent (and, perhaps, setting a background for the non-hover state that leads it to look the way it normally does), or by abandoning the image in favor of CSS spriting.
you just need to change it the following way:
#header_feedback:hover
{
background: url('./img/addevent_tip.png');
}
no whitespace between 'url' and the actual url
#header_feedback a img{ display:none;}
#header_feedback a:hover img{display:block}
I am using toggleClass and slideToggle to accomplish the following:
when the user selects a link, it will slide down the div, then it will set the link as open, displaying the appropriate background image, this is just a simple, (+) and (-) to open and close the div.
What I am having trouble with, is displaying the background-image to the right of the link, giving it about 5-10px of margin-left, to give it some spacing.
Here is a screen shot of what it is doing: Closed (displaying (+) sign): http://cl.ly/4634afa1e7aa4fe10072
Open (displaying (-) sign): http://cl.ly/8bc59ab07da46a173d62
HTML for link: Mapping Our Future: Strategic Plan 2010-2015
CSS for when it displays the link untouched, and after it is selected:
// link is not open
.our-future-intro-slide {
background: url('/images/uploads/images/plus_sign.png') no-repeat 120% 0%;
}
// link is open
.our-future-intro-slide-open {
background: url('/images/uploads/images/plus-icon.png') no-repeat 120% 0%;
}
Here is the jQuery, I figure I'll throw that in, it works, just the css for making the background-image show up to the right of the text.
$(document).ready(function() {
$('.our-future-intro-slide').click(function() {
$(this).toggleClass("our-future-intro-slide-open");
$(".our-future-intro").slideToggle(100);
});
});
Try this:
.our-future-intro-slide {
background: url('/images/uploads/images/plus_sign.png') no-repeat top right;
padding-right: 30px; /* or whatever the width of the background image is */
}
And, of course, the same modifications for the other rule.
I don't know if I understand totally, but have you tried using :after? Something like
.link:after{background:#FFF;}
I think you will be interested in this post - Pure CSS "Popups".
UPDATE: that's another way to align images on links hover.
In one of the recent Stackoverflow podcasts, Jeff talked about having a single image file having all of those tiny images that are all over a page and then cutting it with CSS so that all the images get displayed correctly. The whole point is to reduce the number of server requests so that the page gets loaded faster. I was like "wow, that's really cool, I could really use this in our product".
My question is: How is this done with CSS? I need to load the images with background-image, but then how do I specify the offset of the sub-image in the large image? That is, suppose that there is a hammer icon in the large image at (50px, 50px) and it has a size of 32px * 32px, how can I force the browser to only display that bit?
Basically you use your single image as the background image, but move it off (to the left and up) by the offset of the image you want to display. E.g. to display the hammer icon:
.hammer
{
background: transparent url(myIcons.jpg) -50px -50px no-repeat;
}
But as far as I know, you have to make sure that the element that's using the background image has the correct size (e.g. 32x32 px).
A search for CSS Sprites will give you more information.
It's called css sprites.
I's basically an old trick used in games programming where you load a single bitmap containing all the "states" of some item you need to draw, the advantage is that this way the image get's preloaded and there's no delay when you need to actually use it, in the case of css, it's normally implemented by using the image as background to the element, and applying different offsets and bounds on :hover, :active and "normal" classes.
There's more info in the stackoverflow Blog
Here's a nice generator: http://www.csssprites.com/
You know the answer ... ask google in this case look at the source of the google search results page, with a tool like firebug and you will find
.w10
background-position:-152px 0;
}
.w10, .w11, .w20, .w21, .w24, .wci, .wpb
background:transparent url(/images/nav_logo4.png) no-repeat scroll 0 0;
border:0 none;
cursor:pointer;
height:16px;
margin-left:8px;
vertical-align:bottom;
width:16px;
}
So all w10, w11, w20 etc share the same image (nav_logo4.png) all have fixed hight and width. and all specify (different) backgroup-position's.