Set background image from db - css

Is it possible to set the background image programatically?
I know how this can be done using css however this sets and fixes the background image. I have a model of books each with an image of the book and I would like to set the background to the book's image when the user fetches the book record.
def show
#book = Book.find(params[:id])
#image = #book.image
# set the background image to #image
end

Try to add this in your view (ex. show.html.erb or index.html.erb ):
<style media="screen">
.image_div { background-image: url(<%= #book.image %>); }
</style>
#book.image needs to return the actual path to the image of #book object, you'll need to access whatever property stores the path #book.image.path or #boook.image.url or whatever fits your codebase

Try this:
#pic {
width: 100%;
height: auto;
}
<img src="" id="pic">

Related

How to use ViewData to change css for a specific view

So I'm having a view that uses a layout and I wanted to change the css for body for just him, and i stumbled upon this solution:
Top of my view:
#{
ViewData["PageId"] = "Login";
}
Css:
body#Login {
padding-top: 0;
background: #000428;
background: -webkit-linear-gradient(to left, #004e92, #000428);
background: linear-gradient(to left, #004e92, #000428);
}
But when I decided I wanted to change the css for the html too, it didn't work?
html#Login {
overflow-y: auto;
}
Can someone explain how that even works, and why can't there be any space between body and #Login
Your selector requires the body tag having a Id called Login like this:
<body id="Login">
This is the Target Element of your Selector
</body>
So if the body doesn't have this Id, the selector didn't match. A non-matching example could be this one:
<body>
This element has no Id called Login and so Css wouldn't apply
</body>
You could overwrite the body with some additional Code, that's right. But keep in mind, that the order matters in CSS! So you've to include your second code after the original CSS code, which you want to overwrite. When the CSS is loaded in the _Layout file, you could use a section for example, to make sure that it's applied after the shared CSS to overwrite it:
<link rel="stylesheet" rel="css/master-shared-stylesheet.css">
#RenderSection("AdditionalPageCss")
Then you can do something like this in the View, where you want to overwrite master-shared-stylesheet.css:
#section AdditionalPageCss {
<style type="text/css">
/* Overwrite */
body {
overflow-y: auto;
}
</style>
}

Image preloading techniques (for use as hover state CSS background images) don't seem to work on Chrome

I'm using the following technique to pre-load images that are applied as CSS background images when hovering buttons:
#preload_area {
background-image:
url(../images/image1.svg),
url(../images/image2.svg);
width: 0px;
height: 0px;
display: inline;
}
Also tried to pre-load just one image, this way:
#preload_area {
background: url(../images/image1.svg) -9999px -9999px no-repeat;
}
None of this works: after hard refresh, when hovering my button the first time, I still see a blink (corresponding to loading the hover image). Obviously after that first time there's no blink any more.
Why is not working on Chrome? (it does work on Firefox)
Why is it not working on Chrome? Because all browser vendors want the fastest browser. They will not load unnessecary assets.
You want a cross browser way to preload? Use a sprite, as [CBroe] suggested. This solution has been around for ages and is rock solid. Any other trick, rendering the image invisible, can work today but be broken tomorrow.
Preloading in CSS doesn't actually mean that the file is loaded before everything else it just means it's the first resource to queue for download from your CSS file.
This means that your HTML has already been retrieved from the server and has probably already queued up or downloaded other resources before the CSS. It's not uncommon for CSS preloaded images to load after all of the HTML content.
Now while the image will be earlier in the queue than other resources referenced in the CSS it doesn't mean that it returns before those other resources. If the size of the file is larger than the other files being queued up it may take longer to be downloaded than those other files which are being downloaded at the same time.
One way to see what is happening with Chrome is to go to your webpage and navigate to the "Network" tab in the Chrome Devtools then refresh the page. It will show you the details of when each item is being loaded and how long that item takes to be received from the server.
Depending what image you're loading and your use case there are several other options.
1) If the file size is large and taking too long to download figure out how to reduce the file size.
2) If you have control of the page the user is navigating from you could prefetch the image for the cache in the prior page.
3) You could also try using HTML preload in addition to the CSS. HTML preloading I believe is only supported by Chrome at the moment so it might be perfect for this scenario. Add the following to the head of your html.
<link rel="preload" as="image" href="image1.svg">
<link rel="preload" as="image" href="image2.svg">
Live Demo:
http://blackmiaool.com/soa/43093224/
No one promise that invisible images will be loaded. Browsers have right to not preload your invisible images, so the css approach in your question may not work in some browsers. The demo above is written by myself. It actually renders image on the screen to guarantee the image is loaded.
HTML:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>test</title>
</head>
<body>
<h1 style="color:white;text-align:center;">Try to hover</h1>
<div class="show-area"></div>
<link rel="stylesheet" href="style.css">
<script src="../js/jquery.min.js"></script>
<script>
function preloadImage(src, cb) {
//create a image
const $dom = $("<img />", {
src: src
});
//check whether the image is already loaded
if ($dom[0].naturalWidth) {
cb && cb();
return;
}
//Put the image at the left bottom of the screen, and set its opacity to 0.01 to keep it from people eyes.
//Since it's actually rendered on the screen, the browser must load the image
$dom.css({
opacity: 0.01,
position: 'fixed',
bottom: 0,
left: 0,
height: 1,
width: 1,
'z-index': 10000,
'pointer-events': 'none',
});
$(document.body).append($dom);
//listen its `load` event to remove it and invoke callback
$dom.on("load", function() {
$dom.remove();
cb && cb();
});
}
//try to get the urls in the css file, and preload them
$("link").each(function() {
const href = $(this).attr("href");
$.get(href, function(style) {
const urls = [];
let match = style.match(/url\([\s\S]+?\)/g);
match.forEach(function(str) {
str = str.replace(/\s/g, "")
.replace(/^url\(/, "")
.replace(/\)$/, "");
let url = str.match(/^["']?([\S]+?)["']?$/);
if (!url || !url[1]) {
console.warn("Can't find url of " + str);
} else {
url = url[1];
preloadImage(url);
}
});
});
});
</script>
</body>
</html>
css:
body{
margin: 0;
background-color: black;
}
.show-area {
height: 100px;
width: 300px;
margin: auto;
margin-top: 100px;
background: url( ./1.jpg) no-repeat center;
background-size: contain;
}
.show-area:hover {
background-image: url("./2.jpg ");
}
Made a test with chrome, it seams that the image is loaded. The blink is due to place the image i think. To beter understand take a look at this test.
A test with a very big image
div#preload_area::before {
content: " ";
background: url(http://gfsnt.no/oen/foto/Haegefjell_Jan_2013_Large.jpg) no-repeat;
}
div#preload_area {
width: 50%;
height:100vh;
}
div#preload_area:hover {
background: url(http://gfsnt.no/oen/foto/Haegefjell_Jan_2013_Large.jpg);
background-repeat:no-repeat;
background-size:100% auto;
}
IMHO, this is no preloading. It's just loading, and you use a trick to display the right image when you hover the button.
If you really want to preload, or, as I understand your need, "you want the image already there, when you try to hover the button", then you have different options:
prefetch:
<link rel="prefetch" href="image1.svg">
<link rel="prefetch" href="image2.svg">
A nice thing to add for this is that "there's no same-origin restriction for link prefetching".
preload:
<link rel="preload" href="image1.svg">
<link rel="preload" href="image2.svg">
With "preload", the resources must be downloaded, whereas it's not always the case with prefetch.
Preload is supported by Chrome, Opera, Android browser and some more, but no Firefox & others. More details here
These techniques are described in more depth on css-tricks.com
Hope this helps you.
If you donĀ“t want loading-gaps, you could use a sprite-image, or you can set the background image as base64 encoded image. In this case, the images are always loaded when the css file is loaded.
.myImg {
background-image: url(data:image/svg+xml;base64,PD9...);
}
Here you can convert your svg images to base64: http://b64.io
I recently use this for "back to top" button in my blog http://anggit.com.
Will it works for you?
CSS:
<style>
#to_top {
display: block;
width: 48px;
height: 48px;
overflow: hidden;
}
#to_top img { /* in case the actual image size is over 48px */
width: 48px;
height: 48px;
}
#to_top:hover #image-1 { /* hover will remove the 1st image, the 2nd image will appear */
display: none;
}
</style>
HTML:
<a id="to_top" href="#">
<img id="image-1" src="image48x48.png" alt="Top" />
<img id="image-2" src="image48x48-hover.png" alt="Top" />
</a>

why is my background image not working in html5?

<style>
background-image: url(".....");
</style>
The background tends to be blank when I use this snippet.Is there any other way to get background image for my page ?.
The background tends to be blank when i use this snippet
That's because you haven't specified the tag in which you want to
apply the background image to.
you haven't specified a valid path to the image.
Simply do something like below but of course replace the URL with your own:
body {
background-image: url("paper.gif");
}
You need to specify which element you want to give the background.
Either you give the element a class or a id or something like body.
.class {
background-image: url("http://icons.veryicon.com/ico/System/Icons8%20Metro%20Style/Logos%20Wikipedia.ico");
}
#id {
background-image: url("http://icons.veryicon.com/ico/System/Icons8%20Metro%20Style/Logos%20Wikipedia.ico");
}
body {
background-image: url("https://www.wikipedia.org/portal/wikipedia.org/assets/img/Wikipedia-logo-v2.png");
}
<div id="id">Test1</div>
<div class="class">Test2</div>
Also you can write it inline
<body style="background-image: url('img/bg.jpg')">
You need to specify the tag, class, or id you want the background-image to be in. Example
body, .class, #id {
background-image: url("img.png");
}
or inline-style
<div style="background-image: url('something.gif')"></div>
You also need to be sure of the image path of the image you want to put
for instance if image is in the same folder as css or html say
body {
background-image: url("image.png");
}
if in a folder outside the css folder
body {
background-image: url("../foldername/image.png");
}
and so on

Is it possible to change img src attribute using css?

I'm trying to change img src (not the background img src) with css
<img id="btnUp" src="img/btnUp.png" alt="btnUp"/>
#btnUp{
cursor:pointer;
}
#btnUp:hover{
src:img/btnUpHover; /* is this possible ? It would be so elegant way.*/
}
You can use :
content: url("/_layouts/images/GEARS_AN.GIF")
There is another way to fix this : using CSS box-sizing.
HTML :
<img class="banner" src="http://domaine.com/banner.png">
CSS :
.banner {
display: block;
-moz-box-sizing: border-box;
box-sizing: border-box;
background: url(http://domain2.com/newbanner.png) no-repeat;
width: 180px; /* Width of new image */
height: 236px; /* Height of new image */
padding-left: 180px; /* Equal to width of new image */
}
http://css-tricks.com/replace-the-image-in-an-img-with-css/
you could try something like this
<img id="btnUp" src="empty.png" alt="btnUp" />
or
<div id="btnUp" title="btnUp"> <div/>
#btnUp{
cursor:pointer;
width:50px;
height:50px;
float:left;
}
#btnUp{
background-image:url('x.png')
}
#btnUp:hover{
background-image:url('y.png')
}
You can use CSS to a) make the original image invisible by setting its width and height to 0, or moving it off-screen etc, and b) insert a new image in its ::before or ::after pseudo-element.
That will be a performance hit though, as the browser will then load both the original and the new image. But it won't require Javascript!
You can't set the image src attribute via CSS. you can get is, as if you wanted to set use background or background-image.
No - CSS can only be used to change CSS background images, not HTML content.
In general UI elements (not content) should be rendered using CSS backgrounds anyway. Swapping classes can swap background images.
You can use a mixture of JavaScript and CSS to achieve this, but you can not do this with CSS alone. <img id="btnUp" src="empty.png" alt="btnUp" onmouseover="change(img)" onmouseout="changeback(img)" />
Instead of img you would put file name sans file type.
function change(img){
document.getElementById("btnUp").src= img + ".png";
}
function changeback(img){
document.getElementById("btnUp").src= img + ".png";
}
Then you use CSS to modify the img tag or the id to your liking.
You could set the image to a completely transparent image, then change the background image like so:
img {
background-image: url("img1.png");
}
//For example, if you hover over it.
img:hover {
background-image: url("img2.png");
}
The images do have to be the same size though. :(
Hope this helps!
content:url('imagelinkhere');
This is working, I tested it

Dynamically change background of a div in css

This is an example of code in CSS:
block {
margin-left: 1in;
margin-top; 1in;
position: absolute;
background-image: url('../images/myimage.png');
background-size: 100% 100%;
}
Now I am using this CSS file on more than one HTML page and there need to be able to change this image per page. Maybe through HTML?
<block><somehowchangeimagehere></somehowchangeimagehere></block>
? Please, only HTML & CSS.
One way to handle this is to put a class on the BODY tag for each page, then make different subclasses:
<body class="pageOne">
CSS:
.pageOne block {
background-image: url('../images/myimageOne.png');
}
.pageTwo block {
background-image: url('../images/myimageTwo.png');
}
The image URL is relative to the CSS page URL, not the HTML page URL. It should just work.
If you insert something like this in your html after you include the stylesheet you can override the stylesheet:
<style type="text/css">
block {
background-image('some_image_thats_specific_to_the_page');
}
</style>

Resources