Need your attention with understanding of loading css background images - html

I want to know in what cases from the following the css background images will and will not load. If you can explain also the "why" in a short answer, would be very helpful.
Also, if you aware of some differences between browsers in loading css background images in the following situations, please tell.
Situation 01
div { height: 300px; }
.classone {
background-image: url("imageone.jpg");
}
.classtwo {
background-image: url("imagetwo.jpg");
}
<div class="classone"></div>
Would the imagetwo.jpg be loaded in this case?
Situation 02
div { height: 300px; }
.classone {
background-image: url("imageone.jpg");
}
.classone {
background-image: none;
}
<div class="classone"></div>
Would the imageone.jpg be loaded in this case?
Note: the background-image: none come after the background-image: url("")

Generally in CSS, What comes last, takes place. So in solution 02, second definition of "classone" will replace the first one.
Edit
Browser downloads your entire css first, Then downloads necessary images while performing it. As your browser finds out you replaced background image, doesn't downlaod it.

Related

CSS class multiple times in one file

I have a html file with a div like
<div id="mydiv" class="mydiv">...</div>
In that html, I have one css file (mycss.css) linked.
at 600th line of that css file, I have
#mydiv
{
float:left;
background-image: url(divimg1.png);
background-repeat: no-repeat;
width:44px;
height:43px;
}
at 700th line, in the same css file, I have
#mydiv
{
background-image: url(divimg2.svg);
}
Now, most of the time I am getting divimg2 but very rarely/intermittently I am getting divimg1. I was under impression that when browser reads css files, it read top to bottom and closest one that means divimg2 should appear all the time. What am I missing.
I understand there shouldn't be two occurrences of same class but here I am looking for why for the above case, behaviour is intermittent?
Use important tag in CSS to get first preference.
#mydiv
{
background-image: url(divimg2.svg) !important;
}

Blinking checkbox [duplicate]

I have an anchor that changes its background image when hovered with a class class-btn that contains a background-image.
When hovered, it has
a.class-btn:hover
{
background-image('path/to/image-hovered.jpg');
}
When the page loads the first time and you hover this button the first time, it blinks (it takes about half a second to download the hovered image). How to avoid that blinking without JavaScript (only simple css and html is allowed)?
I tried to search Stack Overflow for the similar question, but with no luck.
Just added:
Should I "preload" the hovered image? How?
Should I play with z-index or opacity?
It happens with all browsers and thus the solution should work for all browsers.
Here is a simple and effective css image preloading technique I have used several times.
You can load several images by placing content: url() url() url()... etc.
body:after {
display: none;
content: url('path/to/image-hovered.jpg') url('path/to/another-image-hovered.jpg');
}
The easiest way to avoid this is to make use of image sprites. For a good overview, check out this CSS Tricks article.
That way, you not only solve the flicker problem you're seeing, but will also reduce the number of HTTP requests. Your CSS will look something like:
a.class-btn { background: url('path/to/image.jpg') 0 0 no-repeat; }
a.class-btn:hover { background-position: 0 -40px; }
The specifics will depend on your images. You can also make use of an online sprite generator to make the process easier.
A simple trick I use is to double up the original background image making sure to put the hovered image first
.next {
background: url(../images/next-hover.png) center center no-repeat;
background: url(../images/next.png) center center no-repeat;
&:hover{
background: url(../images/next-hover.png) center center no-repeat;
}
}
No performance hit and very simple
Or if you're not using SCSS yet:
.next {
background: url(../images/next-hover.png) center center no-repeat;
background: url(../images/next.png) center center no-repeat;
}
.next:hover{
background: url(../images/next-hover.png) center center no-repeat;
}
If you do this:
#the-button {
background-image: url('images/img.gif');
}
#the-button:before {
content: url('images/animated-img.gif');
width:0;
height:0;
visibility:hidden;
}
#the-button:hover {
background-image: url('images/animated-img.gif');
}
This will really help!
See here:
http://particle-in-a-box.com/blog-post/pre-load-hover-images-css-only
P.S - not my work but a solution I found :)
#Kristian's method of applying hidden 'content: url()' after the body didn't seem to work in Firefox 48.0 (OS X).
However, changing "display: none;" to something like:
body:after {
position: absolute; overflow: hidden; left: -50000px;
content: url(/path/to/picture-1.jpg) url(/path/to/picture-2.jpg);
}
... did the trick for me. Perhaps Firefox won't load hidden images, or maybe it's related to rendering(?).
You can preload images
function preloadImages(srcs, imgs, callback) {
var img;
var remaining = srcs.length;
for (var i = 0; i < srcs.length; i++) {
img = new Image();
img.onload = function() {
--remaining;
if (remaining <= 0) {
callback();
}
};
img.src = srcs[i];
imgs.push(img);
}
}
// then to call it, you would use this
var imageSrcs = ["src1", "src2", "src3", "src4"];
var images = [];
preloadImages(imageSrcs, images, myFunction);
This is a non-CSS solution: if the hover images are in one directory and have a common naming convention, for example contain a substring '-on.', it is possible to select the file names and put it into the HTML as a series of:
<img src='...' style='display: none' />
If they are the same dimensions, one possibility is to draw the two images directly on top of each other, with the CSS :hover class for the top image having display: none;
This way both images will be preloaded, but hovering will make the second visible.
The "double up the original background image" trick didn't work for me so I used another css trick:
.next {
background: url(../images/next.png) center center no-repeat;
}
.next:hover {
background: url(../images/next-hover.png) center center no-repeat;
}
.next:after {
content: url(../images/next-hover.png);
display: none;
}
This technique works nicely for me and ensures not only is the hover image pre-loaded, but it's also ready and waiting to be displayed. (Most other solutions rely on switching the background image on hover, which just seems to take the browser a bit of time to figure out, however much the image is pre-loaded.)
Create :before and :after pseudo elements on the container with the two images, but hide the one you want to see on hover. Then, on hover, switch the visibility.
So long as they both share the same size and positioning rules, you should see a neat swap.
.image-container {
&:before { display: block; background-image: url(uncovered.png); }
&:after { display: none; background-image: url(uncovered.png); }
}
.image-container:hover {
&:before { display: none; }
&:after { display: block; }
}
I had the same issue.
After trying everything related with css i can not solve the problem.
What finally solved the problem was simulating that someone hovers the element.
The css is the normal one.
CSS
#elemName{
/* ... */
}
#elemName:hover{
/* change bg image */
}
JS
var element = document.getElementById('elemName');
var event = new MouseEvent('mouseover', {
'view': window,
'bubbles': true,
'cancelable': true
});
element.dispatchEvent(event);
Just change the size of the background image, instead of the source of it! So...
a.class-btn {
background-image: url('path/to/image-hovered.jpg');
background-size: 0;
}
a.class-btn:hover {
background-size: auto;
}
The best way to do this is to just insert the images onto the webpage and set display to none.

Add text watermark in print mode using css that works for all major browsers?

I'm trying add a simple text watermark that I want to appear for each page that it will get printed on and look reasonable on Firefox, IE and Chrome.
I've gone through all the related threads that I could find and have applied the suggested answers, but to no avail. Either it appears fine on every page, but doesn't show on the first page (Firefox). Or it only appears on the first page (Chrome). Or doesn't show at all.
I was wondering, is there a standard way to do css watermarks that works for all browsers that I may have missed somehow?
For those curious as to what my html/css looks like at the moment:
<div class="watermark">This is a watermark!</div>
#media print {
.watermark {
display: inline;
position: fixed !important;
opacity: 0.25;
font-size: 3em;
width: 100%;
text-align: center;
z-index: 1000;
top:700x;
right:5px;
}
}
Any help is much appreciated!
Edit: This isn't just for watermarking images, otherwise as suggested I should use an image editor. This is for watermarking pages of document content (sections of text of various sizes).
The real problem is that you need a .watermark at the bottom of each printed page, but CSS has no concept of these printed pages.
The best you could probably do is to use the page-break-after CSS attribute to force a page break at certain points, then you could position your watermark just before that.
Something like (untested):
#media all {
.watermark {
display: none;
background-image: url(...);
float: right;
}
.pagebreak {
display: none;
}
}
#media print {
.watermark {
display: block;
}
.pagebreak {
display: block;
page-break-after: always;
}
}
<body>
some content for page 1...
<div class="watermark"></div>
<div class="pagebreak"></div>
some content for page 2...
<div class="watermark"></div>
<div class="pagebreak"></div>
</body>
Really I think those 2 classes could just be the same element, but this seemed more understandable in code.
The down side here of course is that you need to manually specify where each page break happens, and realistically, if someone prints your webpage on a 4"x6" notecard, its going to be radically different than standard size paper. But still, it's a step in the right direction.
You can't do this in css, simply because it won't work.
Think of this, the user just removes your css, gets your image URLs and copies the images, without the watermark. Right click 'save image url' will also bypass css.
There are two good ways to add watermarks that are fail-safe.
Edit the actual images
If you have control over the images, such as if you are building a photography portfolio, just batch process them in your image editor and add the watermarks before you upload them to the web.
This is a good idea because then your images are ready watermarked regardless of where you use them, so they're social media / promo pack ready etc.
Do it on request
Set up an .htaccess rule that intercepts any image requests and redirects them via some server side code that uses an image processing library to add the watermark and return the binary image data. You can cache a watermarked image with a hash code and check for a watermarked version existing first that will allow you to bypass the processing.
This means that any image request, regardless of whether it comes from css, HTML, or a direct URL will serve a watermarked image. Do use some logic to skip any images used for the decoration of your site, otherwise you'll get watermarked in unexpected places!
The advantage here is that the original image is untouched, if you update your watermark, perhaps as part of a rebranding, you won't need to update all your images.
Another advantage of this approach is that you can apply it to any images, even if you don't create them - for example, if you have users uploading images to your site. Care should be taken with this however, before you watermark, make sure you have the right to watermark the image.
issue reason.
print not support background-image.
This is my solution.
1.Absoluted position for Main elements(need to print div).
2.add element
<style>
.mainContend{
position: absolute;
top: 0;
}
.watermark{
opacity: .8;
}
</style>
<script>
var addWatermark = function () {
var bodHeight = document.body.scrollHeight;
//imge size is 1000*400px
var imgNum = Math.floor(bodHeight/400) ;
var template = '<img src="../img/icon/watermark.png" class="watermark">';
var innerHTML;
//create image number
for(var i = 0;i < imgNum;i++){
innerHTML +=template;
}
// innerHTML.appendTo("#reportContent);
$("#reportContent").append(innerHTML);
}
window.onload = addWatermark;
</script>
<div id="reportContent">
<div class="mainContend" id="mainContend">
content reportContentreportContentreportContent
</div>
</div>
Here is how I successfully managed to use watermark on every page in print preview
HTML:
<!-- place this only once in page -->
<div style="opacity: .5; filter: alpha(opacity=50);" class="watermark"></div>
<!-- place this in your table thead -->
<div style="opacity: .5; filter: alpha(opacity=50);" class="watermark_print"></div>
CSS:
div.watermark_print{
display: none;
width: 100%;
height: 100%;
background: url("{{{watermark}}}") no-repeat;
background-position: center;
z-index: 99999999;
border: none !important;
background-size: 400px !important;
}
div.watermark {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: url("{{{watermark}}}") no-repeat;
background-position: center;
z-index: 99999999;
border: none !important;
background-size: 400px !important;
}
table {
width: 100%;
table-layout: fixed;
border-spacing: 0;
}
#media print {
div.watermark {
display: none;
}
div.watermark_print {
display: block;
position: fixed;
inset: 0;
}
}
That should do the trick, we have two watermark, one in HTML page review and another hidden in normal view but in print preview, we show it and because we are repeating table header in every page so we have this watermark on every page.

css: avoid image hover first time blinking

I have an anchor that changes its background image when hovered with a class class-btn that contains a background-image.
When hovered, it has
a.class-btn:hover
{
background-image('path/to/image-hovered.jpg');
}
When the page loads the first time and you hover this button the first time, it blinks (it takes about half a second to download the hovered image). How to avoid that blinking without JavaScript (only simple css and html is allowed)?
I tried to search Stack Overflow for the similar question, but with no luck.
Just added:
Should I "preload" the hovered image? How?
Should I play with z-index or opacity?
It happens with all browsers and thus the solution should work for all browsers.
Here is a simple and effective css image preloading technique I have used several times.
You can load several images by placing content: url() url() url()... etc.
body:after {
display: none;
content: url('path/to/image-hovered.jpg') url('path/to/another-image-hovered.jpg');
}
The easiest way to avoid this is to make use of image sprites. For a good overview, check out this CSS Tricks article.
That way, you not only solve the flicker problem you're seeing, but will also reduce the number of HTTP requests. Your CSS will look something like:
a.class-btn { background: url('path/to/image.jpg') 0 0 no-repeat; }
a.class-btn:hover { background-position: 0 -40px; }
The specifics will depend on your images. You can also make use of an online sprite generator to make the process easier.
A simple trick I use is to double up the original background image making sure to put the hovered image first
.next {
background: url(../images/next-hover.png) center center no-repeat;
background: url(../images/next.png) center center no-repeat;
&:hover{
background: url(../images/next-hover.png) center center no-repeat;
}
}
No performance hit and very simple
Or if you're not using SCSS yet:
.next {
background: url(../images/next-hover.png) center center no-repeat;
background: url(../images/next.png) center center no-repeat;
}
.next:hover{
background: url(../images/next-hover.png) center center no-repeat;
}
If you do this:
#the-button {
background-image: url('images/img.gif');
}
#the-button:before {
content: url('images/animated-img.gif');
width:0;
height:0;
visibility:hidden;
}
#the-button:hover {
background-image: url('images/animated-img.gif');
}
This will really help!
See here:
http://particle-in-a-box.com/blog-post/pre-load-hover-images-css-only
P.S - not my work but a solution I found :)
#Kristian's method of applying hidden 'content: url()' after the body didn't seem to work in Firefox 48.0 (OS X).
However, changing "display: none;" to something like:
body:after {
position: absolute; overflow: hidden; left: -50000px;
content: url(/path/to/picture-1.jpg) url(/path/to/picture-2.jpg);
}
... did the trick for me. Perhaps Firefox won't load hidden images, or maybe it's related to rendering(?).
You can preload images
function preloadImages(srcs, imgs, callback) {
var img;
var remaining = srcs.length;
for (var i = 0; i < srcs.length; i++) {
img = new Image();
img.onload = function() {
--remaining;
if (remaining <= 0) {
callback();
}
};
img.src = srcs[i];
imgs.push(img);
}
}
// then to call it, you would use this
var imageSrcs = ["src1", "src2", "src3", "src4"];
var images = [];
preloadImages(imageSrcs, images, myFunction);
This is a non-CSS solution: if the hover images are in one directory and have a common naming convention, for example contain a substring '-on.', it is possible to select the file names and put it into the HTML as a series of:
<img src='...' style='display: none' />
If they are the same dimensions, one possibility is to draw the two images directly on top of each other, with the CSS :hover class for the top image having display: none;
This way both images will be preloaded, but hovering will make the second visible.
The "double up the original background image" trick didn't work for me so I used another css trick:
.next {
background: url(../images/next.png) center center no-repeat;
}
.next:hover {
background: url(../images/next-hover.png) center center no-repeat;
}
.next:after {
content: url(../images/next-hover.png);
display: none;
}
This technique works nicely for me and ensures not only is the hover image pre-loaded, but it's also ready and waiting to be displayed. (Most other solutions rely on switching the background image on hover, which just seems to take the browser a bit of time to figure out, however much the image is pre-loaded.)
Create :before and :after pseudo elements on the container with the two images, but hide the one you want to see on hover. Then, on hover, switch the visibility.
So long as they both share the same size and positioning rules, you should see a neat swap.
.image-container {
&:before { display: block; background-image: url(uncovered.png); }
&:after { display: none; background-image: url(uncovered.png); }
}
.image-container:hover {
&:before { display: none; }
&:after { display: block; }
}
I had the same issue.
After trying everything related with css i can not solve the problem.
What finally solved the problem was simulating that someone hovers the element.
The css is the normal one.
CSS
#elemName{
/* ... */
}
#elemName:hover{
/* change bg image */
}
JS
var element = document.getElementById('elemName');
var event = new MouseEvent('mouseover', {
'view': window,
'bubbles': true,
'cancelable': true
});
element.dispatchEvent(event);
Just change the size of the background image, instead of the source of it! So...
a.class-btn {
background-image: url('path/to/image-hovered.jpg');
background-size: 0;
}
a.class-btn:hover {
background-size: auto;
}
The best way to do this is to just insert the images onto the webpage and set display to none.

Can't get CSS Sprite to work..what am I doing wrong?

I am using CSS Sprite Generator to create sprites for a web page I am working on, but it doesn't seem to work, and I don't know why...I guess it's something obvious but..!
So, I picked up 3 images, zipped, generated the PNG file (I checked out the result it is seems fine) and I got the following css classes back:
.sprite-welcom1 { background-position: 0 -30px; }
.sprite-welcom3 { background-position: 0 -109px; }
.sprite-3 { background-position: 0 -188px; }
So here is the HTML I am testing on, and for some reason all I get is a nice blank page:
<html>
<head>
<style>
.sprite-welcom1 { background-position: 0 -30px; }
.sprite-welcom3 { background-position: 0 -109px; }
.sprite-3 { background-position: 0 -188px; }
.sprite-bg {
background: url(csg-495a902b04181.png) no-repeat top left;
}
</style>
</head>
<body>
<div class="sprite-bg sprite-3"></div>
</body>
</html>
Any tips?
Don't use a generator. Take the time to do it yourself from scratch. Then next time you use this method, you'll know what to look for when something has gone wrong and you'll answer your own question, and heck, maybe someone else's on Stack Overflow.
This generator isn't producing any meaningful class names for your styles, which means if you go to edit them later you're not going to know two classes from Tuesday what's going on unless you've memorized the numbers. Meaningful names will save you headaches when you return to your stylesheet later on.
Open up Photoshop, GIMP, or almost any modern image editing software. Make sure your program has the rulers option switched on, and measure your element's background image coordinates this way. In the absence of rulers - which is probably a rarity, you could always fudge around with the MeasureIt Firefox extension and the .png opened in a tab.
Define a width and height for <div class="sprite-bg sprite-3">.
Your .sprite-bg rule for background-position, set as part of the composite rule for background (the top left part), has higher precedence than the stand-alone background-position setting for .sprite-3 because it appears later in the stylesheet.
Place the rule for .sprite-bg first.
the div is empty. put something inside. like space ( ).
You have to declare a height and width for the div element. That's it.
Hrm, not quite sure what you're trying to achieve here. The multiclassing seems a bit messy. I've posted my method of spritemaps below, see if this does what you need. Usually this involves a combination of elements, the most common being an unordered list with links for navigation, but for this purpose it's just divs.
Also don't forget the order of background-position.
background-position: |top| |left|;
That's screwed me up a couple of times. Finally, A List Apart has a great article on Sprite Maps (http://www.alistapart.com/articles/sprites/)
<html>
<head>
<style>
.sprite-container div {
background: url(csg-495a902b04181.png) top left no-repeat;
width: 20px; //width is neccessary
height: 20px; //height is neccessary
}
.sprite-3 { background-position: 0 -188px; }
.sprite-4 { background-position: -20px -188px; }
</style>
</head>
<body>
<div class="sprite-container">
<div class="sprite-3"></div>
<div class="sprite-4"></div>
</div>
</body>
</html>
As others have mentioned, your sprite-bg element needs to have either some content to give it a height / width, or have those properties specified in the css, thusly:
.sprite-bg {
background: url(csg-495a902b04181.png) no-repeat top left;
width: 100px; /* (or whatever the width should be) */
height: 100px; /* (or whatever the height should be) */
}
As someone else mentioned, I'd move the rules for the .sprite-welcom1, .sprite-welcom3 and
.sprite-3 to beneath the main .sprite-bg in the stylesheet.
For some reason, Firefox 3 sometimes wants 2 classes in the CSS Selector to make the sprite map work. My hunch is that the rules of specificity are causing problems while the sprite map loads. By adding the additional class, it works correctly.
/* Bad */ .childClass2 { background-position: -10px -20px; }
/* Good */ .parentClass1 .childClass2 { background-position: -10px -20px; }
It's always good to “namespace” your CSS with a parentClass, to avoid unexpectedly styling a DOM tag someplace else. Here are some additional enhancements to everyones ideas from above.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<HTML xmlns="http://www.w3.org/1999/xhtml">
<head>
<style type="text/css">
.sprite-container div {
background: transparent url(//www.yourDomain.com/csg-495a902b04181.png) no-repeat scroll 0 0;
width: 200px; /* width is necessary */
height: 20px; /* height is necessary */
}
.sprite-container .sprite-3 { background-position: 0 -188px; }
.sprite-container .sprite-4 { background-position: -20px -188px; }
</style>
</head>
<body>
<div class="sprite-container">
<div class="sprite-3"></div>
<div class="sprite-4"></div>
<!-- Empty divs are fine! Unless you *really* want text on top of
your sprite map. :o) Btw: ­ is invisible when a hyperlink
is wrapped around it. &nbsp is not... it creates an
underscored hyperlink. Use ­ which is a soft-hyphen.
-->
</div>
</body>
</html>
This code works in: IE 7, Firefox 3, Google Chrome 1, Opera 9 & Safari 3.
Tip: Avoiding http:// in the URL will allow the sprite map to be served up from both http:// and https:// connections.
(Scroll to the right to see the “no-repeat scroll 0 0;” )