0

I have some HTML created by wordpress generated data that basically shows images within a div.

I want the following if possible;

If div has less than 4 images - only show the first image in the div! Here is the example HTML generated;

 <div class="display-block">
 <img src="image">
 <img src="image">
 <img src="image">
 <img src="image">
 </div>

 <div class="display-block">
 <img src="image">
 <img src="image">
 <img src="image">
 </div>

So based on the above, the first display-block div will show all its children images, but the second one which only has 3 children images, will only show the first image.

This is basically so i can fill a thumbnail equally visually.

Here is a screenshot also so you can see what I mean; enter image description here

So, the first block 'productivity' only has two images and doesn't fill the its container nicely. This is what i want to target like so

This div has less than 4 images, so hide all but the first one and make it fill it's container which I can do by changing image max width. The second block 'code snippets' only has 1 image and fill's it's container nicely because I was able to target this with the only-child selector.

And then the 3rd block 'website design inspiration' has 4 or more images, so it pulls the first 4 and fills its' container nicely.

BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
Joel Rosen
  • 157
  • 1
  • 11
  • 2
    If you only need to format the images themselves differently (and not the div around them), you can use “CSS Quantity Queries” like so, https://alistapart.com/article/quantity-queries-for-css Otherwise, you will either have to use jQuery - or, if possible, make that decision server-side already. If those images get output in a loop over some data set, then it should be possible to count them at that point, and give the container element an appropriate class based on that. – CBroe Mar 01 '17 at 13:52
  • Will there be occasions where there will, or might be, more than four images in a `
    `?
    – David Thomas Mar 01 '17 at 13:57
  • @CBroe: What a fantastic name for a technique that will never get confused with names of actual, distinct CSS features. – BoltClock Mar 01 '17 at 17:59

3 Answers3

1

Assuming that the maximum number of <img> elements in a <div> element will be four, the following CSS should serve your needs:

img {
  /* hiding all images by default: */
  display: none;
}

/* Showing the first <img> element (if
   it's also the first child of its
   parent): */    
img:first-child,

/* Selecting the image which is the
   fourth-last-child of its parent
   element, and from there selecting
   all <img> elements which follow: */
img:nth-last-child(4)~img {
  display: inline-block;
}

div.display-block {
  margin-bottom: 1em;
}

img {
  box-shadow: 0 0 3px 1px limegreen;
  height: 4em;
  width: 2em;
  /* using opacity, rather than
     'display: none' in order that
     you can easily see which
     <img> elements are selected */
  opacity: 0.2;
}

img:first-child,
img:nth-last-child(4)~img {
  opacity: 1;
}
<div class="display-block">

  <img src="image">
  <img src="image">
  <img src="image">
  <img src="image">


</div>


<div class="display-block">

  <img src="image">
  <img src="image">
  <img src="image">


</div>

JS Fiddle demo.

With regard to the comment to another question:

…now [I] need to make the first [image's] width change to fill the box…

Given that requirement, all you really have to do is define width: 100%, but bear in mind that this will also cause overflow on those <div> elements with the four <img> elements showing, so you would need to define scrolling behaviour, such as overflow-x: auto:

div.display-block {
  margin-bottom: 1em;
  /* my assumption is that you're wanting a
     horizontal carousel, therefore I'm
     forcing the <img> elements to be on the
     same 'line' of the parent element: */
  white-space: nowrap;

  /* allowing the browser to decide whether
     a scroll bar is necessary: */
  overflow-x: auto;
  width: 80%;
  margin: 0 auto;
  border: 2px solid #000;
}

img {
  box-shadow: 0 0 3px 1px limegreen;
  /* setting the width of the <img>
     elements to 100% of the width
     of the parent; here we set only
     the width so as to allow the
     browser to maintain the image's
     aspect ratio: */
  width: 100%;
  /* hiding the <img> elements by
     default: */
  display: none;
}

img:first-child,
img:nth-last-child(4)~img {
  /* displaying the <img> elements
     matching the above selectors: */
  display: inline-block;
}

div.display-block {
  margin-bottom: 1em;
  white-space: nowrap;
  overflow-x: auto;
  width: 80%;
  margin: 0 auto;
  border: 2px solid #000;
}

img {
  box-shadow: 0 0 3px 1px limegreen;
  width: 100%;
  display: none;
  background-color: #f90;
}

img:first-child,
img:nth-last-child(4)~img {
  display: inline-block;
}
<div class="display-block">

  <img src="http://lorempixel.com/300/300/nightlife/1">
  <img src="http://lorempixel.com/200/300/nightlife/2">
  <img src="http://lorempixel.com/300/200/nightlife/3">
  <img src="http://lorempixel.com/500/500/nightlife/4">


</div>


<div class="display-block">

  <img src="http://lorempixel.com/300/300/nature/1">
  <img src="http://lorempixel.com/300/300/nature/2">
  <img src="http://lorempixel.com/300/300/nature/3">


</div>

JS Fiddle demo.

References:

David Thomas
  • 249,100
  • 51
  • 377
  • 410
  • very nice but I think you may have to use nth-child instead of nth-last-child as if there are more than 4 images this wouldn't work – Pete Mar 01 '17 at 14:07
  • 1
    @Pete: hence my (so-far-ignored) comment to the question (I'll look at it some more, but it shouldn't be all that tricky to amend to 'more than four,' hopefully) :) – David Thomas Mar 01 '17 at 14:08
  • @DavidThomas thanks for your answer to the question. Damian,s concise answer worked perfectly in this case. I appreciate your time though. Joel – Joel Rosen Mar 02 '17 at 01:10
0

There is probably a more compact way of doing this but this works:

$(document).ready(function(){
$(".display-block").each(function(){
    if ($(this).find("img").length <4)
    {
       $(this).hide();
    }
    else
    {
       $(this).show();
    }
  })
});

Another more compact way:

$(document).ready(function(){
    $(".display-block").hide();
    $(".display-block img:nth-child(4)").each(function(){
        $(this).closest(".display-block").show();
    });
});
MikeS
  • 1,734
  • 1
  • 9
  • 13
0

You need to loop through every div with class .display-block and check if count of children is less than 4. if so, then hide every child other than first :) Look at this code:

$(".display-block").each(function() {
  if($(this).children().length < 4) {
    $(this).children(":not(:first-of-type)").fadeOut(0);
  }
});

You can also look at the final example here:

$(".display-block").each(function() {
  if ($(this).children().length < 4) {
    $(this).children(":not(:first-of-type)").fadeOut(0);
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="display-block">

  <img src="image">
  <img src="image">
  <img src="image">
  <img src="image">


</div>


<div class="display-block">

  <img src="image">
  <img src="image">
  <img src="image">


</div>
Damian Bartosik
  • 498
  • 6
  • 24
  • Damian! Thanks so much.. That's really close but now i need to make the first images width change to fill the box! - take a look here - http://buckets.me/Joelyorca/ – Joel Rosen Mar 01 '17 at 14:05
  • Sorted it - added - $(this).children(":not(:first-of-type)").fadeOut(0); $('.display-block img:first').css({ width: '200px' into my jQuery function! – Joel Rosen Mar 01 '17 at 14:11
  • @joelyorca i was preparing a jsfiddle for you with that fix, glad to see you resolved your problem :) But remember, not to look for first image by $('.display-block img:first'), because it sets 200px width to all images, better use this selector: $(this).children(":first-of-type") or simply: $(this).children().first() – Damian Bartosik Mar 01 '17 at 14:13
  • Thanks for your help Damian. I'm currently building a full web app in wordpress solo and could do with a little ad hoc help. Would you be available for a day or two's work? – Joel Rosen Mar 01 '17 at 16:38