1

I'm trying to place two images on top of each other, with both of the images horizontally and vertically centered inside their container.

One of the images will be have its opacity animated to reveal the image underneath.

The images are both the same size, but I don't know the size of the images beforehand. I also would like to do this in just pure CSS and HTML.

Here is what I ended up with.

.data-box{
  border: 2px solid #d4d4d4;
  border-radius: 3px;
  display: flex;
  height: 120px;
  margin: 5px;
  margin-bottom: 10px;
  margin-right: 10px;
  padding: 0;
  position: relative;
  width: 120px;
}

.logo {
  align-items: center;
  display: flex;
  justify-content: center;
  margin: auto;
  position: relative;
}

.data-name {
  position: absolute;
  width: 100%;
  height: 23px;
  bottom: 0px;
  right: 0px;
  background: rgba(200, 200, 200, 0.3);
}

span {
  position: absolute;
  width: 100%;
  bottom: 2px;
  text-align: center;
}

img {
  position: absolute;
}
<div class="data-box">
  <div class="logo">
    <img class="grayscale-image" src="https://placeholdit.imgix.net/~text?txtsize=8&txt=65%C3%9765&w=65&h=65" alt="">
    <img class="color-image" src="https://placeholdit.imgix.net/~text?txtsize=8&txt=65%C3%9765&w=65&h=65" alt="">
  </div>
  <div class="data-name"><span>Flickr</span></div>
</div>

I made the images position: absolute so they would leave the normal flow of the browser and render directly on top of each other instead of next to each other.

This works correctly in Chrome, but in Firefox and Safari the image's top left corner is horizontally and vertically centered:

broken firefox and safari behavior

How can I horizontally and vertically center these images while still having them render directly on top of each other?

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
Jamison Dance
  • 19,896
  • 25
  • 97
  • 99

5 Answers5

1

Solution

Add this to your code:

img {
  position: absolute;
  top: 0;
  left: 0;
  transform: translate(-50%, -50%);
}

.data-box {
  border: 2px solid #d4d4d4;
  border-radius: 3px;
  display: flex;
  height: 120px;
  margin: 5px;
  margin-bottom: 10px;
  margin-right: 10px;
  padding: 0;
  position: relative;
  width: 120px;
}
.logo {
  align-items: center;
  display: flex;
  justify-content: center;
  margin: auto;
  position: relative;
}
.data-name {
  position: absolute;
  width: 100%;
  height: 23px;
  bottom: 0px;
  right: 0px;
  background: rgba(200, 200, 200, 0.3);
}
span {
  position: absolute;
  width: 100%;
  bottom: 2px;
  text-align: center;
}
img {
  position: absolute;
  top: 0;
  left: 0;
  transform: translate(-50%, -50%);
}
<div class="data-box">
  <div class="logo">
    <img class="grayscale-image" src="https://placeholdit.imgix.net/~text?txtsize=8&txt=65%C3%9765&w=65&h=65" alt="">
    <img class="color-image" src="https://placeholdit.imgix.net/~text?txtsize=8&txt=65%C3%9765&w=65&h=65" alt="">
  </div>
  <div class="data-name"><span>Flickr</span>
  </div>
</div>

Explanation

Although setting an element to position: absolute removes it from the normal flow, it doesn't actually position it anywhere.

The CSS offset properties (top, bottom, left and right) have an initial value of auto, which keeps an absolutely positioned element where it normally would be if it were in the document flow. As you can see, browser behavior will vary when the offsets aren't defined.

For an explanation of how the code above works, see this post: Element will not stay centered, especially when re-sizing screen

Community
  • 1
  • 1
Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
1

I don't think you need flexbox at all:

.data-box {position:relative; display:inline-block;}
.logo {position:relative;}
.color-image {position:absolute; top:0; left:0; bottom:0; right:0; opacity:0.5;}
.data-name {position:absolute; left:0; right:0; bottom:5px; text-align:center;}
<div class="data-box">
  <div class="logo">
    <img class="grayscale-image" src="https://placeholdit.imgix.net/~text?txtsize=8&txt=65%C3%9765&w=65&h=65" alt="">
    <img class="color-image" src="https://placeholdit.imgix.net/~text?txtsize=8&txt=65%C3%9765&w=65&h=65" alt="">
  </div>
  <div class="data-name"><span>Flickr</span></div>
</div>
andi
  • 6,442
  • 1
  • 18
  • 43
0

Could you set the img in a div, and have the behind image set as the background of the div?

0

It's not the most elegant solution but this works:

img {
  position: absolute;
  transform: translate(-50%, -50%);
}
0

I'll try to get straight to the point. Here's an example that centralizes two images inside a parent.

<html>
<head>
<title>Exemple</title>

<style type="text/css">
 .parent{
  margin: auto auto;
  width: 500px;
  height: 500px;
  border: 3px solid #ccc;
 }

 .child1, .child2{
  width: 50%;
  height: 50%;
  margin: 25%;
  background-color: rgb(226,26,60);
 }

   .child1{
       opacity:0.5;
   }
</style>

</head>

<body>
<div class="parent">
<img class="child1" src="https://placeholdit.imgix.net/~text?txtsize=8&txt=65%C3%9765&w=65&h=65" alt="">
<img class="child2" src="https://placeholdit.imgix.net/~text?txtsize=8&txt=65%C3%9765&w=65&h=65" alt="">
</div>
</body>


</html>

Use margin with percentage to align both images in the middle of the parent div. Here I set the with and height to 50%, which means there's 50% left. That's why you set the margin to 25%, so he puts it in the middle of the parent.

Good luck