Using HTML data-attribute to set CSS background-image url
Asked Answered
D

10

104

I plan on building a custom photo gallery for a friend and I know exactly how I am going to be producing the HTML, however I am running into a small issue with the CSS.
(I would prefer to not have the page styling rely on jQuery if possible)


My question regards:
Data-Attribute in HTML
Background-image in CSS
I am using this format for my html thumbnails:
<div class="thumb" data-image-src="images/img.jpg"></div>

and I assume the CSS should look something like this:

.thumb {
    width:150px;
    height:150px;
    background-position:center center;
    overflow:hidden;
    border:1px solid black;

    background-image: attr(data-image-src);/*This is the question piece*/
}


My goal is to take the data-image-src from the div.thumb in my HTML file and use it for each div.thumb(s) background-image source in my CSS file.

Here is a Codepen Pen in order to get a dynamic example of what I am looking for:
http://codepen.io/thestevekelzer/pen/rEDJv

Dibs answered 31/3, 2013 at 21:8 Comment(0)
K
75

If you wanted to keep it with just HTML and CSS you can use CSS Variables. Keep in mind, css variables aren't supported in IE.

<div class="thumb" style="--background: url('images/img.jpg')"></div> 
.thumb {
    background-image: var(--background);
}

Codepen: https://codepen.io/bruce13/pen/bJdoZW

Kellikellia answered 2/4, 2019 at 12:43 Comment(9)
This is probably the best answer at this moment. No javascript is always good.Kennard
+1. This is a more flexible solution than just adding the image directly inline as in another answer below, because you can declare multiple image paths for, say, multiple resolutions, and then decide in your CSS code which image to load for which resolution.Ciccia
at this point why not just set background-image in style attribute, why even bother with variable??Hippel
@MuhammadUmer I use background-image a lot too, just trying to fit the askers question as best as possible. Two benefits to using a variable I can think of off the top of my head are: 1) You can overwrite it more easily using CSS, not needing an !important. 2) You can setup default images in case the variable isn't set in :root{}. I updated my CodePen to illustrate these changes.Kellikellia
Also add background-size: cover; as per the @whitehawk comment if you want the image to fit properly.Patrolman
Just found a reason to set background-image directly: I don't know why but Chrome flickers the background image when I hover if I use the background-image: var(--background) method.Yettayetti
Beautiful. This allowed me to style pseudo-elements on the fly!!!Leggy
AWESOME... I'm giving a try right nowHoneywell
this style trick (awesome!) bridges 2 worlds: css and html! By using css variables you make the background image - or whatever - a variable value instead of a hardcoded one. Now one can only modify the css vars to update the view in html. By filling the gap between css and html with this trick now, you instantly update your css without even touching it! Isn't that great? One only remark: don't define your css vars at root but at the root node of your view, a div, section, anything for reasons that can't be explained here!Slider
B
74

You will eventually be able to use

background-image: attr(data-image-src url);

but that is not implemented anywhere yet to my knowledge. In the above, url is an optional "type-or-unit" parameter to attr(). See https://drafts.csswg.org/css-values/#attr-notation.

Banks answered 25/8, 2013 at 17:52 Comment(13)
When you say eventually, is there a way to know WHEN that will be from the W3 site roughly?Dibs
Random guess without knowing anything about specific implementation status is 1-2 years before it's available in all the browser tracks.Banks
@torazaburo year one is over, still full of hope.Mendiola
Not on the chromium roadmap for 2016 :( #246571Pettigrew
@Felipe. Yes, we know. This question is about something else.Banks
caniuse.com/#feat=css3-attr To date, no browser has implemented this feature yet.Gigantic
Still nothing :|Accomplish
@BartBurg it says only for content property. As per caniuse.com/#feat=css3-attr attr() on any CSS property is not supported yet.Karol
2021... still no browsers supporting, feels like this is not going to happen :(Retirement
It's doesn't work at all. It's no solve any issue.Wodge
developer.mozilla.org/en-US/docs/Web/CSS/attrPraetorian
For more recent readers... this feature still hasn't been implemented by any of the major browser vendors: caniuse.com/css3-attrFerrante
2028 still hasn't been implementedOuttalk
B
18

It is not best practise to mix up content with style, but a solution could be

<div class="thumb" style="background-image: url('images/img.jpg')"></div>
Body answered 28/5, 2015 at 16:23 Comment(0)
B
7

You will need a little JavaScript for that:

var list = document.getElementsByClassName('thumb');

for (var i = 0; i < list.length; i++) {
  var src = list[i].getAttribute('data-image-src');
  list[i].style.backgroundImage="url('" + src + "')";
}

Wrap that in <script> tags at the bottom just before the </body> tag or wrap in a function that you call once the page loaded.

Buckler answered 29/5, 2013 at 20:45 Comment(0)
C
2

How about using some Sass? Here's what I did to achieve something like this (although note that you have to create a Sass list for each of the data-attributes).

/*
  Iterate over list and use "data-social" to put in the appropriate background-image.
*/
$social: "fb", "twitter", "youtube";

@each $i in $social {
  [data-social="#{$i}"] {
    background: url('#{$image-path}/icons/#{$i}.svg') no-repeat 0 0;
    background-size: cover; // Only seems to work if placed below background property
  }
}

Essentially, you list all of your data attribute values. Then use Sass @each to iterate through and select all the data-attributes in the HTML. Then, bring in the iterator variable and have it match up to a filename.

Anyway, as I said, you have to list all of the values, then make sure that your filenames incorporate the values in your list.

Cincture answered 10/10, 2017 at 15:15 Comment(3)
This requires you to have a known list of values in your styles declaration. When I asked this question, I was attempting to have the markup drive what the styles displayed instead of the other way around.Dibs
Yeah, that’s tuff. Sorry!Cincture
This helped me with a similar issue, and also showed me a Sass feature I didn't know existed, cheers!Alger
A
1

HTML

<div class="thumb" data-image-src="img/image.png">

jQuery

$( ".thumb" ).each(function() {
  var attr = $(this).attr('data-image-src');

  if (typeof attr !== typeof undefined && attr !== false) {
      $(this).css('background', 'url('+attr+')');
  }

});

Demo on JSFiddle

You could do this also with JavaScript.

Acis answered 16/4, 2015 at 12:49 Comment(1)
Would if (attr) { get you in trouble? I don't see the point in the strict typeof and false checks, since both false and undefined are falsy values.Birnbaum
M
1

For those who want a dumb down answer like me

Something like how to steps as 1, 2, 3

Here it is what I did

First create the HTML markup

<div class="thumb" data-image-src="images/img.jpg"></div>

Then before your ending body tag, add this script

I included the ending body on the code below as an example

So becareful when you copy

<script>
var list = document.getElementsByClassName('thumb');

for (var i = 0; i < list.length; i++) {
  var src = list[i].getAttribute('data-image-src');
  list[i].style.backgroundImage="url('" + src + "')";
}
</script>

</body>
Marleenmarlen answered 16/2, 2019 at 5:57 Comment(0)
J
0

HTML CODE

<div id="borderLoader"  data-height="230px" data-color="lightgrey" data- 
width="230px" data-image="https://fiverr- res.cloudinary.com/t_profile_thumb,q_auto,f_auto/attachments/profile/photo/a54f24b2ab6f377ea269863cbf556c12-619447411516923848661/913d6cc9-3d3c-4884-ac6e-4c2d58ee4d6a.jpg">

</div>

JS CODE

var dataValue, dataSet,key;
dataValue = document.getElementById('borderLoader');
//data set contains all the dataset that you are to style the shape;
dataSet ={ 
   "height":dataValue.dataset.height,
   "width":dataValue.dataset.width,
   "color":dataValue.dataset.color,
   "imageBg":dataValue.dataset.image
};

dataValue.style.height = dataSet.height;
dataValue.style.width = dataSet.width;
dataValue.style.background = "#f3f3f3 url("+dataSet.imageBg+") no-repeat 
center";
Jody answered 15/4, 2018 at 16:44 Comment(0)
D
0

Here is simple example using jQuery we can put the images in background

$('*[data-background-image]').each(function() {
    $(this).css({
        'background-image': 'url(' + $(this).data('background-image') + ')'
    });
});
div{
  height:200px;
  width:100% ;
  background-size: cover;
  background-position: center center;
  background-repeat: no-repeat;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div data-background-image="https://via.placeholder.com/500"> </div>
Debauch answered 3/5, 2021 at 7:22 Comment(2)
While this code may answer the question, adding some explanation on how and why it solves it will improve the quality of your answerDrongo
Thanks for background-size: cover; makes the image fit properly! :-)Patrolman
J
0

CSS3 Variables

HTML:

<div style="--thumbnail: url(https://example.com/images/source.png)"></div>

CSS:

&:after
{
  content: "";
  ...
  background-image: var(--thumbnail);
}
Jahn answered 2/8, 2023 at 12:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.