1

I'm working on a small update to http://codepen.io/wesbos/pen/adQjoY and wanted to use a CSS variable to change the image, just to see if I can do it. So far, it's not working.

<img src=imageFile>

<style>
:root {
    --image: 1;
    --imageFile: '"https://source.unsplash.com/7bwQXzbF6KE/800x500"';
}

img {
    src: var(--imageFile);
}
</style>

and I have some If, Then, Else, implemented in <script> ... </script> to change the imageFile variable.

In the DevTools console I get:

GET file:///Users/tim/bloc/JavaScript30-master/03%20-%20CSS%20Variables/imageFile net::ERR_FILE_NOT_FOUND

The image doesn't change. Can you help? Here is my full code before the update:

// get the inputs
const inputs = [].slice.call(document.querySelectorAll('.controls input'));

// listen for changes
inputs.forEach(input => input.addEventListener('change', handleUpdate));
inputs.forEach(input => input.addEventListener('mousemove', handleUpdate));

function handleUpdate(e) {
// append 'px' to the end of spacing and blur variables
    const suffix = (this.id === 'base' ? '' : 'px');
    document.documentElement.style.setProperty(`--${this.id}`, this.value + suffix);
}
:root {
  --base: #ffc600;
  --spacing: 10px;
  --blur: 10px;
}

body {
  text-align: center;
}

img {
  padding: var(--spacing);
  background: var(--base);
  -webkit-filter: blur(var(--blur));
  /* 👴 */
  filter: blur(var(--blur));
}

.hl {
  color: var(--base);
}

body {
  background: #193549;
  color: white;
  font-family: 'helvetica neue', sans-serif;
  font-weight: 100;
  font-size: 50px;
}

.controls {
  margin-bottom: 50px;
}

a {
  color: var(--base);
  text-decoration: none;
}

input {
  width:100px;
}
<h2>Update CSS Variables with <span class='hl'>JS</span></h2>
<div class="controls">
  <label>Spacing:</label>
  <input type="range" id="spacing" min="10" max="200" value="10">

  <label>Blur:</label>
  <input type="range" id="blur" min="0" max="25" value="10">

  <label>Base Color</label>
  <input type="color" id="base" value="#ffc600">
</div>

<img src="http://unsplash.it/800/500?image=899">

<p class="love">Made by <a href="http://twitter.com/wesbos">@wesbos</a> 😘</p>
<p class="love">Chrome 49+, Firefox 31+</p>

3
  • 1
    So, the original image is hosted online but the replacement image you are trying to load is from your own local directory? That seems like the problem. Commented Dec 27, 2016 at 19:04
  • 2
    The <img> tag does not have a src CSS property. However, you could try with background-image. Commented Dec 27, 2016 at 19:08
  • @torazaburo: You can just set the src HTML attribute directly. See my answer. Commented Dec 28, 2016 at 2:45

3 Answers 3

3

src is an HTML attribute, not a CSS property.

src=imageFile points to a resource in the current URL directory path called imageFile. That's why the browser is attempting to GET file:///Users/tim/bloc/JavaScript30-master/03%20-%20CSS%20Variables/imageFile, which naturally doesn't work.

You can still use custom properties, but as you need to set an HTML attribute, not a CSS property, the img rule is not needed. Give the img an ID instead, remove the double nesting of quotes from your custom property value as they're not needed (not even in JavaScript), and set the value of the src HTML attribute to the custom property value directly:

var customProps = window.getComputedStyle(document.documentElement);
var img = document.createElement('img');
img.id = 'imageFile';
img.alt = '';
img.src = customProps.getPropertyValue('--imageFile');
document.body.appendChild(img);
:root {
    --image: 1;
    --imageFile: https://source.unsplash.com/7bwQXzbF6KE/800x500;
}
<!--
The script should generate an img element that looks like this:
<img id="imageFile" alt="" src="https://source.unsplash.com/7bwQXzbF6KE/800x500">
-->

Some notes:

  • I'm leaving the --image custom property in although it's unused in this example. I presume it's meant to be appended to the URL as query string data — which shall be left as an exercise for the reader.

  • The ID is also technically unused in this example as I'm adding the element via JavaScript because it's not possible to mark up an img element without a non-empty src in a valid HTML document, but it will be useful when swapping out the image later as described in the question.

  • In case anyone is wondering if using JavaScript for this sort of thing is a hack, it's not — the spec itself explicitly lists JavaScript as a valid (even typical) use case for CSS custom properties.

Sign up to request clarification or add additional context in comments.

Comments

0

If you want to use CSS to specify the source of your file you can use something like this:

HTML:

<img>

CSS:

img{
  content:url("IMAGE URL");
}

for your reference: https://jsfiddle.net/tqoLe7r3/

2 Comments

The OP would like to know how to make this work with CSS variables. See jsfiddle.net/tqoLe7r3/1.
doesn't work for me in Firefox
0

In your :root declaration, you can only set CSS values as variables.

Try this:

:root{
  --imageFile: url('https://source.unsplash.com/7bwQXzbF6KE/800x500');
}
img {
  content: var(--imageFile);
}

Like this: https://jsfiddle.net/wdkmbeL7/

4 Comments

"you can only set CSS values as variables" That's not true at all. See w3.org/TR/css-variables-1/#syntax In addition, the content property is not supported on anything other than ::before and ::after. Only some browsers support it, out of spec. I would not rely on it until after css-content-3 enters mainstream (which I'm not counting on happening within the next couple of years).
@surfmuggle it's working for me. It might be because I'm linking out to an image on Wikipedia.
I doubt that loading from wikipedia is the cause - see this fiddle jsfiddle.net/4wcxe1ag - using css-content instead of the img-tag attribute src does not load the picture - at least not in chrome 75 nor in firefox 67.
It's working just fine for me in chrome 75. Here's what a screen shot of it looks like on my end. i23.photobucket.com/albums/b378/corrin_wyndryder/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.