2

I'm trying to put text over/on top of an image within a div using flexbox. Have tried various things but they still behave as individual flex items and appear next to each other.

The problem is that whenever there is more than 1 item in a flexbox container that appear next to each other and I have not found a way to get the on top of and centered over the image.

In addition to the below I have tried to remove flexbox properties from .inner and am surprise the items inside of .inner still behave as flex items.

header {
  text-align: center;
}

.outer {
  display: flex;
  justify-content: space-around;
  align-items: center;
}

.inner {
  display: flex;
  justify-content: center;
  align-items: center;
}

.inner-item {
  position: absolute;
  align-self: center;
}

.inner-img {
  max-width: 100px;
}

footer {
  text-align: center;
  margin-top: 60px;
}
<header>
  <h1>Header</h1>
</header>
<div class="outer">
  <div class="inner">
    <img class="inner-item inner-img" src="http://klequis.com/so/green.circle.svg" />
    <span class="inner-item">Item Text</span>
  </div>
  <div class="inner">
    <img class="inner-item inner-img" src="http://klequis.com/so/green.circle.svg" />
    <span class="inner-item">Item Text</span>
  </div>
  <div class="inner">
    <img class="inner-item inner-img" src="http://klequis.com/so/green.circle.svg" />
    <span class="inner-item">Item Text</span>
  </div>
</div>
<footer>
  <h1>Footer</h1>
</footer>

link on codepen codepen

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
klequis
  • 427
  • 1
  • 6
  • 17
  • Use `order` too if you want to change which element goes on top https://codepen.io/anon/pen/OpvjyW – DaniP Mar 21 '17 at 20:08
  • https://codepen.io/anon/pen/OpvjNW – Michael Benjamin Mar 21 '17 at 20:08
  • in case you want this https://codepen.io/anon/pen/qroXNe – Aman Mar 21 '17 at 20:11
  • @Michael_B that is one item above the other vertically. I want to have above the other on z axis such that the text is on-top-of the circle img – klequis Mar 21 '17 at 20:14
  • @Aman - that is the idea except that your solution puts the top half of the circles above the top of the page. I edited the my codepen to show this. Added header and footer. You can see the circles overlap the header. Same problem with footer which I fixed with margin but wondering if there isn't a cleaner solution? – klequis Mar 21 '17 at 20:27
  • @klequis you want header on the top? right? – Aman Mar 21 '17 at 20:42
  • @klequis answered your question for footer make it same as header see the code in the answer thanks :) – Aman Mar 21 '17 at 21:00
  • Michael_B & Michael Croker: both your solutions work. I don't see any visible difference on the page. You also both posted at the same time so not sure how that is handled on Stack Overflow. Should I mark both as answer? – klequis Mar 21 '17 at 21:03
  • @klequis, if both answers are useful, you can upvote both.. in terms of acceptance (checkmark), there is a difference in the answers. My answer assumes you want all text on a single line (like in your demo): `white-space: nowrap` .. the other answer assumes you want the text to wrap. – Michael Benjamin Mar 22 '17 at 00:18
  • 1
    I might want wrap once the spec is done so I decided with a coin toss. Thank you both. I have not used transform before so will read up on that. – klequis Mar 22 '17 at 01:26
  • 1
    I explain centering with `transform` here: http://stackoverflow.com/q/36817249/3597276 – Michael Benjamin Mar 22 '17 at 01:42

3 Answers3

2

Set .inner to position: relative then absolutely position the text over the center of the image.

.outer {
  display: flex;
  justify-content: space-around;
  align-items: center;
}

.inner {
  display: flex;
  justify-content: center;
  align-items: center;
  position: relative;
}

.inner-img {
  max-width: 100px;
}

span.inner-item {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  text-align: center;
}
<div class="outer">
  <div class="inner">
    <img class="inner-item inner-img" src="http://klequis.com/so/green.circle.svg" />
    <span class="inner-item">Item Text</span>
  </div>
  <div class="inner">
    <img class="inner-item inner-img" src="http://klequis.com/so/green.circle.svg" />
    <span class="inner-item">Item Text</span>
  </div>
  <div class="inner">
    <img class="inner-item inner-img" src="http://klequis.com/so/green.circle.svg" />
    <span class="inner-item">Item Text</span>
  </div>
</div>
Michael Coker
  • 52,626
  • 5
  • 64
  • 64
1

.outer {
  display: flex;
  justify-content: space-around;
  align-items: center;
}

.inner {
  display: flex;
  justify-content: center;
  align-items: center;
  position: relative;  /* NEW */
}

.inner-item {
  align-self: center;
}

/* NEW */
.inner-item:last-child {
  white-space: nowrap; /* assuming you want text in one line, like in your demo */
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
}

.inner-img {
  max-width: 100px;
}
<div class="outer">
  <div class="inner">
    <img class="inner-item inner-img" src="http://klequis.com/so/green.circle.svg" />
    <span class="inner-item">Item Text</span>
  </div>
  <div class="inner">
    <img class="inner-item inner-img" src="http://klequis.com/so/green.circle.svg" />
    <span class="inner-item">Item Text</span>
  </div>
  <div class="inner">
    <img class="inner-item inner-img" src="http://klequis.com/so/green.circle.svg" />
    <span class="inner-item">Item Text</span>
  </div>
</div>
Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
0

Since i have answered your first question in comment. for the second question you asked in the comment is right never ever use margin it is really bad. I have modified some code to make it better

.header {
  text-align: center;
  min-height:100px;
}

.outer {
  display: flex;
  justify-content: space-around;
  align-items: center;
}

.inner {
  display: flex;
  justify-content: center;
  align-items: center;
}

.inner-item {
  position: absolute;
  align-self: center;

}

.inner-img {
  max-width: 100px;
}

footer {
  text-align: center;
  margin-top: 60px;
}
<div class="header">
<header>
  <h1>Header</h1>
</header>
  </div>
<div class="outer">
      <div class="inner">
        <img class="inner-item inner-img" src="http://klequis.com/so/green.circle.svg" />
        <span  class="inner-item">Item Text</span>
      </div>
      <div class="inner">
        <img class="inner-item inner-img" src="http://klequis.com/so/green.circle.svg" />
        <span  class="inner-item">Item Text</span>
      </div>
      <div class="inner">
        <img class="inner-item inner-img" src="http://klequis.com/so/green.circle.svg" />
        <span  class="inner-item">Item Text</span>
      </div>
    </div>
<footer>
  <h1>Footer</h1>
</footer>
Aman
  • 806
  • 2
  • 12
  • 38