制作一个div,它覆盖可自动缩放的图像,并且与图像一样高但是更窄并且居中

时间:2015-10-16 15:48:35

标签: jquery css css3

我有一个带有自动调整图像的网页,因此它总是和页面一样宽。在这张图片上,我想叠加四个相邻的半透明面板,上面叠加完全不透明的文字。面板和文本区域必须与图像一样高。但是面板占据的区域必须比图像窄,以其为中心,具有指定的最大和最小宽度。效果应该类似于下面的屏幕截图和http://www.j-paine.org/css_demos/test23.html的现场演示,但面板区域的左右边缘与红色条的边缘完全对齐:
........

我使用jQuery进行了演示工作,如下所述,但是我可以在没有JavaScript的情况下在纯CSS中完成我想做的事情吗?我问,因为我的jQuery代码似乎没有让对齐得当。此外,虽然它适用于Firefox,但它不适用于Chrome。在Chrome上,面板区域与页面左侧对齐。

为了制作我的演示,我有以下div和其他元素的层次结构。这可以在test23.html中看到,其中ID和类定义为(注释)test23.css,它链接到:

image-holder-div
  (This holds the image and overlays. I've made it relative
   so as start a new stacking context.)
  The image
  image-overlay-div
    (This must be as high as the image, but narrower
     and centered within it, with maximum and minimum
     width. Its left and right edges should be aligned
     with the red bars, i.e. with those of class 
     inner-div . I have given it height 100% and position
     absolute, so that it is as high as image-holder-div
     and defines its position relative to that. I set its
     'left' and 'width' by copying them from inner-div
     in jQuery.)
  image-overlay-segment-1-holder
    (This holds the first panel. It has height 100%,
     position absolute, z-index 10, and width and left 
     edge set so as to occupy the first quarter of 
     image-overlay-div.)
    image-pale-orange-overlay
      (This must go in front of the image. It has 
       an opacity of 0.2, width and height of 100%, 
       position absolute, and z-index 20.)
    image-text-overlay
      (This must go in front of the pale orange, 
       and the text must be completely opaque. It
       has height and width of 100%, position
       absolute, and z-index 30.)
  image-overlay-segment-2-holder, and similarly for panel 3 and 4
    (These work in the same way as above.)

对齐image-overlay-div的jQuery代码是:

function setPos()
{
  var its_left = $( ".inner-div" ).position().left;
  var its_width = $( ".inner-div" ).width();
  $( "#image-overlay-div" ).css( "left", its_left + "px" );
  $( "#image-overlay-div" ).css( "width", its_width + "px" );
}

$( document ).ready( setPos );

$( window ).resize( setPos );

上面的层次结构是我能想到的最简单的工作方式。我发现的一个限制是,我无法使文本覆盖为淡橙色叠加的子项,因为它继承了后者的不透明度,因此文本是半透明的。

另外,在纯CSS中,我无法找到一种方法使图像叠加div与图像一样高,但水平对齐就像我想要的那样。为了使它与图像一样高,我需要它具有绝对位置(我认为),但是我无法看到如何对齐它。如果我更改位置值以便我可以对齐它,那么我就无法获得正确的高度。这就是我使用JavaScript的原因。但我真的需要,或者我错过了一些关于CSS的有用事实?

对于想要在不从我的网站下载示例的情况下尝试此操作的任何人,我在下方添加了Stack Overflow code snippet



function setPos()
{ 
  var its_left = $( ".inner-div" ).position().left;
  var its_width = $( ".inner-div" ).width();
  $( "#image-overlay-div" ).css( "left", its_left + "px" );
  $( "#image-overlay-div" ).css( "width", its_width + "px" );
}

$( document ).ready( setPos );

$( window ).resize( setPos );

.inner-div
  { width: 75%; 
    max-width: 700px; 
    min-width: 300px; 
    margin: 0 auto; 
    height: 10px;
    background-color: red;
  }
/*
This styles the red lines across the top and
bottom of the page. In the site I'm building, 
most content has to sit between the left and
right edges this line defines. That includes
the image and its overlays. 
*/


#image-holder-div
  { position: relative;
  }
/*
A div holding the image and the divs that are 
overlaid onto it. I made the position is relative 
in order to create a new stacking content.
*/


.image 
  { height: auto;
    max-width: 100%;
    min-width: 100%;
  }
/*
Makes my image occupy 100% of the page width,
resizing as the browser does.
*/


#image-overlay-div
  { left: 99px;
    width: 99px;
    top: 0;
    height: 100%;
    position: absolute;
  }
/*
This div has the same size and
position as the image. I had to use
jQuery for this, to set the 'left'
and 'width' properties to those of
.inner-div . So the 99px's above
should get overwritten as soon as
the page loads.
*/


#image-overlay-segment-1-holder
  { left: 0.5%;
    top: 0;  
    width: 24%;
    height: 100%;
    z-index: 10;
    position: absolute;
  }
/*
Holds the first pale overlay.
Note that width and position are
relative to image-overlay-div (not to the
entire page width), which should be 
the same as being relative to
.inner-div .
*/


#image-overlay-segment-2-holder
  { left: 25.5%;
    top: 0;  
    width: 24%;
    height: 100%;
    z-index: 10;
    position: absolute;
  }
/*
Holds the 2nd pale overlay.
*/


#image-overlay-segment-3-holder
  { left: 50.5%;
    top: 0;  
    width: 24%;
    height: 100%;
    z-index: 10;
    position: absolute;
  }
/*
Holds the 3rd pale overlay.
*/


#image-overlay-segment-4-holder
  { left: 75.5%;
    top: 0;  
    width: 24%;
    height: 100%;
    z-index: 10;
    position: absolute;
  }
/*
Holds the 4th pale overlay.
*/


.image-pale-orange-overlay
  { background-color: orange;
    opacity: 0.2;
    width: 100%;
    height: 100%;
    z-index: 20;
    position: absolute;
  }
/*
The class for the pale orange overlays.
These are translucent, so that the image
shows through them.
*/


.image-text-overlay
  { width: 100%; 
    left: 0;
    top: 0;
    height: 100%;
    text-align: center;
    z-index: 30;
    position: absolute;
    padding-top: 20px;
    font-family: sans-serif;
    font-weight: bold;
    font-size: 2.5vw;
  }
/*
The class for text overlaying the pale
orange ovelay. This must be completely
opaque, so must not inherit the opacity
of the layer behind.
*/

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>

<body>

<div class=inner-div style="margin-bottom:30px;">
</div>

<div id=image-holder-div>

  <img src="http://www.j-paine.org/catalogue/archers_big.jpeg" 
class=image>

  <div id=image-overlay-div>

    <div id=image-overlay-segment-1-holder>

      <div class=image-pale-orange-overlay>
      </div>

      <div class=image-text-overlay>
        <div><a href="http://www.jocelyns-cartoons.uk">READ</a></div>
      </div>

    </div>
    <!-- End image-overlay-segment-1-holder -->

    <div id=image-overlay-segment-2-holder>

      <div class=image-pale-orange-overlay>
      </div>

      <div class=image-text-overlay>
        <div><a href="http://www.jocelyns-cartoons.uk">MORE</a></div>
      </div>

    </div>
    <!-- End image-overlay-segment-2-holder -->

    <div id=image-overlay-segment-3-holder>

      <div class=image-pale-orange-overlay>
      </div>

      <div class=image-text-overlay>
        <div><a href="http://www.jocelyns-cartoons.uk">CARTOONS</a></div>
      </div>

    </div>
    <!-- End image-overlay-segment-3-holder -->

    <div id=image-overlay-segment-4-holder>

      <div class=image-pale-orange-overlay>
      </div>

      <div class=image-text-overlay>
        <div><a href="http://www.jocelyns-cartoons.uk">HERE!</a></div>
      </div>

    </div>
    <!-- End image-overlay-segment-4-holder -->

  </div>
  <!-- End image-overlay-div -->

</div>
<!-- End image-holder-div -->

<div class=inner-div style="margin-top:30px;">
</div>

</body>
</html>
&#13;
&#13;
&#13;

5 个答案:

答案 0 :(得分:1)

这样的东西可能就是你想要的吗?

小提琴:https://jsfiddle.net/o8w972nw/

<强> HTML

<div class="imgBg">
    <div class="wrap">
        <div class="rect">a</div>        
        <div class="rect">b</div>
        <div class="rect">c</div>
        <div class="rect">d</div>
    </div>
</div>

<强> CSS

.imgBg
{
    width:1000px;
    height:1000px;
    background:url('http://placehold.it/1000x1000');
}

.wrap
{
    display:flex;
    justify-content:center;
    align-content:center;

}

.rect
{
    text-align:center;
    height:500px;
    width:50px;
    padding:10px;
    margin:10px;
    background-color:rgba(100, 50, 0, 0.3);
}

答案 1 :(得分:1)

尝试这种css方法。

#image-overlay-div
{ 
    width: 75%;
    height: 100%;   
    top: 0;
    left: 50%;
    margin-left: -37.5%;
    position: absolute;
}
@media (min-width:933px){
    #image-overlay-div
    { 
    max-width: 700px; 
    left: 50%;
    margin-left: -350px;
    }
}
@media (max-width:400px){
    #image-overlay-div
    { 
    min-width: 300px; 
    left: 50%;
    margin-left: -150px;
    }
}  

答案 2 :(得分:1)

我创建了Fiddle我认为确实需要发生的事情。那里有很多复杂的东西,所以我会解释我的所作所为。

我将图像添加为 background-image 到正文。然后我创建了一个容纳四个项目的容器。为了计算它的高度,我做了一个calc()来计算100vw(身体宽度的100%),并将其除以700/578(图像的宽度和高度)。

然后我将容器设为flex容器,这样就可以将子容器保持在中心位置,并在它们之间使用justify-content: space-between;等量的空格。然后,为了将它们拉伸到容器高度的100%,我应用了align-items: stretch;

瞧。它已经完成了。

希望这有帮助。

答案 3 :(得分:1)

我制作了面板display: inline-block;并使用rgba更改了不透明度的方式。

这是CodePen

HTML:

<img src="http://www.j-paine.org/catalogue/archers_big.jpeg">
<div id="wrapper">
  <div id="panel-holder">
    <div id="panel-1" class="panel">SOME</div>
    <div id="panel-2" class="panel">CART</div>
    <div id="panel-3" class="panel">OONS</div>
    <div id="panel-4" class="panel">HURR</div>
  </div>
</div>

SCSS:

body{
  margin: 0;
  padding: 0;
  height: 100%;
}
img{
  position: absolute;
  left: 0;
  top: 0;
  min-width: 100%;
  max-width: 100%;
  height: auto;
}
#wrapper{
  width: 100%;
}
#panel-holder{
  position: relative;
  width: 75%;
  max-width: 700px; 
  min-width: 300px;
  min-height: 100%;
  margin: 2em auto 0;
}
.panel{
  display: inline-block;
  width: 24%;
  text-align: center;
  background: rgba(255, 0, 0, 0.5);
  color: black;
  margin: 0 .125%;
  height: 100vw;
}

我说实话我很难让列垂直扩展而没有内容。如果您的面板内容丰富,或者其他一些方法可以均匀展开,您可能会发现可以删除height: 100vw;。它通过让第四个面板位于下面来打破小视口大小,这可能是由于约束panel-holder的宽度。

答案 4 :(得分:0)

在尝试了上面的答案后,我的回答是我的问题。它位于http://www.j-paine.org/css_demos/test37.html,并在最后复制到代码段。

与我的问题中的演示不同,它不使用JavaScript。它主要来源于Ryan Andrew Chudd的回答,增加了Gust van de Wal使用&#39;计算div大小的技巧。这些是我认为重要的一点:

1)使用&#39; calc&#39;对于视口相对单位,我们可以计算图像与视口一样宽的高度,然后我们可以使它具有该高度。通过在其他地方使用相同的计算,我们可以强制其他div具有相同的高度。 (这样做的一个缺点是它会使维护更加困难,因为每当我们更改为具有不同宽高比的图像时,我们都必须更新所有计算。)

2)使用&#39; rgba&#39;而不是'不透明&#39;半透明背景消除了孩子继承父母不透明度的问题。这减少了所需元素的数量。

3)Ryan定位他的元素的方式消除了对z-indices的需求,而是依赖于CSS的堆叠顺序规则。 (可以说这对维护来说是一个缺点,因为堆叠顺序不再明确。)

4)vertical-align:top以及HTML在display:inline-block元素之间插入的隐式间距需要注意。

这是http://www.j-paine.org/css_demos/test37.html的代码段副本:

&#13;
&#13;
/* 
See  
http://stackoverflow.com/questions/33174608/make-a-div-which-overlays-an-autoresizable-image-and-is-as-high-as-the-image-but
*/


.inner-div
  { width: 75%;
    max-width: 700px;
    min-width: 300px;
    margin: 0 auto;
    height: 10px;
    background-color: red;
  }
/*
This is my usual inner-div red bar.
*/


#image-holder-div
  { margin: 0;
    padding: 0;
    position: relative;
  }
/*
This is a div which imitates how Ryan
styled his body element. The image is 
positioned absolute within it.
*/


.image
  { position: absolute;
    left: 0;
    top: 0;
    min-width: 100%;
    max-width: 100%;
    height: calc(100vw / (700 /578));  
  }
/*
This positions the image absolute 
within the above div, and makes its
width scale with the browser width.
Unlike in test32, the scaling is done
with a 'calc', and should therefore
precisely match the height of .panel .
*/


#image-holder-div
  { width: 100%;
  }
/*
This is Ryan's wrapper for the panels.
*/


#panel-holder
  { position: relative;
    width: 75%;
    max-width: 700px; 
    min-width: 300px;
    margin: 0 auto;
  }
/*
This is positioned relative within
wrapper, and was also Ryan's. It mimics 
the width and horizontal position of inner-div.
*/


.panel
  { display: inline-block;
    vertical-align: top;
    width: 24%;
    margin-left: 0.5%;
    margin-right: 0.5%;
    text-align: center;
    background: rgba( 255, 153, 0, 0.2 );
    color: black;
    font-weight: bold;
    height: calc(100vw / (700 / 578));  
  }
/*
This is mainly Ryan's styling. He added
the display:inline-block and the use of
rgba for colour and opacity. The calc is
mine, imitating Gust van de Wal's answer
to my posting.
*/
&#13;
<center><h1>Test 37</h1></center>

<div class=inner-div style="margin-bottom:30px;">
</div>

<div id=image-holder-div>

  <img src="http://www.j-paine.org/catalogue/archers_big.jpeg" 
  class=image>

  <div id="image-overlay-div">

    <div id="panel-holder">

      <div class="panel">
        <a href="http://www.jocelyns-cartoons.uk">READ</a>      
      </div><!--

   --><div class="panel">
        <a href="http://www.jocelyns-cartoons.uk">MORE</a>
      </div><!--

   --><div class="panel">
        <a href="http://www.jocelyns-cartoons.uk">CARTOONS</a>
      </div><!--

   --><div class="panel">
        <a href="http://www.jocelyns-cartoons.uk">HERE!</a>
      </div>

    </div>

  </div>

</div>

<div class=inner-div style="margin-top:30px;">
</div>
&#13;
&#13;
&#13;