108

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

10 Answers 10

82

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

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

9 Comments

This is probably the best answer at this moment. No javascript is always good.
+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.
at this point why not just set background-image in style attribute, why even bother with variable??
@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.
Also add background-size: cover; as per the @whitehawk comment if you want the image to fit properly.
|
76

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.

14 Comments

When you say eventually, is there a way to know WHEN that will be from the W3 site roughly?
Random guess without knowing anything about specific implementation status is 1-2 years before it's available in all the browser tracks.
@torazaburo year one is over, still full of hope.
Not on the chromium roadmap for 2016 :( #246571
caniuse.com/#feat=css3-attr To date, no browser has implemented this feature yet.
|
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>

Comments

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.

Comments

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.

3 Comments

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.
Yeah, that’s tuff. Sorry!
This helped me with a similar issue, and also showed me a Sass feature I didn't know existed, cheers!
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.

1 Comment

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.
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";

Comments

0

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>

Comments

0

CSS3 Variables

HTML:

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

CSS:

&:after
{
  content: "";
  ...
  background-image: var(--thumbnail);
}

Comments

-1

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>

2 Comments

While this code may answer the question, adding some explanation on how and why it solves it will improve the quality of your answer
Thanks for background-size: cover; makes the image fit properly! :-)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.