I have my current code:
#content img[src="/img/test.gif"] {
background-image:url(dark-img.png) !important;
}
From my understanding !important; overrides existing values?
Why isn't this overriding the current HTML image in place there? The background shows up, behind the HTML image.
I want it in front of the HTML image, is this possible using CSS or JS?
Edit: For what its worth, im making a userscript that will modify the existing style of the site. So I do not have direct access to the HTML image.
You don't need javascript for image replacement! As long as you can identify the image by a CSS selector, you can use CSS to do the trick.
See the solution here
http://www.audenaerde.org/csstricks.html#imagereplacecss
Here is the code using only css:
<img src="tiger.jpg"
style="padding: 150px 200px 0px 0px;
background: url('butterfly.jpg');
background-size:auto;
width:0px;
height: 0px;">
sets the image size to 0x0,
adds a border of the desired size (150x200), and
uses your image as a background-image to fill.
If you upvote this answer, give #RobAu's answer an upvote, too.
The replacement of an image in CSS can be done in several ways.
Each of them has some drawbacks (like semantics, seo, browsercompatibility,...)
On this link 9 (nine!) different techniques are discussed in a very good way :
http://css-tricks.com/css-image-replacement/
If you are interested in css in general : the whole site is worth a look.
The background-image property, when applied to an image, refers to (drum roll ... ) the background-image of the image. It will always be behind the image.
If you want the image to appear in front of the image, you are going to have to use two images, or another container with a background-image that covers the first image.
BTW, it is bad practice to rely on !important for overriding. It can also be ineffective since 1) it can't override declarations in an element's style attribute, and 2) it only works if it can work based on the markup and the current CSS. In your case, all the huffing and puffing and !important declarations won't make an image do something it can't do.
I answered a similar question in another SO page..
https://robau.wordpress.com/2012/04/20/override-image-src-in-css/
<img src="linkToImage.jpg" class="egg">
.egg {
width: 100%;
height: 0;
padding: 0 0 200px 0;
background-image: url(linkToImage.jpg);
background-size: cover;
}
So effectively hiding the image and padding down the background. Oh what a hack but if you want an with alt text and a background that can scale without using Javascript?
Use your 'userscript' to change 'src' attribute value.
If there is an ID there, you can do this:
document.getElementById('TheImgId').src = 'yournewimagesrc';
If there is no ID:
var imgElements = document.getElementsByTagName('img');
Do iteration of imgElements. When its src value is match with your criteria, change the value with your own, do break.
Update:
Javascript:
<script language="javascript">
function ChangeImageSrc(oldSrc, newSrc) {
var imgElements = document.getElementsByTagName('img');
for (i = 0; i < imgElements.length; i++){
if (imgElements[i].src == oldSrc){
imgElements[i].src = newSrc;
break;
}
}
}
</script>
HTML:
<img src="http://i.stack.imgur.com/eu757.png" />
<img src="http://i.stack.imgur.com/IPB9t.png" />
<img src="http://i.stack.imgur.com/IPB9t.png" />
<script language="javascript">
setTimeout("ChangeImageSrc('http://i.stack.imgur.com/eu757.png', 'http://i.stack.imgur.com/IPB9t.png')", 5000);
</script>
Preview:
The first image will be replaced after 5 secs. Try Live Demo.
you'll have to place the first image as a background-image too. Then you can override it. You could do in a "standard" css file for the site, and every user gets its own, where he can override what he wants.
i agree with all the answers here, just thought id point out that 'browsers' such as IE won't like the img[src="/img/test.gif"] as a means of selecting the image. it would need a class or id.
The images shown in tags are in the foreground of the element, not the background, so setting a background image in an won't override the image; it'll just appear behind the main image, as you're seeing.
What you want to do is replace the image. Here's your options:
Start with an element with a background image, not an tag. Then changing the background image in CSS will replace it.
Start with an tag, but use Javascript to change the src attribute. (this can't be done in CSS, but is simple enough in JS)
EDIT:
Seeing your edit in the question, I'd suggest option 2 - use Javascript to change the src attribute. It's quite simple; something like this would do the trick:
document.getElementById('myimgelement').src='/newgraphic.jpg';
You should be able to replace it by just doing something like:
.image {
content: url('https://picsum.photos/seed/picsum/400');
width: 200px;
height: 200px;
}
Unfortunately seems that it does not work in Firefox :(
Related
I am working on a simple slideshow. I am using Javascript for the process of the slideshow and CSS for display of it. For some reason the CSS shows the first image perfectly but the JavaScript function is not engaging with the CSS to change the images. Suggestions?
Here is my code:
<body>
<style scoped id="slider">
html{
background: url('Africa Twin Mountainside.jpg') no-repeat center center fixed;
background-size: cover;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
}
</style>
<script type="text/javascript">
var images = [
"Africa Twin Mountainside.jpg",
"FZ-10.jpg",
"GSXR track.jpg",
"Pioneer 1k mountain.jpg",
"Raptor sand.jpg"
];
var step = 0;
function slideit(){
var imageUrl = images[step];
document.getElementById('slider').src = background;
step++;
if(step>=images.length)
step=0;
setTimeout("slideit()", 1000);
}
slideit();
</script>
</body>
This should work for you:
var images = [
"Africa Twin Mountainside.jpg",
"FZ-10.jpg",
"GSXR track.jpg",
"Pioneer 1k mountain.jpg",
"Raptor sand.jpg"
];
function slideit(step){
document.getElementById('slider').src = images[step || 0];
step++;
if(step === images.length) {
step = 0;
}
setTimeout(function() {
slideit(step);
}, 1000);
}
slideit();
This is going to be somewhat long, but hopefully this will point you in the right direction to rework your solution properly.
I'll start with this: <style scoped id="slider">
Firstly, the scoped attribute for <style> tags are currently only supported by Firefox, so I would avoid it altogether for the time being. The purpose of the scoped attribute is to constrain the style to the enclosing element, but you can easily do the same thing with the class attribute instead.
Since this is a simple, single-page idea you're implementing, it's perfectly acceptable to use <style> tags directly in your html document, but in general, it's better to create a separate css stylesheet and attach it to your page with a <link> tag. If you do include styles in the html document, it would typically be found inside the <head> tag.
Additionally, I don't think I've ever seen someone declare styles for the html tag; from my experience that's typically used for the body tag instead, but perhaps someone more knowledgable that I can comment on that.
Lastly, you've given this style tag an id, however I can think of no practical use for this, and when you try to manipulate it in your javascript with document.getElementById('slider').src = background;, you're selecting this <style> block - which doesn't have a src attribute, so that piece of code does nothing at all.
What you really want to use here is an <img> tag, which does have a src attribute that can be manipulated - you were on the right track here, but used the wrong tools. I would ditch the <style> element you have here altogether and just use an <img> like so:
<img id="slider" src="Africa Twin Mountainside.jpg">
You can then style this in css:
#slider {
width: 100%;
height: auto;
margin: auto;
}
This will scale up your image to take up the entire width of the browser; the size can be adjusted to your preference. It will also center your image in the browser if you choose a width < 100%.
Now we can look at your script. Peter Chon's answer is a well-written, working solution that will work when combined with the <img> tag that I've written above, and is essentially the same thing I would have written. You almost had the script part right, and if you compare what's written in Peter's answer to yours you can see that you were nearly on the mark. He would probably be willing to explain further if you have questions.
You had the methodology for how to implement your slideshow (mostly) correct, but the execution didn't work because you didn't understand what tools to use to get the job done. W3Schools get's a bad rap around these parts, but it's not a bad place to start if you're looking to learn about the basics without investing in a book, and if you read through their tutorials you can get at least a basic understanding of how tags and their attributes can be used to accomplish things.
If I had book references I'd provide them, but I don't. One that I considered getting was "HTML and CSS: Design and Build Websites" by John Duckett. It's got good reviews on Amazon, but I haven't read it personally.
My question has three parts
Part 1: To show an animated image caption for a image (this part is done as in the example row one http://jsfiddle.net/JBnbG/32/ )
Part 2: Show center part of youtube hqdefault.jpg thumbnail image in a div of 150x150 dimension (This part is also done as second row in the example)
Part 3: I want to integrate the part 1 & part 2 features in to part 3. problem is that caption works but the image is not alined in center as show in second row of the example.
Example is in http://jsfiddle.net/JBnbG/32/
I cant change structure otherwise it wont work caption part work properly
I would appreciate if some can help to fix the issue with keeping the HTML structure intact
I guess my question is, are you loading the example html dynamically from youtube, or just the images?
If the html is yours, it's a simple styling adjustment.
I forked it on jsfiddle , I think this is what you mean.
Not quite sure what happened to the styling, but I set the image
id="ContentPlaceHolder1_rptVideos_imgVideo_1" style="height:auto; width:200px;margin-left:-25px;"
or, another way is:
left:-25px; position:relative;
Which btw, all these styles should be declared as a class in you stylesheet.
If you're loading the html dynamically, I commented out the javascript that achieves the same thing.
Depending on what you're working with, if using php, you might want to get a script that will auto crop to the appropriate size. Timthumb.php is the most notable one, although there's a security issue that will never be fully bulletproof, although pretty solid as is.
Cheers!
Check this working code: http://jsfiddle.net/surendraVsingh/JBnbG/39/
Changes to be done in CSS:
.VideoContainer > span {
display: block;
}
.VideoContainer > span > img {
display: inline-block;
margin-left: -60px;
margin-top: -25px;
}
I have a PHP page that is bringing in results from a Database and displaying them on a page. Certain images have a red 'ball' to the left of their name to dictate that they have more information to be seen.
For example, there is 30 on one page, 12 of which have a red ball. I need to be able to manipulate the positioning of the first ball and leave the others as they are.
<img class="premium-icon" src="../../images/ball.png" alt="Premium Listing" />
<a href="page.php?cmd=auth&src=book&id=968365&a=CVTYJH5kavEbhwSDs" target="_blank" alt="" title="">
<p><span style="">Result</span></p>
</a>
This is how they are layed out, each image has the same class and I'm unable to stop this.
I'm looking for a pure CSS solution, however a Javascript one would be appreciated.
Thankyou for any help.
EDIT
A little bit more information, all of this is brought in from a Database so I don't know if in the final product the first image will even have a premium-icon. This is all in case that image does, as that image needs to be moved. So, it will always be the first-child as I'm only trying to select the first ever premium-icon.
You can use the first-of-type pseudoclass: http://jsfiddle.net/WAG6e/.
Edit: As BoltClock mentions, :first-of-type ignores the class, so actually you'd need to build your HTML such that the first img is the one you want to style. Then, it's a matter of specifying the tag name:
img:first-of-type {
border: 1px solid red;
}
The pseudo-class that you are looking for is the :first-child. According to w3schools, it works on all major browsers, since you have a <!DOCTYPE> declared.
So, a sample CSS to your problem:
img.premium-icon:first-child {
margin-left: 10px;
}
Remember that if your img isn't the first child on the results container, then the desired pseudo-class will be :first-of-type, but it only works on IE9+.
But, as pointed by #ptriek, :first-of-type can't be used together with class names. Then, you would need to change your HTML.
Personally, what I always do is a class name like .first on the desired element, set on my serverside code, so my CSS will be simple and working on all browsers:
img.premium-icon.first {
...
}
What about img:first-child { ... } ?
$('.premium-icon:first')
use that
Assuming class "premium-icon" is reserved for the relevant pictures, this JS could help:
var a=document.getElementsByClassName("premium-icon");
if (a) if (a.length>0) {manipulate_image(a[0]);}
Okay, let's say you have something like this:
<span class="image" style="background-image: url('http://www.example.com/images/image1.png')"></span>
Every CSS tutorial I've ever read has covered the concept of using a background color after the background-image code, which of course takes the place of the image when one is unavailable, but...
How do you specify a backup background-image - one that should be displayed if the image referenced is unavailable? If there's no CSS trick for this, maybe JavaScript could handle it?
In modern browsers you can chain background images and have more than one on each node. You can even chain background-position and background-repeat etc!
This means you can declare your first image (which is the fallback) and then the second one appears over it, if it exists.
background-color: black;
background-image: url("https://via.placeholder.com/300x300?text=Top Image"), url("https://via.placeholder.com/300x300?text=Failed To Load");
background-position: 0 0, 0 0;
background-repeat: no-repeat, no-repeat;
JFIDDLE DEMO
Simple answer:
You could either nest the span inside another span - with the outer span set to use the backup background image. If the inside span's background isn't available, then you'll see the outside one's
Better, more difficult answer:
You could achieve a similar result in pure CSS, by adding some psuedo content before the span, and then styling that to have the fallback background. However, this usually takes some trial and error to get it right;
Something lile
span.image:before{content:" "; background:url(backup.png); display: block; position:absolute;}
Well, I know that the actual tag has onload, onerror, and onabort events.
You could try loading it in an image, then if that succeeds, use JS to set the background property of the body.
EDIT: Never mind. I like his answer better.
Just declare the preferred default image after your background declaration:
.image
{
background: #000 url('http://www.example.com/images/image1.png') 0 0 no-repeat;
width: xxpx;
height: xxpx;
background-image: url('http://www.example.com/images/image1.png');
}
<span class="image"></span>
idk the dimensions of your img, so they are "xxpx"
working demo: http://jsfiddle.net/jalbertbowdenii/rJWwW/1/
I have a bunch of hidden images on my website. Their container DIVs have style="display: none". Depending on the user's actions, some images may be revealed via javascript. The problem is that all my images are loaded upon opening the page. I would like to put less strain on the server by only loading images that eventually become visible. I was wondering if there was a pure CSS way to do this. Here are two hacky/complicated ways I am currently doing it. As you can see, it's not clean code.
<div id="hiddenDiv">
<img src="spacer.gif" />
</div>
.reveal .img {
background-image: url(flower.png);
}
$('hiddenDiv').addClassName('reveal');
Here is method 2:
<img id="flower" fakeSrc="flower.png" />
function revealImage(id) {
$('id').writeAttribute(
'src',
$('id').readAttribute('fakeSrc')
);
}
revealImage('flower');
The browser will load any images that has a src attribute set, so what you want to do is to use data-src in the markup and use JavaScript to set the src attribute when you want it to load.
<img class="hidden" data-src="url/to/image.jpg" />
I created this tiny plugin that will take care of the problem:
(function($){
// Bind the function to global jQuery object.
$.fn.reveal = function(){
// Arguments is a variable which is available within all functions
// and returns an object which holds the arguments passed.
// It is not really an array, so by calling Array.prototype
// he is actually casting it into an array.
var args = Array.prototype.slice.call(arguments);
// For each elements that matches the selector:
return this.each(function(){
// this is the dom element, so encapsulate the element with jQuery.
var img = $(this),
src = img.data("src");
// If there is a data-src attribute, set the attribute
// src to make load the image and bind an onload event.
src && img.attr("src", src).load(function(){
// Call the first argument passed (like fadeIn, slideIn, default is 'show').
// This piece is like doing img.fadeIn(1000) but in a more dynamic way.
img[args[0]||"show"].apply(img, args.splice(1));
});
});
}
}(jQuery));
Execute .reveal on the image(s) you want to load/show:
$("img.hidden").reveal("fadeIn", 1000);
See test case on jsFiddle.
Here's a jQuery solution:
$(function () {
$("img").not(":visible").each(function () {
$(this).data("src", this.src);
this.src = "";
});
var reveal = function (selector) {
var img = $(selector);
img[0].src = img.data("src");
}
});
It's similar to your solution, except it doesn't use the fakeSrc attribute in the markup. It clears the src attribute to stop it from loading and stores it elsewhere. Once you are ready to show the image, you use the reveal function much like you do in your solution. I apologize if you do not use jQuery, but the process should be transferable to whichever framework (if any) that you use.
Note: This code specifically must be ran before the window has fired the load event but after the DOM has been loaded.
Weirdly, there's no answer about native lazy loading which is implemented in the majority of the browsers already.
you can do it by adding loading="lazy" attribute to your image.
Addy Osmani wrote a great article about it. You can read more about lazy loading here: https://addyosmani.com/blog/lazy-loading/
It partially depends on how your images must be placed in your code. Are you able to display the images as the background of a <div>, or are you required to use the <img> tag? If you need the <img> tag, you may be screwed depending on the browser being used. Some browsers are smart enough to recognize when an image is inside of a hidden object or in an object of 0 width/height and not load it since it's essentially invisible, anyway. For this reason many people will suggest putting an image in a 1x1 pixel <span> if you want the image to be pre-loaded but not visible.
If you don't require the <img> tag, most browsers won't load images referenced by CSS until the element in question becomes visible.
Mind you that short of using AJAX to download the image there's no way to be 100% sure the browser won't pre-load the image anyway. It's not unbelievable that a browser would want to pre-load anything it assumes may be used later in order to "speed up" the average load times.
Using CSS to put the image an unused class, then adding that class to an element with javascript is going to be your best bet. If you don't use image tags at all, this solution becomes a bit more obvious.
Though, for perspective, most people have the opposite problem where they want to preload an image so it shows up instantly when it's told to be shown.
If you are okay relying on scripting, there is the background image method and the image src method. Put simply, set all your hidden images to some very small image (reduce strain on server) or one that does not exist at all (who cares? The visitor cannot see the image-missing [X] anyway, the div is hidden) then change it with script...
<img src="I_do_not_exist.jpg" id="my_image" />
<input type="button" onclick="document.getElementById('my_image').src='I_exist.jpg';" Value="change image" />
<br /><br /><br />
<div id="mydiv" style="width:40px; height:40px; border:2px solid blue"></div>
<input type="button" onclick="document.getElementById('my_div').style.width='455px';document.getElementById('my_div').style.height='75px';document.getElementById('my_div').style.backgroundImage='url(I_exist.jpg)';" Value="change background image" />
I left a width on the above example to show that nothing is in the div image wise until you ask it to load.
If you make the image a background-image of a div in CSS, when that div is set to 'display: none', the image will not load.
You can do the following for a pure CSS solution, it also makes the img box actually behave like an img box in a responsive design setting (that's what the transparent png is for), which is especially useful if your design uses responsive-dynamically-resizing images.
<img style="display: none; height: auto; width:100%; background-image:
url('img/1078x501_1.jpg'); background-size: cover;" class="center-block
visible-lg-block" src="img/400x186_trans.png" alt="pic 1">
The image will only be loaded when the media query tied to visible-lg-block is triggered and display:none is changed to display:block. The transparent png is used to allow the browser to set appropriate height:width ratios for your <img> block (and thus the background-image) in a fluid design (height: auto; width: 100%).
1078/501 = ~2.15 (large screen)
400/186 = ~2.15 (small screen)
So you end up with something like the following, for 3 different viewports:
<img style="display: none; height: auto; width:100%; background-image: url('img/1078x501_1.jpg'); background-size: cover;" class="center-block visible-lg-block" src="img/400x186_trans.png" alt="pic 1">
<img style="display: none; height: auto; width:100%; background-image: url('img/517x240_1.jpg'); background-size: cover;" class="center-block visible-md-block" src="img/400x186_trans.png" alt="pic 1">
<img style="display: none; height: auto; width:100%; background-image: url('img/400x186_1.jpg'); background-size: cover;" class="center-block visible-sm-block" src="img/400x186_trans.png" alt="pic 1">
And only your default media viewport size images load during the initial load, then afterwards, depending on your viewport, images will dynamically load.
And no javascript!