CSS - Vertical align text in absolute positioned paragraph

13,854

Solution 1

Get rid of the p tag. You already have it in a li anyway.

css

li {
position: relative;
float: left;
overflow: hidden;
}

img {
width: 100%;
height: 100%;
}

span {
background-color: rgba(0, 255, 0, .3);
position: absolute;
text-align:center;
width: 100%;
top:46%;
}

html

<ul>
<li><span>Lorem Ipsum</span><img src="http://www.placehold.it/300x200" /></li>
</ul>

Tested on window IE9 and Chrome.

Don't know if it was for the demo or not but if you want the red shade over the image make a class for a span tag then insert a new span with the class.

span.text {
background-color: rgba(0, 255, 0, .3);
position: absolute;
text-align:center;
width: 100%;
top:46%;
}

span.redshade {
background-color: rgba(255, 0, 0, .3);
width: 100%;
height: 100%;

<ul>
<li><span class="redshade">&nbsp;</span><span class="text">Lorem Ipsum</span><img src="http://www.placehold.it/300x200" /></li>
</ul>

Solution 2

Without hard-coding an assumed height for the text or image, I (unfortunately) can't solve this in less than 3 layers:

  1. Establish absolute positioning
  2. Establish table layout
  3. Establish table-cell layout and vertical-align: middle

Combining 1 and 2 seems to prevent height: 100% from working for reasons unknown to me. I think the rejection of table-cell layout seems to be a misappropriation of the old "don't use tables for layouts" meme; CSS is for layout so this is not misusing the element semantics. (Although unfortunately it requires semantically meaningless divs.)

<ul>
<li>
    <img src="http://www.placehold.it/300x200" />
    <div class="absolute">
        <div class="table">
            <div class="middle">
                <p><span>Lorem Ipsum</span>
                </p>
            </div>
        </div>
    </div>
</li>
</ul>


li {
    position: relative;
    float: left;
    overflow: hidden;
}
img {
    width: 100%;
}
.absolute, .table, .middle {
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
}
.absolute {
    position: absolute;
}
.table {
    display: table;
}
.middle {
    display: table-cell;
    vertical-align: middle;
}
p {
    background-color: rgba(255, 0, 0, .3);
}
span {
    background-color: rgba(0, 255, 0, .3);
}

http://jsfiddle.net/svachalek/vTGxx/4/

Share:
13,854
Sven
Author by

Sven

Updated on June 25, 2022

Comments

  • Sven
    Sven about 2 years

    Before we start:
    Please don't close this as a duplicate of another question. I just searched here on Stackoverflow without finding that exact case.

    The closest is I believe this question. Still, the replies given there don't really work for me, I believe because the paragraph is set position: absolute;.

    Thats the HTML:

    <ul>
        <li><img src="http://www.placehold.it/300x200" /><p><span>Lorem Ipsum</span></p></li>
    </ul>
    

    And the CSS:

    li {
      position: relative;
      float: left;
      overflow: hidden;
    }
    
    img {
      width: 100%;
      vertical-align: middle;
    }
    
    p {
      background-color: rgba(255, 0, 0, .3);
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
    }
    
    span {
        background-color: rgba(0, 255, 0, .3);
        vertical-align: middle;
    }
    

    Fiddle: http://jsfiddle.net/DpVjZ/

    vertical-align: middle; just bumps the text a tiny bit away from the top, but not really in the middle.
    Setting the span position: absolute; and then applying top: 50%; and then margin-top: -x%; won't work because the height of the span is not known as it is dynamic content.
    Although the linked question states that this is bad practice, I also tried the display: table-cell approach without any result. Please help me.

  • Sven
    Sven over 11 years
    Thanks! I like the way your solution delivers a great result and is easy to understand, too.
  • svachalek
    svachalek over 11 years
    The top: 46% is hard-coding a guess about the height of the span; it is not centered for an arbitrary span.
  • 1934286
    1934286 over 11 years
    @svachalek Yes, it is a one-line-of-text solution. Multi-line solutions are much more complicated. It is centered for an arbitrary image size. It will also work were the span and image are known.
  • 1934286
    1934286 over 11 years
    @Sven Thanks for the selection.
  • 1934286
    1934286 over 11 years
    +1 This is a bit complicated but does account for unknown widths and heights. I edited your post to text-align:center the p tag and updated the fiddle and cleaned up the code.