如何从图像叠加中垂直居中文本

Posted

技术标签:

【中文标题】如何从图像叠加中垂直居中文本【英文标题】:How to vertically center text from image overlay 【发布时间】:2020-03-16 04:48:02 【问题描述】:

我正在尝试重新创建 google 图像行布局,因为我找不到任何可以帮助我的库。无论您添加多少图像或大小,该行都会自动调整。除了“悬停文本”的垂直对齐之外,我非常接近。我想把它放在图像的中心。我读到这可以通过 line-height 来完成,但是当您使用较长的文本时,这将无法正常工作。

这是我的代码jsFiddle

<div class="image-row">
  <a href="#1" class="wrapper">
      <span class="text">Hover text</span>
      <img src="https://source.unsplash.com/random/768x960"  />
  </a>
  <a href="#2" class="wrapper">
      <span class="text">Hover text</span>
      <img src="https://source.unsplash.com/random/1280x851"  />
  </a>
    <a href="#2" class="wrapper">
      <span class="text">Hover text</span>
      <img src="https://source.unsplash.com/random/1600x1600"  />
  </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;

人们告诉我这在没有 jQuery 并且只使用 CSS 的情况下是可能的,但是我失去了所有的响应能力..

【问题讨论】:

你可以让你的.text覆盖一个flexbox。只需添加display: flex; align-items: center; justify-content: center 可能重复***.com/questions/5703552/… 不幸的是,使用 flexbox 会破坏我的代码。当我开始开发这个时,我尝试先使用 flexbox,但我无法得到想要的结果。 【参考方案1】:

您可以将以下代码添加到您的 css 中的 .text 类中:

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

这里是 jsfiddle https://jsfiddle.net/jfgnta38/1/

另外,如果可以的话,你应该学习 flexbox,这是一个非常有用的“工具”,可以将你的元素放在你想要的地方。

【讨论】:

【参考方案2】:

请看下面的代码

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

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

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

      <img src="https://source.unsplash.com/random/1600x1600"  />
        <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;

** 请替换上面的代码,它会很容易达到你的要求。

【讨论】:

【参考方案3】:

您可以尝试使用引导程序https://getbootstrap.com/docs/4.0/layout/grid/ 来完成它

【讨论】:

除了 boostrap 网格是 12 列,并不真正适合 “不管你添加多少图像”

以上是关于如何从图像叠加中垂直居中文本的主要内容,如果未能解决你的问题,请参考以下文章

如何在我的叠加 div 中垂直居中我的跨度?

如何在图像旁边垂直居中文本? [复制]

如何在图中垂直居中文本?

CSS如何在不改变图像样式的情况下垂直居中图像和文本

在另一个没有尺寸的情况下垂直/水平居中图像

如何在具有(流体高度)的响应框中垂直居中文本[重复]