Freddy
Freddy

Reputation: 867

On image hover, cover original image and display text

When hovering on an image, I want a secondary image to display with text, but my approach doesn't seem to work correctly.

How I want imagine it:

Red being normal, and image on right being the hover state.

enter image description here

Here's my current approach:

.img-wrap {
  position: relative;
  height: 360px;
  width: 360px;
}

.img-description {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  background: rgba(29, 106, 154, 0.72);
  color: #fff;
  visibility: hidden;
  opacity: 0;
  transition: opacity .2s, visibility .2s;
}

.img-wrap:hover .img-description {
  visibility: visible;
  opacity: 1;
}
ul {
    list-style-type: none;
    margin: auto;
}
<div class="img-wrap">
  <ul class="clearfix">
    <li>
      <img src="https://cdn2.hubspot.net/hubfs/1878396/LR%20-%20Landing%20page%20images/LR%20-%20Scottish%20Campaign/large-cta.png?t=1528962213286" />
    </li>
  </ul>
  <img class="img-img" src="https://insights.zonal.co.uk/hubfs/LR%20-%20Landing%20page%20images/LR%20-%20Scottish%20Campaign/cta-bg.png" />
  <h2 class="img-description">TEST</h2>
  <span class="button large-cta-button">Read more</span>
</div>

Upvotes: 0

Views: 1011

Answers (4)

Hastig Zusammenstellen
Hastig Zusammenstellen

Reputation: 4440

Here's one way to do it by positioning elements over top of the image. There's some info in the annotations, just ask if you need to know more.

open in full screen (buttons are too tall to see hover fly-in effect)

body {
  margin: 0;
  padding: 0;
}
.container {
  display: flex;
  width: 100%;
  flex-wrap: wrap; /* allows .block's to wrap into the next row when end of row is reached */
}
.block {
  position: relative; /* needs to be relative for absolute positioned children */
  width: 50%;
  padding: 2px; /* the way we'll separate the blocks (margin screws with calculations and box-sizing doesnt currently allow for compensating for margin, only padding and borders, thus far) */
  box-sizing: border-box; /* need this so that we can put padding around the images/inside the block and not affect the width % */
  overflow: hidden; /* have to hide the overflow so the button element that is hidden outside of the parent is not seen */
}
.block img {
  display: block; /* gets rid of the blank space under images */
  width: 100%; /* make it repsonsive to container width. height will be auto */
}
.cover {
  position: absolute; /* make sure parent is position: relative */
  top: 2px; /* 2px because we've put padding inside the block and need the position to be relative to the image not the block */
  right: 2px;
  bottom: 2px;
  left: 2px;
  background-color: hsla(184.2, 55.6%, 54.1%, 0.7);
  opacity: 0;
  transition: all 0.2s linear; /* your animation transition settings */
}
.block:hover > .cover {
  opacity: 1;
}
.button {
  /* i recommend making the block the clickable a tag, not the button, to make things a little more mobile friendly (hover covers make for an additional click needed to follow links on many?/most? mobile devices) */
  position: absolute; /* relative to parent (.block ) */
  right: -50%; /* adjust this and transition speed to make it fly in better */
  bottom: 10%;
  display: flex;
  /* default flex direction is row (left to right) */
  justify-content: center; /* with row justify centers horizontally */
  align-items: center; /* and align centers vertically. opposite for column */
  padding: 8px;
  font-size: 19px;
  text-decoration: none; /* get rid of the underline that is default for a tags */
  color: hsla(0, 0%, 100%, 0.9);
  background-color: hsla(0, 0%, 0%, 0.2);
  border-style: solid;
  border-width: 1px;
  border-color: hsla(0, 0%, 100%, 0.9);
  border-radius: 2px;
  transition: all 0.2s linear;
}
.block:hover > .button {
  right: 10%; /* fly in the button on .block hover */
}
.button:hover {
  background-color: hsla(228.8, 76.2%, 58.8%, 0.2);
}
.button i {
  margin-left: 10px;
  font-size: 120%; /* font is 120% the size of whats inherited from parent (.button = 19px so icon (i) = 22.8ish px) - this is to compensate for the icon being a caret which is much smaller than a full sized icon */
}
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"/>
<div class="container">
  <div class="block">
    <img src="https://cdn2.hubspot.net/hubfs/1878396/LR%20-%20Landing%20page%20images/LR%20-%20Scottish%20Campaign/large-cta.png?t=1528962213286">
    <div class="cover"></div>
    <a class="button" href="https://stackoverflow.com/q/50852429/3377049">Flyin In <i class="fa fa-caret-right"></i></a>
  </div>
  <div class="block">
    <img src="https://cdn2.hubspot.net/hubfs/1878396/LR%20-%20Landing%20page%20images/LR%20-%20Scottish%20Campaign/large-cta.png?t=1528962213286">
    <div class="cover"></div>
    <a class="button" href="https://stackoverflow.com/q/50852429/3377049">Zoooom <i class="fa fa-caret-right"></i></a>
  </div>
</div>

fiddle

https://jsfiddle.net/Hastig/5c0swnq6/

Upvotes: 0

Jared Chu
Jared Chu

Reputation: 2862

There is no need to use another image, just use background color and opacity.

.img-wrap {
  position: relative;
  height: 360px;
  width: 360px;
}

.img-wrap img{
  width: 100%;
  height: 100%;
}

.img-description {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  background: #62ada9;
  color: #fff;
  opacity: 0;
  transition: opacity .3s, visibility .3s;
}

.img-wrap:hover .img-description {
  opacity: 0.8;
}

.img-description h2{
  text-align: center;
}
<div class="img-wrap">
  <img src="https://cdn2.hubspot.net/hubfs/1878396/LR%20-%20Landing%20page%20images/LR%20-%20Scottish%20Campaign/large-cta.png?t=1528962213286" />
  <div class="img-description"><h2>TEST</h2></div>
</div>

Upvotes: 1

Mihai T
Mihai T

Reputation: 17697

For the transparent color overlay you can use a pseudo-element like :after on the li. That way it will always stay on top of the li and on the img. The img should have a max-width:100% so it won't overflow it's parent ( li ).

And then, there is some styling involved which is pretty straight forward. You could also add some animations on how the blueish overlay should appear, but that's up to you.

If you have any questions, please ask in comments.

.img-wrap {
  position: relative;
  height: 360px;
  width: 360px;
}

img {
  max-width: 100%;
  height: auto;
}

.img-wrap ul {
  padding: 0;
}

.img-wrap li {
  position: relative;
}

.img-wrap .img-description {
  position: absolute;
  opacity: 0;
  z-index: 2;
  transition: 0.3s ease-out;
  top: 50%;
  transform: translate(-50%, -50%);
  left: 50%;
  width:auto;
}

.img-wrap li .img-description h2 {
  margin-bottom: 50px;
}

.img-wrap li .img-description a {
  padding: 10px;
  color: #fff;
  border: 1px solid #fff;
}

.img-wrap li:after {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  background: rgba(29, 106, 154, 0.72);
  color: #fff;
  visibility: hidden;
  opacity: 0;
  transition: opacity .2s, visibility .2s;
  height: 100%;
  width: 100%;
  content: "";
}

.img-wrap:hover li:after {
  visibility: visible;
  opacity: 1;
}

.img-wrap:hover .img-description {
  opacity: 1;
}

ul {
  list-style-type: none;
  margin: auto;
}
<div class="img-wrap">
  <ul class="clearfix">
    <li>
      <img src="https://cdn2.hubspot.net/hubfs/1878396/LR%20-%20Landing%20page%20images/LR%20-%20Scottish%20Campaign/large-cta.png?t=1528962213286" />
      <div class="img-description">
        <h2>
          TEST
        </h2>
        <a>Test link</a>
      </div>
    </li>
  </ul>
</div>

Upvotes: 3

jotbordeaux
jotbordeaux

Reputation: 1

Try to change your html at the beginning. You should place your "mask" inside the main div. Try something like:

<div class="img-wrap">
 <div class="mask">
  <div class="content">
  </div>
 </div>
</div>

Then you should put hover on img-wrap and change opacity from 0 to 1 on hover :)

In the "content" div just put your text and button.

Upvotes: -1

Related Questions