Search code examples
htmlcssimageresponsive-designvertical-alignment

Responsive image sizing with vertically centered text in List items


My goal is to have 3 images side by side that have vertically and horizontally centered text inside, and have the images Responsive

From my understanding, when vertically centering something in a parent element, the parent element is supposed to be absolute, and the child is supposed to be relative and translated -50% after doing top: 50%.

I have a codepen here: http://codepen.io/anon/pen/ozyJBP

but something seems to be wrong. When I comment out the position: relative and then uncomment it, it never reverts back to the way it was.

I'm trying to keep the aspect ratio of the images, but now I can't even figure out why the text won't vertically center. My real code more closely resembles the bottom UL.

HTML:

<ul>
    <li><p>On Sale</p><img src="http://placehold.it/300x180"/></li>
    <li><a href="#"><p>Special Offers</p><img src="http://placehold.it/300x180"/></a></li>
    <li><a href="#"><p>Must Have</p><img src="http://placehold.it/300x180"/></a></li>
</ul>

<br><br><br><br><br>


        <ul id="offersList">
            <li id="onSaleBG">
                <div class="offers">On Sale</div>
            </li>
            <li id="specialOffersBG">
                <div class="offers">Special Offers</div>
            </li>
            <li id="mustHaveBG">
                <div class="offers">Must Have</div>
            </li>
        </ul>

CSS:

li {
    display: inline-block;
    position: relative;
}

ul li p {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translateY(-50%);
    transform: translateX(-50%);
    background: #2f3134;
    padding: 20px 25px;
    display: inline-block;
    color: white;
}



#onSaleBG {
    background: url(http://placehold.it/300x180) no-repeat;
}

#specialOffersBG {
    background: url(http://placehold.it/300x180) no-repeat;
}

#mustHaveBG {
    background: url(http://placehold.it/300x180) no-repeat;
}

.offers {
    background: #2f3134;
    padding: 20px 25px;
    display: inline-block;
    position: relative;
    top: 50%;
    transform: translateY(-50%);
}

#offersList li {
    height: 180px;
    width: 300px;
    color: white;
    position: relative;
}

Solution

  • The main problem is your translate setting: To use it both for the x and y axis, you have to write it like this (inside ul li p), otherwise the second translate will overwrite the first one:

      transform: translate(-50%, -50%);
    

    Also, you have to add margin: 0 to this rule to reset the default margins. So the complete rule is:

    ul li p {
      position: absolute;
      left: 50%;
      top: 50%;
      transform: translate(-50%, -50%);
      display: inline-block;
      margin: 0;
      padding: 20px 25px;
      background: #2f3134;
      color: white;
    }
    

    Codepen with this solution: http://codepen.io/anon/pen/vXAbVy