0

I'm trying to recreate the google image row layout because I can't find any library that can help me. It doesn't matter how many images you add or the size, the row will auto adjust. I'm pretty close except for the vertical alignment of the "Hover text". I'd like to have it in the center of the image. I read this could be done by line-height but this does not work properly when you use a longer piece of text.

Here is my code jsFiddle

<div class="image-row">
  <a href="#1" class="wrapper">
      <span class="text">Hover text</span>
      <img src="https://source.unsplash.com/random/768x960" width="768" height="960"/>
  </a>
  <a href="#2" class="wrapper">
      <span class="text">Hover text</span>
      <img src="https://source.unsplash.com/random/1280x851" width="1280" height="851"/>
  </a>
    <a href="#2" class="wrapper">
      <span class="text">Hover text</span>
      <img src="https://source.unsplash.com/random/1600x1600" width="1600" height="1600"/>
  </a>
</div>
function picRow(selector) {

            masterArray = [];

            // create each lineArray and push it to masterArray 
            $(selector).each(function () {

                // get "selector" css px value for margin-bottom 
                // - parse out a floating point number 
                // - and divide by the outer width to get a decimal percentage
                margin = (parseFloat($(this).css("margin-bottom"), 10)) / ($(this).outerWidth());
                marginRight = margin * 100 + "%";
                // subtract subtract the total child margin from the total width to find the usable width
                usableWidth = (1 - ((($(this).find("img").length) - 1) * margin));

                // for each child img of "selector" - add a width/height as value in the ratios array
                ratios = [];
                $(this).find("img").each(function () {
                    ratios.push(($(this).attr('width')) / ($(this).attr('height')));
                });

                // sum all the ratios for later divison
                ratioSum = 0;
                $.each(ratios, function () {
                    ratioSum += parseFloat(this) || 0;
                });

                lineArray = [];
                $.each(ratios, function (i) {
                    obj = {
                        // divide each item in the ratios array by the total array
                        // as set that as the css width in percentage
                        width: ((ratios[i] / ratioSum) * usableWidth) * 100 + "%",
                        height: ((ratios[i] / ratioSum) * usableWidth) * 100 + "%",
                        // set the margin-right equal to the parent margin-bottom
                        marginRight: marginRight
                    };
                    lineArray.push(obj);
                });
                lineArray[lineArray.length - 1].marginRight = "0%";
                // alert(lineArray[lineArray.length - 1].marginRight);
                masterArray.push(lineArray);
            });

            $(selector).each(function (i) {

                $(this).find("img").each(function (x) {
                    $(this).css({
                        "width": masterArray[i][x].width,
                        "margin-right": masterArray[i][x].marginRight
                    });

                });
                $(this).find(".text").each(function (x) {
                                var imgHeight = $(this).parent().find("img").height();
                                //console.log(imgHeight)
                    $(this).css({
                        "width": masterArray[i][x].width,
                        "height": imgHeight,
                        "margin-right": masterArray[i][x].marginRight                        
                    });
                });
            });

        }

        $(document).ready(function () {
            picRow(".image-row");
        });
        $( window ).resize(function() {
            picRow(".image-row");
        });
html, body {
  height: 100%;
}

.image-row {
  width: 100%;
  margin: 1% 0;
}
.image-row img {
  width: 100%;
  height: auto;
  display: block;
  font-size: 0;
  float: left;
}
.image-row::after {
  content: "";
  display: table;
  clear: both;
}

*{
    box-sizing: border-box;
}

.wrapper {
    position: relative;
    padding: 0;
    /*width:100px;*/
    display:block;
}
.text {
    position: absolute;
    top: 50%;
    /*line-height: 441px;*/
    color:#9CBDBE;
    font-weight:bold;
    font-size:100%;
    background-color:#fff;
    width: 100px;
    text-align: center;
    padding: 1%;
    z-index: 10;
    opacity: 0;
    -webkit-transition: all 0.5s ease;
    -moz-transition: all 0.5s ease;
    -o-transition: all 0.5s ease;
    transition: all 0.5s ease;
}
.text:hover {
    opacity:0.8;
}

img {
    z-index:1;
}

People tell me this is possible without jQuery and just using CSS but then I lose all the responsiveness..

user2103237
  • 69
  • 1
  • 8
  • 3
    You can just make your `.text` overlay a flexbox. Just add `display: flex; align-items: center; justify-content: center` – zgood Nov 20 '19 at 13:00
  • Possible a duplicate https://stackoverflow.com/questions/5703552/css-center-text-horizontally-and-vertically-inside-a-div-block – Awais Nov 20 '19 at 13:01
  • Unfortunately using flexbox breaks my code. When I started developing this I tried to use flexbox first but I couldn't get the desired result. – user2103237 Nov 20 '19 at 13:43

3 Answers3

0

Please find below code

<div class="image-row">
  <a href="#1" class="wrapper">

      <img src="https://source.unsplash.com/random/768x960" width="768" height="960"/>
        <div class="overlay">
    <div class="text">Hover</div>
  </div>
  </a>
  <a href="#2" class="wrapper">

      <img src="https://source.unsplash.com/random/1280x851" width="1280" height="851"/>
        <div class="overlay">
    <div class="text">Hover</div>
  </div>
  </a>
    <a href="#2" class="wrapper">

      <img src="https://source.unsplash.com/random/1600x1600" width="1600" height="1600"/>
        <div class="overlay">
    <div class="text">Hover</div>
  </div>
  </a>
</div>

--- Jquery

function picRow(selector) {

            masterArray = [];

            // create each lineArray and push it to masterArray 
            $(selector).each(function () {

                // get "selector" css px value for margin-bottom 
                // - parse out a floating point number 
                // - and divide by the outer width to get a decimal percentage
                margin = (parseFloat($(this).css("margin-bottom"), 10)) / ($(this).outerWidth());
                marginRight = margin * 100 + "%";
                // subtract subtract the total child margin from the total width to find the usable width
                usableWidth = (1 - ((($(this).find("img").length) - 1) * margin));

                // for each child img of "selector" - add a width/height as value in the ratios array
                ratios = [];
                $(this).find("img").each(function () {
                    ratios.push(($(this).attr('width')) / ($(this).attr('height')));
                });

                // sum all the ratios for later divison
                ratioSum = 0;
                $.each(ratios, function () {
                    ratioSum += parseFloat(this) || 0;
                });

                lineArray = [];
                $.each(ratios, function (i) {
                    obj = {
                        // divide each item in the ratios array by the total array
                        // as set that as the css width in percentage
                        width: ((ratios[i] / ratioSum) * usableWidth) * 100 + "%",
                        height: ((ratios[i] / ratioSum) * usableWidth) * 100 + "%",
                        // set the margin-right equal to the parent margin-bottom
                        marginRight: marginRight
                    };
                    lineArray.push(obj);
                });
                lineArray[lineArray.length - 1].marginRight = "0%";
                // alert(lineArray[lineArray.length - 1].marginRight);
                masterArray.push(lineArray);
            });

            $(selector).each(function (i) {

                $(this).find("img").each(function (x) {

                                   $(this).parent().css({
                        "width": masterArray[i][x].width,
                        "margin-right": masterArray[i][x].marginRight
                    });

                });

            });

        }

        $(document).ready(function () {
            picRow(".image-row");
        });
        $( window ).resize(function() {
            picRow(".image-row");
        });

-- CSS

html, body {
  height: 100%;
}

.image-row {
  width: 100%;
  margin: 1% 0;
}
.image-row img {
  width: 100%;
  height: auto;
  display: block;
  font-size: 0;
  float: left;
}
.image-row::after {
  content: "";
  display: table;
  clear: both;
}

*{
    box-sizing: border-box;
}

.wrapper {
    position: relative;
    padding: 0;
    display: block;
    font-size: 0;
    float: left;
}
.overlay {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  height: 100%;
  width: 100%;
  opacity: 0;
  transition: .5s ease;
  background-color: #fff;
}

.wrapper:hover .overlay {
  opacity: 0.8;
}

.text {
  color: #000;
  font-size: 20px;
  position: absolute;
  top: 50%;
  left: 50%;
  -webkit-transform: translate(-50%, -50%);
  -ms-transform: translate(-50%, -50%);
  transform: translate(-50%, -50%);
  text-align: center;
}
img {
    z-index:1;
}

** Please replace above code then it will achieve your requirement easily.

0

You can add this following code to your .text class in your css :

.text { 
position: absolute; 
top: 50%; 
line-height: 150px; 
color:#9CBDBE; 
font-weight:bold; 
font-size:17px; 
background-color:#fff; 
width: 100px; 
text-align: center; 
padding: 1%; 
z-index: 10; 
opacity: 0; 
-webkit-transition: all 0.5s ease; 
-moz-transition: all 0.5s ease; 
-o-transition: all 0.5s ease; 
transition: all 0.5s ease; 
}

Here is the jsfiddle https://jsfiddle.net/jfgnta38/1/

Also, if i may, you should learn flexbox which is a really useful "tool" to put your element where you want.

franjuju
  • 52
  • 5
-1

You can try using bootstrap https://getbootstrap.com/docs/4.0/layout/grid/ to get it done

Deejay
  • 907
  • 1
  • 6
  • 10
  • Except boostrap grid is for 12 columns and not really suited for *"doesn't matter how many images you add"* – freedomn-m Nov 20 '19 at 14:37