CSS set background-image by data-image attr

66,471

Solution 1

a nice alternative to data- attributes (or the attr() approach in general) can be the use of custom properties (MDN, csswg, css-tricks).

as their values are not restricted to strings, we can pass around any type that is allowed as a custom property value!

also, you get the benefit of updating these properties at runtime, with a swap of a stylesheet.

.kitten {
  width: 525px;
  height: 252px;
  background-image: var(--bg-image);
}
<div  class="kitten"
      style="--bg-image: url('http://placekitten.com/525/252');">
</div>

Solution 2

As of writing, the browser support of attr() notation on CSS properties other than content - like background-image - is very limited.

Besides, as per CSS level 2 spec, combining url() and attr() is not valid:
content: url(attr(data-image));.

Hence there is no cross-browser CSS solution at the moment to achieve the desired result. Unless using JavaScript is an option:

var list = document.querySelectorAll("div[data-image]");

for (var i = 0; i < list.length; i++) {
  var url = list[i].getAttribute('data-image');
  list[i].style.backgroundImage="url('" + url + "')";
}
div[data-image] {
  width: 100px; height: 100px; /* If needed */
  border: 2px solid black;
}
<div data-image="http://placehold.it/100"></div>

Solution 3

In your HTML:

<div data-image="path_to_image/image_file.extension" ... ></div>

In your CSS:

div:after {
    background-image : attr(data-image url);
    /* other CSS styling */
}

Problems:

This is your required answer. Check this documentation in w3.org. But the main problem is it won't work, not yet!. In many browsers, attr() runs successfully when it is used in content: attribute of the CSS coding. But using it in other attributes of CSS, it doesn't work as expected, not even in major browsers.

Solution:

  • Use scripts such as JavaScript or jQuery.

References:

Thanks:

Solution 4

If the goal is being able to set the background-image style of an HTML element from within the HTML document rather than the CSS definition, why not use the inline style attribute of the HTML element?

div[style^='background-image'] {
  width:400px;
  height:225px;
  background-repeat:no-repeat;
  background-size:contain;
  background-position:center center;
  /* background-image is not set here... */
}
<!-- ... but here -->
<div style="background-image:url(http://img01.deviantart.net/5e4b/i/2015/112/c/5/mandelbrot_62____courage_to_leave___by_olbaid_st-d646sjv.jpg)"></div>

EDIT:

If selecting the <div> by style is not an option, you may be able to give it a class and select it by class name.

Share:
66,471
Hossain Khademian
Author by

Hossain Khademian

I'm a professional Android App Developer. I enjoy exploring new things, techs and frameworks. I have 5 years experience in Native Android App Development plus 2 years in Kotlin language and 3 years in NodeJS for server-side scripting. I actively tries to learn new things and importantly enhance the previous ones I love robotics, space, aliens, computers, romance, music, and ... internationalization!

Updated on July 05, 2022

Comments

  • Hossain Khademian
    Hossain Khademian almost 2 years

    I have sort of elements with this pattern:

    <div data-image="{imageurl}" ...></div>
    

    I want to set this elements background-image to data-image. I test this CSS code:

    div[data-image] {
        border: 2px solid black;
        background-image: attr(data-image url);
    }
    

    border show correctly but nothing happened for background How can do I fix this code only with css (not js or jq)?

  • Hashem Qolami
    Hashem Qolami over 9 years
    Note that url( attr(data-image) ) is definitely wrong. According to CSS Values and Units Module Level 3, url() notation only accepts bare/quoted <string> as URI. The OP has already used the valid syntax of attr(), but it is not implemented in browsers yet.
  • cuSK
    cuSK over 9 years
    @HashemQolami, thank you. But I didn't understand the documentation of url. What exactly will come in place of url( attr() )??
  • Hashem Qolami
    Hashem Qolami over 9 years
    As I mentioned, the OP used the valid syntax: attr(data-image url) which is stated by the spec. The new syntax of attr() is: attr( <attr-name> <type-or-unit>? [ , <fallback> ]? ) where optional <type-or-unit> specifies the type of the given <attr-name> and the <fallback> would be the default value if named attribute is missing.
  • cuSK
    cuSK over 9 years
    @HashemQolami, thank you for your valuable help. I never learnt anything from documentations, everything I learn is from a person's teachings. But, I still include the links to documentation for clearing problems to questioners.
  • rr-
    rr- about 8 years
    What I meant was that such attr() usage remains unimplemented in the browsers, which is pity.
  • cuSK
    cuSK about 8 years
    @rr- Yeah... People think that technology is growing fast, but we realize that it is growing too slow. :)
  • user2428118
    user2428118 almost 8 years
    I think = needs to be : in your CSS.
  • TheCrazyProfessor
    TheCrazyProfessor about 7 years
    Limit yes, attir(data) works in most browser but the CSS3 version attr(data type fallback) are not supported. See browser status for CSS3 attr
  • REJH
    REJH about 7 years
    Seufs. I really hoped that this would work but alas. Pretty weird that attr() has been supported since forever (Chrome 2.0(!) for example) but only for 'content'. Who invented this? Tesla? Did any progress on this go down with him like all the other cool stuff he dreamed up? :(
  • Joschi
    Joschi over 6 years
    This is a simple solution to the question without browser incombabilities and thus should be upvoted.
  • pseudosavant
    pseudosavant over 4 years
    This should be the accepted solution IMO. It allows you to set an attribute that the CSS can use to specify the background image. This is just using style instead of data-*. Very clever solution.
  • Ayyash
    Ayyash about 4 years
    yeah but if you have a dynamic list, that won't work
  • Eliran Malka
    Eliran Malka about 4 years
    @Ayyash - what do you mean by dynamic list, and why wouldn't it work?
  • Ayyash
    Ayyash about 4 years
    where the output is generated in a for-loop, and the --bg-image is reset on every iteration to a new value
  • Rocksn17
    Rocksn17 over 3 years
    What if you have a csp with no inline styles allowed... security and that?
  • DevWL
    DevWL over 3 years
    Very clever :) !
  • andfra
    andfra about 3 years
    Why it that not working "solution" has 18 votes up?
  • Eliran Malka
    Eliran Malka over 2 years
    @Rocksn17 - then your only alternative is using an <img />, and that has its own security flaws. i guess this whole problem is an interesting kind of css-injection :)
  • Jason C
    Jason C almost 2 years