简体   繁体   中英

How to vertically center text from image overlay

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

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.

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM