2

In CSS, I want to be able to specify a background image for a given selector without it actually being downloaded or rendered. I then want to be able to read the image URL with javascript, modify it in js, and then apply the modified URL to the selector for real so it will actually download and display. (I suppose that last part will have to be done with jQuery directly changing styles on each element, but that is not what this question is about.) This is part of some devious thing I'm trying to make really easy responsive images.

I have tried:

.sneaky {
    background: url("youcantseemeyet.jpg");
    background-image: url("blank.jpg");
}

But I can't find a way for javascript to know about the original background property.

Also tried:

.sneaky:after {
    background: url("youcantseemeyet.jpg");
}

But I don't think javascript can see pseudo-elements.

Also tried:

.sneaky {
    x-background: url("youcantseemeyet.jpg");
}

and:

.sneaky {
    background: x-url("youcantseemeyet.jpg");
}

But I think javascript just tosses custom properties/values out the window.

How do CSS Polyfills work? Because they allow you to use CSS properties and values that would normally be invalid in a browser, so how does javascript access the CSS?

Another idea: I don't suppose there is a way to pre-empt the CSS with javascript, read the url() but block the file from downloading, is there?

Moss
  • 3,695
  • 6
  • 40
  • 60
  • Easiest solution: generate a new ` – Amadan Nov 13 '14 at 08:10
  • I want to be able to declare the URL in CSS at or near the spot where you would normally declare a background image. – Moss Nov 13 '14 at 17:24

3 Answers3

1

I upvoted the question for your motivation to do this. Resposive Image resizing for Performance gain is a great way to reduce the bytes downloaded without affecting the quality of the page.

Here's one way of doing it: http://codepen.io/anon/pen/bNGgLZ

You can use html5 data attribute to store the url (so that the image is not downloaded initially) and then apply the image size based on the window size using javascript

<div class="sneaky" data-url="img_test.png">abcd</div>
<style>
.sneaky {
 background: #000 url("transparent_placeholder.png");
 color:#fff;
}
</style>

<script>
var el = document.querySelector(".sneaky");
alert(el.getAttribute("data-url"));

//Decide image size based on client window size and then assign backgroundImage property to download it from server
var size = "smaller";
el.backgroundImage = "url("+size+"_img_test.png)"
</script>
Prabu Raja
  • 239
  • 1
  • 8
  • Thanks. I'm hoping to find a way to declare the background image in the stylesheet, like you normally would. I would use a solution like this for actual ``s. Also I intend to choose the image size based on the element size, not the screen size. I know I can just use media queries to select different sized images, but I am hoping for something more automatic. – Moss Nov 13 '14 at 20:38
  • How is element size decided? Responsive? How many number of images you will have in a page (or your whole site) you want to do this thing? – Prabu Raja Nov 13 '14 at 21:00
  • This is supposed to be a general solution for anyone to use on any number of images on a site. What do you mean how is element size decided? – Moss Nov 13 '14 at 22:16
  • When you said "choose the image size based on the element size", do you mean the element is responsive? – Prabu Raja Nov 13 '14 at 22:44
  • The element could be responsive, it could be fluid, it could be fixed. The point is the javascript would read it's width, however it is set, and get an image that fits. – Moss Nov 13 '14 at 23:02
  • I've never seen anyone using a css property for storing values and do none other than that. It'd be good to know though :) – Prabu Raja Nov 13 '14 at 23:12
0

You can use the background position property to remove the image from rendering area and use window.getComputedStyle to retrieve the url

CSS

.sneaky {
    background-image:url(youcantseemeyet.jpg);
    background-position:-9999px -9999px;
}

Javascript

var url=window.getComputedStyle(document.querySelector('.sneaky'),null).backgroundImage

If you want to apply a second background images to .sneaky, better to include a sub div without padding/margin and apply second background to it

Frank Dai
  • 50
  • 5
  • But I said I want to avoid downloading the image. The point is to put a high res image in the CSS and have the javascript fetch a down-sized version to fit whatever box the image is in. – Moss Nov 13 '14 at 15:55
0

I figured out what to do. Kind of obvious now that I thought about it. Just hide the desired URL in a query string, like: url('/img/placeholder.gif?/path/to/real/image.jpg'). Ah, query strings, I love them.

UPDATE A problem with using a query string is that every unique query string still results in a new HTTP request, even if it is ultimately returning the same resource. So, alternatively you can use a hash mark, like url('/img/placeholder.gif#/path/to/real/image.jpg'). When the image is requested, it will completely ignore the hash tag part, BUT you can still retrieve that information with javascript. It is just a bit tricky. Assuming you have no other URLs with hash tags in them (because why would you), you can simply retrieve a list of all selectors in all stylesheets which do use the hash tag part with the following script.

var selection = []
  , sheets = document.styleSheets
  , sheet, rule, i, j

for (i in sheets){
    sheet = sheets[i]
    for (j in sheet.cssRules) {
        rule = sheet.cssRules[j]
        if (/url\(.*#.*\)/.test(rule.cssText)) selection.push( rule.selectorText );
    }
}
Moss
  • 3,695
  • 6
  • 40
  • 60